Skip to content
Snippets Groups Projects
Unverified Commit 113a77fa authored by Jakko's avatar Jakko Committed by Newbyte
Browse files

Add initial files to repository (MR 1)

parent 139b9b6d
No related branches found
No related tags found
1 merge request!1Add initial files to repository
Makefile 0 → 100644
install:
install -Dm 755 src/swclock-offset-boot.sh \
$(DESTDIR)$(PREFIX)/sbin/swclock-offset-boot
install -Dm 755 src/swclock-offset-shutdown.sh \
$(DESTDIR)$(PREFIX)/sbin/swclock-offset-shutdown
install_openrc:
install -Dm 755 openrc/swclock-offset-boot.initd \
$(DESTDIR)/etc/init.d/swclock-offset-boot
install -Dm 755 openrc/swclock-offset-shutdown.initd \
$(DESTDIR)/etc/init.d/swclock-offset-shutdown
# swclock-offset
Some devices have a working but non-writable real-time clock (RTC).
This repository contains two shell scripts: One writes the offset between
'hwclock' and 'swclock' to a file at shutdown, another one reads the
offset from the file at boot and sets the 'swclock'. This way the system
time in userspace is kept in present time.
## Build
The repository contains a simple Makefile. By `make install` the two
shell scripts get installed to `/sbin`. Adding `PREFIX=/usr` places them
to `/usr/sbin`. Variable `DESTDIR` allows to change the install path to
something like `DESTDIR=$pkgdir`.
To install the two OpenRC service files, perform `make install_openrc`.
They get installed to `/etc/init.d`. Variable `DESTDIR` applies here as
well, `PREFIX` does not.
## Managing OpenRC services
After installing the files, OpenRC services need to be set accordingly.
### Replace service hwclock by osclock
The service "osclock" is a dummy service simply providing "clock".
This avoids other services that need "clock" to call the service
"hwclock".
```
rc-update -q del hwclock boot
rc-update -q add osclock boot
```
### Assign swclock-offset services to runlevels "boot" and "shutdown"
The service "swclock-offset-boot" needs to run after the sysfs has
been mounted. As the sysfs is mounted in runlevel sysinit, assigning
the service to runlevel boot is enough to keep the order.
```
rc-update -q add swclock-offset-boot boot
rc-update -q add swclock-offset-shutdown shutdown
```
### Update dependency tree cache
Before installation of the package "swclock-offset", the system time
might jump back and forth. Because of this, OpenRC can get confused
whether the cached dependency tree is old or new. To avoid this
uncertainty, trigger an update of the dependency tree cache.
```
rc-update -q --update
```
### On package removal
Restore the original state of the services.
```
rc-update -q del swclock-offset-boot boot
rc-update -q del swclock-offset-shutdown shutdown
rc-update -q del osclock boot
rc-update -q add hwclock boot
```
## systemd service files
Files for systemd are not available yet. Basically they should be set
up in a similar way like the OpenRC service files.
The script `swclock-offset-boot` needs to be executed once during boot,
after sysfs becomes available (because it reads `/sys/class/rtc/rtc0/since_epoch`)
and before fsck (because fsck complains if timestamps are inconsistant).
On shutdown, the script `swclock-offset-shutdown` needs to be executed
once. This needs to be done before the filesystems get unmounted because
the script writes the offset to the file `/var/cache/swclock-offset/offset-storage`.
Additionally, like on OpenRC, the usual synchronization between hwclock
and swclock needs to be disabled (likely some other systemd service that
needs to be disabled).
## Delete cache file and folder on package removal
Independent of the init system, on package removal the cache file and
its folder should be removed as a clean-up action. This can be done by
e.g.:
```
#!/bin/sh
offset_file="/var/cache/swclock-offset/offset-storage"
offset_directory="/var/cache/swclock-offset"
if [ -f $offset_file ]; then
rm $offset_file
fi
if [ -d $offset_directory ]; then
rmdir $offset_directory
fi
```
#!/sbin/openrc-run
# To avoid time inconsistency at filesystems check, the system time
# shall be set before "fsck".
description="Setting the system time according to an offset file."
depend()
{
before fsck
}
start()
{
ebegin "Setting system time"
/sbin/swclock-offset-boot
eend $?
}
stop()
{
return 0
}
#!/sbin/openrc-run
# A dedicated shutdown service is used to write the offset file instead
# of using the stop function of the swclock-offset service at boot. This
# approach is more fail-safe on different installation/deinstallation
# situations.
#
# Because the shutdown services are performed late within the shutdown
# runlevel, dependencies are needed to execute the script before
# processes are killed and filesystems are remounted read-only.
description="Writing the offset between system time and RTC to a file."
depend()
{
before killprocs mount-ro
}
start()
{
ebegin "Saving swclock-offset"
/sbin/swclock-offset-shutdown
eend $?
}
stop()
{
return 0
}
#!/bin/sh
# SPDX-FileCopyrightText: 2021 Jakob Hauser <jahau@rocketmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This shell scripts reads the offset from the file and sets the 'swclock'.
#
# To keep the offset calculation simple, the epoch timestamp is used.
#
# The RTC is read from the sysfs node.
#
# To set the system time, command "date" is used. The "@" sign marks an
# epoch time format. As the "date" command offers no quiet option, the
# output is written to the null device.
rtc_sys_node="/sys/class/rtc/rtc0/since_epoch"
offset_file="/var/cache/swclock-offset/offset-storage"
# check presence of rtc sys node
if [ ! -f $rtc_sys_node ]; then
exit 1
fi
# check presence of offset file
if [ ! -f $offset_file ]; then
exit 2
fi
# calculate system time
hwclock_epoch=$(cat $rtc_sys_node)
offset_epoch=$(cat $offset_file)
swclock_epoch=$((hwclock_epoch + offset_epoch))
# set system time, dump output
date --utc --set=@$swclock_epoch > /dev/null
#!/bin/sh
# SPDX-FileCopyrightText: 2021 Jakob Hauser <jahau@rocketmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This shell scripts writes the offset between 'hwclock' and 'swclock'
# to a file.
#
# To keep the offset calculation simple, the epoch timestamp is used.
#
# The system time is read by command "date". The RTC is read from the
# sysfs node.
rtc_sys_node="/sys/class/rtc/rtc0/since_epoch"
offset_directory="/var/cache/swclock-offset"
# check presence of rtc sys node
if [ ! -f $rtc_sys_node ]; then
exit 1
fi
# check presence of offset directory
if [ ! -d $offset_directory ]; then
mkdir -p $offset_directory
fi
# calculate offset
swclock_epoch=$(date --utc +%s)
hwclock_epoch=$(cat $rtc_sys_node)
offset_epoch=$((swclock_epoch - hwclock_epoch))
# write offset file
echo $offset_epoch > $offset_directory/offset-storage
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment