[systemd-devel] How do I create/destroy instances dynamically when config files appear/disappear?

Andrei Borzenkov arvidjaar at gmail.com
Tue Mar 20 12:47:31 UTC 2018


On Tue, Mar 20, 2018 at 12:52 AM, John Ioannidis <systemd-devel at tla.org> wrote:
> I want to have a service with several instances, each of which has a
> configuration file; when configuration files appear and disappear, I want
> the corresponding instances to be created and started, and die,
> respectively, and in particular have the running processes corresponding to
> the removed units be killed.
>

There is really no way to do it currently. If instance names are not
known in advance, it is not possible even to dynamically activate
units this way; and there is definitely no way to stop units when come
file goes away.

> I can get them to start the first time, but they do not stop when
> configuration files change. If I systemctl daemon-reload, the links in
> /run/systemd/system-generators get properly adjusted,

generators are simply not the right tool for dynamic changes. There
are path units for activating units when files appear but there are no
corresponding mechanism to stop them.

> but I cannot figure
> out how to tell my service to kill the no-longer-needed processes. If I also
> systemctl reload the service, all existing processes are killed, which is
> absolutely not what I want.
>
> Here is what I've done: what am I doing wrong?
>
> I tried modelling this after what OpenVPN does:
>
> # cat /etc/systemd/system/letters.service
> [Unit]
> Description=Letters service
> After=network.target
>
> [Service]
> Type=oneshot
> RemainAfterExit=yes
> ExecStart=/bin/true
> ExecReload=/bin/true
> WorkingDirectory=/var/tmp/letters
>
> [Install]
> WantedBy=multi-user.target
>
> # cat /etc/systemd/system/letters at .service
> [Unit]
> Description=Letters for %i
> PartOf=letters.service
> ReloadPropagatedFrom=letters.service
> Before=systemd-user-sessions.service
> After=syslog.target network-online.target
> Wants=network-online.target
>
> [Service]
> Type=simple
> PrivateTmp=false
> WorkingDirectory=/var/tmp/letters
> ExecStart=/usr/local/bin/letter --daemon --pidfile /run/letters/%i.pid
> PIDFile=/run/letters/%i.pid
> ExecReload=/bin/kill -HUP $MAINPID
> DeviceAllow=/dev/null rw
> ProtectSystem=true
> ProtectHome=true
>
> [Install]
> WantedBy=multi-user.target
>
> # cat /etc/systemd/system-generators/letters
> #!/bin/sh
> exec 2>> /tmp/opg2
> set -eux
> GENDIR="$1"
> WANTDIR="$1/letters.service.wants"
> SERVICEFILE="/lib/systemd/system/letters at .service"
> CONFIG_DIR=/var/letters/
> mkdir -p "$WANTDIR"
> for CONFIG in `cd $CONFIG_DIR; ls *.conf 2> /dev/null`; do
>  NAME=${CONFIG%%.conf}
>  ln -s "$SERVICEFILE" "$WANTDIR/letters@$NAME.service"
> done
> exit 0
>
>
> Now for the fun:
>
> # touch /var/letters/aleph.conf /var/letters/e.conf /var/letters/zeta.conf
> # systemctl daemon-reload
> # ls -l /run/systemd/generator/letters.service.wants
> total 0
> lrwxrwxrwx 1 root root 36 Mar 19 17:37 letters at aleph.service ->
> /lib/systemd/system/letters at .service
> lrwxrwxrwx 1 root root 36 Mar 19 17:37 letters at e.service ->
> /lib/systemd/system/letters at .service
> lrwxrwxrwx 1 root root 36 Mar 19 17:37 letters at zeta.service ->
> /lib/systemd/system/letters at .service
> # systemctl enable letters.service
> Created symlink /etc/systemd/system/multi-user.target.wants/letters.service
> → /etc/systemd/system/letters.service.
> # systemctl start letters.service
> # ps ax | grep lett
> 22853 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/e.pid
> 22927 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/aleph.pid
> 22928 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/zeta.pid
>
> So far so good. This is working as expected. Even better:
>
> # touch /var/letters/tcha.conf
> # systemctl daemon-reload
> # systemctl start letters.service
> # ps ax | grep lett
> 22853 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/e.pid
> 22927 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/aleph.pid
> 22928 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/zeta.pid
> 23083 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/tcha.pid
>
> But now the trouble begins:
>
> # rm /var/letters/e.conf
> # systemctl daemon-reload
> # ls -l /run/systemd/generator/letters.service.wants
> total 0
> lrwxrwxrwx 1 root root 36 Mar 19 17:44 letters at aleph.service ->
> /lib/systemd/system/letters at .service
> lrwxrwxrwx 1 root root 36 Mar 19 17:44 letters at tcha.service ->
> /lib/systemd/system/letters at .service
> lrwxrwxrwx 1 root root 36 Mar 19 17:44 letters at zeta.service ->
> /lib/systemd/system/letters at .service
>
> The link letters at e.service has been correctly removed,  but the
> corresponding process still exists:
> # ps ax | grep e.pid
> 22853 ?        S      0:00 /usr/local/bin/letter --daemon --pidfile
> /run/letters/e.pid
>
>
>
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
>


More information about the systemd-devel mailing list