main/swclock-offset: new package (MR 2191)

Some devices have a working but non-writable real-time clock (RTC).
This package 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.

[ci:skip-build] already built successfully in CI
This commit is contained in:
Jakob Hauser 2021-05-24 07:26:28 +02:00 committed by Clayton Craft
parent 4c0ec94eb4
commit e6b0103b8c
No known key found for this signature in database
GPG key ID: 7A3461CA187CEA54
9 changed files with 189 additions and 1 deletions

View file

@ -15,6 +15,7 @@ fi
# Shell: shellcheck
sh_files="
./main/mdss-fb-init-hack/mdss-fb-init-hack.sh
./main/postmarketos-base/rootfs-usr-lib-firmwareload.sh
./main/postmarketos-mkinitfs/init.sh.in
./main/postmarketos-mkinitfs/init_functions.sh
@ -23,7 +24,8 @@ sh_files="
./main/postmarketos-mkinitfs/mkinitfs_test.sh
./main/postmarketos-mkinitfs-hook-debug-shell/20-debug-shell.sh
./main/postmarketos-update-kernel/update-kernel.sh
./main/mdss-fb-init-hack/mdss-fb-init-hack.sh
./main/swclock-offset/swclock-offset-boot.sh
./main/swclock-offset/swclock-offset-shutdown.sh
$(find . -path './main/postmarketos-ui-*/*.sh')
$(find . -path './main/postmarketos-ui-*/*.pre-install')

View file

@ -0,0 +1,31 @@
# Maintainer: Jakob Hauser <jahau@rocketmail.com>
pkgname=swclock-offset
pkgver=0.1
pkgrel=0
pkgdesc="Keep system time at an offset to a non-writable RTC"
url="https://gitlab.com/postmarketOS/pmaports"
arch="noarch"
license="GPL-3.0-or-later"
install="$pkgname.post-deinstall"
subpackages="$pkgname-openrc"
source="$pkgname-boot.initd $pkgname-shutdown.initd $pkgname-boot.sh $pkgname-shutdown.sh"
options="!check" # No tests
package() {
install -Dm755 "$srcdir/$pkgname-boot.initd" "$pkgdir/etc/init.d/$pkgname-boot"
install -Dm755 "$srcdir/$pkgname-shutdown.initd" "$pkgdir/etc/init.d/$pkgname-shutdown"
install -Dm755 "$srcdir/$pkgname-boot.sh" "$pkgdir/sbin/$pkgname-boot"
install -Dm755 "$srcdir/$pkgname-shutdown.sh" "$pkgdir/sbin/$pkgname-shutdown"
}
openrc() {
install="$subpkgname.post-install $subpkgname.pre-deinstall"
default_openrc
}
sha512sums="
777dff161dcae742d1bfb7acbf413a319c9e623292a315ccd8cf5f3f0df9258d54d3e9891bdff741a6146ab285bc5a27c7921bc93902b4a2006104666a835ecd swclock-offset-boot.initd
a834fe9f721a4797f5675361fe07b500f93a2082753ed0a0fd583ccfd49738acfe04fb526e2936f3ce270053d151c7080a6a5356246fb816638e72992c6f77db swclock-offset-shutdown.initd
288373bef5d7e5a64d118396491b424fb9cd38bfb3e7c422762c4c1441894617e59140035cd824846880c159fe3b9f6f8ceaddd552014e53b4e0ab05da7931dc swclock-offset-boot.sh
49f2ac3b4f41904097d1b5e903b810abd3da005972fffc14bd34d3c25aaa9b92d293a10bfa4348e160060670ed19d50e06ac6c9b8ebe663e56bf30e36c28edf9 swclock-offset-shutdown.sh
"

View file

@ -0,0 +1,23 @@
#!/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
}

View file

@ -0,0 +1,32 @@
#!/bin/sh
# 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

View file

@ -0,0 +1,17 @@
#!/bin/sh
# The service "osclock" is a dummy service simply providing "clock".
# This avoids other services that need "clock" to call the service
# "hwclock".
#
# 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.
# replace service hwclock by osclock
rc-update -q del hwclock boot
rc-update -q add osclock boot
# assign swclock-offset services to runlevels
rc-update -q add swclock-offset-boot boot
rc-update -q add swclock-offset-shutdown shutdown

View file

@ -0,0 +1,11 @@
#!/bin/sh
# This script restores the original state.
# remove swclock-offset services
rc-update -q del swclock-offset-boot boot
rc-update -q del swclock-offset-shutdown shutdown
# replace service osclock by hwclock
rc-update -q del osclock boot
rc-update -q add hwclock boot

View file

@ -0,0 +1,29 @@
#!/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
}

View file

@ -0,0 +1,30 @@
#!/bin/sh
# 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

View file

@ -0,0 +1,13 @@
#!/bin/sh
# remove offset file and directory
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