GNU/Linux >> Linux の 問題 >  >> Linux

Linux で正しい CLOCK_TAI を取得する方法はありますか?

clock_gettime が欲しいと思います CLOCK_TAI で 適切に動作するようにします。私もそうでした。

参照されている回答の重要な文は次のとおりです。「起動時に CLOCK_REALTIME からのオフセットがゼロに初期化され、ntpd も chronyd もデフォルトで正しい値 (現在は 35) に設定されていないことに注意してください。」

オフセットが 37 になったことを除けば、これはまだ正しいかもしれませんが、最近の ntpd は少なくともオフセットを設定するように構成できます。 openSUSE マシンで次のことを行いました:

vi /etc/ntp.conf # Add the line: leapfile /var/lib/ntp/etc/ntp.leapseconds
update-leap
service ntpd restart
less /var/log/ntp # Check for errors

次に clock_gettime(CLOCK_TAI, &res)

ntp は ntp_adjtime を使用してオフセットを設定すると思います MOD_TAI で . grep -P '(ADJ|MOD)_TAI' で chrony ソースを検索する 一致するものが見つからないため、chrony にはまだこの機能がないようです。


libtai を使用できます djb から:https://cr.yp.to/libtai.html

<ブロック引用>

それは何ですか?

libtai は、日付と時刻を保存および操作するためのライブラリです。

libtai は 2 つのタイム スケールをサポートします。(1) TAI64。1 秒の精度で数千億年をカバーします。 (2) TAI64NA、同じ期間を 1 アト秒の精度でカバー。どちらのスケールも、現在の国際リアルタイム標準である TAI に基づいて定義されています。

libtai は、TAI64 の内部フォーマットである struct tai を提供し、高速な時間操作のために設計されています。 tai_pack() および tai_unpack() ルーチンは、struct tai と移植可能な 8 バイトの TAI64 ストレージ形式の間で変換します。libtai は、TAI64NA に同様の内部および外部形式を提供します。

libtai は、日付を年-月-日の形式で格納するための構造体 caldate を提供します。構造体 caldate を、グレゴリオ暦の下で、簡単な日付計算のために修正ユリウス日番号に変換できます。

libtai は、UTC オフセットとともにカレンダーの日付と時刻を格納するための構造体 caltime を提供します。正確な日付と時刻を表示するために、うるう秒を考慮して struct tai から struct caltime inUTC に変換できます。その全体的な UTC から TAI への変換速度は、通常の UNIX mktime() 実装よりも 100 倍優れています。

このバージョンの libtai には、gettimeofday() を備えた UNIX システムが必要です。 64 ビット演算をサポートするコンパイラを使用して、他のオペレーティング システムに簡単に移植できます。

libtai ソース コードはパブリック ドメインにあります。


chrony を実行しているので 古い ntpd の代わりに 、カーネル パラメーターを正しく取得する自動化された方法がなかったため、別の方法を調べました。

TAI と UTC の間のオフセットは比較的一定 (1 年に 1 回未満の変更) であるため、カーネル パラメータを静的に設定することが可能であり、アプリケーションで CLOCK_TAI クロックを使用すると正しい値が得られます。

tools/testing/selftests/timers/set-tai.c には、カーネル ソースにカーネル オフセットを設定するためのテスト アプリケーションがあります。 .そして、あなたが tzdata を持っていると仮定すると パッケージがインストールされている場合、UTC と TAI の間のオフセットが /usr/share/zoneinfo/leap-seconds.list にあるファイルがあります .

カーネル テスト アプリケーションを切り詰めたので、メインは次のようになりました:

int main(int argc, char **argv)
{
    int i, ret;

    ret = get_tai();
    printf("tai offset started at %i\n", ret);

    if (argc < 2)
    {
        printf("New offset not given, not setting\n");
    }
    else
    {
        i = strtol(argv[1],NULL,10);
        printf("Attempting to set TAI offset to %d\n",i);
        printf("Checking tai offsets can be properly set: ");
        ret = set_tai(i);
        ret = get_tai();
        if (ret != i) {
            printf("[FAILED] expected: %i got %i\n", i, ret);
            return EXIT_FAILURE;
        }
    }
    printf("[OK]\n");
    return EXIT_SUCCESS;
}

次に、私のユースケースでは、 leap-seconds.list から正しい値を抽出するだけでした ファイルと実行中の set-tai これをパラメーターとして (/etc/rc.local で) 起動時に発生させるため)。これを行う方法の例:

TAI_OFFSET=$(grep -v '^#' /usr/share/zoneinfo/leap-seconds.list | tail -1 | awk '{ print $2 }')
if [ -x /usr/local/sbin/set-tai ]; then
  /usr/local/sbin/set-tai $TAI_OFFSET
fi

これが他の誰かに役立つことを願っています!


Linux
  1. Linuxで元に戻すことはできますか?

  2. 非ルート プロセスを Linux の特権ポートにバインドする方法はありますか?

  3. Linux に STDCALL はありますか?

  1. javaを使用してLinuxマシンでユーザーのUIDを取得する方法はありますか?

  2. Linux / OS Xでmongodサービスを開始する正しい方法は何ですか?

  3. Linuxにjdkをインストールする正しい方法は何ですか

  1. Linux で DD のパーセンテージを取得する方法はありますか?

  2. Linux で LD_PRELOAD と LD_LIBRARY_PATH をブロックする方法はありますか?

  3. プロセスを聞く方法はありますか?