[systemd-devel] Connect /usr/bin/init to docker container's STDOUT/STDIN
Hi, sorry in advance if I'm posting to the wrong list. I need to run systemd inside a docker container and attach it to the container's stdin/stdout. The reason for this weird request is the following: 1) I need to use the container for running Gilab CI jobs 2) the software being tested needs systemd to be up and running inside the container 3) Gitlab CI needs a shell running inside the container and attached to the container's STDIN/STDOUT In principle 2) and 3) conflicts because both systemd and the shell needs to be the ENTRYPOINT of the container: systemd needs to run as PID 1 and the shell needs to be attached to container's STDOUT/STDIN. I have been able to solve the problem by: - using /usr/sbin/init as ENTRYPOINT - enabling a custom unit starting a shell attached to STDOUT/STDIN of PID 1: [Unit] Description=Start bash shell attached to container STDIN/STDOUT [Service] Type=simple PassEnvironment=PATH LD_LIBRARY_PATH ExecStart=/bin/bash -c "exec /bin/bash < /proc/1/fd/0 > /proc/1/fd/1 2>/proc/1/fd/2" ExecStopPost=/usr/bin/systemctl poweroff [Install] WantedBy=multi-user.target - defining the container=docker environment variable This works beautifully in a CentOS 7 container running systemd 219: # ls -l /proc/1/fd total 0 lr-x-- 1 root root 64 Sep 29 17:39 0 -> pipe:[1308703] l-wx-- 1 root root 64 Sep 29 17:39 1 -> pipe:[1308704] l-wx-- 1 root root 64 Sep 29 17:39 2 -> pipe:[1308705] but fails when running a Ubuntu 20.04 container with systemd 245: # ls -l /proc/1/fd total 0 lrwx-- 1 root root 64 Sep 29 17:08 0 -> /dev/null lrwx-- 1 root root 64 Sep 29 17:08 1 -> /dev/null lrwx-- 1 root root 64 Sep 29 17:08 2 -> /dev/null In the latter case the fds of PID 1 are connected to /dev/null, so the shell is immediately terminated and no Gtilab CI job can be run. The same behavior occurs with systemd 219 if I don't set container=docker, but with systemd 245 it happens anyway. It happens anyway also in CentOS 7 when running systemd 234 after updating it as described here: https://copr.fedorainfracloud.org/coprs/jsynacek/systemd-backports-for-centos-7/ So I believe this problem might have been introduced by a systemd version subsequent to 219 and that hopefully it might be fixed somehow by means of e.g. proper configuration of the container/environment, but I need some advice about what to do since I'm clueless. Thanks in advance for any help and sorry for the long message, Nicola
Re: [systemd-devel] systemd has not the same behaviour following the version of the kernel ; StopWhenUnneeded no longer works
Thanks for your answer. After some research, it seems that issue is already registered and fixed : https://github.com/systemd/systemd/issues/23410 BR, Eric -Message d'origine- De : systemd-devel De la part de Colin Guthrie Envoyé : mercredi 28 septembre 2022 18:18 À : systemd-devel@lists.freedesktop.org Objet : Re: [systemd-devel] systemd has not the same behaviour following the version of the kernel ; StopWhenUnneeded no longer works Long standing issue with udev rules and a kernel change. IIRC you should try ACTION!="remove" in your udev rule instead. There are other posts on the list about this but I'm running out the door so thought I'd through a hint at least - if it doesn't work, I may have got the action name wrong, so look around! Cheers Col eric-olivier.per...@sysnav.fr wrote on 27/09/2022 16:16: > Hi, > > I’m using debian 10 (systemd 241) . I launch a service (tank.service) > when a specific USB device is connected. For that, i have written an > udev rule that requests the service start in case of « add » event, > thanks to « SYSTEMD_WANTS » : > > /SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="04b4", > ATTRS{idProduct}=="6570", TAG+="systemd", > ENV{SYSTEMD_WANTS}="tank.service"/ > > I want service to be stopped when the USB device is removed. For that, > I use « StopWhenUnneeded » feature. > > tank.service : > > /[Unit]/ > > /Description= tank routine/ > > */StopWhenUnneeded=true/* > > // > > /[Service]/ > > /Type=simple/ > > // > > /ExecStartPre=-/bin/bash /actimyo/bin/tankinsert.sh/ > > /ExecStart=/bin/bash /actimyo/bin/tank.sh/ > > /ExecStop=/bin/bash /actimyo/bin/tankremove.sh/ > > // > > With kernel 4.9.150 , it works well : the service is stopped when the > USB device is removed. > > However, I updated the kernel to version 5.15.32 and the service do > not stop when the USB device is removed . The feature « > StopWhenUnneeded » no longer works. > > Does anybody understand why ? Could anybody give me a solution ? > > _Systemd logs when USB device is removed with kernel 4.9.150 (complete > logs in attached file « logs systemd removing tank-4-9-150.txt ») :_ > > Jun 17 09:21:34 b-0024 kernel: usb 1-1: USB disconnect, device number > 2 > > Jun 17 09:21:34 b-0024 kernel: usb 1-1.2: USB disconnect, device > number 3 > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: Unit is not needed anymore. > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: Trying to enqueue job > tank.service/stop/fail > > Jun 17 09:21:34 b-0024 systemd[1]: Added job tank.service/stop to > transaction. > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: Installed new job > tank.service/stop as 724 > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: Enqueued job > tank.service/stop as 724 > > Jun 17 09:21:34 b-0024 systemd[1]: Sent message type=signal sender=n/a > destination=n/a path=/org/freedesktop/systemd1/unit/tank_2eservice > interface=org.freedesktop.DBus.Properties member=PropertiesChanged > cookie=605 reply_cookie=0 signature=sa{sv}as error-name=n/a > error-message=n/a > > Jun 17 09:21:34 b-0024 systemd[1]: Sent message type=signal sender=n/a > destination=n/a path=/org/freedesktop/systemd1/unit/tank_2eservice > interface=org.freedesktop.DBus.Properties member=PropertiesChanged > cookie=606 reply_cookie=0 signature=sa{sv}as error-name=n/a > error-message=n/a > > Jun 17 09:21:34 b-0024 systemd[1]: Sent message type=signal sender=n/a > destination=n/a path=/org/freedesktop/systemd1 > interface=org.freedesktop.systemd1.Manager member=JobNew cookie=607 > reply_cookie=0 signature=uos error-name=n/a error-message=n/a > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: About to execute: > /bin/bash /actimyo/bin/tankremove.sh > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: Forked /bin/bash as > 2496 > > Jun 17 09:21:34 b-0024 systemd[1]: Sent message type=signal sender=n/a > destination=n/a path=/org/freedesktop/systemd1/unit/tank_2eservice > interface=org.freedesktop.DBus.Properties member=PropertiesChanged > cookie=608 reply_cookie=0 signature=sa{sv}as error-name=n/a > error-message=n/a > > Jun 17 09:21:34 b-0024 systemd[1]: Sent message type=signal sender=n/a > destination=n/a path=/org/freedesktop/systemd1/unit/tank_2eservice > interface=org.freedesktop.DBus.Properties member=PropertiesChanged > cookie=609 reply_cookie=0 signature=sa{sv}as error-name=n/a > error-message=n/a > > Jun 17 09:21:34 b-0024 systemd[1]: tank.service: Changed running -> > stop > > Jun 17 09:21:34 b-0024 systemd[1]: Stopping Detect tank presence... > > Jun 17 09:21:34 b-0024 systemd[2496]: tank.service: Executing: > /bin/bash /actimyo/bin/tankremove.sh > > _Systemd logs_ _when USB device is removed with kernel 5.15.32 > (complete logs in attached file « logs systemds removing tank > kernel-5-15-32.txt »):_ > > Jun 17 09:21:33 b-0021 kernel: [ 438.934344] usb 1-1: USB disconnect, > device number 2 > > Jun 17 09:21:33 b-0021 kernel:
Re: [systemd-devel] [EXT] Re: Q: handling generator-like dependency: target won't start on boot
On Thu, Sep 29, 2022 at 4:01 PM Ulrich Windl wrote: > > >>> Andrei Borzenkov schrieb am 29.09.2022 um 13:57 in > Nachricht > : > ... > >> I don't quite understand what an "initial transaction" is, > > > > The set of (start) jobs starting with default.targtet (or whatever > > target was given to systemd as "initial target") and following > > dependency chain (Wants and Requires). It is computed once when > > systemd is started and it can only include units that are available > > when systemd computes it. Anything added later (even if it has > > dependency with units that are already part of the transaction) will > > not be seen and used by systemd. > > Would using daemon-reexec instead make a difference? > Very unlikely.
[systemd-devel] Antw: Re: [EXT] Re: Q: handling generator-like dependency: target won't start on boot
>>> Andrei Borzenkov schrieb am 29.09.2022 um 13:57 in Nachricht : ... >> I don't quite understand what an "initial transaction" is, > > The set of (start) jobs starting with default.targtet (or whatever > target was given to systemd as "initial target") and following > dependency chain (Wants and Requires). It is computed once when > systemd is started and it can only include units that are available > when systemd computes it. Anything added later (even if it has > dependency with units that are already part of the transaction) will > not be seen and used by systemd. Would using daemon-reexec instead make a difference? ... Regards, Urich
Re: [systemd-devel] bond for wlan/lan failover: hook for dhcp changes?
grawity: > You could use the networkd-broker tool (or its predecessor > networkd-dispatcher) to react to networkd's configuration events, or a > netlink-based tool (similar to `ip mon addr`) to directly watch IP address > changes. Thanks! So it seems there is no pure systemd way to get triggered. BTW: Can't find "networkd-broker" anywhere. > To be honest though, a bond0 that's connected to two completely different > networks kind of makes no sense to me at all. How is it better than just > having two network interfaces? A bond with Mode=active-backup is kind of a hard switch between the interfaces, even if both may be up. And the local network behind it doesn't have to deal with two interfaces, e.g. for your actual internet uplink or for whatever reason.
Re: [systemd-devel] [EXT] Re: Q: handling generator-like dependency: target won't start on boot
On Thu, Sep 29, 2022 at 9:41 AM Ulrich Windl wrote: > > >>> Andrei Borzenkov schrieb am 28.09.2022 um 20:34 in > Nachricht : > > On 28.09.2022 09:25, Ulrich Windl wrote: > >> Hi! > >> > >> I'm trying to establish a mechanism that uses a generator-like mechanism as > > described below. Unfortunately it starts when triggering the target > > manually, > > but it never starts on system boot. I could need some advice how to make it > > work. > >> > >> Basically I have a generator-like unit, say "g.servive", that creates other > > instance-like services like i@.service. > >> Finally I have a target, say "t.target", that wants (among others) those > > instance-like services and is wanted by default.target. > >> > >> As said in the beginning: When booting the target does not start (and I > > don't see any errors logged), but when I "systemctl start t.target", > > everything starts up fine. > >> > >> More details: > >> > >> generator-like services: > >> WantedBy default.target and t.target, and it "Wants=nss-user-lookup.target > > time-sync.target paths.target" (the Before= list is identical). In addition > > it has "Before=default.target t.target". > >> It starts a "oneshot" script that creates the instance-like services with > > RemainAfterExit=true. > >> > >> instance-like services: > >> PartOf=t.target, Requires generator-like.service (also After that service). > > In addition it "Wants=nss-user-lookup.target time-sync.target paths.target" > > (After= uses the same list). The service is Type=forking, and the unit is > > WantedBy=t.target > >> > >> The script used in the generator-like service creates the unit files in > > /run/systemd/system, and it runs "/usr/bin/systemctl daemon-reload" whenever > > a unit file had been created or changed. > >> > > > > daemon-reload does not re-evaluate initial "transaction" and your new > > units are not used because they did not exist when this transaction was > > computed. > > Hi! > > I don't quite understand what an "initial transaction" is, The set of (start) jobs starting with default.targtet (or whatever target was given to systemd as "initial target") and following dependency chain (Wants and Requires). It is computed once when systemd is started and it can only include units that are available when systemd computes it. Anything added later (even if it has dependency with units that are already part of the transaction) will not be seen and used by systemd. > but is sounds like a design deficit: No, that is exactly how it was designed. systemd was created to start the set of units during boot and stop these units during shutdown (with monitoring and restarting running units). systemd never was designed as a fully dynamic, event driven service manager. Why do you think generators had been invented? Exactly because you cannot modify the initial boot transaction and must provide units *before* systemd starts computing this transaction if you want them to be started on boot. > The "real generators" (initially I wanted to use those) are too limited > (i.e..: started too early in the boot process) Now you know why. > to be useful. I also noticed that daemon-reload seems to re-run the > generators (like systemd-sysv-generator), so I wonder what use it will be if > such generated units are being ignored. They are ignored for the purpose of initial boot transaction which was implied by dependency on default.target. They will be considered for any transaction initiated after daemon-reload. I am not sure what happens if you add more units as dependency of t.target after it has already been activated and then issue "systemctl start t.target". Will the start request be propagated to dependent units or not (I believe it changed over time). > > At least what you write seems to explain what I see so far. > > Would it work to write yet another unit that starts t.target? If that would > work, it clearly demonstrates the design problem in systemd. > I do not understand what you mean here. You need to give an example.
Re: [systemd-devel] bond for wlan/lan failover: hook for dhcp changes?
You could use the networkd-broker tool (or its predecessor networkd-dispatcher) to react to networkd's configuration events, or a netlink-based tool (similar to `ip mon addr`) to directly watch IP address changes. To be honest though, a bond0 that's connected to two completely different networks kind of makes no sense to me at all. How is it better than just having two network interfaces? On Thu, Sep 29, 2022 at 12:22 PM m1027 wrote: > Hi, > > With a working wlan/lan bond0 failover, how can we trigger other > local services whenever a failover happens? > > Why: In our case, a local openvpn client service needs SIGUSR1 > whenever the own IP address changes, after a failover. See man > openvpn(8), --ipchange. > > The problem: After a failover, the openvpn client keeps sitting on > the wrong IP address/interface. Sending SIGUSR1 manually helps > indeed: openvpn then reconfigures itself and uses the correct IP > address. The man page recommends to write a hook script for the > local dhcpcd to send SIGUSR1 to the openvpn client, however we are > not using dhcpcd but systemd. > > Some more information: > > - Failover works in general here; pulling out the cable from lan1 > activates wlan0 and vice versa, and this triggers external DHCP > servers to issue a new IP address. The external servers are > triggered because of FailOverMACPolicy=active for bond0. > > - Our bond0 is on top of wlan0 + lan1 and configured like this: > > [NetDev] > Name=bond0 > Kind=bond > [Bond] > Mode=active-backup > AdSelect=bandwidth > FailOverMACPolicy=active > > - We know of networkmanager's dispatcher scripts but are looking for > a solution within systemd. (It's also unclear whether our network > setup could be configured entirely by networkmanager.) > > - There is a workaround: There is the "inactive " option for > the openvpn client to shutdown in case of no action. And we can > additionally set the client to Restart=always. However, this > interrupts even working openvpn client sessions every 60 sec of > inactivity. > > Thanks for any pointers... > > -- Mantas Mikulėnas
[systemd-devel] bond for wlan/lan failover: hook for dhcp changes?
Hi, With a working wlan/lan bond0 failover, how can we trigger other local services whenever a failover happens? Why: In our case, a local openvpn client service needs SIGUSR1 whenever the own IP address changes, after a failover. See man openvpn(8), --ipchange. The problem: After a failover, the openvpn client keeps sitting on the wrong IP address/interface. Sending SIGUSR1 manually helps indeed: openvpn then reconfigures itself and uses the correct IP address. The man page recommends to write a hook script for the local dhcpcd to send SIGUSR1 to the openvpn client, however we are not using dhcpcd but systemd. Some more information: - Failover works in general here; pulling out the cable from lan1 activates wlan0 and vice versa, and this triggers external DHCP servers to issue a new IP address. The external servers are triggered because of FailOverMACPolicy=active for bond0. - Our bond0 is on top of wlan0 + lan1 and configured like this: [NetDev] Name=bond0 Kind=bond [Bond] Mode=active-backup AdSelect=bandwidth FailOverMACPolicy=active - We know of networkmanager's dispatcher scripts but are looking for a solution within systemd. (It's also unclear whether our network setup could be configured entirely by networkmanager.) - There is a workaround: There is the "inactive " option for the openvpn client to shutdown in case of no action. And we can additionally set the client to Restart=always. However, this interrupts even working openvpn client sessions every 60 sec of inactivity. Thanks for any pointers...