Donnerstag, 5. Juli 2012

Synchronize clock in initial ramdisk


For some reason my server-system running Ubuntu 12.04 with full disk encryption refuses to boot after a crash due to power loss. I soon discovered, that often after powering on after a power loss, the system clock was reset to Jan 1 2002 (or something). This means that after entering the decryption-password the partitions refuse to mount because the "last mount timestamp" is in the future. There is something in the mount-init-script that corrects for such errors as long as the clock is not off by more than 24 hours. In my case it's off by several years. The system only boots when I set the correct date while in initial ramdisk.

To automate this, I thought let's just synchronize the clock via NTP. So I add ntpclient to the initial ramdisk and make sure it's executed automatically.

Step By Step


Download and compile ntpclient (http://doolittle.icarus.com/ntpclient/)
Note that the version provided there does not compile under ubuntu 12.04.
I created a fork on github that fixes that (https://github.com/ChristophGr/ntpclient/zipball/master)
Compile the ntp-client by invoking "make".

$ make
cc -fno-strict-aliasing -std=c89 -W -Wall -O2 -DENABLE_DEBUG -DENABLE_REPLAY   -c -o ntpclient.o ntpclient.c
cc -fno-strict-aliasing -std=c89 -W -Wall -O2 -DENABLE_DEBUG -DENABLE_REPLAY   -c -o phaselock.o phaselock.c
cc   ntpclient.o phaselock.o -lrt  -o ntpclient


now copy the resulting binary somewhere for the initial ramdisk to pick up. It should be a path that is not writable by regular users.

# cp ntpclient /usr/local/


Create a new file in the initial ramdisk source "/etc/initramfs-tools/hooks/ntpclient" and add the following content:

#!/bin/sh
PREREQ=""
prereqs()
{
        echo "$PREREQ"
}

case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac

. /usr/share/initramfs-tools/hook-functions

#
# Begin real processing
#

cp /usr/local/ntpclient ${DESTDIR}/sbin

make sure it's executable

# chmod +x /etc/initramfs-tools/hooks/ntpclient
In order to automatically invoke the ntpclient when booting, add this script to /etc/iniramfs-tools/scripts/local-premount

#!/bin/sh -e
# initramfs local-premount script for fixrtc

PREREQ=""

# Output pre-requisites
{
        echo "$PREREQ"
}

case "$1" in
    prereqs)
        prereqs
        exit 0
        ;;
esac

/sbin/ntpclient -s -h <ntp-server-ip>

exit 0;

Replace the ntp-server-ip with the IP (not the URL, as we don't have DNS-resolving in initrd) of an NTP-server close to you. To find one you can do

$ nslookup pool.ntp.org

Make sure the script is executable

# chmod +x /etc/initramfs-tools/scripts/local-premount/syncclock

To finish it, update your ramdisk

# update-initramfs -u

And you're done. From now on, your clock is synced via NTP during every boot before mounting.

Keine Kommentare:

Kommentar veröffentlichen