![]() |
|
| Daemon News Ezine | BSD News | BSD Mall | BSD Support Forum | BSD Advocacy | BSD Updates |
Help, I've Fallenby Gary Kline and David LeonardWith this issue the Help, I've Fallen column enters its third year, and of course the column, like everything else, continues to evolve. This year we'll probably devote two or three columns to single-topic questions --this month we're discussing Time-and-the-single-computer. The remaining columns will be dedicated to random (actually, pseudo-random :-) and frequently-asked questions. The December issue will probably have both questions and links to this year's bunch of Q&A's. Dirk Myers is departing from the column, hopefully temporarily. Dirk had covered the NetBSD side of things and his tenure for the year-plus was certainly sterling. For those who don't know, Dirk is a real writer and self-taught compu-geek. David and Gary only pretend to be writers. Here's wishing you the best, Dirk. If there are any NetBSD-savvy volunteers out there who are willing to share their insights and knowledge on the NetBSD side and who have a few hours a month, this column could use your input! Drop a line. And now, without further ado, we're into some cosmic mysteries regarding Time
How do I set my entire system's time zone?The file /etc/timezone should be a symlink pointing at one of the files under /usr/share/zoneinfo. (See also: symlinks.) The files under the /usr/share/zoneinfo directory tree contain information about various world time zones--when daylight savings begins and ends, how far the time zone is ahead or behind UTC, and so forth. But, which file under /usr/share/zoneinfo? Simply choose the city name that is closest (or most relevant) to you. For example, if you live in El Paso, Texas, your timezone is locally known as Mountain Time so the file you want is /usr/share/zoneinfo/America/Denver: # rm /etc/timezone # ln -s /usr/share/zoneinfo/America/Denver /etc/timezone Similarly, if you live in London, England, use /usr/share/zoneinfo/Europe/London, or if you live out the back of Coonabarabran use /usr/share/zoneinfo/Australia/Sydney. Tid bit: Timezone files used to be organised by country or state name, but are now organised by city or geographic feature names. This is because too many countries tend to change their names, while city names tend to be more long lived. How do I change the timezone used by just one program (like xclock)?The TZ environment variable overrides the /etc/timezone setting. For example, to show the current time in Tokyo: $ env TZ=Asia/Tokyo xclock -digital & Sat Jan 15 09:34:57 JST 2000
Look in /usr/share/zoneinfo for other timezones.
What is the difference between GMT and UTC?The old GMT (Greenwich Mean Time) has effectively been replaced with UTC (Universal Coordinated Time). GMT was the time recorded by an atomic clock kept at Greenwich, England. UTC is based on another time standard called TAI which is derived from hundreds of atomic clocks in the national standards laboratories of many countries. TAI is slightly different from UTC: UTC is corrected roughly every eighteen months with a 'leap second' to agree with TAI. Still, GMT and UTC seem to be used interchangeably in the literature, except by hard core time geeks. Before the Unix zoneinfo files people had to specify their zone as an offset to GMT, e.g. as "GMT-10" or "GMT+7". You can still do this, but because the zoneinfo files so comprehensively cover all the world's inhabited timezones, there is little reason to do this. Tid bit: Because of an oversight in the POSIX standard, POSIX-compliant systems (like BSD Unix tries to be) are not allowed to take into account leap seconds! Today, POSIX systems must report a time that is about 15 seconds behind UTC. This explains why on some systems there is a zoneinfo directory called 'posix', and another directory called 'right'. Why, when I boot into Windows (or some other OS), is its clock off by some integer number of hours?! It gets annoying having to set the clock every time I switch between the two.This happens because BSD Unix stores the UTC time in the hardware clock chip, which is a chip with a battery that keeps time while your computer is switched off. The other operating systems reads the time stored in this chip (known as the RTC, or 'real time clock' chip) but interprets it as being the 'local' time (also known as the 'wall time'.) There are a few ways that you can get Unix to compensate for this. Kernel TIMEZONEIn all three BSDs a kernel setting called TIMEZONE can be used to correct for this. Simply re-configure your kernel, setting the TIMEZONE option to the number of minutes to adjust the hardware clock by. (See also: How do I rebuild a new kernel?) For example, in Brisbane, at GMT-10, which is -600 minutes offset, the following would go into the KERNEL config file: option TIMEZONE=-600 This matches the -10 hours in GMT-10. Thereafter MS Windows' clock will agree with Unix (as long as I don't leave Brisbane time and ignore Windows' Queensland daylight savings wrongness.) OpenBSDIn very recent versions of OpenBSD, you can avoid recompiling a kernel by running config to edit the kernel image. In the example below, I change my kernel's offset for the RTC to -600 minutes:
FreeBSDIn FreeBSD systems, if you set the CMOS time to your local time, you can use /stand/sysinstall to set your system time as appropriate. Then, as root, type and your time concerns are taken care of.# tzsetup In /etc/crontab, the system utility adjkerntz will adjust the local time in the CMOS clock and maintain the timezone offset for the kernel. This will insure that your DOS clock and files are correctly timestamped.
How can I keep my LAN-attached system time automatically synchronised?If you're permanently connected to the internet, or company LAN, you should consider using NTP (Network Time Protocol). ntpd (FreeBSD, OpenBSD) or xntpd (NetBSD) is a process that periodically contacts an NTP server to accurately correct for local clock drifts. It is very wise to set this up for security reasons (it makes later analysis easier, and closes some security holes based on inter-host timing. ntpd (xntpd) may be installed as part of the base system (NetBSD, FreeBSD), or as an add-on package (OpenBSD). First you'll need to find out from your network people which NTP server they recommend. For me its wasabi.it.uq.edu.au, so my /etc/ntp.conf file looks like this: server wasabi.it.uq.edu.au disable auth
Once you have the above information and have created your /etc/ntp.conf,
make sure that xntpd is installed and will run on restart, and reboot.
The reboot is only necessary in OpenBSD to bring the kernel out of secure
mode so that the sensitive clock adjustment hooks are exposed.
/etc/rc.conf (NetBSD, OpenBSD)
controls whether or not ntpd (xntpd) is started at boot time.
In FreeBSD the default start ups are given in /etc/defaults/rc.conf
(ntpd and xntpd are turned off by default), but you should put your local
changes in /etc/rc.conf or /etc/rc.conf.local.
How can I keep my dialin system time automatically synchronised?There are two relatively easy options for synchronising time for dialin systems: ntpdate and rdate.ntpdateNTP can be used here as well, but there is no need to have ntpd (xntpd)running all the time. To prevent ntpd (xntpd) from running at boot time, remove /etc/ntp.conf or turn off the service in /etc/rc.conf (FreeBSD, NetBSD, OpenBSD), or /etc/rc.conf.local (FreeBSD) - note the default given in /etc/defaults/rc.conf is to have both services off. Instead of running the background daemon, you should run the ntpdate program whenever you dial in. It will set the clock just once. If you are using kernel ppp, automation of this can be achieved for PPP connections by creating a shell script called /etc/ppp/ip-up and putting in lines similar to this: #! /bin/sh /usr/local/sbin/ntpdate ntphost.myisp.net &where you replace 'ntphost.myisp.net' with the name of your closest NTP server (ask your ISP for this information, or look for one on
If you are using the user-side ppp, this script will fit the bill:
#!/bin/sh
if [ `id -u` != 0 ]
then
echo "must exec this script as root"
echo "id is `id -u`"
exit 1;
fi
if [ -f /var/spool/lock/LCK..cuaa1 ]
then
ps -gax | grep -v grep | grep ppp
if test "$?" = "0"
then
/usr/local/sbin/ntpdate ntphost.myisp.net
exit 0;
else
#
# we've got a bogus LCK..cuaaN file.
#
exit 1;
fi
else
exit 1;
fi
Don't forget to use chmod to make /etc/ppp/ip-up executable! Tid bit: Some architectures, like the Apple Macintosh, lose time very badly because the periodic (60Hz) interrupt that drives the kernel is hard-wired to a low priority, and gets lost when the computer is under moderate I/O load (like network or disk transfers). As a consequence, time gets skewed very badly on the mac68k - I have seen skews of about 2 hours over one day. The bad news is that ntp gradually becomes afraid to reset the clock to the right time because the deviation gets so large and it prefers to trust the local computer. This is a good security measure but can get annoying. rdateAn alternative to NTP is to use rdate. It's a lot simpler and is bundled with the OpenBSD and NetBSD operating system. For FreeBSD rdate is in the ports tree. You only need to know the name of a computer that your ISP has that runs the RFC868 protocol (a very common protocol with Unix computers). If you ask and they have no idea what you are talking about, just try using one of their main servers--like their web server or mail host--to see if it works. Once you have found a computer you can run rdate against, you can automate it, too, by writing an /etc/ppp/ip-up script: #! /bin/sh ( /usr/sbin/rdate -sa some-computer.myisp.net; /usr/sbin/rdate -p >>/var/log/rdate ) & For the sake of completeness, here is a script for rdate if you are using user-ppp.
#!/bin/sh
RDATE=/usr/local/sbin/rdate ;
if [ `id -u` != 0 ]
then
echo "must exec this script as root"
echo "id is `id -u`"
exit 1;
fi
if [ -f /var/spool/lock/LCK..cuaa1 ]
then
ps -gax | grep -v grep | grep ppp
if test "$?" = "0"
then
(
$RDATE -sa athena > /dev/null 2>&1;
$RDATE -p athena >> /var/log/rdate.LOG
)
exit 0;
else
exit 1;
fi
else
exit 1;
fi
Be sure to read the short man page entry on rdate if you decide to use
it.
How can I keep my isolated system time automatically synchronised?In this situation, I'm assuming that you have more than one Unix computer on a small, private, isolated network. If you have an atomic clock, or special radio clock hardware you could run your own NTP server! But that's not very likely... Instead, BSD Unix normally comes with the timed server. If you run a timed server on all of your Unix computers on the one network, they will talk amongst each other and come up with an "average network time". That is, they all average the speed of their own clocks and use that to adjust for relative skew. It works reasonably well... on small networks.
In NetBSD and OpenBSD, timed is enabled by editing
/etc/rc.conf (look for "timed_flags"). In FreeBSD,
timed is enabled by modifying your /etc/rc.conf or
/etc/rc.local.conf. The default behavior from
/etc/defaults/rc.conf is off.
How do I run a program periodically?
Use cron(8).
Cron is well documented in the manual pages.
How do I get my program to run exactly once, later after I have logged off and gone home?A: The "at" command will do what you're looking for. at can run a list of commands either contained in a file or specified through standard input (interactively, through a pipe, or via redirection).The at command is an excellent way to time-shift any number of tasks that you can automate. This was touched upon in an earlier "Help I've Fallen" column and is worth revisiting here. What the man page may not make clear is that the interactive command line use syntax is: % at [time-shift specifications]<return> command list with one-per-line and end commands with a control-D, (^D). Example 1:
$ at 6am tomorrow mail -s "March, 2000 Plans" everybody@slave.dot.com < March00.Plans echo "Plans sent to entire work group" | ~jqs/records lpr -PMyDesk summary ^D Job 1 will be executed using /bin/sh $ Example 2:
$ at now + 25 minutes mail -s "uu.save tarball" smith@fubarr.net < /tmp/uu.save echo "uu.save sent to fubarr on `date`" | smith@homesite.org ^D Job 2 will be executed using /bin/sh You can also specify a file of commands with the -f flag as well as the time-shift spec and at will execute the commands consecutively for you at that time: % at -f FileList [time-shift specification]<return> or, it can accept commands from standard input given by the following syntax: % echo command | at [time-shift specification] Example 3:
echo lpr /tmp/list* | at 10pm In all cases, the results of your run will be neatly mailed to you by the "Atrun Service" rather than sent to your screen. NOTENecessary at.allow or at.deny files: As root you must create the file /var/at/at.allow and enter your login name (and the login of anyone who wishes to use the at command). Alternatively, you can create /var/at/at.deny and enter the names of anyone who shouldn't be allowed to use this utility. For the fine-grain details, see the manual page: % man at Why isn't make working? I modified some source files, but make just refuses to make! I've recently changed the clock but that shouldn't matter.Of course it matters. Make decides what to do by looking at the timestamps on files and the current time. Perhaps the clock has gone backwards in time since the last time you typed 'make'? This is likely if you have been playing with the clock or compiling things in single-user mode when the clock could have been wrongly set! Carefully examine all the files to see if they have strange dates. Look at the current time with the date command. Tid bit:
When viewing a listing with Amiga DOS, files with
times ahead of the system time were printed as
I was told that Unix clocks are fine for the year 2000, (and they were), but the clocks will stop in 2038? Why is that?
Well they won't exactly 'stop', but dates after approximately
That's because, in those Unixen, time is stored as the number of
seconds since the 'epoch' Other variants of Unix, including DEC Unix and some versions of Linux, have migrated from 32-bit time representations to 64-bit. This allows future time to be expressed up to about the year 292271023045, which is well after the sun has exploded, consumed the earth, and removed all traces of MS-DOS. There are some major reasons why switching to a 64-bit time_t is hard and isn't lightly approached. These mainly involve having to repair all the places where the size of the 32-bit time_t has been used in persistent/standard data structures such as filesystems, network protocols and so on. By the time this article goes to publication, the Year 2000 will have come and gone, and February 28 will be imminent. Based on your observations and media hype, what do you think you'll be doing in the year 2038? Hey man, chill out, we've got 38 years! :) About the AuthorsGary Kline has been porting code since the late 1970's when he helped port several V6 utilities to V7 at Cal Berkeley. When he isn't hacking code, he's hacking prose, or listening to jazz radio and drinking espresso. For more than three years he has been writing the software equivalent of a mind-machine and threatening to release an alpha port to FreeBSD--RSN. David Leonard is a PhD student in the Department of Computer Science and Electrical Engineering at the University of Queensland, Brisbane, Australia. His area of research is QoS-adaptive component software architectures, and in his spare time is a developer for the OpenBSD project. That said, David enjoys living the quiet life with his wife, Kylie and cat, Mu. He especially enjoys frequenting Moreton Bay's many fabulous places to eat. Mmmmm! |