私のGNU / Linuxシステムの日付をエポックに設定できないのはなぜですか?

私のGNU / Linuxシステムの日付をエポックに設定できないのはなぜですか?

アクセス可能な Raspberry Pi および Ubuntu 16.04 x86_64 マシンで、次を実行します。

# date -s @0

返品

date: cannot set date: Invalid argument
thu 1 jan 1970 01:00:00 CET

私は知りたいです:

  • 不可能の理由は何か、
  • システム時間をEpochにリセットするプログラムはありますか?

ベストアンサー1

以前のシステムでは「無効な引数」を正確に再現できませんでしたが、

# strace date -s '@-1'
clock_settime(CLOCK_REALTIME, {4294967295, 0}) = -1 EINVAL (Invalid argument)
settimeofday({4294967295, 0}, NULL)     = -1 EINVAL (Invalid argument)
write(2, "date: ", 6date: )                   = 6
write(2, "cannot set date", 15cannot set date)         = 15
write(2, ": Invalid argument", 18: Invalid argument)      = 18
write(2, "\n", 1

date実際にまだ設定されていない場合でも、設定したい日付が表示されます。)

一般英語では、dateカーネルを呼び出して日付を新起源の1秒前に設定し、カーネルは提案された日付が無効であることを伝えます。

これで、上記のトレースでは、秒が-1の代わりに4294967295であることがわかります。数字は2^32-1で、32ビットシステムで実行されています。これは実際にいいえ問題の原因:strace値に署名する必要があるかどうかわからないという点で、ディスプレイの問題です。実際、秒数は符号付き整数型ですtime_t。 LinuxのGlibc 2.23は、as、as、asでtime_t64ビット符号付き型を定義します。カーネル側で4.4以降、呼び出しパラメータタイプの定義は次のとおりです。__time_t/usr/include/time.h__time_t__TIME_T_TYPE/usr/include/bits/types.h __TIME_T_TYPE__SYSCALL_SLONG_TYPE__SQUAD_TYPE/usr/include/bits/typesizes.h__SQUAD_TYPE/usr/include/bits/types.hsettimeofdaystruct timespec秒はどこにありますか?__kernel_time_t64ビットシステムの符号付き64ビットタイプ。time64_tこれは32ビットシステムの符号付き64ビットタイプです。したがって、カーネルは-1を大きな正の数ではなく-1として扱います。

以前の時代に戻ることができなかった理由は、Linuxカーネルがこれを明示的に拒否するためです。これsettimeofdayシステムコールif が EINVAL("無効なパラメータ") を返す場合timeval_valid与えられた時間的構造を拒否し、この機能負の秒は拒否されます。

カーネルバージョンごとにコード構成が異なりますが、動作が変わらないと思います。

正確にゼロの時間を拒否する理由はなく、テストしたVMで動作します。

おそらく、この完全性チェックの理由は、エポック以降の時間を符号なし整数として格納するコードがあり、エポック前の日付を処理できないためです。一部のコードはゼロを「不明な日付」と解釈する可能性があるため、ゼロを拒否するのは合理的ですが、Linuxは実際にはそうしません。

時代以前の時代は、確実に再現および操作することができます。多くのソフトウェアでは、過去のイベント時間を追跡する必要があります。ほとんどすべてのオペレーティングシステムで使用されるタイムゾーンデータベースには、タイムゾーンがコード化された時期(鉄道が使用され始めた時期)までさかのぼる履歴データが含まれています。しかし、Linuxコンピュータには不明です。現在の時は1970年以前だった。

おすすめ記事