dpkg mengganti file pada sistem file FAT

22

Ketika Anda memutakhirkan atau menginstal ulang paket dengan dpkg(dan akhirnya apa pun yang menggunakannya, seperti apt-get dll) itu mencadangkan file yang ada dengan membuat tautan keras ke file sebelum menggantinya. Dengan begitu jika pembongkaran gagal maka dapat dengan mudah mengembalikan file yang ada. Itu hebat, karena melindungi sistem operasi dari Bad Things ™.

Kecuali ... itu hanya berfungsi jika sistem file Anda mendukung tautan keras . Tidak semua sistem file melakukannya - seperti sistem file FAT.

Saya sedang mengerjakan distribusi Debian untuk platform ARM tertanam yang spesifik, dan lingkungan boot mengharuskan file-file tertentu (termasuk kernel) berada pada sistem file FAT sehingga kode boot dapat menemukan dan memuatnya.

Ketika Anda pergi untuk meningkatkan paket kernel (atau paket lain yang memiliki file di partisi FAT) instalasi gagal dengan:

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

Dan seluruh upgrade gagal.

Saya telah menjelajahi web, dan satu-satunya referensi yang dapat saya temukan adalah orang-orang tertentu dengan masalah khusus ketika melakukan peningkatan tertentu, jawabannya adalah "Hapus / boot / vmlinuz-3.18.11+ dan coba lagi", dan ya, itu memperbaiki masalah khusus itu.

Tapi itu bukan jawaban untukku. Saya adalah distributor OS, bukan pengguna OS, jadi saya perlu cara untuk memperbaikinya yang tidak melibatkan pengguna akhir secara manual menghapus file kernel mereka sebelum melakukan upgrade. Saya perlu cara untuk memberitahu dpkg untuk "menyalin, bukan tautan keras" untuk file di / boot (atau semua file untuk semua yang saya pedulikan, meskipun itu agak memperlambat operasi peningkatan), atau lebih baik lagi "Jika tautan keras gagal, jangan mengeluh, cukup salin saja ".

Saya telah mencoba hal-hal seperti bendera --force-unsafe-iodan bahkan --force-alluntuk dpkg, tetapi tidak ada yang berpengaruh.

Majenko
sumber
Kedengarannya seperti waktu untuk bug daftar harapan. :-)
Faheem Mitha

Jawaban:

13

Perilaku yang Anda lihat diterapkan di archives.cdalam dpkgsumber, baris 1030 (untuk versi 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);

Tampak bagi saya bahwa Anda dapat menangani kegagalan tautan dengan kembali ke perilaku mengubah nama menggunakan baris 1003 dan mengikuti; sesuatu seperti (ini belum diuji):

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);
}

Saya bukan seorang dpkgahli ... (Dan tidak ada pilihan yang tersedia dpkguntuk menyediakan perilaku ini.)

Stephen Kitt
sumber
Tentu saja mengemas versi dpkg saya sendiri adalah suatu kemungkinan, meskipun saya lebih suka tidak memiliki overhead untuk melacak perubahan hulu dalam versi saya.
Majenko
Ok, saya bisa mengkonfirmasi bahwa ini berfungsi dengan baik, jadi ini tentu saja pilihan. Opsi lain yang terjadi pada saya yang kemungkinan adalah secara manual memindahkan file yang menyinggung dalam preinstskrip paket , tetapi karena kernel dibangun oleh skrip pengemasan kernel standar, saya tidak yakin bagaimana saya akan memodifikasinya. Juga tidak akan ada fasilitas rollback otomatis.
Majenko
1
Memang, itu akan berhasil; Anda juga dapat menyelidiki dpkgkait ( dpkg --pre-invoke=).
Stephen Kitt
+1 Bagaimana kabarmu bukan dpkgahli ketika Anda tahu ini!
nikhil
1
kernel raspberrypi juga diperbarui melalui trik serupa, menggunakan dpkg-divert. Diambil dari raspberrypi.stackexchange.com/questions/51410/... ,
akarapatis