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