Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Aug 2013 15:46:58 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        freebsd-arch@freebsd.org
Subject:   Reliable process tracking
Message-ID:  <20130804134658.GC35080@stack.nl>

next in thread | raw e-mail | index | archive | help
When shutting down a service or requesting status, rc.subr currently
uses a combination of pidfiles and process names. This is fairly but not
completely reliable once it is set up correctly (which can take a lot of
work and possibly patching the daemon to use pidfile(3) from our
libutil). It is also incapable of killing multiprocess daemons such as
CGI web servers without cooperation of the daemon.

I think what is needed here is a facility that marks a process and all
of its descendants. Removing the mark should be a privileged or at least
an unusual operation; no unprivileged function specified by POSIX such
as setsid() should do this.

There is no such facility in POSIX, but there are some FreeBSD-specific
facilities that come close:

* Do the tracking in userland using kqueue EVFILT_PROC NOTE_TRACK. I
  think this does not work because there is no way to deal with
  NOTE_TRACKERR. NOTE_TRACKERR could perhaps be avoided by making fork()
  fail instead but that may be rather nasty if the tracking process does
  not call kevent() while many tracked processes are created and
  destroyed again.

* Jails. If there were a way to put a process in jail without affecting
  its privileges, filesystem root directory and network interfaces, this
  would be usable. Processes cannot escape from a jail and there are
  ways to signal all processes in a jail or to terminate forcibly all
  processes in a jail.

* setloginclass(2). The login class attribute cannot be changed by a
  normal user, although login(1) and su(1) will change it to the
  target user's class. The rctl system is also available to limit
  resources based on login class; this can also be useful to kill all
  processes with some login class without racing with fork().

* setlogin(2). Everything except setuid login(1) knows to be careful
  with this, but breaking getlogin(2) seems unwise. Therefore, this is
  only useful for daemons with one passwd line per instance.

Similar facilities in other operating systems: Linux cgroups, Solaris
process contracts.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130804134658.GC35080>