]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/cmd/lxc_init.c
362f5b495911c8a0475e63b2513620e0aa0e3b19
[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 #define _GNU_SOURCE
25 #include <ctype.h>
26 #include <errno.h>
27 #include <getopt.h>
28 #include <libgen.h>
29 #include <pthread.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <sys/wait.h>
37 #include <unistd.h>
38
39 #include <lxc/lxccontainer.h>
40 #include <lxc/version.h>
41
42 #include "error.h"
43 #include "initutils.h"
44 #include "log.h"
45 #include "namespace.h"
46 #include "parse.h"
47 #include "string_utils.h"
48
49 /* option keys for long only options */
50 #define OPT_USAGE 0x1000
51 #define OPT_VERSION (OPT_USAGE - 1)
52
53 #define QUOTE(macro) #macro
54 #define QUOTEVAL(macro) QUOTE(macro)
55
56 lxc_log_define(lxc_init, lxc);
57
58 static sig_atomic_t was_interrupted;
59
60 static void interrupt_handler(int sig)
61 {
62 if (!was_interrupted)
63 was_interrupted = sig;
64 }
65
66 static struct option long_options[] = {
67 { "name", required_argument, 0, 'n' },
68 { "help", no_argument, 0, 'h' },
69 { "usage", no_argument, 0, OPT_USAGE },
70 { "version", no_argument, 0, OPT_VERSION },
71 { "quiet", no_argument, 0, 'q' },
72 { "logfile", required_argument, 0, 'o' },
73 { "logpriority", required_argument, 0, 'l' },
74 { "lxcpath", required_argument, 0, 'P' },
75 { 0, 0, 0, 0 }
76 };
77 static const char short_options[] = "n:hqo:l:P:";
78
79 struct arguments {
80 const struct option *options;
81 const char *shortopts;
82
83 const char *name;
84 char *log_file;
85 char *log_priority;
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 FILE *f;
105 size_t len = 0;
106 char *line = NULL;
107 char path[MAXPATHLEN];
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 ERROR("Failed to create string");
141 goto on_error;
142 }
143
144 fd = open(path, O_WRONLY);
145 if (fd < 0) {
146 SYSERROR("Failed to open \"%s\"", path);
147 goto on_error;
148 }
149
150 ret = write(fd, "1", 1);
151 if (ret != 1)
152 SYSERROR("Failed to write to \"%s\"", path);
153
154 close(fd);
155 break;
156 }
157
158 on_error:
159 free(line);
160 fclose(f);
161 }
162
163 static void kill_children(pid_t pid)
164 {
165 FILE *f;
166 char path[PATH_MAX];
167 int ret;
168
169 ret = snprintf(path, sizeof(path), "/proc/%d/task/%d/children", pid, pid);
170 if (ret < 0 || (size_t)ret >= sizeof(path)) {
171 ERROR("Failed to create string");
172 return;
173 }
174
175 f = fopen(path, "r");
176 if (!f) {
177 SYSERROR("Failed to open %s", path);
178 return;
179 }
180
181 while (!feof(f)) {
182 pid_t pid;
183
184 if (fscanf(f, "%d ", &pid) != 1) {
185 ERROR("Failed to retrieve pid");
186 fclose(f);
187 return;
188 }
189
190 kill_children(pid);
191 kill(pid, SIGKILL);
192 }
193
194 fclose(f);
195 }
196
197 static void remove_self(void)
198 {
199 int ret;
200 ssize_t n;
201 char path[MAXPATHLEN] = {0};
202
203 n = readlink("/proc/self/exe", path, sizeof(path));
204 if (n < 0 || n >= MAXPATHLEN) {
205 SYSDEBUG("Failed to readlink \"/proc/self/exe\"");
206 return;
207 }
208 path[n] = '\0';
209
210 ret = umount2(path, MNT_DETACH);
211 if (ret < 0) {
212 SYSDEBUG("Failed to unmount \"%s\"", path);
213 return;
214 }
215
216 ret = unlink(path);
217 if (ret < 0) {
218 SYSDEBUG("Failed to unlink \"%s\"", path);
219 return;
220 }
221 }
222
223 int main(int argc, char *argv[])
224 {
225 int i, ret;
226 pid_t pid, sid;
227 struct sigaction act;
228 struct lxc_log log;
229 sigset_t mask, omask;
230 int have_status = 0, exit_with = 1, shutdown = 0;
231
232 if (arguments_parse(&my_args, argc, argv))
233 exit(EXIT_FAILURE);
234
235 log.prefix = "lxc-init";
236 log.name = my_args.name;
237 log.file = my_args.log_file;
238 log.level = my_args.log_priority;
239 log.quiet = my_args.quiet;
240 log.lxcpath = my_args.lxcpath;
241
242 ret = lxc_log_init(&log);
243 if (ret < 0)
244 exit(EXIT_FAILURE);
245 lxc_log_options_no_override();
246
247 if (!my_args.argc) {
248 ERROR("Please specify a command to execute");
249 exit(EXIT_FAILURE);
250 }
251
252 /* Mask all the signals so we are safe to install a signal handler and
253 * to fork.
254 */
255 ret = sigfillset(&mask);
256 if (ret < 0)
257 exit(EXIT_FAILURE);
258
259 ret = sigdelset(&mask, SIGILL);
260 if (ret < 0)
261 exit(EXIT_FAILURE);
262
263 ret = sigdelset(&mask, SIGSEGV);
264 if (ret < 0)
265 exit(EXIT_FAILURE);
266
267 ret = sigdelset(&mask, SIGBUS);
268 if (ret < 0)
269 exit(EXIT_FAILURE);
270
271 ret = pthread_sigmask(SIG_SETMASK, &mask, &omask);
272 if (ret < 0)
273 exit(EXIT_FAILURE);
274
275 ret = sigfillset(&act.sa_mask);
276 if (ret < 0)
277 exit(EXIT_FAILURE);
278
279 ret = sigdelset(&act.sa_mask, SIGILL);
280 if (ret < 0)
281 exit(EXIT_FAILURE);
282
283 ret = sigdelset(&act.sa_mask, SIGSEGV);
284 if (ret < 0)
285 exit(EXIT_FAILURE);
286
287 ret = sigdelset(&act.sa_mask, SIGBUS);
288 if (ret < 0)
289 exit(EXIT_FAILURE);
290
291 ret = sigdelset(&act.sa_mask, SIGSTOP);
292 if (ret < 0)
293 exit(EXIT_FAILURE);
294
295 ret = sigdelset(&act.sa_mask, SIGKILL);
296 if (ret < 0)
297 exit(EXIT_FAILURE);
298
299 act.sa_flags = 0;
300 act.sa_handler = interrupt_handler;
301
302 for (i = 1; i < NSIG; i++) {
303 /* Exclude some signals: ILL, SEGV and BUS are likely to reveal
304 * a bug and we want a core. STOP and KILL cannot be handled
305 * anyway: they're here for documentation. 32 and 33 are not
306 * defined.
307 */
308 if (i == SIGILL || i == SIGSEGV || i == SIGBUS ||
309 i == SIGSTOP || i == SIGKILL || i == 32 || i == 33)
310 continue;
311
312 ret = sigaction(i, &act, NULL);
313 if (ret < 0) {
314 if (errno == EINVAL)
315 continue;
316
317 SYSERROR("Failed to change signal action");
318 exit(EXIT_FAILURE);
319 }
320 }
321
322 remove_self();
323
324 pid = fork();
325 if (pid < 0)
326 exit(EXIT_FAILURE);
327
328 if (!pid) {
329 /* restore default signal handlers */
330 for (i = 1; i < NSIG; i++) {
331 sighandler_t sigerr;
332
333 if (i == SIGILL || i == SIGSEGV || i == SIGBUS ||
334 i == SIGSTOP || i == SIGKILL || i == 32 || i == 33)
335 continue;
336
337 sigerr = signal(i, SIG_DFL);
338 if (sigerr == SIG_ERR) {
339 SYSDEBUG("Failed to reset to default action "
340 "for signal \"%d\": %d", i, pid);
341 }
342 }
343
344 ret = pthread_sigmask(SIG_SETMASK, &omask, NULL);
345 if (ret < 0) {
346 SYSERROR("Failed to set signal mask");
347 exit(EXIT_FAILURE);
348 }
349
350 sid = setsid();
351 if (sid < 0)
352 DEBUG("Failed to make child session leader");
353
354 if (ioctl(STDIN_FILENO, TIOCSCTTY, 0) < 0)
355 DEBUG("Failed to set controlling terminal");
356
357 NOTICE("Exec'ing \"%s\"", my_args.argv[0]);
358
359 ret = execvp(my_args.argv[0], my_args.argv);
360 SYSERROR("Failed to exec \"%s\"", my_args.argv[0]);
361 exit(ret);
362 }
363
364 INFO("Attempting to set proc title to \"init\"");
365 setproctitle("init");
366
367 /* Let's process the signals now. */
368 ret = sigdelset(&omask, SIGALRM);
369 if (ret < 0)
370 exit(EXIT_FAILURE);
371
372 ret = pthread_sigmask(SIG_SETMASK, &omask, NULL);
373 if (ret < 0) {
374 SYSERROR("Failed to set signal mask");
375 exit(EXIT_FAILURE);
376 }
377
378 /* No need of other inherited fds but stderr. */
379 close(STDIN_FILENO);
380 close(STDOUT_FILENO);
381
382 for (;;) {
383 int status;
384 pid_t waited_pid;
385
386 switch (was_interrupted) {
387 case 0:
388 /* Some applications send SIGHUP in order to get init to reload
389 * its configuration. We don't want to forward this onto the
390 * application itself, because it probably isn't expecting this
391 * signal since it was expecting init to do something with it.
392 *
393 * Instead, let's explicitly ignore it here. The actual
394 * terminal case is handled in the monitor's handler, which
395 * sends this task a SIGTERM in the case of a SIGHUP, which is
396 * what we want.
397 */
398 case SIGHUP:
399 break;
400 case SIGPWR:
401 case SIGTERM:
402 if (!shutdown) {
403 pid_t mypid = lxc_raw_getpid();
404
405 shutdown = 1;
406 prevent_forking();
407 if (mypid != 1) {
408 kill_children(mypid);
409 } else {
410 ret = kill(-1, SIGTERM);
411 if (ret < 0)
412 SYSDEBUG("Failed to send SIGTERM to all children");
413 }
414 alarm(1);
415 }
416 break;
417 case SIGALRM: {
418 pid_t mypid = lxc_raw_getpid();
419
420 prevent_forking();
421 if (mypid != 1) {
422 kill_children(mypid);
423 } else {
424 ret = kill(-1, SIGKILL);
425 if (ret < 0)
426 SYSDEBUG("Failed to send SIGTERM to all children");
427 }
428 break;
429 }
430 default:
431 ret = kill(pid, was_interrupted);
432 if (ret < 0)
433 SYSDEBUG("Failed to send signal \"%d\" to %d", was_interrupted, pid);
434 break;
435 }
436 ret = EXIT_SUCCESS;
437
438 was_interrupted = 0;
439 waited_pid = wait(&status);
440 if (waited_pid < 0) {
441 if (errno == ECHILD)
442 goto out;
443
444 if (errno == EINTR)
445 continue;
446
447 SYSERROR("Failed to wait on child %d", pid);
448 goto out;
449 }
450
451 /* Reset timer each time a process exited. */
452 if (shutdown)
453 alarm(1);
454
455 /* Keep the exit code of the started application (not wrapped
456 * pid) and continue to wait for the end of the orphan group.
457 */
458 if (waited_pid == pid && !have_status) {
459 exit_with = lxc_error_set_and_log(waited_pid, status);
460 have_status = 1;
461 }
462 }
463 out:
464 if (ret < 0)
465 exit(EXIT_FAILURE);
466 exit(exit_with);
467 }
468
469 static void print_usage(const struct option longopts[])
470
471 {
472 fprintf(stderr, "Usage: lxc-init [-n|--name=NAME] [-h|--help] [--usage] [--version]\n\
473 [-q|--quiet] [-o|--logfile=LOGFILE] [-l|--logpriority=LOGPRIORITY] [-P|--lxcpath=LXCPATH]\n");
474 exit(0);
475 }
476
477 static void print_version(void)
478 {
479 printf("%s\n", LXC_VERSION);
480 exit(0);
481 }
482
483 static void print_help(void)
484 {
485 fprintf(stderr, "\
486 Usage: lxc-init --name=NAME -- COMMAND\n\
487 \n\
488 lxc-init start a COMMAND as PID 2 inside a container\n\
489 \n\
490 Options :\n\
491 -n, --name=NAME NAME of the container\n\
492 -o, --logfile=FILE Output log to FILE instead of stderr\n\
493 -l, --logpriority=LEVEL Set log priority to LEVEL\n\
494 -q, --quiet Don't produce any output\n\
495 -P, --lxcpath=PATH Use specified container path\n\
496 -?, --help Give this help list\n\
497 --usage Give a short usage message\n\
498 --version Print the version number\n\
499 \n\
500 Mandatory or optional arguments to long options are also mandatory or optional\n\
501 for any corresponding short options.\n\
502 \n\
503 See the lxc-init man page for further information.\n\n");
504 }
505
506 static int arguments_parse(struct arguments *args, int argc,
507 char *const argv[])
508 {
509 while (true) {
510 int c;
511 int index = 0;
512
513 c = getopt_long(argc, argv, args->shortopts, args->options, &index);
514 if (c == -1)
515 break;
516 switch (c) {
517 case 'n':
518 args->name = optarg;
519 break;
520 case 'o':
521 args->log_file = optarg;
522 break;
523 case 'l':
524 args->log_priority = optarg;
525 break;
526 case 'q':
527 args->quiet = true;
528 break;
529 case 'P':
530 remove_trailing_slashes(optarg);
531 args->lxcpath = optarg;
532 break;
533 case OPT_USAGE:
534 print_usage(args->options);
535 case OPT_VERSION:
536 print_version();
537 case '?':
538 print_help();
539 exit(EXIT_FAILURE);
540 case 'h':
541 print_help();
542 exit(EXIT_SUCCESS);
543 }
544 }
545
546 /*
547 * Reclaim the remaining command arguments
548 */
549 args->argv = &argv[optind];
550 args->argc = argc - optind;
551
552 /* If no lxcpath was given, use default */
553 if (!args->lxcpath)
554 args->lxcpath = lxc_global_config_value("lxc.lxcpath");
555
556 /* Check the command options */
557 if (!args->name) {
558 if (!args->quiet)
559 fprintf(stderr, "lxc-init: missing container name, use --name option\n");
560 return -1;
561 }
562
563 return 0;
564 }