dpkg ersetzt Dateien in einem FAT-Dateisystem

22

Wenn Sie ein Paket mit aktualisieren oder neu installieren dpkg(und letztendlich mit allem, was es verwendet, wie z. B. apt-get usw.), werden die vorhandenen Dateien gesichert, indem vor dem Ersetzen ein fester Link zu der Datei erstellt wird. Wenn das Entpacken fehlschlägt, können die vorhandenen Dateien problemlos wiederhergestellt werden. Das ist großartig, da es das Betriebssystem vor schlechten Dingen schützt.

Außer ... es funktioniert nur, wenn Ihr Dateisystem feste Links unterstützt . Nicht alle Dateisysteme - wie z. B. FAT-Dateisysteme.

Ich arbeite an einer Debian-Distribution für eine bestimmte eingebettete ARM-Plattform, und die Boot-Umgebung erfordert, dass sich bestimmte Dateien (einschließlich des Kernels) auf einem FAT-Dateisystem befinden, damit der Boot-Code sie finden und laden kann.

Wenn Sie das Kernel-Paket (oder ein anderes Paket, das Dateien in dieser FAT-Partition enthält) aktualisieren, schlägt die Installation fehl mit:

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

Und das ganze Upgrade schlägt fehl.

Ich habe das Web durchsucht und die einzigen Referenzen, die ich finden kann, sind bestimmte Personen mit bestimmten Problemen bei bestimmten Upgrades. Die Antwort lautet normalerweise "Delete /boot/vmlinuz-3.18.11+ and try again" und ja, das behebt dieses spezifische Problem.

Aber das ist nicht die Antwort für mich. Ich bin ein OS-Distributor und kein OS-Benutzer. Daher benötige ich eine Möglichkeit, dies zu beheben, bei der der Endbenutzer seine Kerneldateien nicht manuell löscht, bevor er ein Upgrade durchführt. Ich brauche eine Möglichkeit, dpkg anzuweisen, Dateien unter / boot "zu kopieren, nicht fest zu verknüpfen" (oder alle Dateien, obwohl dies den Aktualisierungsvorgang etwas verlangsamen würde), oder noch besser "Wenn ein fester Link fehlschlägt, beschwere dich nicht, kopiere es stattdessen ".

Ich habe solche Dinge wie die --force-unsafe-iound sogar --force-allFlaggen ausprobiert dpkg, aber nichts hat irgendeinen Effekt.

Majenko
quelle
Klingt nach Zeit für einen Fehler in der Wunschliste. :-)
Faheem Mitha

Antworten:

13

Das Verhalten, das Sie sehen, ist archives.cin der dpkgQuelle, Zeile 1030 (für Version 1.18.1) implementiert:

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

Es scheint mir, dass Sie den Verbindungsfehler behandeln könnten, indem Sie auf das Umbenennungsverhalten zurückgreifen, das in den Zeilen 1003 und den folgenden verwendet wird. so etwas wie (das ist ungetestet):

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

Ich bin allerdings kein dpkgExperte ... (Und es gibt noch keine Option dpkg, um dieses Verhalten bereitzustellen.)

Stephen Kitt
quelle
Sicherlich ist das Packen meiner eigenen Version von dpkg eine Möglichkeit, obwohl ich es vorziehen würde, nicht den Overhead zu haben, Upstream-Änderungen in meiner Version nachzuverfolgen.
Majenko
Ok, ich kann bestätigen, dass dies gut funktioniert, es ist also sicherlich eine Option. Eine andere Option, die mir einfällt, ist das manuelle Verschieben der anstößigen Dateien im preinstSkript des Pakets. Da der Kernel jedoch aus den Standard-Kernel-Paketskripten besteht, bin ich mir nicht sicher, wie ich das ändern würde. Es würde auch keine automatische Rollback-Funktion geben.
Majenko
1
In der Tat würde das funktionieren; Sie könnten auch dpkgHooks ( dpkg --pre-invoke=) untersuchen.
Stephen Kitt
+1 Wieso bist du kein dpkgExperte, wenn du das weißt?
Nikhil
1
Der raspberrypi-Kernel wird ebenfalls über einen ähnlichen Trick mit dpkg-divert aktualisiert. Aus raspberrypi.stackexchange.com/questions/51410/… ,
akarapatis