ฉันจะแปลงอิมเมจดิสก์ Linux เป็นไฟล์แบบกระจายได้อย่างไร


12

ฉันมีดิสก์อิมเมจมากมายที่สร้างด้วย ddrescue บนพาร์ติชัน EXT และฉันต้องการลดขนาดโดยไม่สูญเสียข้อมูลในขณะที่ยังคงสามารถเมานต์ได้

ฉันจะเติมพื้นที่ว่างในระบบไฟล์ของภาพด้วยค่าศูนย์จากนั้นแปลงไฟล์เป็นไฟล์แบบกระจัดกระจายเพื่อให้พื้นที่ว่างนี้ไม่ได้ถูกจัดเก็บจริงบนดิสก์

ตัวอย่างเช่น:

> du -s --si --apparent-size Jimage.image 
120G Jimage.image
> du -s --si Jimage.image 
121G Jimage.image

นี่เป็นเพียงข้อมูลจริง 50G เท่านั้นดังนั้นการวัดครั้งที่สองควรน้อยกว่ามาก

นี้ควรจะเติมเต็มพื้นที่ว่างด้วยศูนย์:

cat /dev/zero > zero.file
rm zero.file

แต่ถ้าไฟล์ sparse ได้รับการจัดการอย่างโปร่งใสมันอาจสร้างไฟล์ sparse โดยไม่ต้องเขียนอะไรไปยังดิสก์เสมือนทำให้ฉันไม่สามารถเปลี่ยนอิมเมจดิสก์เสมือนเป็นไฟล์ sparse ได้ :) ทำมัน?

หมายเหตุ: ด้วยเหตุผลบางอย่างsudo dd if=/dev/zero of=./zero.fileทำงานเมื่อcatไม่ได้อยู่ในดิสก์อิมเมจที่เมาท์


2
การเขียนเลขศูนย์ลงในไฟล์จะไม่สร้างไฟล์กระจัดกระจาย มันเป็นแนวคิดที่แตกต่าง ในขณะที่คุณค้นหา / อ่านไฟล์กระจัดกระจายเมื่อระบบปฏิบัติการค้นพบบล็อกข้อมูลไม่ได้มีอยู่จริง (รายการบล็อกว่างเปล่าสำหรับข้อมูลในภูมิภาคนั้น) มัน (ระบบปฏิบัติการ) อัตโนมัติจะเติมบัฟเฟอร์การอ่านที่มีศูนย์ไบต์อย่างน่าอัศจรรย์
hotei

หมายเหตุ: sudo cat /dev/zero > zero.fileไม่ทำงานเนื่องจากทุบตีของคุณ (ทำงานเหมือนคุณไม่ใช่รูท) ทำการเปลี่ยนเส้นทางก่อนดำเนินการsudoคำสั่ง ดูunix.stackexchange.com/questions/1416/…
Fritz

คำตอบ:


19

ก่อนอื่นไฟล์ที่กระจัดกระจายจะได้รับการจัดการอย่างโปร่งใสเฉพาะในกรณีที่คุณค้นหาไม่ใช่ถ้าคุณเขียนเลขศูนย์

เพื่อให้ชัดเจนยิ่งขึ้นตัวอย่างจาก Wikipedia

dd if=/dev/zero of=sparse-file bs=1k count=0 seek=5120

ไม่ได้เขียนเลขใด ๆ ก็จะเปิดไฟล์ที่ส่งออกแสวงหา (กระโดดข้าม) 5MB แล้วเขียนศูนย์ศูนย์ (ไม่มีอะไรเช่นที่ทั้งหมด) คำสั่งนี้ ( ไม่ใช่จาก Wikipedia)

dd if=/dev/zero of=sparse-file bs=1k count=5120

จะเขียนเลขศูนย์ 5MB และจะไม่สร้างไฟล์กระจัดกระจาย!

ผลที่ตามมาคือไฟล์ที่ไม่ได้กระจัดกระจายอยู่แล้วจะไม่กระจัดกระจายอย่างน่าอัศจรรย์ในภายหลัง

ประการที่สองเพื่อทำให้ไฟล์ที่มีจำนวนมาก zeroes เบาบางคุณต้องCPมัน

cp --sparse=always original sparsefile

หรือคุณสามารถใช้ตัวเลือกของtarหรือrsyncได้เช่นกัน


1
ตามที่ Wikipedia การเขียนเลขศูนย์ด้วย dd จะสร้างไฟล์ที่กระจัดกระจาย คุณช่วยอธิบายว่า "การค้นหา" หมายถึงอะไร?
endolith

1
แล้วแมวล่ะ ไม่มีอะไรใน man page เกี่ยวกับไฟล์ที่กระจัดกระจายดังนั้นฉันจึงคิดว่าcat /dev/zero > zero.fileตกลงได้อย่างสมบูรณ์แบบเพื่อเติมพื้นที่ว่างด้วยศูนย์?
ลุดวิก Weinzierl

2
@endolith: อัปเดตคำตอบของฉันเพื่อให้ชัดเจนว่าอะไรคือความแตกต่างddสำหรับการเขียนเลขศูนย์หรือสำหรับการค้นหา
mihi

2
@Ludwig Weinzierl: ใช่catคำสั่งนั้นจะเติมดิสก์ทั้งหมดของคุณ (หรืออย่างน้อยจำนวนที่ไม่ได้สงวนไว้สำหรับรูทหรือโควต้า) ด้วยศูนย์ "ของจริง" และสร้างไฟล์ที่ไม่มีกระจัดกระจาย
mihi

1
@endolith คุณจะต้องการพื้นที่เพิ่มเติมใช่ แต่เนื่องจากคุณสามารถบีบอัด tarball ได้คุณจะต้องการพื้นที่สำหรับไฟล์ต้นฉบับและไฟล์ sparse เท่านั้น
mihi

12

บางทีวิธีที่ง่ายที่สุดในการแยกไฟล์ในตำแหน่งที่จะใช้fallocateโปรแกรมอรรถประโยชน์ดังต่อไปนี้:

fallocate -v --dig-holes {file_name}

fallocate (1)เป็นผู้ให้บริการutil ลินุกซ์แพคเกจในเดเบียน


1
ด้วยเหตุผลบางอย่างfallocate --dig-holesส่งผลให้ไฟล์ 103GiB จาก 299GiB ดั้งเดิมในขณะที่cp --sparse=alwaysให้ฉัน 93GiB - ทั้งหมดที่มีผลรวม SHA1 เดียวกัน (ขนาดที่ตรวจสอบผ่านdu -B1Gvs du --apparent-size -B1G) ดังนั้นfallocateดูเหมือนว่าจะให้ผลลัพธ์ที่ด้อยกว่า
Ruslan

3

การแก้ไขคำตอบของฉันเพื่อความสมบูรณ์:

  1. บอลลูนพื้นที่ FS ว่างเปล่าด้วยเลขศูนย์ (คำเตือน: สิ่งนี้จะเปลี่ยนอิมเมจดิสก์ของคุณ):

losetup --partscan --find --show disk.img

สมมติว่ามันให้ / dev / loop1 เป็นดิสก์และมีพาร์ติชันเดียวเท่านั้นมิฉะนั้นเราจำเป็นต้องทำซ้ำสำหรับทุกพาร์ติชันที่มี FS ที่สามารถติดตั้งได้ (ละเว้นการสลับพาร์ติชัน ฯลฯ )

mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile

ปล่อยให้มันล้มเหลวด้วย ENOSPC

/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1

  1. คัดลอกลงในรูปภาพที่กระจัดกระจาย:

'dd' มีตัวเลือกในการแปลงไฟล์ด้วยเลขศูนย์เป็นไฟล์ sparse:

dd if=disk.img of=disk-sparse.img conv=sparse



1
ใช่ตัวเลือกนี้ไม่ได้มาจากเวลาที่ OP ถาม นี่เป็นมากกว่า "ทิ้งเศษขนมปังสำหรับผู้ค้นหารายอื่น" ... :-)
Lam Das

1
ขึ้นอยู่กับประเภทของระบบไฟล์zerofreeอาจจะเร็วกว่าการติดตั้งและเขียนเลขศูนย์ไปยังระบบไฟล์และทำให้ดิสก์อิมเมจเติบโตน้อยลงหากมีศูนย์อยู่แล้วจำนวนมาก
mihi

2

คุณหมายถึงภาพที่สร้างขึ้นของคุณคือ 50 GB และในความเป็นจริงแล้วมีบางอย่างที่พอเพียง?

หากเป็นกรณีนี้คุณไม่สามารถสร้างภาพใหม่ด้วย dd ก่อนได้หรือไม่:

dd if=/dev/zero of=some_image.img bs=1M count=20000

จากนั้นสร้างระบบไฟล์ในนั้น:

mkfsofyourchoice some_image.img

จากนั้นเพียงติดตั้งภาพและคัดลอกทุกอย่างจากภาพเก่าไปยังภาพใหม่ มันจะใช้ได้ผลกับคุณเหรอ?


2

PartImageสามารถสร้างดิสก์อิมเมจที่เก็บเฉพาะบล็อกที่ใช้ของระบบไฟล์เท่านั้นดังนั้นจึงลดพื้นที่ที่จำเป็นลงอย่างมากโดยไม่สนใจบล็อกที่ไม่ได้ใช้ ฉันไม่คิดว่าคุณจะสามารถเมานต์รูปภาพที่ปรากฏได้โดยตรง แต่ไปที่:

image -> partimage -> image -> cp --sparse=alway

ควรผลิตสิ่งที่คุณต้องการ (อาจเป็นไปได้ที่จะติดขั้นตอนสุดท้ายยังไม่ได้ลอง)


1
น่าเสียดายที่รูปภาพที่สร้างขึ้นโดย partimage ไม่สามารถติดตั้งได้โดยไม่ขยายออกไปอีกทำให้เหมาะสำหรับการเก็บถาวรเท่านั้น
Perkins

0

ตอนนี้มีเครื่องมือที่เรียกว่าvirt-sparsifyซึ่งจะทำสิ่งนี้ เติมเต็มพื้นที่ว่างด้วยเลขศูนย์แล้วคัดลอกรูปภาพไปยังไฟล์แบบกระจาย แต่ต้องติดตั้งการอ้างอิงจำนวนมาก


-2

ฉันสงสัยว่าคุณจะต้องมีโปรแกรมที่กำหนดเองที่เขียนลงในสเป็กนั้นถ้านั่นเป็นสิ่งที่คุณต้องการทำจริงๆ แต่มันคือ ...

หากคุณมีพื้นที่ทั้งหมดเป็นศูนย์จำนวนมากเครื่องมือการบีบอัดใด ๆ ที่ดีจะทำให้มันแย่ลงอย่างมาก และการพยายามเขียนไฟล์กระจัดกระจายจะไม่ทำงานในทุกกรณี หากฉันจำได้อย่างถูกต้องแม้ไฟล์ที่กระจัดกระจายจะใช้พื้นที่จัดเก็บข้อมูลเอาต์พุตอย่างน้อย 1 บล็อกโดยที่บล็อกอินพุตมีบิตใด ๆ ที่ไม่ใช่ศูนย์ ตัวอย่างเช่น - สมมติว่าคุณมีไฟล์ที่มีค่าเฉลี่ย 1 บิตที่ไม่เป็นศูนย์ต่อบล็อก 512 ไบต์ - มันไม่สามารถเขียนได้ "กระจัดกระจาย" คุณจะไม่สูญเสียข้อมูลถ้าคุณบีบอัดไฟล์ด้วย zip, bzip, bzip2 หรือ p7zip พวกเขาไม่ชอบการบีบอัด mpeg หรือ jpeg ที่สูญเสีย

ในทางกลับกันถ้าคุณต้องการค้นหาการสุ่มอ่านไฟล์จากนั้นการบีบอัดอาจมีปัญหามากกว่าความคุ้มค่าและคุณกลับไปที่การเขียนแบบเบาบาง โปรแกรมเมอร์ C หรือ C ++ ที่มีความสามารถควรเขียนสิ่งที่ต้องการในเวลาไม่กี่ชั่วโมง


ที่น่าสนใจ - downvote แต่ฉันสังเกตเห็นว่าไม่มีการพิสูจน์ของสิ่งที่ฉันเขียน หากมันถูกต้อง แต่ไม่ช่วยเหลือก็ไม่ใช่เหตุผลที่จะลงคะแนน หากมันไม่ถูกต้องและไม่เป็นประโยชน์ก็ไม่สมควร
hotei

ฉันเห็นที่อื่นว่า OP มีคำถามเกี่ยวกับการติดตั้งภาพที่บีบอัด ฉันสมมติว่านี่เป็นความต่อเนื่องของเธรดนั้น รู้ว่าตอนนี้ฉันสามารถเห็นได้ว่าทำไมข้อเสนอแนะการบีบอัดของฉันจึงไม่ได้รับการยอมรับ โปรแกรม C อย่างง่ายยังคงเป็นวิธีที่ง่ายในการสร้างไฟล์ที่กระจัดกระจาย แต่ - ระบบปฏิบัติการ (ไม่ระบุ) จะให้คุณเมานต์ ISO แบบเบาบาง ในฐานะที่เป็นจู้จี้จุกจิกในฐานะผู้ติดตั้ง ISO ของ Ubuntu คือฉันไม่แน่ใจ 100% ว่าจะใช้งานได้ ... แต่โชคดีที่สุดในทุกกรณี
hotei

4
ทำไมต้องบูรณาการล้อ cp --sparse=alwaysทำงานได้ดีหรือไม่
mihi

@mihi: นั่นเป็นความคิดที่ดี ฉันไม่รู้เกี่ยวกับตัวเลือกที่กระจัดกระจายเนื่องจากไม่มีในรสชาติ BSD ( freebsd.org/cgi/ … ) และฉันไม่เคยมีความต้องการที่จะดูหน้า man Linux สำหรับ cp (จนถึงวันนี้)
hotei

วิธีหนึ่งในการบีบอัดอิมเมจและเมานต์ก็คือการเก็บไว้ในระบบไฟล์ที่รองรับการบีบอัดเนทีฟ ทำการกู้คืนข้อมูลที่น่ากลัวหากคุณมีไดรฟ์ที่เสียหาย แต่นั่นคือสิ่งที่สำรองข้อมูลใช่มั้ย
Perkins
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.