ちょうど問題が発生しました。 Linuxシステムを再起動すると、マウントされたVFATファイルシステム内のすべてのファイルのタイムスタンプが間違った時間帯に表示されます。デバイスは現地時間がUTCであると考え始め、すべてのタイムスタンプをオフセットとともに表示します。
再現段階:
小さなFAT形式の画像を作成します。
dd if=/dev/zero of=small.img bs=1M seek=1 count=0
mkfs.vfat small.img
このイメージをローカルにマウントします。
mount -t vfat -o umask=0022,gid=1001,uid=1001 small.img mnt
タイムゾーンをUTC以外のタイムゾーンに設定します。
マウントされたファイルシステム(たとえば
touch mnt/newfile
)にファイルを作成します。ファイルの変更/変更タイムスタンプを観察してください。現在設定されているタイムスタンプに対して正しいです。
stat mnt/newfile
File: mnt/newfile Size: 0 Blocks: 0 IO Block: 16384 regular empty file Device: 700h/1792d Inode: 40 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-03-22 12:19:56.000000000 +0100 Modify: 2021-03-22 12:19:56.000000000 +0100 Change: 2021-03-22 12:19:56.000000000 +0100 Birth: -
timedatectl
Local time: Mon 2021-03-22 12:19:07 CET Universal time: Mon 2021-03-22 11:19:07 UTC RTC time: Mon 2021-03-22 11:19:07 Time zone: Europe/Vienna (CET, +0100) System clock synchronized: yes NTP service: active RTC in local TZ: no
ファイルシステムをアンマウントして再マウントして、変更があるかどうかを確認します。
umount mnt; mount -t vfat -o umask=0022,gid=1001,uid=1001 small.img mnt; stat mnt/newfile
File: mnt/newfile Size: 0 Blocks: 0 IO Block: 16384 regular empty file Device: 700h/1792d Inode: 64 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-03-22 00:00:00.000000000 +0100 Modify: 2021-03-22 12:19:56.000000000 +0100 Change: 2021-03-22 12:19:56.000000000 +0100 Birth: -
システムを再起動します。
画像を再マウントして、生成されたファイルのタイムスタンプを確認してください。
File: mnt/newfile Size: 0 Blocks: 0 IO Block: 16384 regular empty file Device: 700h/1792d Inode: 26 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-03-22 01:00:00.000000000 +0100 Modify: 2021-03-22 13:19:56.000000000 +0100 Change: 2021-03-22 13:19:56.000000000 +0100 Birth: -
時間が1時間(12:10から13:19)早くなったことがはっきりとわかりますが、時間帯は同じに+0100と表示されます。mount
これで、ファイルタイムスタンプがUTCとして記録されていると考えて、「正しい」オフセットを使用して表示しようとしているようです。
前のステートメントを検証するには、tz=UTC
このオプションを明示的に使用して同じファイルシステムを再マウントします。
mount -t vfat -o umask=0022,gid=1001,uid=1001,tz=UTC small.img mnt; stat mnt/newfile
File: mnt/newfile
Size: 0 Blocks: 0 IO Block: 16384 regular empty file
Device: 700h/1792d Inode: 50 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-03-22 01:00:00.000000000 +0100
Modify: 2021-03-22 13:19:56.000000000 +0100
Change: 2021-03-22 13:19:56.000000000 +0100
Birth: -
システムのタイムゾーンが実際にCETの場合でも:
date
Mon Mar 22 12:26:42 CET 2021
ポリスチレンhttps://stackoverflow.com/questions/10068855/how-do-i-get-the-Cordirect-modified-datetime-of-a-fat32-file-regardless-of-timezo回答が得られないため、この質問に対する回答ではありません。再インストール直後ではなく、コンピュータを再起動した直後にこの変更が表示されるのはなぜですか。 vfatがタイムスタンプを現地時間として保存する場合、再起動後のマウントでタイムスタンプが現地時間ではなくUTCであると仮定するのはなぜですか?
答え1
Linuxカーネル自体に問題があるようですが、タイムゾーンは、(通常)カーネルとユーザー空間の間で異なる場合があります。。 Linuxカーネルソースツリーのファイルは、time.c
保存(およびエクスポート)され、次にFAT時間<-> UNIX時間規則に従って使用されます。この構造のフィールドは、オプションが次の場合、現在のタイムゾーンとUTCの差を表示するために使用されます。kernel/time
struct timezone sys_tz
fs/fat/misc.c
tz_minuteswest
tz=UTC
いいえmount.vfat
コマンドに渡されました。ただし、上記のフィールドは、説明したようにデフォルトで0に設定されています。ここ、
Linuxでは、NULL以外のtzパラメータを使用した最初の呼び出しで(起動後)、tvパラメータがNULLで、tz_ Minuteswestフィールドがゼロです。 (この場合、tz_dsttimeフィールドは0でなければなりません。)この場合、CMOSクロックはローカル時間と見なされ、UTCシステム時間を取得するにはこの量だけ増加する必要があります。この機能を使用するのが悪い考えであることは間違いありません。
したがって、カーネル(および対応するドライバ)が常に正しいタイムゾーンを確認できるようにする唯一の方法は、UTC(たとえば-60 CETなど)に基づいて希望の時間オフセット「西」(時間単位)を使用してパラメータをsettimeofday()
呼び出すことです。 。各システム起動後にゼロに設定されます。これは(何らかの方法で)システムタイムゾーンを設定することで達成できます。tz
tz.tz_minuteswest
tz_dsttime
現在のタイムゾーン他の値(UTCなど)に変更した後timedatectl
コマンドラインツールsaは、通常、目的のタイムゾーンが現在のタイムゾーンと同じ場合、実際のタイムゾーン変更を実行しないためです。この概念を示すために、次のコードを作成します。
#include <sys/time.h>
#include <stdio.h>
int main()
{
struct timeval tv;
struct timezone tz;
int ret = gettimeofday(&tv, &tz);
printf("%d, %dr\n", tz.tz_minuteswest, tz.tz_dsttime);
return ret;
}
コードは次のように実行されます。
$gcc testtz.cpp -o testtz
$./testtz
minuteswest: 0, dsttime: 0r
$timedatectl set-timezone Europe/Vienna
$./testtz
minuteswest: 0, dsttime: 0r
$timedatectl set-timezone UTC
$timedatectl set-timezone Europe/Vienna
$./testtz
minuteswest: -60, dsttime: 0r
timezone
構造の使用は廃止とみなされますが、問題はすぐには消えません。だから私の問題については使用を検討します。time_offset=分オプションのmount.vfat
。