]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/cmd/lxc_init.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
18 #include <sys/types.h>
22 #include <lxc/lxccontainer.h>
23 #include <lxc/version.h>
28 #include "initutils.h"
29 #include "memory_utils.h"
31 #include "raw_syscalls.h"
32 #include "string_utils.h"
34 /* option keys for long only options */
35 #define OPT_USAGE 0x1000
36 #define OPT_VERSION (OPT_USAGE - 1)
38 #define QUOTE(macro) #macro
39 #define QUOTEVAL(macro) QUOTE(macro)
41 static sig_atomic_t was_interrupted
;
43 static void interrupt_handler(int sig
)
46 was_interrupted
= sig
;
49 static struct option long_options
[] = {
50 { "name", required_argument
, 0, 'n' },
51 { "help", no_argument
, 0, 'h' },
52 { "usage", no_argument
, 0, OPT_USAGE
},
53 { "version", no_argument
, 0, OPT_VERSION
},
54 { "quiet", no_argument
, 0, 'q' },
55 { "lxcpath", required_argument
, 0, 'P' },
58 static const char short_options
[] = "n:hqo:l:P:";
61 const struct option
*options
;
62 const char *shortopts
;
68 /* remaining arguments */
73 static int arguments_parse(struct arguments
*my_args
, int argc
,
76 static struct arguments my_args
= {
77 .options
= long_options
,
78 .shortopts
= short_options
81 static void prevent_forking(void)
83 __do_free
char *line
= NULL
;
84 __do_fclose
FILE *f
= NULL
;
88 f
= fopen("/proc/self/cgroup", "r");
92 while (getline(&line
, &len
, f
) != -1) {
96 p
= strchr(line
, ':');
105 /* This is a cgroup v2 entry. Skip it. */
109 if (strcmp(p
, "pids") != 0)
113 p2
+= lxc_char_left_gc(p2
, strlen(p2
));
114 p2
[lxc_char_right_gc(p2
, strlen(p2
))] = '\0';
116 ret
= snprintf(path
, sizeof(path
),
117 "/sys/fs/cgroup/pids/%s/pids.max", p2
);
118 if (ret
< 0 || (size_t)ret
>= sizeof(path
)) {
120 fprintf(stderr
, "Failed to create string\n");
124 fd
= open(path
, O_WRONLY
);
127 fprintf(stderr
, "Failed to open \"%s\"\n", path
);
131 ret
= write(fd
, "1", 1);
132 if (ret
!= 1 && !my_args
.quiet
)
133 fprintf(stderr
, "Failed to write to \"%s\"\n", path
);
140 static void kill_children(pid_t pid
)
142 __do_fclose
FILE *f
= NULL
;
146 ret
= snprintf(path
, sizeof(path
), "/proc/%d/task/%d/children", pid
, pid
);
147 if (ret
< 0 || (size_t)ret
>= sizeof(path
)) {
149 fprintf(stderr
, "Failed to create string\n");
153 f
= fopen(path
, "r");
156 fprintf(stderr
, "Failed to open %s\n", path
);
163 if (fscanf(f
, "%d ", &find_pid
) != 1) {
165 fprintf(stderr
, "Failed to retrieve pid\n");
169 (void)kill_children(find_pid
);
170 (void)kill(find_pid
, SIGKILL
);
174 static void remove_self(void)
178 char path
[PATH_MAX
] = {0};
180 n
= readlink("/proc/self/exe", path
, sizeof(path
));
181 if (n
< 0 || n
>= PATH_MAX
)
185 ret
= umount2(path
, MNT_DETACH
);
194 int main(int argc
, char *argv
[])
198 struct sigaction act
;
199 sigset_t mask
, omask
;
200 int have_status
= 0, exit_with
= 1, shutdown
= 0;
202 if (arguments_parse(&my_args
, argc
, argv
))
207 fprintf(stderr
, "Please specify a command to execute\n");
211 /* Mask all the signals so we are safe to install a signal handler and
214 ret
= sigfillset(&mask
);
218 ret
= sigdelset(&mask
, SIGILL
);
222 ret
= sigdelset(&mask
, SIGSEGV
);
226 ret
= sigdelset(&mask
, SIGBUS
);
230 ret
= pthread_sigmask(SIG_SETMASK
, &mask
, &omask
);
234 ret
= sigfillset(&act
.sa_mask
);
238 ret
= sigdelset(&act
.sa_mask
, SIGILL
);
242 ret
= sigdelset(&act
.sa_mask
, SIGSEGV
);
246 ret
= sigdelset(&act
.sa_mask
, SIGBUS
);
250 ret
= sigdelset(&act
.sa_mask
, SIGSTOP
);
254 ret
= sigdelset(&act
.sa_mask
, SIGKILL
);
259 act
.sa_handler
= interrupt_handler
;
261 for (i
= 1; i
< NSIG
; i
++) {
262 /* Exclude some signals: ILL, SEGV and BUS are likely to reveal
263 * a bug and we want a core. STOP and KILL cannot be handled
264 * anyway: they're here for documentation. 32 and 33 are not
267 if (i
== SIGILL
|| i
== SIGSEGV
|| i
== SIGBUS
||
268 i
== SIGSTOP
|| i
== SIGKILL
|| i
== 32 || i
== 33)
271 ret
= sigaction(i
, &act
, NULL
);
277 fprintf(stderr
, "Failed to change signal action\n");
289 /* restore default signal handlers */
290 for (i
= 1; i
< NSIG
; i
++) {
293 if (i
== SIGILL
|| i
== SIGSEGV
|| i
== SIGBUS
||
294 i
== SIGSTOP
|| i
== SIGKILL
|| i
== 32 || i
== 33)
297 sigerr
= signal(i
, SIG_DFL
);
298 if (sigerr
== SIG_ERR
&& !my_args
.quiet
)
299 fprintf(stderr
, "Failed to reset to default action for signal \"%d\": %d\n", i
, pid
);
302 ret
= pthread_sigmask(SIG_SETMASK
, &omask
, NULL
);
305 fprintf(stderr
, "Failed to set signal mask\n");
311 (void)ioctl(STDIN_FILENO
, TIOCSCTTY
, 0);
313 ret
= execvp(my_args
.argv
[0], my_args
.argv
);
315 fprintf(stderr
, "Failed to exec \"%s\"\n", my_args
.argv
[0]);
318 logfd
= open("/dev/console", O_WRONLY
| O_NOCTTY
| O_CLOEXEC
);
320 ret
= dup3(logfd
, STDERR_FILENO
, O_CLOEXEC
);
325 (void)setproctitle("init");
327 /* Let's process the signals now. */
328 ret
= sigdelset(&omask
, SIGALRM
);
332 ret
= pthread_sigmask(SIG_SETMASK
, &omask
, NULL
);
335 fprintf(stderr
, "Failed to set signal mask\n");
339 /* No need of other inherited fds but stderr. */
341 close(STDOUT_FILENO
);
347 switch (was_interrupted
) {
349 /* Some applications send SIGHUP in order to get init to reload
350 * its configuration. We don't want to forward this onto the
351 * application itself, because it probably isn't expecting this
352 * signal since it was expecting init to do something with it.
354 * Instead, let's explicitly ignore it here. The actual
355 * terminal case is handled in the monitor's handler, which
356 * sends this task a SIGTERM in the case of a SIGHUP, which is
364 pid_t mypid
= lxc_raw_getpid();
369 kill_children(mypid
);
371 ret
= kill(-1, SIGTERM
);
372 if (ret
< 0 && !my_args
.quiet
)
373 fprintf(stderr
, "Failed to send SIGTERM to all children\n");
379 pid_t mypid
= lxc_raw_getpid();
383 kill_children(mypid
);
385 ret
= kill(-1, SIGKILL
);
386 if (ret
< 0 && !my_args
.quiet
)
387 fprintf(stderr
, "Failed to send SIGTERM to all children\n");
392 ret
= kill(pid
, was_interrupted
);
398 waited_pid
= wait(&status
);
399 if (waited_pid
< 0) {
407 fprintf(stderr
, "Failed to wait on child %d\n", pid
);
412 /* Reset timer each time a process exited. */
416 /* Keep the exit code of the started application (not wrapped
417 * pid) and continue to wait for the end of the orphan group.
419 if (waited_pid
== pid
&& !have_status
) {
420 exit_with
= lxc_error_set_and_log(waited_pid
, status
);
430 __noreturn
static void print_usage_exit(const struct option longopts
[])
433 fprintf(stderr
, "Usage: lxc-init [-n|--name=NAME] [-h|--help] [--usage] [--version]\n\
434 [-q|--quiet] [-P|--lxcpath=LXCPATH]\n");
438 __noreturn
static void print_version_exit(void)
440 printf("%s\n", LXC_VERSION
);
444 static void print_help(void)
447 Usage: lxc-init --name=NAME -- COMMAND\n\
449 lxc-init start a COMMAND as PID 2 inside a container\n\
452 -n, --name=NAME NAME of the container\n\
453 -q, --quiet Don't produce any output\n\
454 -P, --lxcpath=PATH Use specified container path\n\
455 -?, --help Give this help list\n\
456 --usage Give a short usage message\n\
457 --version Print the version number\n\
459 Mandatory or optional arguments to long options are also mandatory or optional\n\
460 for any corresponding short options.\n\
462 See the lxc-init man page for further information.\n\n");
465 static int arguments_parse(struct arguments
*args
, int argc
,
472 c
= getopt_long(argc
, argv
, args
->shortopts
, args
->options
, &index
);
487 remove_trailing_slashes(optarg
);
488 args
->lxcpath
= optarg
;
491 print_usage_exit(args
->options
);
493 print_version_exit();
504 * Reclaim the remaining command arguments
506 args
->argv
= &argv
[optind
];
507 args
->argc
= argc
- optind
;
509 /* If no lxcpath was given, use default */
511 args
->lxcpath
= lxc_global_config_value("lxc.lxcpath");
513 /* Check the command options */
516 fprintf(stderr
, "lxc-init: missing container name, use --name option\n");