/***
This file is part of systemd.
Copyright 2016 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "fd-util.h"
#include "log.h"
#include "nspawn-stub-pid1.h"
#include "process-util.h"
#include "signal-util.h"
#include "time-util.h"
#include "def.h"
int stub_pid1(void) {
enum {
int r;
/* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
* for allowing arbitrary processes run in a container, and still have all zombies reaped. */
if (pid < 0)
if (pid == 0) {
/* Return in the child */
setsid();
return 0;
}
log_close();
close_all_fds(NULL, 0);
log_open();
rename_process("STUBINIT");
SIGCHLD, /* posix: process died */
SIGINT, /* sysv: ctrl-alt-del */
-1) >= 0);
/* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't
for (;;) {
if (r < 0) {
goto finish;
}
/* The child we started ourselves died or we reached a timeout. */
(void) reboot(RB_AUTOBOOT);
goto finish;
} else if (state == STATE_POWEROFF)
else
r = 255; /* signal, coredump, timeout, … */
goto finish;
}
/* We reaped something. Retry until there's nothing more to reap. */
continue;
if (quit_usec == USEC_INFINITY)
else {
}
if (r < 0) {
continue;
continue;
goto finish;
}
continue; /* Let's reap this */
if (state != STATE_RUNNING)
continue;
/* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a
* constant… */
else
assert_not_reached("Got unexpected signal");
/* (void) kill_and_sigcont(pid, SIGTERM); */
}
_exit(r < 0 ? EXIT_FAILURE : r);
}