On Mon, 09 Nov 2020 at 12:24:03 +0900, Norbert Preining wrote: [Paul wrote]: > > These are not "systemd user services" as described in your email subject, > > they are > > per-user instances of systemd system services.
How to tell: run systemd-cgls and look at where they appear in the tree. Everything below user@${uid}.service is a user service. Everything below session-${n}.service is a non-systemd-managed user process. The rest are system services or non-systemd-managed system processes. Normally, the only system service that is instanced per-user is user@.service, which is the `systemd --user` that is started by systemd-logind on behalf of each user. It is unusual to instance other system services on a per-user basis, because there is already `systemd --user` available to manage per-user services (like dbus-daemon --session, pulseaudio, gpg-agent). When you have an instanced service, systemd doesn't know what the instance represents: that's private to the service itself. It's often an arbitrary instance name (the Debian packages for openvpn, postfix, tor and openarena-server are examples of this), but it could be some related resource like a virtual console (getty@tty2.service). > > package, it seems you need a onedrive.service in addition to > > We ship also one onedrive.service. This is used when a user starts > systemctl --user onedrive That's a user-service, which is unrelated (it's managed by a different per-user instance of systemd, and is not visible to the system-wide instance). I think Paul means you might need a *system service* named onedrive.service. For example, have a look at postfix and openvpn. They have a non-instanced service that just runs /bin/true, and an instanced service that runs the actual daemon. The instanced service postfix@.service is marked as PartOf=postfix.service, which means that when you stop or restart postfix.service, systemd will automatically stop or restart all the instances. However, I think systemd upstream would probably say that this is a hack, because a no-op service that runs /bin/true is not really a service, and that the non-instanced service should be replaced by a non-instanced target (for example postfix@.service PartOf=postfix.target). Unlike services, targets are specifically designed to be used to group units together, without starting daemons or other processes themselves. For example, /lib/systemd/system/systemd-nspawn@.service has PartOf=machines.target, which means that `systemctl restart machines.target` will restart all services matching systemd-nspawn@foo.service; and similarly the cron-* services, targets, etc. installed by the systemd-cron package are PartOf=cron.target. I think most Debian package maintainers have used no-op non-instanced services because that gives them the most obvious migration path from sysv-rc services to systemd services (sysv-rc has no concept of instances, targets or user services, only an equivalent of systemd non-instanced system services), or because debhelper historically did not have full support for non-service units. It should be possible to use targets instead since at least dh compat level 11 (the point at which responsibility for handling systemd services moved from dh_installinit, dh_systemd_enable and dh_systemd_start to dh_installsystemd). > What about the following code in postinst? > restart_units="`systemctl list-units --no-legend --type=service > --state=running 'onedrive*' | awk '{print$1}'`" > if ! [ "x$restart_units" = "x" ] ; then > echo -n "Restarting running Onedrive processes ... " > for unit in $restart_units ; do > echo -n "$unit " > systemctl restart "$unit" > done > echo "." > fi > Would this be against any policy? It would be against the policy of "if you write less code, you'll have fewer bugs"? :-) (In addition to the units you intended, this would restart an unrelated onedriveperchild.service or onedrivetorulethemall.service, which could result in data loss.) It would be better to give onedrive@.service PartOf=onedrive.target, and have the postinst restart onedrive.target - which I think dh_installsystemd will set up automatically, so you might not have to write any code for it at all, other than creating the .target unit. smcv