Consistent behavior on a systemctl stop vs reboot

If I call systemctl to shutdown or reboot, the effect is that it does
not honor kodi-x11.service's ExecStop= line which results in an
unclean exit of kodi and of data loss since kodi writes out some data
when it exits.  By contrast, calling systemctl to stop the service
works as expected.

It seems systemd treats processes in user.slice differently that those
in system.slice and that removing PAMName=login was to blame for kodi's
processes running in user.slice.

Discussion:
https://lists.freedesktop.org/archives/systemd-devel/2020-December/045713.html
https://bbs.archlinux.org/viewtopic.php?id=261684
This commit is contained in:
graysky 2020-12-14 07:47:28 -05:00
parent 29b2b65590
commit 34515c3338
6 changed files with 33 additions and 7 deletions

View File

@ -23,6 +23,7 @@ Users of other distros should install the following files:
* `init/*.service` to `/usr/lib/systemd/system/` * `init/*.service` to `/usr/lib/systemd/system/`
* `init/sysusers.conf` to `/usr/lib/sysusers.d/`, then run `systemd-sysusers` * `init/sysusers.conf` to `/usr/lib/sysusers.d/`, then run `systemd-sysusers`
* `init/tmpfiles.conf` to `/usr/lib/tmpfiles.d/`, then run `systemd-tmpfiles --create` * `init/tmpfiles.conf` to `/usr/lib/tmpfiles.d/`, then run `systemd-tmpfiles --create`
* `polkit/10-kodi.rules` to `/usr/share/polkit-1/rules.d/`, then run `udevadm control --reload-rules && udevadm trigger`
Note that the kodi user's home directory is `/var/lib/kodi/` in this example, NOT `/home/kodi/` like a regular user. Note that the kodi user's home directory is `/var/lib/kodi/` in this example, NOT `/home/kodi/` like a regular user.

View File

@ -1,6 +1,6 @@
[Unit] [Unit]
Description=Kodi standalone (GBM) Description=Kodi standalone (GBM)
After=remote-fs.target systemd-user-sessions.service network-online.target nss-lookup.target sound.target bluetooth.target polkit.service upower.service mysqld.service After=remote-fs.target network-online.target nss-lookup.target sound.target bluetooth.target polkit.service upower.service mysqld.service
Wants=network-online.target polkit.service upower.service Wants=network-online.target polkit.service upower.service
Conflicts=getty@tty1.service Conflicts=getty@tty1.service
@ -9,7 +9,6 @@ User=kodi
Group=kodi Group=kodi
EnvironmentFile=-/etc/conf.d/kodi-standalone EnvironmentFile=-/etc/conf.d/kodi-standalone
SupplementaryGroups=input SupplementaryGroups=input
PAMName=login
TTYPath=/dev/tty1 TTYPath=/dev/tty1
Environment=WINDOWING=gbm Environment=WINDOWING=gbm
ExecStart=/usr/bin/kodi-standalone ExecStart=/usr/bin/kodi-standalone

View File

@ -1,6 +1,6 @@
[Unit] [Unit]
Description=Kodi standalone (Wayland) Description=Kodi standalone (Wayland)
After=remote-fs.target systemd-user-sessions.service network-online.target nss-lookup.target sound.target bluetooth.target polkit.service upower.service mysqld.service After=remote-fs.target network-online.target nss-lookup.target sound.target bluetooth.target polkit.service upower.service mysqld.service
Wants=network-online.target polkit.service upower.service Wants=network-online.target polkit.service upower.service
Conflicts=getty@tty1.service Conflicts=getty@tty1.service
@ -8,7 +8,6 @@ Conflicts=getty@tty1.service
User=kodi User=kodi
Group=kodi Group=kodi
EnvironmentFile=-/etc/conf.d/kodi-standalone EnvironmentFile=-/etc/conf.d/kodi-standalone
PAMName=login
TTYPath=/dev/tty1 TTYPath=/dev/tty1
Environment=WINDOWING=wayland Environment=WINDOWING=wayland
ExecStart=/usr/bin/cage -- /usr/bin/kodi-standalone ExecStart=/usr/bin/cage -- /usr/bin/kodi-standalone

View File

@ -1,6 +1,6 @@
[Unit] [Unit]
Description=Kodi standalone (X11) Description=Kodi standalone (X11)
After=remote-fs.target systemd-user-sessions.service network-online.target nss-lookup.target sound.target bluetooth.target polkit.service upower.service mysqld.service After=remote-fs.target network-online.target nss-lookup.target sound.target bluetooth.target polkit.service upower.service mysqld.service
Wants=network-online.target polkit.service upower.service Wants=network-online.target polkit.service upower.service
Conflicts=getty@tty1.service Conflicts=getty@tty1.service
@ -8,7 +8,6 @@ Conflicts=getty@tty1.service
User=kodi User=kodi
Group=kodi Group=kodi
EnvironmentFile=-/etc/conf.d/kodi-standalone EnvironmentFile=-/etc/conf.d/kodi-standalone
PAMName=login
TTYPath=/dev/tty1 TTYPath=/dev/tty1
Environment=WINDOWING=x11 Environment=WINDOWING=x11
ExecStart=/usr/bin/xinit /usr/bin/kodi-standalone -- :0 -quiet -nolisten tcp vt1 ExecStart=/usr/bin/xinit /usr/bin/kodi-standalone -- :0 -quiet -nolisten tcp vt1
@ -16,6 +15,11 @@ ExecStop=/usr/bin/killall --user kodi --exact --wait kodi-x11
Restart=on-abort Restart=on-abort
StandardInput=tty StandardInput=tty
StandardOutput=journal StandardOutput=journal
# Without this we will wait the default 90s for this service to go down
# due to xinit staying alive. I don't know of a better way to do this
# without several service files one for the xserver and another for kodi.
# If this bothers you, run kodi-gbm instead which doesn't suffer from this.
TimeoutStopSec=10s
[Install] [Install]
Alias=display-manager.service Alias=display-manager.service

View File

@ -5,11 +5,19 @@ g kodi - -
u kodi - "Kodi User" /var/lib/kodi u kodi - "Kodi User" /var/lib/kodi
# supplemental groups # supplemental groups
# see: https://wiki.archlinux.org/index.php/Users_and_groups#Pre-systemd_groups
m kodi audio m kodi audio
m kodi input
m kodi optical m kodi optical
m kodi uucp
m kodi video m kodi video
# other groups, see: /usr/lib/sysusers.d/arch.conf or basic.conf
# m kodi network
# m kodi power
# m kodi tty
# m kodi disk
# m kodi storage
# uncomment the following line for Ubunutu users needing access to /etc/ttyxxxx # uncomment the following line for Ubunutu users needing access to /etc/ttyxxxx
# https://github.com/graysky2/kodi-standalone-service/issues/14 # https://github.com/graysky2/kodi-standalone-service/issues/14
# m kodi dialout # m kodi dialout

15
polkit/10-kodi.rules Normal file
View File

@ -0,0 +1,15 @@
polkit.addRule(function(action, subject) {
if (subject.user == "kodi") {
polkit.log("action=" + action);
polkit.log("subject=" + subject);
if (action.id.indexOf("org.freedesktop.login1.") == 0) {
return polkit.Result.YES;
}
if (action.id.indexOf("org.freedesktop.udisks.") == 0) {
return polkit.Result.YES;
}
if (action.id.indexOf("org.freedesktop.udisks2.") == 0) {
return polkit.Result.YES;
}
}
});