FS#59170 - [pacman] [systemd] Use systemd Inhibitor Locks

Attached to Project: Arch Linux
Opened by AMM (amish) - Thursday, 28 June 2018, 12:40 GMT
Last edited by Bartłomiej Piotrowski (Barthalion) - Monday, 20 August 2018, 06:58 GMT
Task Type Feature Request
Category Packages: Core
Status Closed
Assigned To Dave Reisner (falconindy)
Christian Hesse (eworm)
Bartłomiej Piotrowski (Barthalion)
Architecture All
Severity Low
Priority Normal
Reported Version 5.1.0
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 3
Private No

Details

Summary and Info:
systemd >= 183 includes a logic to inhibit system shutdowns and sleep states so that package manager can ensure that the system is not turned off (accidentally) while package installation / upgrade / removal is in progress.

Read more at https://www.freedesktop.org/wiki/Software/systemd/inhibit/

This can be easily achieved by alpm-hooks.

I have created a skeleton script (which I am now using from few days without any issue).

1) First create a symlink /usr/bin/pacman-systemd-inhibit-sleep pointing to /usr/bin/sleep. (just so that we know what to kill later!)

2) Add two more cases to /usr/share/libalpm/scripts/systemd-hook

inhibit-start) systemd_live; systemd-inhibit --what="shutdown:sleep:idle:handle-power-key:handle-suspend-key:handle-hibernate-key:handle-lid-switch" --who=pacman --why="Pacman is making changes to the system" --mode=block nohup pacman-systemd-inhibit-sleep 900 > /dev/null 2>&1 & ;;

inhibit-stop) systemd_live; killall -qe pacman-systemd-inhibit-sleep || true ;;

3) Create hook named 00-50-systemd-inhibit.hook (so it runs first)

[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Package
Target = *

[Action]
Description=Inhibiting system shutdown, reboot etc.
When = PreTransaction
Exec = /usr/share/libalpm/scripts/systemd-hook inhibit-start

4) Create hook named zz-50-systemd-inhibit.hook (so it runs last)

[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = Package
Target = *

[Action]
Description=Permitting system shutdown, reboot etc.
When = PostTransaction
Exec = /usr/share/libalpm/scripts/systemd-hook inhibit-stop

Notes:
1) Number 50 in hook names allows to add more hooks (just before OR after) above hooks by choosing a different number.
2) Above assumes that pacman does not take more than 15 minutes to make changes which I believe is sufficient or can be increased. (this does not kill pacman if it takes more time but inhibition will be removed)
This task depends upon

Closed by  Bartłomiej Piotrowski (Barthalion)
Monday, 20 August 2018, 06:58 GMT
Reason for closing:  Won't implement
Comment by AMM (amish) - Thursday, 28 June 2018, 12:41 GMT
CAVEAT:
1) In case pacman transaction fails for any reason - inhibition will remain for 15 minutes. But pacman failing (at that stage after all checks are already done) should be a rare case anyway.
2) Does not work if direct poweroff or reboot commands are used (but thats how systemd / @poettering expects i.e. legacy commands to go ahead without checking for inhibitions)
Comment by Eli Schwartz (eschwartz) - Thursday, 28 June 2018, 13:03 GMT
Not sure whether this should be in the pacman package or the systemd package, but either way it is not a pacman development request but rather a packaging request.
Comment by AMM (amish) - Thursday, 28 June 2018, 13:51 GMT
Actually I am just proposing an idea.

There are 2 ways to achieve this:

1) As mentioned in this feature request via hooks (i.e. without pacman code modification)

2) Via systemd dbus interface in which case this will become a pacman feature development request.
Code examples here: https://www.freedesktop.org/wiki/Software/systemd/inhibit/
This will also eliminate CAVEAT number 1 and 15 min assumption. But then pacman will "depend" on systemd and dbus interface.

Its developers choice if pacman hooks should be used (in which case it would become part of systemd package)
or dbus interface (in which case pacman code needs few line additions before and after transaction code)
Comment by Allan McRae (Allan) - Thursday, 28 June 2018, 14:32 GMT
Pacman will not depend on systemd.
Comment by Christian Hesse (eworm) - Thursday, 28 June 2018, 14:45 GMT
My solution is a lot more simple... Add this to your shell's profile:

alias pacman='systemd-inhibit --why="Package management in progress" pacman'
Comment by AMM (amish) - Thursday, 28 June 2018, 15:11 GMT
@eworm: Yes I know about alias way of doing it :)

But it has a problem. It will inhibit shutdown / sleep for all execution of pacman. i.e. even for pacman -Q or -D or -T or -F.

It will inhibit shutdown even when waiting for user confirmation at "Proceed with installation?". (shutdown will be blocked till there is yes or no given)
It will inhibit shutdown even when I am just downloading the packages via "pacman -Syuw --noconfirm". (till the download is in progress)

My solution will not do that.

Even with -S or -R cases it will not block till the transaction actually starts.

Pacman already provides many systemd hooks so I thought this should be a default case. i.e. pacman should prevent shutdown via hooks atleast.
Comment by loqs (loqs) - Thursday, 28 June 2018, 19:04 GMT
How often are such incidents of a none user induced shutdown coinciding with a pacman transaction seen?
Comment by AMM (amish) - Friday, 29 June 2018, 01:35 GMT
Most race conditions dont happen often (some are just theoretical) but yet those are the reasons for many software bugs. One should not ignore a race condition just because it does not happen often (or has never happened). Systemd guys would not develop such a feature without a need, that too with a package manager in mind. Ofcourse to implement it or not is completely developers choice.
Comment by Bartłomiej Piotrowski (Barthalion) - Tuesday, 03 July 2018, 13:48 GMT
Given it's easy to implement on one's own, I think possible solutions should land on wiki and the issue be closed. Sounds obvious not to power off during -S or -R and it's not our job to prevent users from doing it.
Comment by AMM (amish) - Tuesday, 03 July 2018, 14:29 GMT
You are assuming that there will be only one user using the system and the same user will be running pacman. But thats not the case always. I have started replacing few windows desktops in office with Arch Linux and I already had users shutting down system while I was working in background via ssh (especially during office closing time). Luckily I was not doing pacman upgrade.

Even windows gives a big warning - do not turn off - update in progress. Ofcourse pacman is not a GUI so it can not display such warning. And hence I am proposing this feature. (And we already have 3 votes for this feature)

Yes I have already implemented above. But in my opinion package manager should take care of such race conditions by default even if its trivial to implement on own.
Comment by Bartłomiej Piotrowski (Barthalion) - Wednesday, 04 July 2018, 07:10 GMT
If you are managing machines remotely, the ball is on your side to place a lock for maintenance. There is no race condition.

Loading...