dpkg remplacement de fichiers sur un système de fichiers FAT

22

Lorsque vous mettez à niveau ou réinstallez un package avec dpkg(et finalement tout ce qui l'utilise, comme apt-get, etc.), il sauvegarde les fichiers existants en créant un lien dur vers le fichier avant de le remplacer. De cette façon, si le déballage échoue, il peut facilement remettre les fichiers existants. C'est génial, car il protège le système d'exploitation contre les mauvaises choses ™.

Sauf ... cela ne fonctionne que si votre système de fichiers prend en charge les liens durs . Tous les systèmes de fichiers ne le font pas, comme les systèmes de fichiers FAT.

Je travaille sur une distribution de Debian pour une plate-forme ARM intégrée spécifique, et l'environnement de démarrage nécessite que certains fichiers (le noyau inclus) se trouvent sur un système de fichiers FAT afin que le code de démarrage puisse les localiser et les charger.

Lorsque vous allez mettre à niveau le package du noyau (ou tout autre package contenant des fichiers dans cette partition FAT), l'installation échoue avec:

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

Et toute la mise à niveau échoue.

J'ai parcouru le Web et les seules références que je peux trouver sont des personnes spécifiques ayant des problèmes spécifiques lors de mises à niveau spécifiques, dont la réponse est généralement "Supprimer / boot / vmlinuz-3.18.11+ et réessayer", et oui, cela résout ce problème spécifique.

Mais ce n'est pas la réponse pour moi. Je suis un distributeur de système d'exploitation, pas un utilisateur de système d'exploitation, j'ai donc besoin d'un moyen de résoudre ce problème qui n'implique pas que l'utilisateur final supprime manuellement ses fichiers de noyau avant de procéder à une mise à niveau. J'ai besoin d'un moyen de dire à dpkg de "copier, pas de lien dur" pour les fichiers sur / boot (ou tous les fichiers pour tout ce que je veux, bien que cela ralentisse quelque peu l'opération de mise à niveau), ou mieux "Si un lien dur échoue, ne vous plaignez pas, copiez-le à la place ".

J'ai essayé des choses comme les drapeaux --force-unsafe-ioet même , mais rien n'a d'effet.--force-alldpkg

Majenko
la source
Cela ressemble à du temps pour un bug de liste de souhaits. :-)
Faheem Mitha

Réponses:

13

Le comportement que vous voyez est implémenté dans archives.cla dpkgsource, ligne 1030 (pour la version 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);

Il me semble que vous pourriez gérer l'échec de la liaison en retombant au comportement de renommage utilisé aux lignes 1003 et suivantes; quelque chose comme (ce n'est pas testé):

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

Je ne suis pas un dpkgexpert cependant ... (Et il n'y a pas d'option déjà disponible dpkgpour fournir ce comportement.)

Stephen Kitt
la source
Assurément, empaqueter ma propre version de dpkg est une possibilité, bien que je préfère ne pas avoir la surcharge de suivi des changements en amont dans ma version.
Majenko
Ok, je peux confirmer que cela fonctionne bien, c'est donc certainement une option. Une autre option qui me vient à l'esprit qui peut être une possibilité est de déplacer manuellement les fichiers incriminés dans le preinstscript du package , mais comme le noyau est construit par les scripts de conditionnement du noyau standard, je ne sais pas comment je modifierais cela. Il n'y aurait pas non plus de fonction de restauration automatique.
Majenko
1
En effet, cela fonctionnerait; vous pouvez également enquêter sur les dpkgcrochets ( dpkg --pre-invoke=).
Stephen Kitt
+1 Comment n'êtes-vous pas un dpkgexpert quand vous le savez!
nikhil
1
Le noyau raspberrypi est également mis à jour via une astuce similaire, en utilisant dpkg-divert. Tiré de raspberrypi.stackexchange.com/questions/51410/… ,
akarapatis