[systemd-devel] [systemd] Behavior of "Requires" and "After" in service unit

Mantas Mikulėnas grawity at gmail.com
Mon May 9 05:12:01 UTC 2022


On Mon, May 9, 2022 at 7:17 AM Hamza, Muhammad <Muhammad_Hamza at mentor.com>
wrote:

> Hello,
>
>
>
> I am trying to use swupdate services to perform updates on my BSP but
> there is a problem that I am facing.
>
> When update usb is plugged in during the boot time, swupdate core and
> swupdate-usb service run right after
>
> each-other where swupdate-usb service is dependent on swupdate-core
> service. Therefore, the update fails as
>
> core has not initialized yet when swupdate-usb launches the client.
>
> I have tried adding service type as “exec” in swupdate core service and
> have tried both Requires and After in swupdate-usb
>
> service but in all case swupdate-usb does not wait for core to be
> initialized completely before launching.
>
> My understanding is that when service type is set to exec service manager
> will only assume that swupdate core service is
>
> launched once main process of core is executed and with “Requires” set in
> swupdate-usb service it should wait till
>
> swupdate core service has executed its main process and is assumed
> launched.
>

Even with Type=exec, systemd won't automatically know when your process has
"initialized completely". Type=exec only means that the kernel call to
start executing the process has been fired off – systemd has no automatic
visibility beyond that, since the initialization stage varies greatly from
one program to another.

(In fact, looking at your example, systemd thinks that *the shell script*
is the main process, it doesn't find out about the actual daemon until
later. Please get rid of the .sh script and change your ExecStart= to
directly launch the daemon binary.)

What you need is either Type=notify or Type=forking, and the process needs
to *explicitly notify* systemd that it has reached initialization – for
Type=notify it must send a READY=1 message over a socket (see sd_notify),
and for Type=forking it needs to "daemonize" at the correct point.

I checked the source code of swupdate on GitHub, and it seems it already
has support for sending READY – there's even a whole section about systemd
integration
<https://github.com/sbabic/swupdate/blob/master/doc/source/swupdate.rst#systemd-integration>
in its docs. So in short, you need to compile it with CONFIG_SYSTEMD, then
you'll be able to use Type=notify in the .service unit. Example taken from
the swupdate docs:

[Service]
*Type=notify*
*ExecStart=/usr/bin/swupdate* -u '-t default -u http://localhost -i 25'


(The "socket activation" part isn't required, but may help as well.)

Finally, Type=oneshot is for services where systemd waits for the main
process to start *and finish* (e.g. for services that perform a single
update and don't have a daemon at all). It sounds a bit like it would be
the right choice for swupdate-usb, but it's never correct to use oneshot
for daemons like swupdate-core.

-- 
Mantas Mikulėnas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20220509/884a038b/attachment.htm>


More information about the systemd-devel mailing list