Сбой ntpdate, если в системе установлена ​​дата, превышающая 2038 год

Вы можете использовать путь к вашей внешней команде "func", например / usr / bin / func .

3
26.03.2016, 00:43
2 ответа

То, что вы видите - это распространенная "ошибка", известная как проблема 2038 года, она же ошибка Y2K38, которая все еще присутствует в 32-битных серверах Linux.

Примерно к 2000 году мы осознали, что кроме ошибки y2k/миллениума, будет еще одна ошибка, связанная со временем. (да, я был частью команды по "предотвращению" y2k)

Поскольку эпоха Unix - это 32-битный секундный счетчик, который начинался 1 января 1970 года и был только знаковым 32-битным целым числом, он имел (и все еще имеет в некоторых системах) верхний предел 03:14:07 UTC 19 января 2038 года. https://en.wikipedia.org/wiki/Year_2038_problem

В последних реализациях он был расширен до 64 бит.

Начиная с NetBSD версии 6.0 (выпущенной в октябре 2012 года), операционная система операционная система NetBSD использует 64-битный time_t как для 32-битной, так и для 64-битных архитектур. Приложения, которые были скомпилированы для более старого NetBSD с 32-битным time_t, поддерживаются через уровень двоичной уровень совместимости, но такие старые приложения все равно будут страдать от [13]

OpenBSD, начиная с версии 5.5, выпущенной в мае 2014 года, также использует 64-битное время для 32-битных и 64-битных архитектур. time_t как для 32-битной, так и для 64-битной архитектуры. В отличие от NetBSD, здесь нет слоя двоичной совместимости. Поэтому, приложения, ожидающие 32-битный time_t, и приложения, использующие что-либо отличное от time_t для хранения значений времени. отличные от time_t для хранения значений времени, могут сломаться.[14]

Linux использует 64-битный time_t только для 64-битных архитектур; чистый 32-битный ABI не изменяется из-за обратной совместимости.[15] Существует ведутся работы, в основном для встроенных систем Linux, по поддержке 64-битного time_t на 32-битных архитектурах

В качестве фольклорной истории и довольно продуманной мистификации, Джон Титор был отправлен назад во времени, чтобы получить мейнфрейм, чтобы помочь исправить проблемы наследия в будущем из-за ошибки 2038, и предсказал американскую гражданскую/ядерную войну под управлением Хиллари Клинтон в параллельной нашей реальности.

http://www.strangerdimensions.com/2011/10/03/john-titor-the-ibm-5100/

История Джона Титора началась в 2036 году. Титор принадлежал к команде из семи человек, отобранных для путешествия во времени. Он пережил невообразимые ужасы в мире, разрушенном эгоизмом, цинизмом и коррумпированным правительством, опустошенном ядерной войной. Что еще хуже, то немногое, что осталось от их технологий, было под угрозой. под угрозой из-за надвигающейся ошибки тайм-аута UNIX в 2038 году.

См. также https://en.wikipedia.org/wiki/9223372036854775807

Системы, использующие 32-битный тип, подвержены проблеме 2038 года. поэтому многие реализации перешли на более широкий 64-битный тип, с максимальным значением 263-1, соответствующим моменту времени 292 миллиарда лет от настоящего времени.

Итак, возвращаясь к вашему вопросу о ntpdate.

О пределе 2038 года. Проблема в том, что time_t был (есть) 32-битным signed int. Т.е. 32-битным целым числом с последним битом, предназначенным для сигнала. Поэтому, по сути, вы можете хранить только числа (то есть количество секунд между -0x7fffffff и +7fffffff (+2147483647). Таким образом, +2147483647 ограничивает представление временного интервала до 1 января 1970+2147483647 секунд, что означает, что ntpdate может хранить в вашей системе даты только до 03:14:07 UTC 19 января 2038 года.

Что касается дат после 2038 года, то проблема в том, что кодовые процедуры, преобразующие строки во внутреннее представление (time_t/32-битное целое число), заворачиваются или просто сбрасываются на день/0 секунду в зависимости от реализации библиотеки.

По поводу верхнего предела года. time_t в вашей системе является знаковым целым числом, поэтому библиотека делает проверку верхнего предела как значение беззнакового целого, что при +4294967295 секунд после 1 января 1970 года даст ей верхний предел где-то в районе 2106 года. В зависимости от реализации, проверка может действительно выполняться в строке больше или поведение обусловлено свойствами 32-битного целого числа, проверяя только код ntpdate.

INT_MAX (32 бита) = 2147483647
UINT_MAX (32 бита) = 4294967295 (0xffffffff)

От https://en.wikipedia.org/wiki/Year_2038_problem

Например, изменение time_t на беззнаковое 32-битное целое число, которое расширит диапазон до 2106 года, негативно повлияет на программы, которые хранят, извлекают или манипулируют датами до 1970 года, поскольку такие даты представлены отрицательными числами

В качестве последней сноски, имейте в виду, что в системе может отсутствовать соответствие y2k38 как в коде системы/ОС, так и в часах RTC.

На уровне ОС, переход на 64-битный linux (если архитектура позволяет) исправит это сейчас, или, надеюсь, 32-битный Linux исправит это в ближайшем будущем.

Что касается RTC в старых машинах, это означает, что вы получите искаженные данные после 2038 года, по крайней мере, в журналах, пока ntpd не включится и не исправит системную дату.

1
27.01.2020, 21:16

Сначала несколько замечаний:

  • Текущая версия NTP (v4) работает с использованием эр.
  • Одна эра составляет 136 лет (секунды, представленные 32-битным целым числом без знака). Или примерно

     60 * 60 * 24 * 365 * 136 = 4288896000 
    2 ^ 32 = 4294967296 
     
    4294967296 - 4288896000 = 6071296 
    6071296/60 / 60 ∕ 24 ≈ 70 (дней, не считая скачков) 
     
  • Эра 0: основная эпоха , или базовая дата «эры 0» , это 00:00 1 января 19:00 по всемирному координированному времени.

  • Эра 1: начинается где-то в начале 2036 года. (За два года до UNIX-2038)
  • Эра 2: начинается где-то в начале 2172 года.
  • и т. Д. (Для некоторых других примеров см. стр. 14 RFC 5905 .)
  • ntpdate использует временные метки NTP, которые являются 64-битными. 32-битный для секунд и 32-битный для дробей.
  • Возможно, немного сбивает с толку; NTP-дата использует 128 бит и включает эру. Это охватывает эпоху Вселенной и далекое будущее.

Как указано в разделе NTP « Проблема 2038 года » - страница Википедии , у вас есть абсолютный предел 68 лет между двумя NTP-метки времени. ( 136/2 = 68 ). Хотя, чтобы исключить двусмысленность, следует использовать более узкую полосу.

Отметки времени NTP работают со ссылкой на относительное, а не на абсолютное время; Сервер предоставляет клиенту поправку на относительное смещение относительно своего собственного времени. То есть: здесь не говорится:

- Дата 26 марта 2016 года

, а скорее (упрощенно, как работает NTP):

- Вы отключены на +123412512,918 секунды , или:
- вы вылетели по номеру -2652221.3466 секунд и т. Д.

Или процитируем RFC:

Метки времени представляют собой беззнаковые значения, и операции с ними производят результат в тех же или соседних эрах. Эра 0 включает даты от основной эпохи до некоторого времени в 2036 году, когда поле временной метки оборачивается вокруг и устанавливается базовая дата для эры 1.

В вашем случае, когда у вас 2099 год, у вас более 68 лет в будущем - примерно 15 лет. Вы попадаете в 2152 год, и мы имеем:

 2152 - 2016 = 136 (One era)

Или, другими словами:

                    2099 - 2036 = 63          (years into era 1)
        63 * 365 * 24 * 60 * 60 = 1986768000  (approx NTP time stamp for 2099)
       116 * 365 * 24 * 60 * 60 = 3658176000  (approx NTP time stamp for 2016)
       3658176000 - 1986768000  = 1671408000  (approx diff)
1671408000 / 60 / 60 / 24 / 365 = 53          (approx years)

1986768000 < 3658176000 thus add 1671408000

2099 + 53 = 2152 (the year your system was corrected to)

Итак, да, отвечая на ваш вопрос:

- Имеет ли ntpdate эффективный диапазон?

Да. ± 68 лет, хотя максимальный эффективный диапазон несколько уже.

NTP сам по себе бесконечен.

Если интересно, посмотрите RFC 5905 . Также обратите внимание, что устаревшие RFC могут содержать интересную информацию, такую ​​как Приложение E. Временная шкала NTP и ее хронометрия в RFC 1305 .


(PS: По сравнению с временными метками UNIX, 1970 + 68 = 2038 .)

4
27.01.2020, 21:16

Теги

Похожие вопросы