[systemd-devel] Adopt processes spawned before /lib/systemd/systemd takes over as PID 1?

Lennart Poettering lennart at poettering.net
Fri Apr 17 10:22:42 PDT 2015


On Fri, 17.04.15 09:00, Matt Hoosier (matt.hoosier at gmail.com) wrote:

> Hi,
> 
> I'm writing to see whether there's a "best" way to allow systemd to inherit
> ownership of a process forked from a hand-crafted /sbin/init process before
> that hand-crafted process turns over the keys to systemd by doing
> exec("/lib/systemd/systemd") over the top of itself and allowing it to take
> over as PID 1.

We support this only really for "kernel-like" processes that are
started from the initrd, and basically run as long as the system is up
without every being restarted in between, thus effectively appearing
much like a kernel process and nothing systemd should
manage. Processes like this should be marked with argv[0][0] = '@',
see for details:

https://wiki.freedesktop.org/www/Software/systemd/RootStorageDaemons/

> I know that sounds like an odd thing to ask about. The use-case has to do
> with being able to start some work extremely early during boot of embedded
> systems to achieve performance goals. I don't wish to subvert systemd, and
> in fact would love for systemd to be able to monitor the process, stop it,
> restart according to the normal [Service] configuration in a unit file
> describing the process.

Hmm, are you sure that invoking the binary from systemd as first
service is really that much slower than starting systemd only afterwards?

> I can achieve a poor man's version of this right now by telling my
> hand-spawned process to write out a pid file, and then supplying a unit
> file that looks something like:
> 
>   #foo.service
>   [Unit]
>   Description=Proxy unit file for foo run prior to systemd
>   ...
> 
>   [Service]
>   Type=forking
>   ExecStart=/bin/true
>   PIDFile=/var/run/my-hand-forked-process-pidfile.txt

urks, but yeah, this should work, however, this will not move the
process into the service's cgroup. For that you can probably script
something easily that echoes the PID manually into the cgroups dir of
the service (which you can reference via %c). 

> This is at least enough to get my process into the overall dependency graph
> and to allow other units to depend on the process nominally described by
> foo.service. But any kind of use of the 'Restart' option is out of the
> question using this approach. Similarly, 'systemctl start foo.service'
> wouldn't be able to really start the service explicitly.
> 
> Is there a (sneaky?) way to inform systemd that a daemon described property
> in a service file, has already been launched and that systemd should simply
> adopt the running instance?

Not really. Maybe you can make the start routine of your daemon smart
enough to check if the daemon is already up. If so, you move that
process to the cgroup the routine is started in. If not you fork off
the real daemon. That way, you can start the daemon before systemd,
then systemd will start it again, but instead of forking off a new
instance it would just adopt the existing instance by systemd. When
the daemon is the restarted through systemd then it will terminate the
daemon cleanly and the new forked of process will be a regular again,
if you follow what I mean.

But this is all ugly, this is really nothing we want to support
officially I am sure...

Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list