Поскольку я использую 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
Надеюсь, что это полезно для кого-то еще!