On Wed Sep 11 10:45:48 PDT 2013 Lennart Poettering wrote:

So, it's a really bad idea to turn off UPS from userspace, simply because you will race against the kernel's fs sync() code, and you never know what will finish first: your UPS shutdown timeout or your fs sync(). Doing this from userspace is hence racy.

If you want to use a hack like this then at least do it via the /usr/lib/systemd/system-shutdown/ drop-in directory which is called very late during shutdown. It will shorten the race window, but not erase it, since the kernel will flush various buffers only after the reboot() system call is invoked.

Here is the effect on a simple openSUSE 12.3 test rig of replacing my home-made service unit /lib/systemd/system/ups-delayed-shutdown.service with a script in the /usr/lib/systemd/system-shutdown/ drop-in directory. I used the default UPS offdelay of 20 secs. The X's indicate the race window. (Sorry for the ascii art.)

1) My "bad idea" ups-delayed-shutdown.service

systemctl               system
poweroff                 halt
   |     |XXXXXXXXXXXXXXXX|
   0   2 | 4   6   8  10  12  14  16  18  20  22  24  26  28  30  32 secs
         |                                       |
      upsdrvctl                                 UPS
      shutdown                                shutdown

2) Replaced by script in /usr/lib/systemd/system-shutdown/

systemctl               system
poweroff                 halt
   |                 |XXXX|
   0   2   4   6   8 |10  12  14  16  18  20  22  24  26  28  30  32 secs
                     |                                       |
                 upsdrvctl                                  UPS
                 shutdown                                 shutdown

The script solution has the advantage of reducing the race window from 9 to 3 secs. Note that the same security can also be achieved by the service unit by setting offdelay = 26 in ups.conf. My script is

   #! /bin/bash
   # Delayed turn off for the UPS unit.
   # Needed for automatic system restart when wall power returns.
   UPSDRVCTL_BIN=/usr/lib/ups/driver/upsdrvctl
   $UPSDRVCTL_BIN shutdown

I tried adding

   echo `date -I` `date +%T` "$0 calls $UPSDRVCTL_BIN shutdown" >> 
/var/log/UPS.log

to get a trace of the activity, but nothing is written in /var/log/UPS.log.

Roger
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to