dpkg แทนที่ไฟล์บนระบบไฟล์ FAT


22

เมื่อคุณอัพเกรดหรือติดตั้งแพคเกจใหม่dpkg(และท้ายที่สุดสิ่งที่ใช้มันเช่น apt-get ฯลฯ ) มันจะสำรองไฟล์ที่มีอยู่โดยการสร้างฮาร์ดลิงก์ไปยังไฟล์ก่อนที่จะแทนที่มัน ด้วยวิธีนี้หากการคลายแพ็กล้มเหลวจะสามารถนำไฟล์ที่มีอยู่กลับมาได้อย่างง่ายดาย เยี่ยมมากเพราะมันช่วยปกป้องระบบปฏิบัติการจากสิ่งที่เกิดขึ้น Bad Things ™

ยกเว้น ... มันจะทำงานเฉพาะถ้าระบบแฟ้มของคุณสนับสนุนการเชื่อมโยงอย่างหนัก ระบบไฟล์ทั้งหมดไม่ได้ทำเช่นระบบไฟล์ FAT

ฉันกำลังทำงานกับการแจกจ่าย Debian สำหรับแพลตฟอร์ม ARM ที่ฝังตัวเฉพาะและสภาพแวดล้อมการบูตต้องการไฟล์บางอย่าง (เคอร์เนลที่รวมอยู่) อยู่บนระบบไฟล์ FAT ดังนั้นรหัสการบูตสามารถค้นหาและโหลดได้

เมื่อคุณไปอัพเกรดแพ็คเกจเคอร์เนล (หรือแพ็คเกจอื่น ๆ ที่มีไฟล์ในพาร์ติชัน FAT นั้น) การติดตั้งจะล้มเหลวด้วย:

dpkg: error processing archive linux-image3.18.11+_3.18.11.2.armadillian_armhf.deb (--install):
 unable to make backup link of `./boot/vmlinuz-3.18.11+' before installing new version: Operation not permitted

และการอัปเกรดทั้งหมดล้มเหลว

ฉัน scoured เว็บและการอ้างอิงเดียวที่ฉันสามารถหาได้คือคนที่มีปัญหาเฉพาะเมื่อทำการอัพเกรดเฉพาะคำตอบที่มักจะ "ลบ / บูต / vmlinuz-3.18.11+ และลองอีกครั้ง" และใช่ว่า แก้ไขปัญหาเฉพาะที่

แต่นั่นไม่ใช่คำตอบสำหรับฉัน ฉันเป็นผู้จัดจำหน่ายระบบปฏิบัติการไม่ใช่ผู้ใช้ระบบปฏิบัติการดังนั้นฉันต้องการวิธีแก้ไขปัญหานี้ซึ่งไม่เกี่ยวข้องกับผู้ใช้ปลายทางด้วยการลบไฟล์เคอร์เนลด้วยตนเองก่อนทำการอัปเกรด ฉันต้องการวิธีบอก dpkg ให้กับ "copy, not hard link" สำหรับไฟล์ที่อยู่ใน / boot (หรือไฟล์ทั้งหมดสำหรับทุกสิ่งที่ฉันสนใจแม้ว่ามันจะทำให้การอัปเกรดช้าลงบ้าง) หรือดีกว่า "ถ้าฮาร์ดลิงก์ล้มเหลว อย่าบ่นแค่คัดลอกแทน "

ฉันได้ลองสิ่งต่าง ๆ เช่น--force-unsafe-ioและแม้จะติด--force-allธงdpkgแต่ก็ไม่มีผลใด ๆ


เสียงเหมือนเวลาสำหรับข้อผิดพลาดสิ่งที่ปรารถนา :-)
Faheem Mitha

คำตอบ:


13

ลักษณะการทำงานที่คุณเห็นกำลังจะดำเนินการในarchives.cในdpkgแหล่งที่มาสาย 1030 (สำหรับรุ่น 1.18.1):

debug(dbg_eachfiledetail, "tarobject nondirectory, 'link' backup");
if (link(fnamevb.buf,fnametmpvb.buf))
  ohshite(_("unable to make backup link of '%.255s' before installing new version"),
          ti->name);

ฉันว่าคุณสามารถจัดการกับความล้มเหลวของลิงค์ได้โดยกลับไปสู่พฤติกรรมการเปลี่ยนชื่อที่ใช้บรรทัดที่ 1003 และต่อไปนี้ บางสิ่งที่ชอบ (นี่ยังไม่ทดลอง):

debug(dbg_eachfiledetail, "tarobject nondirectory, 'link' backup");
if (link(fnamevb.buf,fnametmpvb.buf)) {
  debug(dbg_eachfiledetail,"link failed, nonatomic");
  nifd->namenode->flags |= fnnf_no_atomic_overwrite;
  if (rename(fnamevb.buf,fnametmpvb.buf))
    ohshite(_("unable to move aside '%.255s' to install new version"),
            ti->name);
}

ฉันไม่ใช่dpkgผู้เชี่ยวชาญ แต่ ... (และไม่มีตัวเลือกที่พร้อมใช้งานในdpkgการแสดงพฤติกรรมนี้)


แน่นอนว่าการแพ็กเกจ dpkg เวอร์ชันของฉันเองนั้นเป็นไปได้ แต่ฉันไม่ต้องการให้มีค่าใช้จ่ายในการติดตามการเปลี่ยนแปลงอัปสตรีมในเวอร์ชันของฉัน
Majenko

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

1
แน่นอนว่าจะได้ผล คุณสามารถตรวจสอบdpkghooks ( dpkg --pre-invoke=)
สตีเฟ่น Kitt

+1 คุณเป็นอย่างไรdpkgเมื่อคุณรู้เรื่องนี้!
nikhil

1
เคอร์เนล raspberrypi ได้รับการปรับปรุงผ่านกลอุบายที่คล้ายกันโดยใช้ dpkg-divert นำมาจากraspberrypi.stackexchange.com/questions/51410/… ,
akarapatis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.