]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/cmd/lxc_init.c
github: Update for main branch
[mirror_lxc.git] / src / lxc / cmd / lxc_init.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE 1
26 #endif
27 #include <ctype.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <getopt.h>
31 #include <libgen.h>
32 #include <limits.h>
33 #include <pthread.h>
34 #include <signal.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <sys/wait.h>
41 #include <unistd.h>
42
43 #include <lxc/lxccontainer.h>
44 #include <lxc/version.h>
45
46 #include "compiler.h"
47 #include "config.h"
48 #include "error.h"
49 #include "initutils.h"
50 #include "memory_utils.h"
51 #include "parse.h"
52 #include "raw_syscalls.h"
53 #include "string_utils.h"
54
55 /* option keys for long only options */
56 #define OPT_USAGE 0x1000
57 #define OPT_VERSION (OPT_USAGE - 1)
58
59 #define QUOTE(macro) #macro
60 #define QUOTEVAL(macro) QUOTE(macro)
61
62 static sig_atomic_t was_interrupted;
63
64 static void interrupt_handler(int sig)
65 {
66 if (!was_interrupted)
67 was_interrupted = sig;
68 }
69
70 static struct option long_options[] = {
71 { "name", required_argument, 0, 'n' },
72 { "help", no_argument, 0, 'h' },
73 { "usage", no_argument, 0, OPT_USAGE },
74 { "version", no_argument, 0, OPT_VERSION },
75 { "quiet", no_argument, 0, 'q' },
76 { "lxcpath", required_argument, 0, 'P' },
77 { 0, 0, 0, 0 }
78 };
79 static const char short_options[] = "n:hqo:l:P:";
80
81 struct arguments {
82 const struct option *options;
83 const char *shortopts;
84
85 const char *name;
86 bool quiet;
87 const char *lxcpath;
88
89 /* remaining arguments */
90 char *const *argv;
91 int argc;
92 };
93
94 static int arguments_parse(struct arguments *my_args, int argc,
95 char *const argv[]);
96
97 static struct arguments my_args = {
98 .options = long_options,
99 .shortopts = short_options
100 };
101
102 static void prevent_forking(void)
103 {
104 __do_free char *line = NULL;
105 __do_fclose FILE *f = NULL;
106 char path[PATH_MAX];
107 size_t len = 0;
108
109 f = fopen("/proc/self/cgroup", "r");
110 if (!f)
111 return;
112
113 while (getline(&line, &len, f) != -1) {
114 int fd, ret;
115 char *p, *p2;
116
117 p = strchr(line, ':');
118 if (!p)
119 continue;
120 p++;
121 p2 = strchr(p, ':');
122 if (!p2)
123 continue;
124 *p2 = '\0';
125
126 /* This is a cgroup v2 entry. Skip it. */
127 if ((p2 - p) == 0)
128 continue;
129
130 if (strcmp(p, "pids") != 0)
131 continue;
132 p2++;
133
134 p2 += lxc_char_left_gc(p2, strlen(p2));
135 p2[lxc_char_right_gc(p2, strlen(p2))] = '\0';
136
137 ret = snprintf(path, sizeof(path),
138 "/sys/fs/cgroup/pids/%s/pids.max", p2);
139 if (ret < 0 || (size_t)ret >= sizeof(path)) {
140 if (my_args.quiet)
141 fprintf(stderr, "Failed to create string\n");
142 return;
143 }
144
145 fd = open(path, O_WRONLY);
146 if (fd < 0) {
147 if (my_args.quiet)
148 fprintf(stderr, "Failed to open \"%s\"\n", path);
149 return;
150 }
151
152 ret = write(fd, "1", 1);
153 if (ret != 1 && !my_args.quiet)
154 fprintf(stderr, "Failed to write to \"%s\"\n", path);
155
156 close(fd);
157 return;
158 }
159 }
160
161 static void kill_children(pid_t pid)
162 {
163 __do_fclose FILE *f = NULL;
164 char path[PATH_MAX];
165 int ret;
166
167 ret = snprintf(path, sizeof(path), "/proc/%d/task/%d/children", pid, pid);
168 if (ret < 0 || (size_t)ret >= sizeof(path)) {
169 if (my_args.quiet)
170 fprintf(stderr, "Failed to create string\n");
171 return;
172 }
173
174 f = fopen(path, "r");
175 if (!f) {
176 if (my_args.quiet)
177 fprintf(stderr, "Failed to open %s\n", path);
178 return;
179 }
180
181 while (!feof(f)) {
182 pid_t find_pid;
183
184 if (fscanf(f, "%d ", &find_pid) != 1) {
185 if (my_args.quiet)
186 fprintf(stderr, "Failed to retrieve pid\n");
187 return;
188 }
189
190 (void)kill_children(find_pid);
191 (void)kill(find_pid, SIGKILL);
192 }
193 }
194
195 static void remove_self(void)
196 {
197 int ret;
198 ssize_t n;
199 char path[PATH_MAX] = {0};
200
201 n = readlink("/proc/self/exe", path, sizeof(path));
202 if (n < 0 || n >= PATH_MAX)
203 return;
204 path[n] = '\0';
205
206 ret = umount2(path, MNT_DETACH);
207 if (ret < 0)
208 return;
209
210 ret = unlink(path);
211 if (ret < 0)
212 return;
213 }
214
215 int main(int argc, char *argv[])
216 {
217 int i, logfd, ret;
218 pid_t pid;
219 struct sigaction act;
220 sigset_t mask, omask;
221 int have_status = 0, exit_with = 1, shutdown = 0;
222
223 if (arguments_parse(&my_args, argc, argv))
224 exit(EXIT_FAILURE);
225
226 if (!my_args.argc) {
227 if (my_args.quiet)
228 fprintf(stderr, "Please specify a command to execute\n");
229 exit(EXIT_FAILURE);
230 }
231
232 /* Mask all the signals so we are safe to install a signal handler and
233 * to fork.
234 */
235 ret = sigfillset(&mask);
236 if (ret < 0)
237 exit(EXIT_FAILURE);
238
239 ret = sigdelset(&mask, SIGILL);
240 if (ret < 0)
241 exit(EXIT_FAILURE);
242
243 ret = sigdelset(&mask, SIGSEGV);
244 if (ret < 0)
245 exit(EXIT_FAILURE);
246
247 ret = sigdelset(&mask, SIGBUS);
248 if (ret < 0)
249 exit(EXIT_FAILURE);
250
251 ret = pthread_sigmask(SIG_SETMASK, &mask, &omask);
252 if (ret < 0)
253 exit(EXIT_FAILURE);
254
255 ret = sigfillset(&act.sa_mask);
256 if (ret < 0)
257 exit(EXIT_FAILURE);
258
259 ret = sigdelset(&act.sa_mask, SIGILL);
260 if (ret < 0)
261 exit(EXIT_FAILURE);
262
263 ret = sigdelset(&act.sa_mask, SIGSEGV);
264 if (ret < 0)
265 exit(EXIT_FAILURE);
266
267 ret = sigdelset(&act.sa_mask, SIGBUS);
268 if (ret < 0)
269 exit(EXIT_FAILURE);
270
271 ret = sigdelset(&act.sa_mask, SIGSTOP);
272 if (ret < 0)
273 exit(EXIT_FAILURE);
274
275 ret = sigdelset(&act.sa_mask, SIGKILL);
276 if (ret < 0)
277 exit(EXIT_FAILURE);
278
279 act.sa_flags = 0;
280 act.sa_handler = interrupt_handler;
281
282 for (i = 1; i < NSIG; i++) {
283 /* Exclude some signals: ILL, SEGV and BUS are likely to reveal
284 * a bug and we want a core. STOP and KILL cannot be handled
285 * anyway: they're here for documentation. 32 and 33 are not
286 * defined.
287 */
288 if (i == SIGILL || i == SIGSEGV || i == SIGBUS ||
289 i == SIGSTOP || i == SIGKILL || i == 32 || i == 33)
290 continue;
291
292 ret = sigaction(i, &act, NULL);
293 if (ret < 0) {
294 if (errno == EINVAL)
295 continue;
296
297 if (my_args.quiet)
298 fprintf(stderr, "Failed to change signal action\n");
299 exit(EXIT_FAILURE);
300 }
301 }
302
303 remove_self();
304
305 pid = fork();
306 if (pid < 0)
307 exit(EXIT_FAILURE);
308
309 if (!pid) {
310 /* restore default signal handlers */
311 for (i = 1; i < NSIG; i++) {
312 sighandler_t sigerr;
313
314 if (i == SIGILL || i == SIGSEGV || i == SIGBUS ||
315 i == SIGSTOP || i == SIGKILL || i == 32 || i == 33)
316 continue;
317
318 sigerr = signal(i, SIG_DFL);
319 if (sigerr == SIG_ERR && !my_args.quiet)
320 fprintf(stderr, "Failed to reset to default action for signal \"%d\": %d\n", i, pid);
321 }
322
323 ret = pthread_sigmask(SIG_SETMASK, &omask, NULL);
324 if (ret < 0) {
325 if (my_args.quiet)
326 fprintf(stderr, "Failed to set signal mask\n");
327 exit(EXIT_FAILURE);
328 }
329
330 (void)setsid();
331
332 (void)ioctl(STDIN_FILENO, TIOCSCTTY, 0);
333
334 ret = execvp(my_args.argv[0], my_args.argv);
335 if (my_args.quiet)
336 fprintf(stderr, "Failed to exec \"%s\"\n", my_args.argv[0]);
337 exit(ret);
338 }
339 logfd = open("/dev/console", O_WRONLY | O_NOCTTY | O_CLOEXEC);
340 if (logfd >= 0) {
341 ret = dup3(logfd, STDERR_FILENO, O_CLOEXEC);
342 if (ret < 0)
343 exit(EXIT_FAILURE);
344 }
345
346 (void)setproctitle("init");
347
348 /* Let's process the signals now. */
349 ret = sigdelset(&omask, SIGALRM);
350 if (ret < 0)
351 exit(EXIT_FAILURE);
352
353 ret = pthread_sigmask(SIG_SETMASK, &omask, NULL);
354 if (ret < 0) {
355 if (my_args.quiet)
356 fprintf(stderr, "Failed to set signal mask\n");
357 exit(EXIT_FAILURE);
358 }
359
360 /* No need of other inherited fds but stderr. */
361 close(STDIN_FILENO);
362 close(STDOUT_FILENO);
363
364 for (;;) {
365 int status;
366 pid_t waited_pid;
367
368 switch (was_interrupted) {
369 case 0:
370 /* Some applications send SIGHUP in order to get init to reload
371 * its configuration. We don't want to forward this onto the
372 * application itself, because it probably isn't expecting this
373 * signal since it was expecting init to do something with it.
374 *
375 * Instead, let's explicitly ignore it here. The actual
376 * terminal case is handled in the monitor's handler, which
377 * sends this task a SIGTERM in the case of a SIGHUP, which is
378 * what we want.
379 */
380 case SIGHUP:
381 break;
382 case SIGPWR:
383 case SIGTERM:
384 if (!shutdown) {
385 pid_t mypid = lxc_raw_getpid();
386
387 shutdown = 1;
388 prevent_forking();
389 if (mypid != 1) {
390 kill_children(mypid);
391 } else {
392 ret = kill(-1, SIGTERM);
393 if (ret < 0 && !my_args.quiet)
394 fprintf(stderr, "Failed to send SIGTERM to all children\n");
395 }
396 alarm(1);
397 }
398 break;
399 case SIGALRM: {
400 pid_t mypid = lxc_raw_getpid();
401
402 prevent_forking();
403 if (mypid != 1) {
404 kill_children(mypid);
405 } else {
406 ret = kill(-1, SIGKILL);
407 if (ret < 0 && !my_args.quiet)
408 fprintf(stderr, "Failed to send SIGTERM to all children\n");
409 }
410 break;
411 }
412 default:
413 ret = kill(pid, was_interrupted);
414 break;
415 }
416 ret = EXIT_SUCCESS;
417
418 was_interrupted = 0;
419 waited_pid = wait(&status);
420 if (waited_pid < 0) {
421 if (errno == ECHILD)
422 goto out;
423
424 if (errno == EINTR)
425 continue;
426
427 if (my_args.quiet)
428 fprintf(stderr, "Failed to wait on child %d\n", pid);
429 ret = -1;
430 goto out;
431 }
432
433 /* Reset timer each time a process exited. */
434 if (shutdown)
435 alarm(1);
436
437 /* Keep the exit code of the started application (not wrapped
438 * pid) and continue to wait for the end of the orphan group.
439 */
440 if (waited_pid == pid && !have_status) {
441 exit_with = lxc_error_set_and_log(waited_pid, status);
442 have_status = 1;
443 }
444 }
445 out:
446 if (ret < 0)
447 exit(EXIT_FAILURE);
448 exit(exit_with);
449 }
450
451 __noreturn static void print_usage_exit(const struct option longopts[])
452
453 {
454 fprintf(stderr, "Usage: lxc-init [-n|--name=NAME] [-h|--help] [--usage] [--version]\n\
455 [-q|--quiet] [-P|--lxcpath=LXCPATH]\n");
456 exit(EXIT_SUCCESS);
457 }
458
459 __noreturn static void print_version_exit(void)
460 {
461 printf("%s\n", LXC_VERSION);
462 exit(EXIT_SUCCESS);
463 }
464
465 static void print_help(void)
466 {
467 fprintf(stderr, "\
468 Usage: lxc-init --name=NAME -- COMMAND\n\
469 \n\
470 lxc-init start a COMMAND as PID 2 inside a container\n\
471 \n\
472 Options :\n\
473 -n, --name=NAME NAME of the container\n\
474 -q, --quiet Don't produce any output\n\
475 -P, --lxcpath=PATH Use specified container path\n\
476 -?, --help Give this help list\n\
477 --usage Give a short usage message\n\
478 --version Print the version number\n\
479 \n\
480 Mandatory or optional arguments to long options are also mandatory or optional\n\
481 for any corresponding short options.\n\
482 \n\
483 See the lxc-init man page for further information.\n\n");
484 }
485
486 static int arguments_parse(struct arguments *args, int argc,
487 char *const argv[])
488 {
489 for (;;) {
490 int c;
491 int index = 0;
492
493 c = getopt_long(argc, argv, args->shortopts, args->options, &index);
494 if (c == -1)
495 break;
496 switch (c) {
497 case 'n':
498 args->name = optarg;
499 break;
500 case 'o':
501 break;
502 case 'l':
503 break;
504 case 'q':
505 args->quiet = true;
506 break;
507 case 'P':
508 remove_trailing_slashes(optarg);
509 args->lxcpath = optarg;
510 break;
511 case OPT_USAGE:
512 print_usage_exit(args->options);
513 case OPT_VERSION:
514 print_version_exit();
515 case '?':
516 print_help();
517 exit(EXIT_FAILURE);
518 case 'h':
519 print_help();
520 exit(EXIT_SUCCESS);
521 }
522 }
523
524 /*
525 * Reclaim the remaining command arguments
526 */
527 args->argv = &argv[optind];
528 args->argc = argc - optind;
529
530 /* If no lxcpath was given, use default */
531 if (!args->lxcpath)
532 args->lxcpath = lxc_global_config_value("lxc.lxcpath");
533
534 /* Check the command options */
535 if (!args->name) {
536 if (!args->quiet)
537 fprintf(stderr, "lxc-init: missing container name, use --name option\n");
538 return -1;
539 }
540
541 return 0;
542 }