[systemd-devel] Revisiting the "ExecRestart" issue

Brandon Black blblack at gmail.com
Wed Apr 23 19:20:10 PDT 2014


On Wed, Apr 23, 2014 at 3:06 PM, Lennart Poettering
<lennart at poettering.net>wrote:

> > To recap my results: there were primarily two things in the way of
> naively
>
> using ExecReload to trigger gdnsd's overlapped restart:
> >
> > 1) gdnsd wants to use sd_notifyf() to indicate the MAINPID switch in the
> > new daemon, which is a descendant of the ExecReload process.  The
> > ExecReloadprocess doesn't get a copy of $NOTIFY_SOCKET even with
> > NotifyAccess=all.  So I hacked around that by having the daemon set
> > $NOTIFY_SOCKET for itself, to the value
> "@/org/freedesktop/systemd1/notify",
> > which seems semi-standard for the moment.
> >
> > 2) ExecReload control processes can't become the MAINPID even after
> > notification because they're not in the correct cgroup (or subgroup, or
> > whatever it is that's special about most control procs), unlike
> > Start'scontrol process, which is in the right
> > cgroup for its descendants to become MAINPID successfully.  This was
> hacked
> > around by grabbing the basic unit name from sd_pid_get_unit() (let's call
> > the result "$U") and then writing our pid to "/sys/fs/cgroup/systemd
> > /system.slice/$U/cgroup.procs" from the new daemon before it drops root
> > privs and later notifies about the MAINPID switch.
>
> Hmm, yeah, the new process really needs to be forked off the original
> main process.


The problem here is that the daemon performs operations that require root
privilege on startup, and then dumps its privileges for runtime, and thus
its execve'd child won't have the root privs it would need to start
everything over again.  In theory some of these privileged things, like
listening sockets, could be handed to the exec child, but that assumes the
configured set of listening sockets hasn't changed (which might be the
reason for the restart).  Other things like mlockall() can't be handed off
over fork/execve once privileges are gone.


> Control processes really can't become the main process I
> fear...


They can; I've already done it by writing to /sys as documented above, but
that doesn't seem like a reliable API for doing so going forward on all
platforms and in all situations.  What's the fundamental problem with
officially letting a control process from ExecReload= become the main
process via some reasonably-standard mechanism?  That's already what
happens to the "control process" for ExecStart=.

I'd propose two changes (and work on the patches myself) that would make
this case work for me reliably, if they're acceptable:

1) Can we get $NOTIFY_SOCKET set for control procs like ExecReload
when NotifyAccess=all ?  That's what I initially thought that setting would
do, but apparently it doesn't.  Or any other standard mechanism I could
rely on so that I'm not hardcoding a fallback socket path.

2) Given the above, would it be reasonable that if a control process from a
verb like ExecReload sent a MAINPID= message over the control socket,
systemd would accept this as the new main pid *and* internally take care of
promoting the specified PID to the proper cgroup?

-- Brandon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20140423/97a63cf5/attachment-0001.html>


More information about the systemd-devel mailing list