plocate データベースを何度も再構築しても、次のような結果が得られます。
/var/lib/plocate/plocate.db: has version 4294967295, expected 0 or 1; please rebuild it.
一体私がどうしたの?
/sbin/updatedb.plocate:
linux-vdso.so.1 (0x0000007f1c7d4000)
libzstd.so.1 => /lib/aarch64-linux-gnu/libzstd.so.1 (0x0000007f1c6c0000)
libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007f1c490000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f1c3f0000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007f1c3c0000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f1c210000)
/lib/ld-linux-aarch64.so.1 (0x0000003000000000)
/bin/plocate:
linux-vdso.so.1 (0x00000077e07be000)
liburing.so.2 => /lib/aarch64-linux-gnu/liburing.so.2 (0x00000077e0760000)
libzstd.so.1 => /lib/aarch64-linux-gnu/libzstd.so.1 (0x00000077e0690000)
libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x00000077e0460000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x00000077e0430000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x00000077e0280000)
/lib/ld-linux-aarch64.so.1 (0x0000003000000000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x00000077e01e0000)
plocate 1.1.15
Copyright 2020 Steinar H. Gunderson
License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
updatedb (plocate) 1.1.15
Copyright (C) 2007 Red Hat, Inc. All rights reserved.
This software is distributed under the GPL v.2.
This program is provided with NO WARRANTY, to the extent permitted by law.
答え1
TL; DRこれはAndroid /termux/prorootただし、これはplocateのコード変更で解決できます。1.1.20解放する。
4294967295
(例0xffffffff
:)はい(uint32_t)-1
。これは、plocateのupdatebが不完全に作成されたデータベースファイルを検出するためにsentinelバージョン番号として使用する値です。
plocateのupdatebがデータベースを作成するときは、まずダミー値(上記のバージョン番号が無効)を使用してヘッダーブロックを作成します。
データベースの残りの部分を作成した後、今回は正しい値(現在は正しいバージョン値を含む1
)でオーバーライドヘッダーを返します。
データベース出力ストリームがリンクされていないファイル(として開くO_TMPFILE
)に書き込まれているので、ファイルを実際のパスにリンクする必要があります。
これパスワードおおよその:
/* Open database */
fd = open(path.c_str(), O_WRONLY | O_TMPFILE, 0640);
outfp = fdopen(fd, "wb");
/* Write dummy header. */
...
/* Write database. */
...
/* Write real header */
fseek(outfp, 0, SEEK_SET);
fwrite(&hdr, sizeof(hdr), 1, outfp);
/* Link database path */
snprintf(procpath, sizeof(procpath), "/proc/self/fd/%d", fileno(outfp));
linkat(AT_FDCWD, procpath, AT_FDCWD, outfile.c_str(), AT_SYMLINK_FOLLOW);
fclose(outfp);
これは、許可されていないハードリンクの作成を許可しないAndroidで実行されるため、上記の操作は通常linkat
失敗します。
しかし施行されているproot
、施行されているマネージャーたとえばlinkat(..., "/proc/X/fd/Y", ..., AT_SYMLINK_FOLLOW)
、この場合、リンクされていないファイルにFDが使用されます。
linkat
prootのハンドラにより、「動作」コンテンツのコピーリンクされていないファイル、linkat
通話中。何もないよりも優れていますが、元のファイル記述子への追加の書き込みはファイルシステムのファイルに書き込まれません。
の場合、これ以上書き込みはありませんが、updatedb
最終書き込みと呼び出しの間に書き込みはありません。その後、出力バッファがフラッシュされるため、欠落は通常問題になりません。ただし、prootを実装すると、このモードによってデータが失われる可能性があります。fflush
fwrite
linkat
fflush
fclose
linkat
パブリックバグトラッカーがないようですが、この問題をptrace plocateの作成者に報告しました。これを追加するとfflush
問題は解決しますが、それ以外は有害ではありません。修正する:解決する994819b。