GNU ddrescue نے 100.00% دکھایا۔ میری پہلی منظم فائل ریکوری پاس کا نتیجہ 0 useful recovered user files تھا۔
یہ دونوں نتائج اسی 4 TB ہارڈ ڈرائیو کی خرابی سے آئے تھے، اور یہی تضاد اس ریکوری کو “خراب ڈسک کو کلون کرو اور فائلیں کاپی کر لو” سے کہیں زیادہ دلچسپ بنا گیا۔ ddrescue نے اپنا کام غیر معمولی طور پر اچھی طرح کیا تھا: اس نے فزیکل سورس کا تقریباً 99.999654% کاپی کر لیا تھا۔ کلون صحت مند ہارڈویئر پر تھا۔ پھر بھی APFS خراب تھا، macOS مجھے معمول کے طریقے سے فائل سسٹم فراہم نہیں کر رہا تھا، اور پہلا APFS ریکوری اسٹیک ڈائریکٹری ٹری کے بڑے حصے گنوا سکتا تھا مگر عام فائلوں کا مواد پڑھنے میں ناکام ہو رہا تھا۔
آخرکار میں نے وہ تمام منتخب اور فہرست میں موجود فولڈر ٹری کامیابی سے ریکور کر لیے جن کی مجھے ضرورت تھی، مگر یہ تب ممکن ہوا جب میں نے اس واقعے کو تین الگ مسائل سمجھا: فزیکل بلاک ریکوری، خراب فائل سسٹم کی تشریح، اور تصدیق و دوبارہ شروع کرنے کی سہولت کے ساتھ بڑے پیمانے پر فائل اخراج۔
سب سے پہلے یہ مسئلہ صرف فائل سسٹم کا مسئلہ نہیں رہا تھا
اصل 4 TB Toshiba اس حالت تک پہنچ چکی تھی جہاں میں معمول کی فائل سسٹم سرگرمی کے لیے اس پر مزید بھروسا نہیں کرتا تھا۔ کچھ ریڈز میں 60–75 سیکنڈ لگتے تھے۔ آپریشنز رک سکتے تھے۔ ڈرائیو کبھی کبھار macOS سے غائب ہو جاتی، واضح کلک کی آواز کرتی اور بعض اوقات بند بھی ہو جاتی تھی۔
خرابی سے کچھ ہی پہلے میں نے تقریباً 300 GB اضافی ڈیٹا لکھا تھا اور تقریباً 500,000 فائلوں اور ڈائریکٹریوں کو متاثر کرنے والی بڑے پیمانے کی رینیم کارروائی کی تھی۔ وقت کی مطابقت نے اس میٹا ڈیٹا پر بھاری کام کو مشکوک بنایا، لیکن میں یہ ثابت نہیں کر سکتا کہ اسی نے ہارڈویئر خرابی پیدا کی۔ ممکن ہے اس نے پہلے سے غیر صحت مند ڈرائیو پر اتنا دباؤ ڈالا ہو کہ مسئلہ ظاہر ہو گیا۔
میں جس چیز کو قائم کر سکا، وہ ڈرائیو کا رویہ تھا۔ جب مکینیکل اسٹوریج رک رک کر چلے، غائب ہو اور کلک کرے تو بار بار ڈائریکٹریاں براؤز کرنا غلط تجرید ہے۔ ڈائریکٹری ٹریورسل مزید ریڈز اور سیکس شروع کر سکتی ہے۔ فائل سسٹم ماؤنٹ کرنا میٹا ڈیٹا کا کام شروع کر سکتا ہے۔ ہر تجربہ اسی واحد جزو کا وقت استعمال کرتا ہے جس کی باقی مفید عمر نامعلوم ہے۔
اس لیے میں نے مقصد:
recover my files
سے بدل کر یہ کر دیا:
recover as many readable sectors as possible
میں نے مستقل mapfile کے ساتھ GNU ddrescue 1.30 استعمال کیا۔ سورس ڈرائیو کا عین فزیکل سائز تھا:
4,000,787,027,968 bytes
mapfile ضروری تھا کیونکہ سورس اتنا مستحکم نہیں تھا کہ ایک ہی بار میں کاپی مکمل ہو سکے۔ اس نے رکاوٹیں، منقطع ہونے، دوبارہ آغاز اور بعد کے پاسز کے باوجود ریکوری کو جاری رکھا، بغیر یہ بھولے کہ کون سے حصے پہلے ہی ریکور ہو چکے تھے۔
خام macOS ڈیوائس پاتھ کے ساتھ ایک عملی مسئلہ بھی سامنے آیا: ظاہری ریکوری ایکسٹینٹ حقیقی ڈیوائس حد پر ختم ہونے کے بجائے غیر معقول ہو سکتی تھی۔ اس لیے میں نے ریکوری ڈومین کو اوپر دیے گئے معلوم فزیکل سائز تک محدود کیا۔ اس صورت میں ان پٹ کو واضح حد دینا درستگی کا اقدام تھا، رفتار بہتری نہیں۔
ddrescue میں 100.00% دکھنے کا مطلب یہ کیوں نہیں تھا کہ فائلیں محفوظ تھیں
فزیکل ریکوری کے اختتام کے قریب ddrescue نے تقریباً یہ رپورٹ کیا:
domain size: 4000 GB
rescued: 4000 GB
non-tried: 13481 kB
non-trimmed: 327680 B
non-scraped: 0 B
bad-sector: 27136 B
نمایاں فیصد تھا:
100.00%
لیکن حل نہ ہونے والی حالتوں کا مجموعہ اب بھی تھا:
13,835,816 bytes
یا تقریباً:
13.84 MB
4,000,787,027,968-بائٹ سورس کے مقابلے میں ریکور شدہ حصہ تقریباً تھا:
99.999654%
بلاک ریکوری کے لحاظ سے یہ بہترین نتیجہ ہے۔ یہ فائل سالمیت کا نتیجہ نہیں ہے۔
غائب بائٹس کی جگہ ان کی مجموعی مقدار سے زیادہ اہم ہے۔ غیر استعمال شدہ جگہ سے چند میگابائٹس غائب ہوں تو ممکن ہے نظر آنے والی کسی چیز پر اثر نہ پڑے۔ کسی ویڈیو کے اندر ایک چھوٹا ناقابلِ مطالعہ حصہ ایک فائل خراب کر سکتا ہے۔ فائل سسٹم میٹا ڈیٹا میں اس سے بھی چھوٹا نقصان بہت سے ورنہ سالم ڈیٹا ایکسٹینٹس کا مقام تلاش کرنا مشکل بنا سکتا ہے۔
باقی ریکوری کے لیے یہی میرا مرکزی ذہنی ماڈل بن گیا:
| سطح | یہ کس سوال کا جواب دیتی ہے | کامیابی کیا ثابت نہیں کرتی |
|---|---|---|
| بلاک ریکوری | کیا فزیکل سیکٹرز کاپی ہوئے؟ | یہ نہیں کہ APFS ہر فائل دوبارہ بنا سکتا ہے |
| فائل سسٹم ریکوری | کیا پاتھس، میٹا ڈیٹا اور ایکسٹینٹس حل کیے جا سکتے ہیں؟ | یہ نہیں کہ ہر ایکسٹریکٹ شدہ بائٹ درست ہے |
| فائل تصدیق | کیا فائل متوقع سائز یا ہیش کے ساتھ پہنچی؟ | یہ نہیں کہ کوئی ناقابلِ دریافت فائل کبھی موجود ہی نہیں تھی |
میں نے باقی ناقابلِ مطالعہ حصوں پر چند آخری کوششیں کیں۔ آخرکار انہوں نے کوئی مفید نئی ریڈ دینا بند کر دیا، جبکہ Toshiba زور سے کلک کر رہی تھی۔ اسی مقام پر میں نے اصل ڈرائیو کو فعال ریکوری سورس کے طور پر استعمال کرنا چھوڑ دیا۔
ایک 4 TB ڈسک ریکور کرنے کے لیے میں نے دو 5 TB ڈرائیوز کیوں خریدیں
پہلی نئی ڈرائیو 5 TB Seagate Expansion تھی، جس کی عین فزیکل گنجائش تھی:
5,000,981,077,504 bytes
میں نے اس پر Toshiba کا بلاک لیول کلون لکھا۔ سورس لے آؤٹ نے تقریباً پہلے 4 TB گھیرے، جس سے کاپی شدہ لے آؤٹ کے بعد تقریباً 1 TB باقی رہا۔ میں نے جان بوجھ کر اس اضافی گنجائش کو نہیں چھیڑا۔
میں نے APFS کنٹینر بڑا نہیں کیا۔ سہولت کے لیے کلون کو دوبارہ پارٹیشن نہیں کیا۔ اس پر فائل سسٹم مرمت نہیں چلایا۔ وہ ڈسک ماسٹر کلون بن گئی۔
پھر میں نے دوسری 5 TB ڈرائیو خریدی۔ اسے تازہ فارمیٹ کیا گیا، وہ رائٹ ایبل تھی، الگ سے ٹیسٹ کی گئی تھی اور صرف ریکور شدہ آؤٹ پٹ کے لیے استعمال ہوئی۔
failing 4 TB HDD
│
│ GNU ddrescue
▼
5 TB drive #1
master block-level clone
READ-ONLY
│
│ APFS parsing and extraction
▼
5 TB drive #2
recovered files
WRITABLE
اس کا مطلب تقریباً 3.26 TB استعمال شدہ ڈیٹا والے والیوم کو ریکور کرنے کے لیے نامی طور پر تقریباً 10 TB نیا اسٹوریج خریدنا تھا۔ اضافی ڈسک گنجائش کے لیے نہیں تھی۔ مقصد ایک مستقل اصول محفوظ رکھنا تھا:
If an experiment is wrong, I can return to the same untouched master clone.
ماسٹر پر مرمت، ری سائز، ری پارٹیشن کرنا یا ریکور شدہ آؤٹ پٹ لکھنا تحفظ کو تجربات کے ساتھ ملا دیتا۔ سورس اور منزل کو الگ فزیکل ڈرائیوز پر رکھنے سے غلطیوں سے واپس آنا ممکن رہا۔
منزل پر بھروسا کرنے سے پہلے میں نے تقریباً 10 GB کا رائٹ/ریڈ ٹیسٹ چلایا۔ اس ٹیسٹ میں اس نے دونوں سمتوں میں تقریباً 144.4 MB/s برقرار رکھا۔ ماسٹر کلون سے نمونہ خام ریڈز تقریباً 28–49 MB/s تھیں اور ان جانچوں کے دوران اصل ڈرائیو کا فزیکل I/O ناکامی پیٹرن دوبارہ ظاہر نہیں ہوا۔
اس مقام پر مسئلہ بدل چکا تھا۔ میں اب خراب ہوتے ہارڈویئر کو ڈی بگ نہیں کر رہا تھا۔ میں خراب APFS میٹا ڈیٹا کو ایسے ہارڈویئر پر ڈی بگ کر رہا تھا جو میرے ٹیسٹس میں معمول کے مطابق برتاؤ کر رہا تھا۔
APFS کلون بطور ڈیوائس قابلِ مطالعہ تھا، مگر بطور فائل سسٹم نامعتبر تھا
کلون شدہ APFS فزیکل اسٹور تھا:
4,000,650,887,168 bytes
متعلقہ پارٹیشن اس سیکٹر سے شروع ہوا:
264192
512-بائٹ سیکٹرز کے ساتھ بائٹ آفسیٹ بنتا ہے:
135,266,304 bytes
APFS والیوم نے تقریباً یہ مقدار استعمال شدہ بتائی:
3,260,976,717,824 bytes
۔
ایک ریڈ اونلی APFS جانچ آخرکار fsroot ٹری تک پہنچا اور یہ رپورٹ کیا:
Checking fsroot tree.
error: (oid 0xe36cb) apfs_root:
btn: dev_read_finish(3828538, 1): Input/output error
fsroot tree is invalid.
یہ وہ مقام تھا جہاں “ddrescue نے تقریباً پوری ڈسک کاپی کر لی” مکمل تشخیص کے طور پر مفید نہیں رہا۔ خام کلون موجود تھا۔ اس کے اندر فائل سسٹم ساخت اب بھی غیر ہم آہنگ تھا۔
میں نے جان بوجھ کر فائل سسٹم جانچ کو بغیر تبدیلی رکھا۔ اپنے واحد اعلیٰ معیار کے ماسٹر کلون پر fsck_apfs -n کو مرمت آپریشن میں تبدیل نہیں کیا۔ عام اسٹوریج پر مرمت مناسب ہو سکتا ہے، مگر یہاں اس سے وہ ثبوت بدل جاتا جسے میں اب بھی سمجھنے کی کوشش کر رہا تھا۔
The Sleuth Kit APFS نیم اسپیس کی فہرست بنا سکتا تھا مگر فائل مواد پر ناکام ہوتا تھا
The Sleuth Kit 4.15.0 پہلا ریکوری اسٹیک تھا جس نے کلون کو امید افزا بنایا۔ پورا کلون شدہ ڈیوائس، معلوم پارٹیشن آفسیٹ اور میرے شناخت کیے ہوئے APFS سپر بلاک کو استعمال کرتے ہوئے میں fls سے حقیقی ڈائریکٹری نام گنوا سکتا تھا:
fls \\
-o 264192 \\
-B 4594668 \\
-p \\
/dev/rdiskN
میں جان بوجھ کر N استعمال کرتا ہوں۔ دوبارہ کنکشن اور ری بوٹس کے ساتھ macOS ڈسک نمبرز بدلتے تھے، اس لیے میں نے کسی پچھلی /dev/disk6 تخصیص کو شناخت نہیں سمجھا۔
fls نیم اسپیس کے بڑے حصوں میں ٹریورس کر سکتا تھا۔ صرف ایک بڑے ٹری نے تقریباً 8,900 ڈائریکٹریاں دکھائیں۔ ایک لمحے کے لیے لگا کہ مشکل حصہ حل ہو گیا ہے۔
پھر میں نے فائل کا مواد حاصل کرنے کی کوشش کی۔
ایک نمائندہ ناکامی یہ تھا:
libc++abi: terminating due to uncaught exception
of type std::runtime_error:
could not read APFSBlock
tsk_recover اخراج شروع کر کے بعد میں کسی APFS بلاک پر ناکام ہو سکتا تھا۔ الگ الگ icat کوششوں میں بھی اسی نوعیت کا مسئلہ آیا۔
اہم فرق یہ تھا:
directory traversal works
اس سے یہ لازم نہیں آتا تھا:
file content retrieval works
کسی پارسر کے پاس پاتھ نیم تلاش کرنے کے لیے کافی باقی بچا میٹا ڈیٹا ہو سکتا ہے، لیکن بعد میں بائٹ اسٹریم واپس کرنے کے لیے درکار فائل آبجیکٹ، ایکسٹینٹ میٹا ڈیٹا یا مواد بلاکس حل کرتے وقت وہ ناکام ہو سکتا ہے۔
میں نے پہلے بڑے پیمانے کی ریکوری انجن کو خرابی برداشت کرنے والا بنایا، مگر اس نقصان کے لیے پارسر پھر بھی درست نہیں تھا
پارسر فوراً بدلنے کے بجائے میرا پہلا ردعمل TSK اخراج کو زیادہ زیادہ برداشت پذیر بنانا تھا۔
میں نے fls اور icat کے گرد Python ریکوری ریپر بنایا۔ یہ SQLite میں پائیدار حالت رکھتا، ناکامیاں لاگ کرتا، دوبارہ شروع کی حمایت کرتا، جزوی آؤٹ پٹ الگ لکھتا اور پہلے پاس میں کم اہم macOS دیکھ بھال ڈیٹا کی ترجیح گھٹا دیتا تھا۔
میں نے “ہاٹ اسپاٹ” قاعدہ بھی شامل کیا: اگر ایک ڈائریکٹری میں مسلسل چار فائلیں اسی صفر-بائٹ APFSBlock پیٹرن کے ساتھ ناکام ہوتیں تو اسکرپٹ اس برانچ کے باقی حصے پر وقت لگانا بند کر دیتا، اسے مؤخر کرتا اور کہیں اور آگے بڑھ جاتا۔ عملی مفروضہ یہ تھا کہ ایک جیسے ناکامیاں کا گروہ شاید سینکڑوں الگ الگ تباہ شدہ پے لوڈز کے بجائے ایک خراب میٹا ڈیٹا انحصار مشترک کرتا ہو۔
آرکسٹریشن مفید تھی۔ بنیادی APFS ریڈر نہیں۔
ایک محفوظ کیے گئے مقام پر ریکوری ڈیٹابیس میں یہ تھا:
DEFERRED_HOTSPOT: 30,356 files
FAILED: 486 files
486 ناکامیاں کی تقسیم یہ تھی:
409 APFSBlock crashes
75 rc=0 but output-size mismatch
2 other rc=1 failures
اور منظم پاس نے پیدا کیا تھا:
0 useful recovered user files
75 سائز عدم مطابقتیں نے میرے اپنے ریپر کا بگ ظاہر کیا: کچھ سسٹم میٹا ڈیٹا فائلیں نے ڈیٹا واپس کیا تھا، مگر میرے پارسر نے متوقع سائز صفر ریکارڈ کیا تھا۔ اس تشریح کو درست کرنا اہم تھا، لیکن غالب نتیجہ نہیں بدلا۔ عام صارف فائلیں اب بھی could not read APFSBlock کے ساتھ صفر بائٹس پر ختم ہو رہی تھیں۔
میں نے ایک چھوٹی AVIF فائل کو قابلِ تکرار ٹیسٹ کیس کے طور پر منتخب کیا۔ TSK اس کا متوقع سائز جانتا تھا:
expected size: 56,309 bytes
recovered: 0 bytes
وہ فائل ایک اور کئی گھنٹے کے بڑے پیمانے کی پاس سے کہیں زیادہ قیمتی ہو گئی۔ اگر کوئی نیا طریقہ ایک 56 KB ٹیسٹ فائل بھی ریکور نہیں کر سکتا جو مسلسل ناکام ہوتی تھی، تو اسے باقی ٹیرابائٹس تک رسائی دینا مناسب نہیں تھا۔
ڈسک بلاکس اور APFS میٹا ڈیٹا پاتھ الگ ناکامی ڈومینز تھے
اس مقام تک میرے پاس تین مشاہدات تھے:
GNU ddrescue:
almost the entire physical source was copied
TSK fls:
many real paths were discoverable
TSK icat:
many ordinary file contents still failed
تلاش سلسلہ کو تصوراتی طور پر الگ کرنے پر یہ مشاہدات ایک دوسرے کے مطابق ہو جاتے ہیں:
pathname
↓
directory record
↓
file object / inode metadata
↓
extent mapping
↓
physical data blocks
نیچے کے قریب ڈیٹا بلاکس محفوظ رہ سکتے ہیں جبکہ میٹا ڈیٹا سلسلہ میں اوپر کا کوئی رابطہ خراب ہو۔ ایک اور امکان یہ ہے کہ دو APFS امپلیمینٹیشنز اسی خراب ساخت میں مختلف طریقے سے ٹریورس کریں۔
میں کوئی ایک خراب APFS آبجیکٹ الگ نہیں کر سکا جو ہر ناکامی کی وضاحت کرتا، اس لیے میں اسے تصدیق شدہ بنیادی سبب نہیں کہوں گا۔ ثبوت نے البتہ ایک زیادہ مفید تجربہ کی حمایت کی: کلون شدہ بائٹس کو بدلے بغیر رکھو اور پارسر بدل دو۔
142 APFS چیک پوائنٹس فوری رول بیک کا راستہ نہیں بنے
APFS چیک پوائنٹ ڈسکرپٹر علاقہ کے خام، ریڈ اونلی اسکین میں 142 ممکنہ NXSB چیک پوائنٹ سپر بلاکس ملے، جن کے ٹرانزیکشن شناختی نمبرز کی حد یہاں سے شروع ہوئی:
223133
اور یہاں تک گئی:
222992
واضح سوال یہ تھا کہ کیا کوئی پرانا چیک پوائنٹ زیادہ صحت مند میٹا ڈیٹا ٹری کو حوالہ کرتا تھا۔
میں نے apfs-fuse بلڈ کیا اور fuse-t کے ذریعے مختلف چیک پوائنٹ ٹرانزیکشن شناختی نمبرز آزمائے۔ جدید ترین چیک پوائنٹ رک گیا۔ پرانے XIDs کے ساتھ بھی یہی ہوا۔ میں نے ہر چیک پوائنٹ کے لیے سخت ٹائم آؤٹ شامل کیا، اور مسلسل 50 سے زیادہ کوششیں کوئی قابلِ استعمال ماؤنٹ پیدا نہ کر سکیں۔ میں نے NFS اور SMB دونوں fuse-t بیک اینڈز بھی آزمائے۔
اس سے یہ ثابت نہیں ہوا کہ تمام چیک پوائنٹس خراب تھے۔ تجربہ کا انحصار چیک پوائنٹ، apfs-fuse، fuse-t، macOS ڈیوائس رویہ اور ماؤنٹ بیک اینڈ پر تھا۔ اس اسٹیک میں کہیں بھی ناکامی وہی نظر آنے والا نتیجہ پیدا کر سکتا تھا۔
بعد کے ایک پارسر نے صفر APFS سنیپ شاٹس رپورٹ کیے، جس سے ایک فرق مزید واضح ہوا جسے مجھے درست رکھنا تھا: وہ چیک پوائنٹ ٹرانزیکشن حالتیں صارف-نظر آنے والا APFS سنیپ شاٹس جیسی چیز نہیں تھیں۔
جو پارسر --help پر رک جائے، وہ میری ڈسک تشخیص نہیں کر سکتا
میں نے go-apfs-v2 بھی بلڈ کیا۔ بلڈ مکمل ہوا، مگر حتیٰ کہ:
apfs --help
بھی رک جاتا تھا اور ٹائم آؤٹ کے ذریعے اسے ختم کرنا پڑتا تھا۔
خام اور بفرڈ دونوں ڈیوائس پاتھس پر کم سے کم بلاک معائنہ بھی رک گئی۔ میں نے apfsutil کے ساتھ اسی نوعیت کا محدود ٹیسٹ کیا؛ دونوں ڈیوائس شکلیں تقریباً 15 سیکنڈ بعد ٹائم آؤٹ ہو گئے۔
یہ مفید ناکامیاں تھے کیونکہ انہوں نے مجھے غلط نتیجہ اخذ کرنے سے روکا۔ جو ٹول اپنا ہیلپ پاتھ بھی قابلِ اعتماد طور پر مکمل نہ کر سکے، اس کی ناکامی اس بارے میں کمزور ثبوت ہے کہ خراب فائل قابلِ ریکوری ہے یا نہیں۔
میرا اصول بن گیا:
ریکوری ٹول کی ناکامی کو ڈیٹا کے بارے میں ثبوت سمجھنے سے پہلے ریکوری ٹول ہی کی تصدیق کرو۔
macOS کو کلون خودکار طور پر ماؤنٹ کرنے سے روکنے نے ایک اور خطرہ ختم کیا
macOS خود بھی ایک اور بدلتا جزو تھا۔ میں چاہتا تھا کہ صحت مند منزل معمول کے مطابق ماؤنٹ شدہ رہے، مگر اسٹوریج دوبارہ کنیکٹ کرتے وقت Disk Arbitration خراب APFS کلون کو خودکار طور پر ماؤنٹ کرنے کی کوشش نہ کرے۔
آخرکار میں نے یہ محفوظ ترتیب استعمال کی:
- صحت مند ریکوری منزل کو کنیکٹ اور ماؤنٹ کرنا۔
- اس کی والیوم شناخت اور خالی جگہ کی تصدیق کرنا۔
diskarbitrationdکو فریز کرنا۔- تصدیق کرنا کہ کوئی فعال
mount_apfsعمل موجود نہیں۔ - ماسٹر کلون اٹیچ کرنا۔
- معلوم فزیکل سائز اور APFS شناخت سے ماسٹر کو متحرک طور پر شناخت کرنا۔
- تصدیق کرنا کہ ماسٹر ماؤنٹ شدہ نہیں ہے۔
- ریڈ اونلی ریکوری کام کرنا۔
- رکتے وقت حالت محفوظ کرنا، Disk Arbitration دوبارہ شروع کرنا، پھر معمول کے مطابق شٹ ڈاؤن یا ایجیکٹ کرنا۔
Disk Arbitration کو فریز کرنے کے لیے میں نے حقیقت میں یہ کمانڈ استعمال کی:
sudo kill -STOP "$(pgrep -x diskarbitrationd)"
میں نے تصدیق کی کہ عمل حالت میں T موجود ہے، اور آگے بڑھنے سے پہلے غیر متعلق mount_apfs پروسیسز بھی جانچ کیے۔
اہم حفاظتی سبق مخصوص ڈسک نمبر نہیں تھا بلکہ اس کے برعکس تھا: کل کے ڈسک نمبر پر کبھی بھروسا نہ کرو۔ ری بوٹ کے بعد پچھلا /dev/disk6 کسی دوسرے فزیکل ڈیوائس کو اشارہ کر سکتا ہے۔ میں نے APFS UUID اور معلوم فزیکل سائز کو شناخت سمجھا، پھر انہی سے موجودہ ڈیوائس پاتھ اخذ کیا۔
libfsapfs نے وہی فائل ریکور کر لی جسے TSK نے صفر بائٹس کے طور پر واپس کیا تھا
اہم پیش رفت libfsapfs سے آئی، جو ایک مختلف APFS امپلیمینٹیشن ہے۔
میں نے اسے macOS پر سورس سے بلڈ کیا۔ بننے والی fsapfsinfo بائنری نے اپنی شناخت یوں بتائی:
fsapfsinfo 20260923
پھر macOS ڈیوائس انٹرفیس کا ایک اہم فرق سامنے آیا۔
خام کریکٹر-ڈیوائس پارٹیشن:
/dev/rdiskNs2
آفسیٹ 4096 کے قریب invalid-argument ریڈ کے ساتھ جلد ناکام ہو گئی۔
بفرڈ بلاک-ڈیوائس شکل:
/dev/diskNs2
کام کر گئی۔
وہی فزیکل کلون۔ وہی APFS پارٹیشن۔ مختلف macOS ڈیوائس انٹرفیس۔
fsapfsinfo نے کنٹینر کھولا اور ایک والیوم تلاش کیا۔ پھر میں نے عین وہ 56,309-بائٹ فائل آزمائی جسے TSK ایکسٹریکٹ نہیں کر سکا تھا۔
TSK نے یہ دیا تھا:
expected: 56,309
recovered: 0
APFSBlock failure
libfsapfs کے ذریعے فائل انٹری نے یہ دیا:
size: 56,309
MD5: c6f56db33eafc1de0f52a035bc255dc7
RC: 0
یہ پہلا نتیجہ تھا جس نے تشخیص کو واقعی بدل دیا۔ کلون شدہ بائٹس نہیں بدلے تھے۔ ٹیسٹ فائل نہیں بدلی تھی۔ خراب APFS کی مرمت نہیں ہوئی تھی۔
بدلی تھی APFS امپلیمینٹیشن۔
کم از کم اب میں جانتا تھا کہ ایک حقیقی صارف فائل جو TSK کے ذریعے ناقابلِ ریکوری لگ رہی تھی، libfsapfs کے ذریعے اتنی گہرائی تک قابلِ رسائی تھی کہ اس کا پورا مواد پڑھا جا سکے اور ڈائجسٹ نکالا جا سکے۔
ٹیرابائٹس کے لیے libfsapfs پر بھروسا کرنے سے پہلے میں نے ایک معلوم خراب فائل ایکسٹریکٹ کی
ایک کامیاب ڈائجسٹ میرے لیے کئی ٹیرابائٹ ریکوری شروع کرنے کے لیے کافی نہیں تھا۔ مجھے منزل کی ڈسک پر اصل بائٹس چاہیے تھے۔
libfsapfs C API کا اندازہ لگانے کے بجائے میں نے لائبریری سورس دیکھا اور وہ ریڈ پاتھ پیروی کیا جسے fsapfsinfo ڈائجسٹ نکالتے وقت پہلے ہی استعمال کر رہا تھا۔ پھر میں نے اسی ایک معلوم ٹیسٹ فائل کے لیے ایک چھوٹا ریڈ اونلی ایکسٹریکٹر بنایا۔
ایکسٹریکٹر نے عین یہ مقدار لکھی:
56,309 bytes
الگ ریکوری ڈسک پر۔ ایکسٹریکٹ شدہ فائل کا MD5 تھا:
c6f56db33eafc1de0f52a035bc255dc7
یہ پچھلے ڈائجسٹ سے مطابق کرتا تھا۔
تب ہی میں نے طریقے کو بڑے پیمانے پر استعمال کیا۔ ایک فائل کے ٹیسٹ نے تین الگ چیزیں ثابت کی تھیں: پاتھ نیم حل ہو سکتا تھا، مکمل متوقع بائٹ تعداد ایکسٹریکٹ ہو سکتا تھا، اور ایکسٹریکٹ شدہ بائٹس وہی ڈائجسٹ پیدا کرتی تھیں جو پہلے مکمل مواد ریڈ نے دی تھی۔
بڑے پیمانے کی ریکوری کا مسئلہ زیادہ تر خرابی محدود رکھنا اور دوبارہ شروع کا تھا
جب libfsapfs نے وہ فائل ریکور کر لی جو TSK نہیں کر سکا تھا تو مشکل مسئلہ ایک بار پھر بدل گیا۔ مجھے ایسا سسٹم چاہیے تھا جو ایک خراب برانچ، ایک ری بوٹ یا ایک Ctrl+C کی وجہ سے پورے کام کو صفر سے دوبارہ آغاز کیے بغیر بہت بڑے ڈائریکٹری ٹری کو عمل کر سکے۔
اس لیے بڑے پیمانے کی ریکوری پائپ لائن نے چند سخت مستقل اصول استعمال کیے:
- ماسٹر کلون کو ریڈ اونلی کھولا جاتا تھا۔
- ریکور شدہ آؤٹ پٹ صرف دوسری 5 TB ڈسک پر لکھی جاتی تھی۔
- ڈائریکٹری اور فائل نام محفوظ رکھے جاتے تھے۔
- پیش رفت SQLite میں رہتی تھی تاکہ عمل ایگزٹس اور ری بوٹس کے بعد بھی قائم رہے۔
- ہر فائل پہلے عارضی پاتھ پر لکھی جاتی تھی۔
- عارضی فائل کو حتمی پاتھ پر صرف تب رینیم کیا جاتا تھا جب مکمل متوقع سائز لکھ دی جاتی۔
- دوبارہ شروع کے دوران متوقع سائز والی موجودہ فائلیں پہچانی جا سکتی تھیں۔
- ناکام یا مسئلہ زدہ کام مکمل کام سے الگ رکھا جاتا تھا۔
- خالی جگہ جانچ کی جاتی اور حفاظتی ذخیرہ برقرار رکھا جاتا تھا۔
- دوبارہ بنائے جا سکنے والے ڈیولپمنٹ آرٹیفیکٹس اور کم اہم سسٹم میٹا ڈیٹا کو چھوڑ یا کم ترجیح کیا جا سکتا تھا۔
ایک کارکردگی تبدیلی فوراً اہم ثابت ہوئی: میں نے ہر فائل کے لیے APFS کنٹینر الگ سے دوبارہ کھولنا بند کر دیا۔
تیز راستہ ایک وقت میں ایک ڈائریکٹری پر کام کرتا تھا۔ ورکر سورس کھولتا، ڈائریکٹری کی فہرست بناتا، اس کی براہِ راست عام فائلیں ریکور کرتا اور ذیلی ڈائریکٹریاں قطار میں واپس ڈال دیتا۔ اگر کوئی ڈائریکٹری ناکام یا ٹائم آؤٹ ہوتی تو کنٹرولر اسے DEFERRED نشان زد کر کے مجموعی پاس کو روکنے کے بجائے آگے بڑھ جاتا۔
جب کوئی معمول کا زیرِ انتظار کام باقی نہ رہتا تو مؤخر ڈائریکٹریاں کو زیادہ الگ تھلگ فی فائل کام والے سست فال بیک پاتھ سے دوبارہ دیکھا جاتا۔ باقی ناکامیاں کو پھر آزادانہ طور پر دوبارہ کوشش کیا جا سکتا تھا۔
discover directory
↓
recover immediate files
↓
verify expected sizes
↓
commit durable state
↓
queue child directories
↓
defer local failures
↓
continue globally
↓
fallback and retry later
یہ معماری ایک بڑے ریکرسِو کمانڈ کے مقابلے میں حقیقی ناکامی پیٹرن کے کہیں زیادہ مطابق تھا۔ نقصان یکساں نہیں تھا، اس لیے ریکوری سسٹم کی پیش رفت بھی یکساں نہیں ہونی چاہیے تھی۔
میں نے لاکھوں فائلوں کو ہیش کرنے کے بجائے متوقع سائز جانچ اور اٹامک رینیم کیوں استعمال کیے
ایک فائل کے ثبوت کے دوران MD5 مفید تھا کیونکہ مجھے مضبوط ثبوت چاہیے تھا کہ پارسر اس فائل کا مکمل مواد پڑھ رہا ہے جسے TSK نہیں پڑھ سکا تھا۔
صرف لاکھوں فائلیں کو ہیش کرنے کے لیے ہر ریکور شدہ بائٹ کو دوسری بار مکمل پڑھنے سے بہت زیادہ اضافی I/O شامل ہو جاتا۔ مرکزی اخراج پاس کے لیے میں نے ایک مختلف مستقل اصول استعمال کیا۔
ہر معمول کی فائل کے لیے APFS میٹا ڈیٹا متوقع سائز فراہم کرتا تھا۔ ورکر عارضی فائل پر لکھتا اور اسے حتمی پاتھ نیم پر صرف اس وقت حتمی پاتھ پر منتقل کرتا جب مکمل ریڈ اس متوقع سائز سے مطابق کرتی۔
اس کا مطلب یہ ہے کہ تعطل کے بعد کوئی مختصر فائل حتمی نام کے ساتھ مکمل فائل بن کر نہیں رہنی چاہیے۔
سائز کا مل جانا کرپٹوگرافک سالمیت کا ثبوت نہیں ہے۔ میں اسے ایسا نہیں سمجھتا۔ لیکن متوقع سائز کی تصدیق اور اٹامک رینیم مل کر بڑے حجم پاس کے لیے درستگی کی ایک عملی حد تھے، جبکہ نمونے اور معلوم ناکامی کیسز کے لیے ہدفی ہیشز مفید رہے۔
SQLite نے ری بوٹ کو تباہ کن کے بجائے معمولی بنا دیا
ریکوری اتنی دیر چلی کہ مجھے کمپیوٹر بند کر کے بعد میں دوبارہ شروع کرنا پڑا۔ اس ضرورت نے ڈیزائن کو “اسکرپٹ” سے “قابلِ ریکوری ورک فلو” میں بدل دیا۔
Ctrl+C فعال ذیلی عمل کو بس چھوڑ نہیں دیتا تھا۔ کنٹرولر تعطل پکڑتا، ورکر روکتا، فعال ڈائریکٹری کو قابلِ ریکوری حالت میں واپس کرتا، SQLite کمیٹ کرتا اور ایگزٹ ہو جاتا۔
صاف انداز میں رکنا تصوراتی طور پر یوں دکھتا تھا:
CURRENT DIRECTORY -> PENDING
CTRL+C: RECOVERY STOPPED SAFELY
STATE SAVED. RUN THE SAME COMMAND TO RESUME.
ری بوٹ کے بعد میں نے ڈسک کی شناخت کی جانچ دوبارہ کیے اور وہی ریکوری کمانڈ شروع کی۔ حالت کا ڈیٹابیس نے موجود قطار ہی سے دوبارہ شروع کیا۔
بعد کا ایک دوبارہ آغاز یوں شروع ہوا:
DEFERRED: 1
DONE: 73,015
PENDING: 7,254
یہ عام پیش رفت بار سے کہیں زیادہ معنی خیز تھا۔ اس نے دکھایا کہ مکمل ہو چکی دسیوں ہزار ڈائریکٹری یونٹس ری بوٹ کے باوجود محفوظ رہی تھیں اور باقی قطار واضح تھی۔
ایک پہلے دوبارہ شروع میں پچھلے سیشن کے دوران متعطل ڈائریکٹری دوبارہ اٹھائی گئی۔ متوقع سائز پر پہلے سے موجود فائلیں پہچان لی گئیں، اور صرف غائب کام لکھنا پڑا۔ میں یہی رویہ چاہتا تھا: ریکوری دوبارہ آغاز کرنا معمول کی بات ہو، خوفناک نہیں۔
326,799 فائلیں اس بات کا پہلا ثبوت تھیں کہ طریقہ اسکیل کر سکتا ہے
نئے ایکسٹریکٹر کو تمام منتخب ڈیٹا پر پھیلانے سے پہلے میں نے ایک بڑے ترجیح ٹری کو بڑے پیمانے کی تصدیق کے ہدف کے طور پر استعمال کیا۔
مکمل حالت نے رپورٹ کیا:
directories completed: 8,940
new files written: 302,541
existing/resumed files: 24,258
recorded failed files: 0
منزل میں یہ تھا:
326,799 files
145,039,215,948 bytes
یا تقریباً:
135.08 GiB
فائلوں کی تعداد عین برابر آ گئی:
302,541 + 24,258 = 326,799
اس مکمل ٹری میں کوئی باقی .partial.* فائل نہیں تھی۔
56,309-بائٹ ٹیسٹ فائل نے ثابت کیا تھا کہ جہاں TSK ناکام ہوا وہاں پارسر کامیاب ہو سکتا ہے۔ 326,799-فائل ریکوری نے ثابت کیا کہ یہی طریقہ دوبارہ شروع منطق، موجود فائلوں کی شناخت اور اس مکمل پاس میں کسی ریکارڈ شدہ فائل ناکامی کے بغیر ایک بڑی حقیقی ڈائریکٹری ساخت سنبھال سکتا ہے۔
بڑی ریکوری مکمل ہونے سے پہلے 1.6 ملین نئی فائلوں سے گزر چکی تھی
ترجیح ٹری صاف طور پر مکمل ہونے کے بعد میں نے ریکوری کو باقی منتخب اوپری سطح ڈیٹا تک پھیلا دیا۔
ایک دانستہ محفوظ توقف پر SQLite نے رپورٹ کیا:
DONE directories: 39,015
PENDING directories: 17,017
DEFERRED directories: 1
new files written: 1,636,305
new bytes written: 902,715,716,335
یہ تقریباً:
840.72 GiB
نیا لکھا گیا ڈیٹا تھا جو اس مقام پر ڈائریکٹری پاسز نے ریکارڈ کیا تھا۔
ایک DEFERRED ڈائریکٹری کا مطلب ڈیٹا کھو جانا نہیں تھا۔ اس کا مطلب تھا کہ تیز راستے نے جان بوجھ کر اس مقامی مسئلہ کو غیر متعلق کام میں تاخیر کرنے دینا بند کر دیا تھا۔ فال بیک مرحلہ خاص طور پر ایسے کیسز کو بعد میں دوبارہ دیکھنے کے لیے موجود تھا۔
بعد کے سیشنز اسی ڈیٹابیس سے دوبارہ شروع ہوئے۔ مکمل شدہ تعداد بڑھی اور زیرِ انتظار قطار کم ہوئی۔ آخرکار میں نے وہ تمام منتخب اور فہرست میں موجود فولڈر ٹریز ریکور کر لیے جن کی مجھے ضرورت تھی۔
آخری ریکوری کے بارے میں میں دیانت داری سے کیا دعویٰ کر سکتا ہوں
میں نتیجے کو “ہر بائٹ ریکور شدہ” نہیں کہوں گا۔ ثبوت اس کی حمایت نہیں کرتا۔
اصل ddrescue میپ میں اب بھی تقریباً 13.84 MB تھا جس کے کامیابی سے کاپی ہونے کی تصدیق نہیں ہوئی تھی۔ میں یہ بھی ثابت نہیں کر سکتا کہ کوئی فائل سسٹم آبجیکٹ مکمل طور پر ناقابلِ دریافت نہیں ہو گیا، کیونکہ اسے گنوانے کے لیے درکار میٹا ڈیٹا خراب علاقے میں ہو سکتا تھا۔
یہ حدود اہم ہیں کیونکہ منظم ریکوری ثابت کر سکتی ہے کہ فہرست میں موجود کوئی آبجیکٹ ایکسٹریکٹ ہوا؛ مگر یہ اس آبجیکٹ کے تاریخی طور پر کبھی موجود نہ ہونے کو ثابت نہیں کر سکتی جسے خراب نیم اسپیس اب ظاہر ہی نہ کر سکے۔
سب سے مضبوط آخری بیان زیادہ محدود ہے:
مجھے درکار ہر منتخب اور فہرست میں موجود فولڈر ٹری منظم ریکوری کے عمل کے ذریعے کامیابی سے ریکور ہو گیا۔
مجھے ماسٹر کلون کو اسی جگہ مرمت کرنے کی ضرورت نہیں پڑی۔ بڑے پیمانے کے اخراج کے لیے اصل کلک کرتی Toshiba کو دوبارہ استعمال نہیں کرنا پڑا۔ پورے ڈسک پر PhotoRec طرز کی کارونگ پاس بھی نہیں کرنا پڑا جو ڈائریکٹری ساخت اور فائل نام قربان کر دیتا۔
ناکام ٹولز بھی مفید ثبوت تھے
پیچھے مڑ کر دیکھیں تو کامیاب راستہ سادہ لگتا ہے:
ddrescue clone
↓
libfsapfs
↓
resumable extractor
↓
recovered files
تحقیق کے دوران یہ اتنا سادہ محسوس نہیں ہوتا تھا، اور ناکام طریقے کو نکال دینا انجینئرنگ سبق کا بڑا حصہ بھی نکال دیتا۔
TSK نے مجھے سکھایا کہ APFS نیم اسپیس ٹریورسل اور مواد حصول الگ ناکامی صورتیں تھے۔
میرے پہلے ریپر بگ نے سکھایا کہ ریکوری اسکرپٹ کی اپنی خرابیوں کی درجہ بندی حتمی حقیقت نہیں ہوتی۔
ہاٹ اسپاٹ طریقۂ کار نے سکھایا کہ مقامی ناکامی کو الگ کیا جائے، اسے مجموعی پیش رفت روکنے نہ دیا جائے۔
چیک پوائنٹ تجربہ نے سکھایا کہ APFS ٹرانزیکشن چیک پوائنٹس کو سنیپ شاٹس کے ساتھ خلط ملط نہ کیا جائے۔
FUSE کی کوششوں نے سکھایا کہ ناکام ماؤنٹ کے لیے فائل سسٹم ڈیٹا کے علاوہ کئی سطحیں بھی ذمہ دار ہو سکتی ہیں۔
--help پر رکنے والے APFS ریڈر نے سکھایا کہ تشخیصات کی تشریح سے پہلے ٹول کی تصدیق کرنا چاہیے۔
/dev/rdiskNs2 بمقابلہ /dev/diskNs2 رویے نے سکھایا کہ بنیادی ڈسک ایک جیسی ہونے کے باوجود آپریٹنگ-سسٹم I/O پاتھ پارسر کا رویہ بدل سکتا ہے۔
اور دو ڈرائیو معماری نے مجھے یہ آزادی دی کہ باقی ہر جگہ غلطیاں کر سکوں جبکہ ماسٹر کلون بدلا نہ جائے۔
وہ ریکوری ورک فلو جو میں دوبارہ استعمال کروں گا
- مکینیکل طور پر خراب ہونے والے اسٹوریج پر معمول کی فائل سسٹم سرگرمی روک دوں گا۔ اگر ریڈز رک رہی ہوں، ڈیوائس غائب ہو یا کلک کرے تو Finder میں گھومنے کے بجائے دوبارہ شروع ہونے کے قابل بلاک لیول کلون کو ترجیح دوں گا۔
- مستقل mapfile اور تصدیق شدہ ریکوری ڈومین کے ساتھ GNU ddrescue استعمال کروں گا۔ mapfile پیش رفت محفوظ رکھتا ہے؛ معلوم سورس سائز ڈیوائس سائز الجھن کو ریکوری کا حصہ بننے سے روکتا ہے۔
- ایک ماسٹر کلون ریڈ اونلی رکھوں گا۔ اسے مرمت، ری سائز یا ری پارٹیشن نہیں کروں گا اور ریکور شدہ فائلوں کے اسٹوریج کے طور پر بھی استعمال نہیں کروں گا۔
- ریکور شدہ فائلیں دوسری فزیکل ڈسک پر لکھوں گا۔ سورس تحفظ اور آؤٹ پٹ اسٹوریج الگ کام ہیں۔
- پہلے کلون شدہ فائل سسٹم کو ریڈ اونلی حالت میں تشخیص کروں گا۔ خراب APFS میٹا ڈیٹا والا صحت مند فزیکل کلون ایک منطقی ریکوری مسئلہ ہے، کلک کرتی سورس ڈسک والا مسئلہ نہیں۔
- پارسر ٹیسٹ کے لیے ایک قابلِ تکرار ناکام فائل منتخب کروں گا۔ ایک 56 KB معلوم خراب فائل نے مجھے متبادل پارسرز کے بارے میں گھنٹوں کے بے سمت بڑے پیمانے کے اخراج سے زیادہ بتایا۔
- پارسر خود تصدیق کروں گا۔ اگر ٹول سورس کو معنی خیز طور پر پڑھنے سے پہلے رک جائے تو اسے ڈیٹا کے ختم ہونے کا ثبوت نہیں سمجھوں گا۔
- یہ فرض نہیں کروں گا کہ ایک APFS امپلیمینٹیشن ہی قابلِ ریکوری ہونے کی تعریف کرتی ہے۔ انہی کلون شدہ بائٹس پر TSK اور
libfsapfsنے بہت مختلف رویہ دکھایا۔ - ڈسکس کو عارضی ڈیوائس نمبرز کے بجائے مستحکم خصوصیات سے شناخت کروں گا۔ فائل سسٹم UUID اور معلوم فزیکل سائز کل کے
/dev/diskNسے زیادہ محفوظ ہیں۔ - طویل اخراج کو ابتدا ہی سے دوبارہ شروع ہونے کے قابل بناؤں گا۔ پائیدار حالت، عارضی فائلیں، اٹامک رینیم، مؤخر کام، محدود دوبارہ کوششیں اور صاف شٹ ڈاؤن ہینڈلنگ اس اسکیل پر درستگی کا حصہ ہیں۔
- تصدیق کی سطحیں الگ رکھوں گا۔ ddrescue فیصد، نظر آنے والا پاتھ نیم، متوقع سائز سے مطابقت اور مواد کا ہیش الگ الگ چیزیں ثابت کرتے ہیں۔
جو عدد اختتامی حد لگ رہا تھا، وہ صرف پہلے مرحلے کا اختتام تھا
پوری ریکوری میں سب سے گمراہ کن عدد اب بھی یہی تھا:
100.00%
یہ “کیا میں نے ڈسک بچا لی؟” کے جواب جیسا لگتا تھا۔
اصل میں یہ ایک کہیں زیادہ محدود سوال کا جواب تھا:
How much of the physical rescue domain did ddrescue successfully copy?
اس نے یہ نہیں بتایا کہ APFS نیم اسپیس دوبارہ بنا سکتا ہے یا نہیں۔ یہ بھی نہیں بتایا کہ ایک پارسر خراب میٹا ڈیٹا میں ٹریورس کر سکتا ہے جسے دوسرا پارسر مسترد کرتا ہے یا نہیں۔ اس نے یہ نہیں بتایا کہ ریکور شدہ فائل کی متوقع لمبائی موجود ہے یا نہیں۔ اور یہ بھی نہیں بتایا کہ کئی ملین فائلوں کا اخراج خرابیوں اور ری بوٹس کے باوجود اپنی حالت کو خراب کیے بغیر چل سکتی ہے یا نہیں۔
ہر سطح کے لیے مجھے الگ ثبوت چاہیے تھا۔
فزیکل ریکوری پہلے کامیاب ہوئی۔ فائل سسٹم اب بھی خراب تھا۔ پہلا پارسر نام دکھا سکتا تھا مگر بہت سی فائلوں کے مواد پر ناکام ہوتا تھا۔ ایک مختلف APFS امپلیمینٹیشن نے وہی ٹیسٹ فائل کامیابی سے پڑھ لی۔ وہ ثبوت ایک فائل کا ایکسٹریکٹر بنا، ایکسٹریکٹر ایک دوبارہ شروع ہونے کے قابل ریکوری انجن بنا، اور انجن نے آخرکار ماسٹر کلون کو بغیر بدلا رکھتے ہوئے میرے مطلوبہ منتخب فولڈر ٹریز دوسری ڈسک پر ریکور کر دیے۔
اصل ہارڈ ڈرائیو کبھی دوبارہ صحت مند نہیں ہوئی۔ APFS نے بھی جادوئی طور پر اپنی مرمت نہیں کی۔ بدلا ریکوری ماڈل تھا۔
بلاک ریکوری، فائل سسٹم ریکوری اور فائل تصدیق الگ انجینئرنگ مراحل ہیں۔ انہیں ایک مسئلہ سمجھنے سے صورتِ حال تقریباً ناامید لگ رہی تھی۔ الگ کرنے سے اسے قابلِ عمل بنایا جا سکا۔