В Украине отменен переход на зимнее время. Верховная Рада поддержала законопроект №8330 «Об изменении порядка исчисления времени на территории Украины». В связи с этими законодательными инновациями, на плечи украинских IT-шников легла производственная задача — 30 октября 2011 навсегда остаться в киевском летнем времени. Теперь этот часовой пояс в unix называется FET — Further-eastern European Time или дальневосточно-европейское время.
Время в Linux. Теория
Текущий часовой пояс в ОС Linux устанавливается файлом /etc/localtime. Этот файл представляет собой ссылку на информационный файл зоны или его копию, в большинстве дистрибутивов расположенный в каталоге /usr/share/zoneinfo. В данном каталоге размещена zoneinfo database база данных информации о зонах, или другими словами, tz database (timezone database — база данных часовых поясов) — совместно собираемая информация о мировых временных зонах. Иногда она упоминается как «база данных Олсона» (Olson database), так как была основана Артуром Дэвидом Олсоном (Arthur David Olson). Редактором и хранителем базы является Пол Эггерт (Paul Eggert). Обновления кода базы данных часовых поясов можно получить непосредственно из источника на
Как не перейти на зимнее время. Решение
Качаем обновление tzdata2011k.tar.gz от 26 сентября 2011 года, в котором присутствует информация по новым часовым поясам для Украины, в которое вошли зоны Europe/Kiev, Europe/Uzhgorod, Europe/Zaporozhye, Europe/Simferopol.
Распаковываем
mkdir tz
mv tzdata2011k.tar.gz ./tz
cd tz/
tar xzf tzdata2011k.tar.gz
Перед внесением изменений проверим переходы времени для нашей текущей зоны. Видим ежегодное расписание переходов времени зимнее/летнее вплоть до 2038 года.
zdump -v Europe/Kiev
...
Europe/Kiev Sun Mar 27 00:59:59 2011 UTC = Sun Mar 27 02:59:59 2011 EET isdst=0 gmtoff=7200
Europe/Kiev Sun Mar 27 01:00:00 2011 UTC = Sun Mar 27 04:00:00 2011 EEST isdst=1 gmtoff=10800
Europe/Kiev Sun Oct 30 00:59:59 2011 UTC = Sun Oct 30 03:59:59 2011 EEST isdst=1 gmtoff=10800
Europe/Kiev Sun Oct 30 01:00:00 2011 UTC = Sun Oct 30 03:00:00 2011 EET isdst=0 gmtoff=7200
...
Europe/Kiev Sun Oct 25 00:59:59 2015 UTC = Sun Oct 25 03:59:59 2015 EEST isdst=1 gmtoff=10800
Europe/Kiev Sun Oct 25 01:00:00 2015 UTC = Sun Oct 25 03:00:00 2015 EET isdst=0 gmtoff=7200
...
Убедимся в наличии необходимого обновления
vi europe
...
Zone Europe/Kiev 2:02:04 - LMT 1880
2:02:04 - KMT 1924 May 2 # Kiev Mean Time
2:00 - EET 1930 Jun 21
3:00 - MSK 1941 Sep 20
1:00 C-Eur CE%sT 1943 Nov 6
3:00 Russia MSK/MSD 1990
3:00 - MSK 1990 Jul 1 2:00
2:00 - EET 1992
2:00 E-Eur EE%sT 1995
2:00 EU EE%sT 2011 Mar lastSun 1:00u
3:00 - FET # Further-eastern European Time
...
На всякий случай делаем резервную копию файла с текущими настройками:
mv /etc/localtime /etc/localtime-old
Компилируем временные зоны для Европы. zic читает текстовый файл с описаниями зон и на выходе формирует файлы специфического формата. Стоит обратить внимание что без ключа -d пишет файлы временных зон сразу в /usr/share/zoneinfo, что нам и необходимо.
cat /etc/sysconfig/clock | grep ZONE
ZONE="Europe/Kiev"
После обновления проверим переходы времени для нашей текущей зоны. В последний раз переход произошел Mar 27 04:00:00 2011
zdump -v Europe/Kiev
...
Europe/Kiev Sun Mar 27 00:59:59 2011 UTC = Sun Mar 27 02:59:59 2011 FET isdst=0 gmtoff=7200
Europe/Kiev Sun Mar 27 01:00:00 2011 UTC = Sun Mar 27 04:00:00 2011 FET isdst=0 gmtoff=10800
Europe/Kiev Mon Jan 18 03:14:07 2038 UTC = Mon Jan 18 06:14:07 2038 FET isdst=0 gmtoff=10800
Europe/Kiev Tue Jan 19 03:14:07 2038 UTC = Tue Jan 19 06:14:07 2038 FET isdst=0 gmtoff=10800
Убедимся, что 30 октября 2011 года время будет «непереход» на зимнее время.
# date
Wed Sep 28 15:48:51 FET 2011
# date --date='768hours'
Sun Oct 30 15:48:58 FET 2011
PS: Всвязи с судебными процедурами, и временной недоступностью первоисточника размещаю копию tzdata2011k.tar.gz.
PS: Для тех кто уже перевел, выкладываю предыдущую версию TZ данных без изменений по Украине от 20 сентября, отмененных 18 октября 2011tzdata2011j.tar.gz
Замечу сразу, ниже описанное, справедливо для рабочих станций которые не являются членами домена, для AD настройка выполняется иным образом, об этом позднее.
Синхронизацией времени в XP озабочена «служба времени Windows» (W32Time), конфигурирование которой зачастую выполняют правкой реестра. Наиболее часто используемые параметры, это список источников времени и интервал синхронизации, через который и происходят обращения к источникам. Обращаю внимание, что при синхронизации используется только один источник, даже если список содержит более обширный перечень. Более одного источника указывают для резервирования, таким образом, при недоступности первого, служба времени перебирает список источников до успешного выполнения синхронизации.
Список источников W32Time настраивается через следующий ключ реестра:
Ключ NtpServer разделяемый пробелами список серверов времени, заданный либо доменным именем, либо непосредственно IP адресом. Каждый сервер может иметь установленные шестнадцатеричные значения флагов, указываемые через запятую после сервера.
Существует 4 возможных значений флагов:
0×01 SpecialInterval
0×02 UseAsFallbackOnly
0×04 SymmatricActive
0×08 Client
При использовании флага SpecialInterval, необходимо установленное значение интервала в ключе «SpecialPollInterval»:
По умолчанию интервал между обновлениями времени в Windows — 1 неделя (604800 сек). При низкой точности системных часов компьютера это слишком большой интервал. При такой настройке за 1 неделю часы Вашего компьютера могут получить погрешность величиной порядка минуты или даже нескольких минут. Рекомендую уменьшить интервал обновления до нескольких часов. Это изменение не увеличит ни трафика, ни нагрузки на NTP-сервер, при этом позволит поддерживать более высокую точность хода часов Вашего компьютера.
При значении флага UseAsFallbackOnly службе времени сообщается, что данный сервер будет использоваться как резервный и перед синхронизацией с ним будут выполнятся обращения к другим серверам списка.
После внесения необходимых настроек в можно перечитать конфигурацию сохраненную в реестре коммандой приведенной ниже, или перезагрузить компьютер.
w32tm /config /update
И при необходимости выполнить немедленную синхронизацию
Переход на летнее время осуществляется в последнее воскресенье марта. Переход на нормальное поясное время осуществляется в последнее воскресенье октября. Из-за этого октябрь является самым длинным месяцем года. Иногда, нормальное поясное время называют «зимним», но данный термин не является корректным.
Перевод часов на зимнее время на территории Российской Федерации выполняется в 3:00 по московскому времени путем перевода стрелки часов на 1 час назад, т.е. с 3:00 на 2:00. На Украине данная процедура осуществляется с 4:00 на 3:00, т.е синхронно с РФ.
Перевод часов на летнее время на территории Российской Федерации выполняется в 2:00 по московскому времени путем перевода стрелки часов на 1 час вперед, т.е. с 2:00 на 3:00. На Украине данная процедура осуществляется с 3:00 на 4:00.
Основное обоснование перевода часов на летнее время — экономия электроэнергии, составляющая по различным источникам 0.5 — 2% годового её потребления.
Для каждого ситемного администратора важно знать, произойдет ли, переход на новое время
корректно. Проверить перевод времени для Linux серверов можно следующими коммандами
# date --date='3660hours'
Sun Mar 28 02:59:58 EET 2010
# date --date='3660hours'
Sun Mar 28 04:00:04 EEST 2010
При этом необходимо помнить о синхронизации времени в сети и присутствию точных источников времени для синхронизации.
Вместо введения, или попытка ответить на вопрос «Зачем?»
Время — одно из важнейших понятий современного мира. Все события имеют определенные координаты на временной оси. Трудно переоценить важность синхронизации времени в IT структуре в различных аспектах управления, безопасности, планирования, отладки, а также, при анализе причин аварий, в особенности, когда требуется определение времени происхождения событий. Асинхронность во времени может приводить к деградации производительности и полному останову кластерных систем. Для распределенных систем измерения и регистрации не синхронность времени приводит к некорректности одномоментных измерений, и последующих расчетов. Для финансовых систем неточность времени может приводить к проблемам с законом.
Один из способов синхронизации времени — это использование внешнего пула серверов времени. Списки серверов можно получить на www.ntp.org. Однако, есть ряд минусов:
это определенного рода уязвимость вашей системы — должен быть открыт UDP порт 123, по которому осуществляется синхронизация;
потеря точности, при использовании внешних каналов связи;
негарантированность постоянной поддержки внешних сервисов времени;
некоторые сети не могут быть подключены к глобальной сети, по различным причинам
Другой способ синхронизации — собственный сервер времени c использованием GPS датчика. При этом данный способ лишен вышеописанных недостатков, а также, такой источник, как GPS имеет stratum 0, т.е. минимально возможную удаленность от эталона.
Далее рассмотрим создание собственного сервера времени, на основе датчика Garmin GPS16-HVS, и сервера с ОС Linux.
Аппаратная часть
Подключение Garmin GPS16-HVS
Информационные интерфейсы, а их в датчике два, реализованы в виде RS-232. Garmin GPS16-HVS поставляется с 5 метровым кабелем оконеченным разъемом RJ-45 (Таблица — 1). Для подключения устройства к серверу необходимо изготовить кабель, как показано на рисунке 1. В отличие, от официальной инструкции, для подключения сигнала PPS, с целью повышения точности до 1 микросекунды, необходимо подключить 6 контакт разъема RJ-45 на 1 контакт разъема DB-9 (на рисунке указано синим цветом). В качестве блока питания используется источник постоянного тока, согласно инструкции допустимый диапазон напряжений от 8 до 40 вольт. Порт 1 используется для передачи сигналов с стандарте «NMEA 0183, Version 3.0″, порт 2 — «RTCM Recomeded Standards For Differential Navstar GPS Service, Version 2.2, RTCM Special Committee No.104″. В данном описании используется порт 1.
Таблица — 1. Описание разъема RJ-45 датчика Garmin GPS16-HVS
RJ-45
Провод
Наименование
1
Красный
POWER
2
Черный
GROUND
3
Желтый
REMOTE POWER ON/OFF
4
Синий
Port 1 DATA IN
5
Белый
Port 1 DATA OUT
6
Серый
PPS
7
Зеленый
Port 2 DATA IN
8
Фиолетовый
Port 2 DATA OUT
Рисунок — 1. Схема подключения Garmin GPS16-HVS к RS-232
Настройка порта и конфигурирование датчика
С помощью minicom c опцией «-s» настроим работу соответствующего COM порта (для COM1 — /dev/ttyS0) для работы с Garmin GPS16-HVS. Для этого в секции Serial port setup установим Serial Device соответственно /dev/ttyS0 и следующие параметры порта 4800 8N1 (4800 baud, no parity, 8 data bits, 1 stop bit.), именно такие заводские установки датчика. Если на предыдущих этапах все было выполнено корректно, то после конфигурирования порта увидим NMEA поток похожий на такой:
Примечание: Если подобного не увидели, а на вывод идет «мусор» по структуре напоминающий NMEA, проверьте 5 и 2 контакты могут быть некорректно вами разведены.
Из всех последовательностей NMEA достаточно использовать $GPRMC, остальные отключим. Для задействования сигналов PPS включим режим распознавания PPS. Для этого сформируем командный файл gpsedit следующего содержания:
Анализируя NMEA поток, можно понять, получает ли датчик сигналы от спутников, см. инструкцию. Для успешной синхронизации необходимо установить связь со спутниками. Сигнал не может проникать через стены, поэтому расположить датчик необходимо вне помещения или хотя бы у окна.
Программная часть
Компиляция ядра с поддержкой PPS
Чтобы максимально приблизится к заявленной точности GPS датчика (10E-6 сек), необходима поддержка PPSAPI (RFC-2783) на уровне ядра операционной системы. Для обеспечения поддержки ядром потребуется две вещи, во-первых, исходные коды ядра Linux, которые можно получить на kernel.org (предпочтительнее использовать наиболее свежую версию ядра), и во-вторых, соответствующий ядру patch, при написании данной статьи были использованы: ядро linux-2.6.30.4 и patch ntp-pps-v2.6.30-rc5-bis.diff.
К распакованным исходным кодам ядра применим полученный patch
$ cd /usr/src/kernels/linux-<ваша версия ядра>
$ patch -p1 < ntp-pps-<ваша версия patch>.diff
Далее необходимо скомпилировать ядро с поддержкой PPS. Выполним команду конфигурирования ядра, и как один из множества вариантов рассмотрим:
$ make menuconfig
В разделе Device Drivers, находим добавленную нами секцию PPS support, в которой выполняем следующие установки.
<M> PPS support
[ ] Use low level IRQ timestamps
[ ] PPS debugging messages
*** PPS clients support ***
< > Kernel timer client (Testing client, use for debug)
<M> PPS line discipline
*** Parallel printer support (forced off) ***
По желанию можно дополнительно включить режим PPS debugging messages, для получения более информативного вывода на этапе отладки, на рабочей системе лучше его не использовать, чтобы не загрязнять логи.
На этапе конфигурирования ядра незабываем о прочих параметрах необходимых для правильного функционирования вашей системы, драйверах устройств, кодировках, поддержке файловых систем и т.п.
Для удобства эксплуатации в разделе General setup можно использовать суффикс добавляемый к ядру
(.pps) Local version - append to kernel release
Записываем конфигурацию ядра, компилируем и устанавливаем.
# make
# make modules_install install
На данном этапе перезагружаем систему с новым ядром.
Инструменты
Перед тем как приступать к компиляции инструментов обновим заголовки, в соответствии с новым ядром
$ cd /usr/src/kernels/linux-<ваша версия ядра>/Documentation/pps
$ make
Для удобства использования копируем ppstest в один из каталогов, прописанный в переменной окружения PATH
cp /usr/src/kernels/linux-<ваша версия ядра>/Documentation/pps/ppstest /usr/sbin/
Кроме этого необходим инструмент ldattach, содержащийся в пакете util-linux-ng версии 2.14 и выше. Исходные коды util-linux-ng можно взять на kernel.org. При написании данной статьи был использован пакет версии 2.16.
Исходный файл ldattach.c, после блока
switch (parity) {
case 'n':
ts.c_cflag &= ~(PARENB|PARODD);
break;
case 'e':
ts.c_cflag |= PARENB;
ts.c_cflag &= ~PARODD;
break;
case 'o':
ts.c_cflag |= (PARENB|PARODD);
break;
}
необходимо дополнить следующими строками:
if (ldisc == 18)
ts.c_iflag |= (IGNBRK|ICRNL);
Это обеспечивает корректную работу с PPS сигналами, совместно ldattach и ntpd.
Включение PPS
При работе ntpd будет необходима сиволическая ссылка на устройство pps. Для этого в файл /etc/udev/rules.d/50-udev.rules добавим следующую строку:
После успешной подготовки ядра и необходимого инструментария можно приступить к компиляции ntp, исходные коды берем на www.ntp.org. Для использования PPSAPI ядра, реализованного на предыдущем этапе необходимо установить LinuxPPS NMEA Patch.
Применяем patch к файлу refclock_nmea.c, после чего конфигурируем ntp, кроме подключения используемых далее драйверов, настраиваем каталоги в которых после установки будут размещены файлы поддержки протокола ntp. Компилируем.
$ cd /usr/src/ntp-<ваша версия>
$ patch -p1 < nmea.patch
$ ./configure --sysconfdir=/etc --prefix=/usr --libdir=/var/lib --enable-ATOM --enable-NMEA \
--enable-LOCAL-CLOCK
$ make
Установим несколько позже, а именно после успешного тестирования.
Конфигурирование ntpd
Поддержка большинства широко распространенных аппаратных источников времени включена в стандартную конфигурацию NTP демона для UNIX-систем. Аппаратные часы согласно соглашению имеют адрес вида 127.127.t.u, где t - тип драйвера аппаратных часов, u - номер экземпляра устройства в диапазоне 0-3, для обеспечения возможности использования нескольких устройств одного типа. Для подключения Garmin можно использовать два типа драйверов:
20 - Generic NMEA GPS Receiver (NMEA)
22 - PPS Clock Discipline (PPS)
Хотя достаточно только 20-го, при совместном использовании 20 и 22 драйверов преимуществ не выявлено, таким образом рассмотрим подробно остановимся на 20 - Generic NMEA GPS Receiver (NMEA).
Для обеспечения работы драйвера NMEA, необходимо создать символические ссылки вида /dev/gpsU и /dev/gpsppsU, где u - номер экземпляра, таким образом:
Этот драйвер поддерживает GPS приемники с выводом последовательностей NMEA $GPRMC по умолчанию, и $GPGGA или $GPGLL как альтернативные. Точность приема зависит от используемого приемника. Тем не менее, в большинстве случаев реальная точность ограничена точностью тайм-кода и латентностью последовательного интерфейса и операционной системы.
Драйвер может использовать поддержку PPSAPI (RFC-2783) уровня операционной системы.
Алтернативные последовательности NMEA могут быть использованы путем задания опции mode в конфигурационной строке server, допускается использование нескольких последовательностей:
server 127.127.20.u mode X
bit 0 - задействует $GPRMC (значение = 1)
bit 1 - задействует $GPGGA (значение = 2)
bit 2 - задействует $GPGLL (значение = 4)
Конфигурационная строка fudge:
time1 time
Параметер калибровки - указывает время смещения, в секундах с плавающей точкой, по умолчанию 0.0.
stratum number
Указывает stratum драйвера, целочисленное от 0 до 15, по умолчанию 0.
refid string
Указывает идентификатор драйвера, ASCII строка от 1 до 4 знаков, по умолчанию GPS.
flag2 0 | 1
Указывает какой фронт сигнала PPS использовать: 0 - передний (по умолчанию), 1 - задний
flag3 0 | 1
Использование PPS дисциплины ядра: 0 - выключено (по умолчанию) , 1 - включено.
Таким образом, добавим следующие сроки в файл /etc/ntp.conf
server 127.127.20.0 minpoll 4 prefer
fudge 127.127.20.0 flag3 1
Запускаем ntpd и в messages видим следующее
Sep 8 11:20:04 db ntpd[441]: ntpd 4.2.4p7@1.1607-o Mon Sep 7 10:46:54 UTC 2009 (3)
Sep 8 11:20:04 db ntpd[442]: precision = 1.000 usec
Sep 8 11:20:04 db ntpd[442]: Listening on interface #0 wildcard, 0.0.0.0#123 Disabled
Sep 8 11:20:04 db ntpd[442]: Listening on interface #1 lo, 127.0.0.1#123 Enabled
Sep 8 11:20:04 db ntpd[442]: Listening on interface #2 eth0, 10.1.2.36#123 Enabled
Sep 8 11:20:04 db ntpd[442]: Listening on interface #3 eth0:0, 192.168.0.254#123 Enabled
Sep 8 11:20:04 db ntpd[442]: kernel time sync status 0040
Sep 8 11:20:04 db ntpd[442]: refclock_nmea: found GPS source "/dev/gps0"
Sep 8 11:20:04 db ntpd[442]: refclock_nmea: try "/dev/gpspps0" for PPS
Sep 8 11:20:04 db ntpd[442]: refclock_nmea: found PPS source "/dev/gpspps0"
Sep 8 11:20:04 db ntpd[442]: refclock_nmea: time_pps_kcbind failed: Operation not supported
Sep 8 11:20:04 db ntpd[442]: frequency initialized 45.546 PPM from /var/lib/ntp/drift
Примечание: refclock_nmea: time_pps_kcbind failed: Operation not supported - это нормально, согласно RFC 2783 данная функция является опциональной, и в LinuxPPS не поддерживается.
После запуска ntpd, если ntp.drift не существует или его данные относятся к другим источникам времени, ntpd вводит специальный режим, позволяющий откорректировать осциллятор системных часов и частоту ошибок, что занимает около 15 минут, после чего ntpd начинает работать в нормальном режиме. Файл ntp.drift - содержит последнюю расчетную частоту ошибок, и записывается каждый час.
После этого можем проверить результаты:
# ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
*127.127.20.0 .GPS. 0 l 12 16 377 0.000 0.014 0.001
10.1.2.254 10.1.2.36 2 u 7 64 377 1.173 -1.069 0.839
10.1.2.2 10.1.2.36 2 u 59 64 377 0.139 -8.971 0.117
127.127.1.0 .LOCL. 10 l 4 64 377 0.000 0.000 0.001
Как указывает строка 127.127.20.0, расхождение с эталоном составляет 14 микросекунд, дрожание 1 микросекунда, что соответствует заявленным характеристикам точности GPS приемника. Результат достигнут.