web-dev-qa-db-ja.com

FATファイルシステム上のファイルを置き換えるdpkg

dpkg(および最終的にはapt-getなどのそれを使用するもの)を使用してパッケージをアップグレードまたは再インストールすると、ファイルを置き換える前にファイルへのハードリンクを作成して既存のファイルをバックアップします。そうすれば、解凍に失敗した場合でも、既存のファイルを簡単に元に戻すことができます。 BadThings™の発生からオペレーティングシステムを保護するので、これは素晴らしいことです。

ただし...それは機能するだけですファイルシステムがハードリンクをサポートしている場合。 FATファイルシステムなど、すべてのファイルシステムが機能するわけではありません。

私は特定の組み込みARMプラットフォーム用のDebianのディストリビューションに取り組んでいます。ブート環境では、ブートコードが見つけられるように特定のファイル(カーネルを含む)が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

そして、アップグレード全体が失敗します。

私はWebを精査しましたが、特定のアップグレードを行うときに特定の問題を抱えている特定の人だけが参照されます。その答えは通常、「/ boot/vmlinuz-3.18.11 +を削除して、再試行してください」です。その特定の問題を修正します。

しかし、それは私にとっての答えではありません。私はOSユーザーではなく、OSディストリビューターなので、アップグレードを行う前にエンドユーザーがカーネルファイルを手動で削除する必要がない、これを修正する方法が必要です。/boot上のファイル(または、アップグレード操作が多少遅くなりますが、気になるすべてのファイル)を「ハードリンクではなくコピー」するようにdpkgに指示する方法が必要です。さらに、「ハードリンクが失敗した場合は、文句を言わないで、代わりにそれをコピーしてください。」.

--force-unsafe-io--force-allフラグをdpkgに設定してみましたが、何の効果もありません。

22
Majenko

表示されている動作は、dpkgソースのarchives.cに実装されています 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ですでに利用できるオプションはありません。)

13
Stephen Kitt