10 คะแนน โดย xguru 2022-07-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เริ่มสืบสวนเพราะการแตกไฟล์ tar.gz ขนาด 518GiB ช้าลงอย่างมาก
  • อธิบายเกี่ยวกับฟอร์แมต Tar พร้อมทั้งเขียนโค้ด tar extractor แบบรวดเร็วไปด้วย

ฟอร์แมตไฟล์ Tar ดั้งเดิม

  • Tar เป็นฟอร์แมตไฟล์เก็บถาวรที่แปลกมากเมื่อเทียบกับฟอร์แมตอื่น
    → ไม่มีส่วนหัวของอาร์ไคฟ์, ไม่มีดัชนีไฟล์สำหรับการค้นหา, ไม่มี magic byte สำหรับยืนยันว่าเป็น tar, ไม่มี footer และไม่มี metadata
    → สิ่งที่อยู่ใน Tar มีเพียงอ็อบเจ็กต์ไฟล์ชนิดเดียว
  • ประเภทไฟล์: 0 (ไฟล์ปกติ), 1 (ฮาร์ดลิงก์), 2 (ซิมโบลิก์ลิงก์)
  • คำอธิบายโครงสร้างของส่วนหัวอ็อบเจ็กต์ไฟล์ขนาด 512 ไบต์
    → ข้อจำกัดใหญ่ที่สุดคือความยาวพาธของไฟล์มีได้เพียง 100 ตัวอักษรเท่านั้น และขนาดไฟล์สูงสุดคือ 8GiB

ไฟล์ส่วนขยาย UStar

  • ความยาวพาธของไฟล์เพิ่มได้สูงสุด 256 ตัวอักษร และเพิ่มประเภทไฟล์ใหม่
  • ขยายส่วนหัวโดยเพิ่ม magic byte และฟิลด์ prefix
  • เพิ่มประเภทไฟล์: 3 (character device), 4 (block device), 5 (ไดเรกทอรี), 6 (ไฟล์ FIFO), 7 (ไฟล์ต่อเนื่อง)
  • แต่ข้อจำกัดขนาด 8GiB ยังคงอยู่

ฟอร์แมตไฟล์ Pax

  • มาตรฐาน POSIX.1-2001 ขยายฟอร์แมต tar ผ่าน CLI ของ pax
  • เหมือนกับ UStar แต่เพิ่มฟอร์แมตไฟล์ x และ g
    → ในฐานะระเบียนส่วนหัวส่วนขยาย x จะมีผลกับไฟล์ถัดไปเท่านั้น ส่วน g จะมีผลกับทุกไฟล์หลังจากนั้น

ฟอร์แมตไฟล์ GNU Tar

  • ฟอร์แมตเฉพาะของตัวเองคือ gnu และแตกต่างจาก pax
  • คล้าย pax ตรงที่อิงกับ UStar แต่ใช้วิธีอื่นในการเข้ารหัสพาธและไฟล์ขนาดใหญ่
    → ชนิด L: payload ของอ็อบเจ็กต์ไฟล์ถัดไปจะแทนค่า "file_path"
    → ชนิด K: payload ของอ็อบเจ็กต์ไฟล์ถัดไปจะแทนค่า "link_path"
    → ใช้สองอย่างนี้ต่อเนื่องกันได้
    → หากไฟล์มีขนาดใหญ่กว่า 8GiB ให้ตั้งค่าไฮบิตของอักขระตัวแรกของ file_size จากนั้นจึง parse ส่วนที่เหลือของสตริงเป็น base 256 (จำนวนเต็ม 95 บิต)

ทำไม GNU tar ถึงแตกไฟล์ช้า?

  • หากใส่ค่าอย่าง file_path="../hello.txt" ลงในส่วนหัวของไฟล์ จะเกิดปัญหาด้านความปลอดภัย แต่ป้องกันได้ไม่ง่าย
  • GNU tar จะสร้าง placeholder และหน่วงการประมวลผลไว้เมื่อพบ ".." ใน link_path
  • แต่ในกรณีของฮาร์ดลิงก์ที่ไม่มี ".." แม้อยากสร้างโดยตรงก็ทำไม่ได้ เพราะมี placeholder อยู่แล้ว
  • กล่าวคือ หากจะสร้างฮาร์ดลิงก์ ต้องตรวจสอบก่อนทั้งหมดว่ามันเป็น delayed link หรือไม่ และถ้าใช่ ลิงก์ใหม่ก็ต้องถูกหน่วงไว้เช่นกัน
    → จึงต้องค้นหา delayed link สำหรับฮาร์ดลิงก์ทุกตัว และแม้ไม่ทราบเหตุผล แต่ในทางปฏิบัติจะค้นหาถึง 2 รอบ
  • ในไฟล์ Tar ของผู้เขียนมีลิงก์ที่มี ".." มากกว่า 800,000 รายการ และมีฮาร์ดลิงก์มากกว่า 5.4 ล้านรายการ จึงทำให้การแตกไฟล์ช้า
  • เพื่อป้องกันปัญหานี้ ให้เพิ่มตัวเลือก --absolute-paths หรือ -P ให้กับ tar
    → เป็นตัวเลือกที่เก็บพาธแบบสัมบูรณ์และปฏิเสธ ".."
    → กล่าวคือ เมื่อใส่ตัวเลือก -P จะเป็นการปิดกลไก delayed linking