История с часами, или личная служба точного времени

Алексей Федорчук
6 сентября 2005 г

Эта история началась с приобретения мной ноутбука Toshiba. Я всегда испытывал недоверие к брэндовым компьютерам: стандарты брэндам не указ, и вечно идут они своим путем.

Так было и в этот раз. Все было хорошо в этой машинке — и экран, и клавиши, и вообще внешность, да и внутренности ей соответствовали вполне. И со всеми ее фичами вроде разобрался, за исключением одной детали: в BIOS мне попасть не удавалось никакими силами.

И не то чтобы я туда так уж стремился, по предыдущему опыту зная, что никаких особых настроек, влияющих на быстродействие, в ноутбучных BIOS’ах не бывает. А во всякого рода энергосберегающих режимах я решил пока положиться на умолчания, так как мало что в этом понимаю. Тем паче что никаких неожиданных неприятностей (типа отключений винчестера или снижений тактовой частоты) в умолчальных настройках вроде не обнаруживалось.

Лишь одно дело требовало хотя бы разового вхождения в BIOS — установка «хардверного» времени: мне оно требовалось по Гринвичу (т.н. UTC), а выставлено оно было по Москве, причем — в зимнем варианте. Казалось бы, мелочь — а не приятно.

К тому же на Unix-машинах несоответствие системного времени реальности может действительно доставить неприятности. Столкнувшись еще на заре своего Linux-юзания с ситуацией, когда команда make отказалась собирать какую-то нужную мне срочно программку на том основании, что изменения в Make-файле сделаны позже:-) текущего момента, я с тех пор всегда уделял юстировке времени особое внимание.

До BIOS’а я достучаться отчаялся (и в итоге достучался лишь случайно), но зато вспомнил про программу hwclock, именно для юстировки системного времени и предназначенную.

К слову сказать, бытует мнение, что системное время — это то же самое, что время «хардверное», то есть совпадает с показаниями часов BIOS. Для Unix-машин это не совсем так. Linux, скажем, или FreeBSD считывают «хардверное» время при загрузке системы, обрабатывают его определенным образом и в дальнейшем их внутреннее время от часов BIOS уже никак не зависит.

Порядок обработки «хардверного» времени зависит от того, по какому времени установлены часы BIOS — по местному (как это обычно бывает для Windows-персоналок), или по Гринвичу (в кругах юниксоидов оно именуется UTC — Coordinated Universal Time, всеобщее скоординированное время, видимо, дабы англичане через чур о себе не возомнили). Точнее, важно не то, как собственно установлены часы — а то, как они (посредством соответствующих параметров к конифгах) воспринимается системой.

Так вот, если система полагает «хардверное» время за местное, то оно принимается за системное без всяких модификаций. Если же система считает часы BIOS установленными по UTC — то то она не просто пересчитывает его в местное в соответствие с определенным часовым поясом, но и, руководствуясь некими зональными правилами, вводит принятую в данной зоне (сиречь государстве, если по простому) коррекцию летнего/зимнего времени — этого замечательного в своей бессмысленности изобретения, призванного затруднить жизнь трудящихся. А в нашей стране учитывается также и декретное время, за который следует благодарить дедушку Ленина…

Так что первый шаг в отладке службы точного времени — это определение системного времени как UTC и установка правильного часового пояса, что делается в одном из главных конфигурационных файлов каталога /etc. Для примера, в дистрибутиве Archlinux и родственных, использующих BSD-подобный стиль загрузки, этому служат специальные переменные в файле /etc/rc.confHARDWARECLOCK и TIMEZONE. Первой достаточно придать значение UTC. А значения второй выбираются среди имен файлов в каталоге /usr/share/zoneinfo, например — Europe/Moscow или Asia/Kamchatka.

В дистрибутивах, использующих стартовые скрипты в стиле SysV, все это может быть организовано несколько по другому (как именно, честно говоря, уже не помню), но принцип остается тем же.

Теперь собственно приступаем к установке времени, для чего нам и потребуется утилита hwclock. Данная без опций (или с опцией --show, подразумеваемой по умолчанию), она выдаст нам показания «хардверных» часов:

$ hwclock
Wed Jul 28 18:59:10 2004  -0.800155 seconds

А с помощью прочих опций значение «хардверного» времени можно изменить произвольным образом, привести его в соответствие с временем системным и наоборот.

Памятуя о том, что доступа к «хардверным» часам не имеется, действуем планомерно. Для начала в меру своего разумения выставляем время часов BIOS:

$ hwclock --set --date "20/07/2004 12:45:00" --utc

За особой точностью тут гнаться не стоит — на следующем этапе, при наличии выхода в Сеть, это можно будет сделать с высокой прецизионностью.

Теперь устанавливаем системное время по выставленному «хардверному»:

$ hwclock --hctosys

Теперь нам понадобится еще две вещи — пакет ntp (насколько я знаю, он входит во все «большие» дистрибутивы Linux, имеется в портах FreeBSD, а на худой конец может быть скачан с ntp.org/) и выход в Сеть. Если оба условия удовлетворены — для начала отправляемся на сайт http://www.eecis.udel.edu/~mills/ntp, где выбираем один из общедоступных серверов точного времени (по понятным причинам лучше выбирать тот, что поближе, хотя это и не обязательно). И даем команду

# ntp http://www.fortytwo.ch/time/


Все — наши системные часы приведены в соответствие с реальность с очень высокой степенью точности (время запаздывания будет дано в выводе команды). Остается отъюстировать в соответствие с ними часы «хардверные» — ведь они ставились в определенной степени «от фонаря»:

# hwclock --systohc

Став таким образом обладателем точных часов. Остается только время от времени корректировать их тем же образом — например, при каждом коннекте, ведь не секрет, что часы BIOS несколько уступают продукции Павла Буре или Картье.