dd ทำงานเลยจุดสิ้นสุดของอุปกรณ์อินพุต
ฉันกำลังพยายามใช้dd
เพื่อโคลนฮาร์ดไดรฟ์ที่ฉันซ่อม ฉันกำลังพยายามdd
คัดลอกข้อมูลออกจากไดรฟ์เป็นชิ้น 10GB แต่กำลังถ่ายโอนข้อมูลมากกว่าที่ไดรฟ์ควรมี ไดรฟ์เองทำหน้าที่และสามารถติดตั้งพาร์ติชันบนไดรฟ์ได้
เมื่อใช้df -h
ฉันได้ขนาดของไดรฟ์เป็น 1,000204886016 ไบต์ (ไดรฟ์ 1TB)
ตอนแรกฉันพยายาม:
sudo dd if=/dev/sdb of=/dev/sdd status=progress
อย่างไรก็ตามสิ่งนี้ทำให้การรวบรวมข้อมูลช้าลงหลังจากประมาณ 300GB และในที่สุดก็ล้มเหลวเนื่องจากข้อผิดพลาดในการอ่าน ฉันตัดสินใจลองคัดลอกเป็นชิ้น 10GB ฉันคำนวณว่าการอ่าน 10GB ด้วยขนาดบล็อก 128kByte ต้องคัดลอก 78125 บล็อก
ในการทำสิ่งนี้ฉันใช้:
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress oflag=seek_bytes seek=n
dd
ได้รับรายงานว่ามีการโอน 10240000000 ไบต์ในแต่ละครั้ง ในการคำนวณค่าการค้นหาสำหรับการวนซ้ำแต่ละครั้งฉันจะรวมไบต์ที่ถ่ายโอนและลบ 1GB เพื่อให้แน่ใจว่ามีการทับซ้อนกัน ลำดับผลลัพธ์คือ:
seek=0
seek=9240000000
seek=18480000000
seek=27720000000
seek=36960000000
...
seek=1071840000000
ฉันเขียนสิ่งเหล่านี้ในเชลล์สคริปต์ด้วยคำสั่ง dd ที่ไม่ต่อเนื่องและเรียกใช้ ฉันปล่อยให้การทำซ้ำครั้งสุดท้ายฟรีเพื่อคัดลอกข้อมูลมากเท่าที่จำเป็น
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress oflag=seek_bytes seek=0
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress oflag=seek_bytes seek=9240000000
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress oflag=seek_bytes seek=18480000000
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress oflag=seek_bytes seek=27720000000
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress oflag=seek_bytes seek=36960000000
...
sudo dd if=/dev/sdb of=/dev/sdd bs=128k status=progress oflag=seek_bytes seek=1071840000000
มันควรจะวิ่งไปไกลจากจุดสิ้นสุดของไดรฟ์โดยการวนซ้ำครั้งสุดท้ายอย่างไรก็ตามมันก็ยังคงดำเนินต่อไป โคลนติดตั้ง แต่ข้อมูลที่เสียหายและขาดหายไปอย่างชัดเจน
- มีสิ่งผิดปกติกับคณิตศาสตร์ของฉันหรือข้อโต้แย้งที่ผมใช้กับ
dd
? - มีวิธีที่ดีกว่าสำหรับฉันในการเขียนคำสั่ง 'dd' เพื่อดึงข้อมูลออกเป็นชิ้น ๆ 10GB หรือไม่
คำตอบ
ปัญหาคือคุณสมมติว่าseek
รับค่าไบต์เมื่อในความเป็นจริงต้องใช้จำนวนบล็อก คุณควรจะใช้seek=0
, 78125
, 156250
ฯลฯ
อย่างไรก็ตามคุณสามารถทำให้มันง่ายขึ้นได้มากโดยการกำจัดdd
:
split -b 10G < /dev/sdd
ฉันพยายามใช้ dd เพื่อโคลนฮาร์ดไดรฟ์ที่ฉันซ่อม
อย่า.
ใช้ddrescueแทนซึ่งทำงานได้ดีกับบล็อกที่อ่านไม่ได้และข้อผิดพลาดของสื่ออื่น ๆ
ฉันค้นพบสาเหตุที่การแก้ปัญหาของฉันล้มเหลวคือความเข้าใจผิดว่าการตั้งค่าสถานะการค้นหาทำอะไร มันเป็นเพียงการเปลี่ยนตำแหน่งการเขียนบนไดรฟ์เอาท์พุท ดังนั้นสคริปต์ก็แค่คัดลอก 10GB แรกซ้ำแล้วซ้ำอีกไปยังเอาต์พุต มันจะไม่ถึงจุดสิ้นสุดของอุปกรณ์
ในการเปลี่ยนอินพุตจำเป็นต้องใช้ค่าสถานะการข้ามด้วย:
sudo dd if=/dev/sdb of=/dev/sdd bs=128k count=78125 status=progress skip=n seek=n
การตั้งค่าoflag=seek_bytes
และiflag=skip_bytes
จะช่วยให้การคำนวณเป็นไบต์เมื่อเทียบกับบล็อก
อย่างไรก็ตามตัวเลือกที่นำเสนอโดยroaima (ใช้ ddrescue) และตัวเลือกอื่น ๆ ( split -b 10G < /dev/sdd
) เป็นวิธีที่ดีกว่าในการกู้คืนไดรฟ์ที่เสียหายและทำการโอนแบบแบ่งกลุ่มตามลำดับ