Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM ubuntu:xenial
FROM ubuntu:focal

ENV DEBIAN_FRONTEND=noninteractive

ARG ARCH_SUFFIX

Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,24 @@ tini -p SIGTERM -- ...
and use cases.*


### System reboot on exit ###

Instead of merely exiting when the child process exists, Tini can invoke
`reboot(2)` to bring the system down when it would exit. When running as the
true PID 1 of a kernel, this prevents a kernel panic that occurs when init
exits. Use the `-R` option to enable this behavior.

This option allows Tini to function as the init process in a VM, for example,
in [firecracker](https://github.com/firecracker-microvm/firecracker).

Additionally, Tini can invoke `sync(2)` before reboot. The `-S` option enables
this extra behavior. If `-S` is specified without `-R` it is ignored.

```
tini -R -S -- ...
```


More
----

Expand Down
2 changes: 1 addition & 1 deletion ci/install_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -o xtrace
DEPS=(
build-essential git gdb valgrind cmake rpm file
libcap-dev python3-dev python3-pip python3-setuptools
hardening-includes gnupg
devscripts gnupg
)

case "${ARCH_SUFFIX-}" in
Expand Down
37 changes: 34 additions & 3 deletions src/tini.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/reboot.h>

#include <assert.h>
#include <errno.h>
Expand Down Expand Up @@ -90,11 +91,11 @@ static int32_t expect_status[(STATUS_MAX - STATUS_MIN + 1) / 32];

#ifdef PR_SET_CHILD_SUBREAPER
#define HAS_SUBREAPER 1
#define OPT_STRING "p:hvwgle:s"
#define OPT_STRING "p:hvwgle:sRS"
#define SUBREAPER_ENV_VAR "TINI_SUBREAPER"
#else
#define HAS_SUBREAPER 0
#define OPT_STRING "p:hvwgle:"
#define OPT_STRING "p:hvwgle:RS"
#endif

#define VERBOSITY_ENV_VAR "TINI_VERBOSITY"
Expand All @@ -111,6 +112,9 @@ static unsigned int kill_process_group = 0;

static unsigned int warn_on_reap = 0;

static unsigned int reboot_on_exit = 0;
static unsigned int sync_before_reboot = 0;

static struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 };

static const char reaper_warning[] = "Tini is not running as PID 1 "
Expand Down Expand Up @@ -249,6 +253,8 @@ void print_usage(char* const name, FILE* const file) {
fprintf(file, " -g: Send signals to the child's process group.\n");
fprintf(file, " -e EXIT_CODE: Remap EXIT_CODE (from 0 to 255) to 0 (can be repeated).\n");
fprintf(file, " -l: Show license and exit.\n");
fprintf(file, " -R: Call reboot(2) instead of exiting.\n");
fprintf(file, " -S: Call sync(2) before reboot. If -R is not specified, this option is ignored.\n");
#endif

fprintf(file, "\n");
Expand Down Expand Up @@ -361,6 +367,14 @@ int parse_args(const int argc, char* const argv[], char* (**child_args_ptr_ptr)[
*parse_fail_exitcode_ptr = 0;
return 1;

case 'R':
reboot_on_exit++;
break;

case 'S':
sync_before_reboot++;
break;

case '?':
print_usage(name, stderr);
return 1;
Expand Down Expand Up @@ -604,7 +618,7 @@ int reap_zombies(const pid_t child_pid, int* const child_exitcode_ptr) {
}


int main(int argc, char *argv[]) {
int tini(int argc, char *argv[]) {
pid_t child_pid;

// Those are passed to functions to get an exitcode back.
Expand Down Expand Up @@ -679,3 +693,20 @@ int main(int argc, char *argv[]) {
}
}
}


int main(int argc, char *argv[]) {
int exit_status = tini(argc, argv);
if (reboot_on_exit) {
if (sync_before_reboot) {
sync();
}
if (exit_status) {
PRINT_WARNING("%s exit status: %d",
argv[0], exit_status);
}
return reboot(RB_AUTOBOOT);
} else {
return exit_status;
}
}
18 changes: 18 additions & 0 deletions tpl/README.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,24 @@ tini -p SIGTERM -- ...
and use cases.*


### System reboot on exit ###

Instead of merely exiting when the child process exists, Tini can invoke
`reboot(2)` to bring the system down when it would exit. When running as the
true PID 1 of a kernel, this prevents a kernel panic that occurs when init
exits. Use the `-R` option to enable this behavior.

This option allows Tini to function as the init process in a VM, for example,
in [firecracker](https://github.com/firecracker-microvm/firecracker).

Additionally, Tini can invoke `sync(2)` before reboot. The `-S` option enables
this extra behavior. If `-S` is specified without `-R` it is ignored.

```
tini -R -S -- ...
```


More
----

Expand Down