7

Мой Linux-компьютер поддерживает CLOCK_TAI , но его смещение от CLOCK_REALTIME неправильно равно нулю (это значение по умолчанию). Есть ли программное обеспечение или другое решение, которое будет поддерживать CLOCK_TAI как TAI?

Из ответов здесь и здесь кажется, что ни ntpd ни chronyd делают этого.

Я был бы счастлив , чтобы установить мои аппаратные часы для TAI , чтобы достичь этого, при условии CLOCK_REALTIME и gettimeofday т.д. вернуть POSIX время ( в основном UTC).

3 ответа3

4

Я думаю, что вы хотите, чтобы 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' находит совпадений, поэтому кажется, что у хроники пока нет этой возможности.

3

Поскольку я использую chrony вместо старого ntpd , у меня не было автоматического способа получить правильный параметр ядра, поэтому я искал альтернативу.

Поскольку смещение между TAI и UTC является относительно постоянным (изменяется <раз в год), можно статически установить параметр ядра, а затем использование часов CLOCK_TAI в приложении даст правильное значение.

Существует тестовое приложение для установки смещения ядра в исходных кодах ядра, в tools/testing/selftests/timers/set-tai.c . И, если у вас установлен пакет tzdata , в файле /usr/share/zoneinfo/leap-seconds.list есть файл со смещением между UTC и TAI.

Я вырубил тестовое приложение ядра, поэтому основным стало:

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

Надеюсь, что это полезно для кого-то еще!

3

Вы можете использовать libtai из djb: https://cr.yp.to/libtai.html

Что это?

libtai - это библиотека для хранения и манипулирования датами и временем.

libtai поддерживает две шкалы времени: (1) TAI64, охватывающий несколько сотен миллиардов лет с точностью до 1 секунды; (2) TAI64NA, охватывающий тот же период с точностью до 1 аттосекунды. Обе шкалы определены в терминах TAI, действующего международного стандарта реального времени.

libtai предоставляет внутренний формат для TAI64, struct tai, предназначенный для быстрых манипуляций со временем. Процедуры tai_pack () и tai_unpack () конвертируют между struct tai и переносимым 8-байтовым форматом хранения TAI64. libtai предоставляет аналогичные внутренние и внешние форматы для TAI64NA.

libtai предоставляет struct caldate для хранения дат в форме год-месяц-день. Он может преобразовать struct caldate по григорианскому календарю в модифицированный номер дня в Юлиане для упрощения арифметики дат.

libtai предоставляет struct caltime для хранения календарных дат и времени вместе со смещениями UTC. Он может конвертировать из struct tai в struct caltime в UTC, учитывая високосные секунды, для точного отображения даты и времени. Он также может преобразовать обратно из struct caltime в struct tai для пользовательского ввода. Общая скорость преобразования UTC в TAI в 100 раз выше, чем в обычной реализации UNIX mktime ().

Эта версия libtai требует UNIX-системы с gettimeofday (). Будет легко портировать на другие операционные системы с компиляторами, поддерживающими 64-битную арифметику.

Исходный код libtai находится в открытом доступе.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .