dpkg заменяет файлы в файловой системе FAT

22

Когда вы обновляете или переустанавливаете пакет с помощью dpkg(и, в конечном счете, всего, что его использует, например, apt-get и т. Д.), Он создает резервные копии существующих файлов, создавая жесткую ссылку на файл перед его заменой. Таким образом, если распаковка не удалась, она может легко вернуть существующие файлы. Это здорово, поскольку защищает операционную систему от неприятностей.

Кроме ... это работает только если ваша файловая система поддерживает жесткие ссылки . Не все файловые системы - такие как файловые системы 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

И все обновление не удается.

Я просмотрел сеть, и единственные ссылки, которые я могу найти, это конкретные люди с конкретными проблемами при выполнении конкретных обновлений, ответ на которые обычно - «Удалить /boot/vmlinuz-3.18.11+ и повторите попытку», и да, что исправляет эту конкретную проблему.

Но это не ответ для меня. Я дистрибьютор ОС, а не пользователь ОС, поэтому мне нужен способ исправить это, не требуя от конечного пользователя ручного удаления файлов ядра перед обновлением. Мне нужен способ указать dpkg «копировать, а не жесткую ссылку» для файлов в / boot (или для всех файлов, которые меня волнуют, хотя это может несколько замедлить операцию обновления), или еще лучше: «Если жесткая ссылка не работает, не жалуйся, просто скопируй вместо этого ".

Я пробовал такие вещи, как --force-unsafe-ioи даже --force-allфлаги dpkg, но ничто не имеет никакого эффекта.

Majenko
источник
Звучит как время для ошибки в списке желаний. :-)
Фахим Митха

Ответы:

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 вполне возможна, хотя я бы предпочел, чтобы в моей версии не было накладных расходов на отслеживание изменений в исходной версии.
Маженко
Хорошо, я могу подтвердить, что это работает нормально, так что это, безусловно, вариант. Другой вариант, который мне приходит в голову, это может быть возможность - вручную перемещать файлы-нарушители в preinstскрипте пакета , но поскольку ядро ​​построено из стандартных скриптов упаковки ядра, я не уверен, как бы я это изменил. Также не было бы возможности автоматического отката.
Маженко
1
Действительно, это будет работать; Вы также можете исследовать dpkgхуки ( dpkg --pre-invoke=).
Стивен Китт
+1 Как ты не dpkgэксперт, когда знаешь это!
nikhil
1
Ядро raspberrypi также обновляется с помощью аналогичного трюка с использованием dpkg-divert. Взято с raspberrypi.stackexchange.com/questions/51410/… ,
akarapatis