Hello Lukas Wunner,

Thanks for following up with both a new proposal and patch!

On Mon, Feb 27, 2017 at 02:34:34PM +0100, Lukas Wunner wrote:
[...]
> Okay, let's define a policy first.  How about:
> 
> (1) Users can set HWCLOCKACCESS=no in /etc/default/hwclock to prohibit
>     setting the system time or time zone from any RTC.  (The parameter
>     is already defined in the config file, but it's not honored by
>     hwclock-set.)
> 
> (2) Users can set HCTOSYS_DEVICE in /etc/default/hwclock to constrain
>     setting the system time or time zone to a specific RTC.  (Same as
>     above, parameter is already defined but not honored by hwclock-set.
>     This will also fix #785445.)  If this parameter is not set,
>     hwclock-set will pick the first RTC that becomes available.
> 
> (3) If the kernel has already set the system time from *any* hwclock,
>     we don't set it once more in hwclock-set.  (We only adjust the
>     timezone.)

(3. would unfix #785445 from 2. again though, right? Maybe also support
HWCLOCKACCESS=force which skips 3. would really offer a solution
option for #785445 ? Reminder: This might also need 'force' to be
converted to simply 'yes' (default) in /etc/init.d/hwclock.sh)

> 
> (4) If systemd is present, we don't adjust the timezone once more in
>     hwclock-set.
> 
> Does this work for you?  I've already coded the above up in my local repo
> but haven't tested it yet, pending your response.  (Tentative patch is
> attached.)

This sounds promising to me. (I have some nitpicks about your patch
inlined below though.)

Targeting this at Debian (doesn't suffer from the problem you're trying
to fix in any officially supported system AFAIK) we'll need to be
careful to not introduce regressions for any currently existing
configuration. (There are unfortunately many (non-default) combinations
to consider, like sysvinit, etc.)

I would very much welcome a wider review of this from interested parties
from their perspective. If you want to reach out to people that would be
very welcome help.... i.e. to some or all of
Debian sysvinit maintainers <pkg-sysvinit-de...@lists.alioth.debian.org>,
Debian systemd Maintainers <pkg-systemd-maintain...@lists.alioth.debian.org>,
Debian kernel team <debian-ker...@lists.debian.org>,
debian-de...@lists.debian.org
... and maybe somewhere else I didn't think of.

(FYI I've already mentioned the bug report and your suggestion on the
debian systemd maintainers irc channel to try to get them interested
and giving feedback already...)

> 
> Thanks,
> 
> Lukas

> diff --git a/debian/hwclock-set b/debian/hwclock-set
> index eacf948..516563c 100755
> --- a/debian/hwclock-set
> +++ b/debian/hwclock-set
> @@ -4,10 +4,6 @@
>  
>  dev=$1
>  
> -if [ -e /run/systemd/system ] ; then
> -    exit 0
> -fi
> -
>  if [ -e /run/udev/hwclock-set ]; then
>      exit 0
>  fi
> @@ -20,17 +16,33 @@ fi
>  BADYEAR=no
>  HWCLOCKACCESS=yes
>  HWCLOCKPARS=
> -HCTOSYS_DEVICE=rtc0
> +HCTOSYS_DEVICE=

This change makes the default inconsistent with /etc/init.d/hwclock.sh
and I don't see why it's needed. Can't we just drop the change?!

>  if [ -f /etc/default/hwclock ] ; then
>      . /etc/default/hwclock
>  fi
>  
> +if [ $HWCLOCKACCESS != yes -o \
> +     ( -n $HCTOSYS_DEVICE -a $HCTOSYS_DEVICE != $2 ) ]

Please avoid -a and -o for pedantic checkbashism reasons, always quote
variables and (together with the previous) just use:

if [ "$HWCLOCKACCESS" != yes ] || [ "$HCTOSYS_DEVICE" != "$rtc" ) ]; then

Note: rtc=$2 should be added below dev=$1 at the top of the script...

> +    exit 0
> +fi
> +
> +# If the kernel has already set the system time from the hwclock,
> +# we only adjust the timezone
> +cat /sys/class/rtc/*/hctosys 2>/dev/null | while read kernel_hctosys ; do
> +    if [ $kernel_hctosys = 1 ] ; then

Please quote "$kernel_hctosys" in case of reading in something crazy/empty...

> +     break
> +    fi
> +done

(Maybe your way is more efficiant and not completely unreadable either,
so ok ... but what do you think about:

KERNEL_DID_HCTOSYS=no
if grep -q '^1$' /sys/class/rtc/*/hctosys 2>/dev/null ; then
        KERNEL_DID_HCTOSYS=yes
fi

... plus change the condition wrapping 'hwclock ... --hctosys' below
to use the new more abstract/descriptive variable name? [1]. grep is
Essential: yes.)


> +
>  if [ yes = "$BADYEAR" ] ; then
> -    /sbin/hwclock --rtc=$dev --systz --badyear
> -    /sbin/hwclock --rtc=$dev --hctosys --badyear
> -else
> -    /sbin/hwclock --rtc=$dev --systz
> -    /sbin/hwclock --rtc=$dev --hctosys
> +    badyear="--badyear"
> +fi

(Thanks for this cleanup.)

> +
> +if [ ! -e /run/systemd/system ] ; then
> +    /sbin/hwclock --rtc=$dev --systz $badyear
> +fi
> +if [ $kernel_hctosys != 1 ] ; then

(Footnote [1]: if [ "$KERNEL_DID_HCTOSYS" = no ]; then)

Again, please always quote variables.... (I might accept not quoting
some variables that are always explicitly initialized in the script
itself, but even then why not just quote it for consistency?)

> +    /sbin/hwclock --rtc=$dev --hctosys $badyear
>  fi
>  
>  # Note 'touch' may not be available in initramfs

(FYI, this initramfs comment is misleading. Might still be useful to
check with initramfs-tools maintainers that they have no intention of
ever adding hwclock to initramfs again though. For the historically
interested: The hwclock was only temporarily added to initramfs briefly
during a development cycle. Never in any officially released Debian
version. History in #763777, #763823, etc. Eventually e2fsck was
patched to avoid needing hwclock in initramfs. IIRC.)

> diff --git a/debian/hwclock.rules b/debian/hwclock.rules
> index 972e4aa..8584deb 100644
> --- a/debian/hwclock.rules
> +++ b/debian/hwclock.rules
> @@ -1,4 +1,4 @@
>  # Set the System Time from the Hardware Clock and set the kernel's timezone
>  # value to the local timezone when the kernel clock module is loaded.
>  
> -KERNEL=="rtc0", RUN+="/lib/udev/hwclock-set $root/$name"
> +KERNEL=="rtc*", RUN+="/lib/udev/hwclock-set $root/$name $kernel"


In general taking the initial policy and inlining it as comments in the
sources would be useful for future generations trying to figure out what
the idea was when this was changes. Also rephrasing it as eg.
# Don't touch timezone when running systemd, because .....
The 'because ...' part makes it easy for future generations to evaluate
if the the check is still valid.

Regards,
Andreas Henriksson

Reply via email to