int main(int argc, char *argv[]) { int ret; pid_t pid; lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; lxc_attach_command_t command; ret = lxc_caps_init(); if (ret) return ret; ret = lxc_arguments_parse(&my_args, argc, argv); if (ret) return ret; if (!my_args.log_file) my_args.log_file = "none"; ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0]); if (ret) return ret; lxc_log_options_no_override(); if (remount_sys_proc) attach_options.attach_flags |= LXC_ATTACH_REMOUNT_PROC_SYS; if (elevated_privileges) attach_options.attach_flags &= ~(elevated_privileges); attach_options.namespaces = namespace_flags; attach_options.personality = new_personality; attach_options.env_policy = env_policy; attach_options.extra_env_vars = extra_env; attach_options.extra_keep_env = extra_keep; if (my_args.argc) { command.program = my_args.argv[0]; command.argv = (char**)my_args.argv; ret = lxc_attach(my_args.name, my_args.lxcpath[0], lxc_attach_run_command, &command, &attach_options, &pid); } else { ret = lxc_attach(my_args.name, my_args.lxcpath[0], lxc_attach_run_shell, NULL, &attach_options, &pid); } if (ret < 0) return -1; ret = lxc_wait_for_pid_status(pid); if (ret < 0) return -1; if (WIFEXITED(ret)) return WEXITSTATUS(ret); return -1; }
int main(int argc, char *argv[]) { struct lxc_container *c; bool ret; if (lxc_arguments_parse(&my_args, argc, argv)) exit(1); if (!my_args.log_file) my_args.log_file = "none"; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0])) exit(1); lxc_log_options_no_override(); c = lxc_container_new(my_args.name, my_args.lxcpath[0]); if (!c) { fprintf(stderr, "System error loading %s\n", my_args.name); exit(1); } if (!c->may_control(c)) { fprintf(stderr, "Insufficent privileges to control %s\n", my_args.name); lxc_container_put(c); exit(1); } if (!c->is_defined(c)) { fprintf(stderr, "%s is not defined\n", my_args.name); lxc_container_put(c); exit(1); } if (do_restore) ret = restore(c); else if (do_pre_checkpoint) ret = pre_checkpoint(c); else ret = checkpoint(c); return !ret; }
int main(int argc, char *argv[]) { struct lxc_container *c; bool s; int ret = EXIT_FAILURE; if (lxc_arguments_parse(&my_args, argc, argv)) exit(ret); if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0])) exit(ret); lxc_log_options_no_override(); /* Set default timeout */ if (my_args.timeout == -2) { if (my_args.hardstop) my_args.timeout = 0; else my_args.timeout = 60; } if (my_args.nowait) my_args.timeout = 0; /* some checks */ if (!my_args.hardstop && my_args.timeout < -1) { fprintf(stderr, "invalid timeout\n"); exit(ret); } if (my_args.hardstop && my_args.nokill) { fprintf(stderr, "-k can't be used with --nokill\n"); exit(ret); } if (my_args.hardstop && my_args.reboot) { fprintf(stderr, "-k can't be used with -r\n"); exit(ret); } if (my_args.hardstop && my_args.timeout) { fprintf(stderr, "-k doesn't allow timeouts\n"); exit(ret); } if (my_args.nolock && !my_args.hardstop) { fprintf(stderr, "--nolock may only be used with -k\n"); exit(ret); } /* shortcut - if locking is bogus, we should be able to kill * containers at least */ if (my_args.nolock) { ret = lxc_cmd_stop(my_args.name, my_args.lxcpath[0]); exit(ret); } c = lxc_container_new(my_args.name, my_args.lxcpath[0]); if (!c) { fprintf(stderr, "Error opening container\n"); goto out; } if (my_args.rcfile) { c->clear_config(c); if (!c->load_config(c, my_args.rcfile)) { fprintf(stderr, "Failed to load rcfile\n"); goto out; } c->configfile = strdup(my_args.rcfile); if (!c->configfile) { fprintf(stderr, "Out of memory setting new config filename\n"); goto out; } } if (!c->may_control(c)) { fprintf(stderr, "Insufficent privileges to control %s\n", c->name); goto out; } if (!c->is_running(c)) { fprintf(stderr, "%s is not running\n", c->name); /* Per our manpage we need to exit with exit code: * 2: The specified container exists but was not running. */ ret = 2; goto out; } /* kill */ if (my_args.hardstop) { ret = c->stop(c) ? EXIT_SUCCESS : EXIT_FAILURE; goto out; } /* reboot */ if (my_args.reboot) { ret = do_reboot_and_check(&my_args, c) < 0 ? EXIT_SUCCESS : EXIT_FAILURE; goto out; } /* shutdown */ s = c->shutdown(c, my_args.timeout); if (!s) { if (my_args.timeout == 0) ret = EXIT_SUCCESS; else if (my_args.nokill) ret = EXIT_FAILURE; else ret = c->stop(c) ? EXIT_SUCCESS : EXIT_FAILURE; } else { ret = EXIT_SUCCESS; } out: lxc_container_put(c); exit(ret); }
int main(int argc, char *argv[]) { int count = 0; int i = 0; int ret = 0; struct lxc_container **containers = NULL; struct lxc_list *cmd_groups_list = NULL; struct lxc_list *c_groups_list = NULL; struct lxc_list *it, *next; char *const default_start_args[] = { "/sbin/init", NULL, }; if (lxc_arguments_parse(&my_args, argc, argv)) return 1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0])) return 1; lxc_log_options_no_override(); count = list_defined_containers(NULL, NULL, &containers); if (count < 0) return 1; qsort(&containers[0], count, sizeof(struct lxc_container *), cmporder); if (my_args.groups && !my_args.all) cmd_groups_list = get_list((char*)my_args.groups, ","); for (i = 0; i < count; i++) { struct lxc_container *c = containers[i]; if (!c->may_control(c)) { lxc_container_put(c); continue; } if (!my_args.ignore_auto && get_config_integer(c, "lxc.start.auto") != 1) { lxc_container_put(c); continue; } if (!my_args.all) { /* Filter by group */ c_groups_list = get_config_list(c, "lxc.group"); ret = lists_contain_common_entry(cmd_groups_list, c_groups_list); if (c_groups_list) { lxc_list_for_each_safe(it, c_groups_list, next) { lxc_list_del(it); free(it->elem); free(it); } free(c_groups_list); } if (ret == 0) { lxc_container_put(c); continue; } }
int main(int argc, char *argv[]) { int ret,pipefd; char *lxcpath = argv[1]; char logpath[PATH_MAX]; sigset_t mask; if (argc != 3) { fprintf(stderr, "Usage: lxc-monitord lxcpath sync-pipe-fd\n\n" "NOTE: lxc-monitord is intended for use by lxc internally\n" " and does not need to be run by hand\n\n"); exit(EXIT_FAILURE); } ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log", (strcmp(LXCPATH, lxcpath) ? lxcpath : LOGPATH ) ); if (ret < 0 || ret >= sizeof(logpath)) return EXIT_FAILURE; ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0, lxcpath); if (ret) INFO("Failed to open log file %s, log will be lost", lxcpath); lxc_log_options_no_override(); pipefd = atoi(argv[2]); if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || sigdelset(&mask, SIGTERM) || sigprocmask(SIG_BLOCK, &mask, NULL)) { SYSERROR("failed to set signal mask"); return 1; } signal(SIGILL, lxc_monitord_sig_handler); signal(SIGSEGV, lxc_monitord_sig_handler); signal(SIGBUS, lxc_monitord_sig_handler); signal(SIGTERM, lxc_monitord_sig_handler); ret = EXIT_FAILURE; memset(&mon, 0, sizeof(mon)); mon.lxcpath = lxcpath; if (lxc_mainloop_open(&mon.descr)) { ERROR("failed to create mainloop"); goto out; } if (lxc_monitord_create(&mon)) { goto out; } /* sync with parent, we're ignoring the return from write * because regardless if it works or not, the following * close will sync us with the parent process. the * if-empty-statement construct is to quiet the * warn-unused-result warning. */ if (write(pipefd, "S", 1)) ; close(pipefd); if (lxc_monitord_mainloop_add(&mon)) { ERROR("failed to add mainloop handlers"); goto out; } NOTICE("pid:%d monitoring lxcpath %s", getpid(), mon.lxcpath); for(;;) { ret = lxc_mainloop(&mon.descr, 1000 * 30); if (mon.clientfds_cnt <= 0) { NOTICE("no remaining clients, exiting"); break; } } lxc_mainloop_close(&mon.descr); lxc_monitord_cleanup(); ret = EXIT_SUCCESS; NOTICE("monitor exiting"); out: if (ret == 0) return 0; return 1; }
int main(int argc, char *argv[]) { struct lxc_container *c; char *cmd, *dev_name, *dst_name; int ret = 1; if (geteuid() != 0) { ERROR("%s must be run as root", argv[0]); exit(1); } if (lxc_arguments_parse(&my_args, argc, argv)) goto err; if (!my_args.log_file) my_args.log_file = "none"; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0])) goto err; lxc_log_options_no_override(); c = lxc_container_new(my_args.name, my_args.lxcpath[0]); if (!c) { ERROR("%s doesn't exist", my_args.name); goto err; } if (!c->is_running(c)) { ERROR("Container %s is not running.", c->name); goto err1; } if (my_args.argc < 2) { ERROR("Error: no command given (Please see --help output)"); goto err1; } cmd = my_args.argv[0]; dev_name = my_args.argv[1]; if (my_args.argc < 3) dst_name = dev_name; else dst_name = my_args.argv[2]; if (strcmp(cmd, "add") == 0) { if (is_interface(dev_name, 1)) { ret = c->attach_interface(c, dev_name, dst_name); } else { ret = c->add_device_node(c, dev_name, dst_name); } if (ret != true) { ERROR("Failed to add %s to %s.", dev_name, c->name); ret = 1; goto err1; } INFO("Add %s to %s.", dev_name, c->name); } else if (strcmp(cmd, "del") == 0) { if (is_interface(dev_name, c->init_pid(c))) { ret = c->detach_interface(c, dev_name, dst_name); } else { ret = c->remove_device_node(c, dev_name, dst_name); } if (ret != true) { ERROR("Failed to del %s from %s.", dev_name, c->name); ret = 1; goto err1; } INFO("Delete %s from %s.", dev_name, c->name); } else { ERROR("Error: Please use add or del (Please see --help output)"); goto err1; } exit(0); err1: lxc_container_put(c); err: exit(ret); }
int main(int argc, char *argv[]) { pid_t pid; int err; char **aargv; sigset_t mask, omask; int i, have_status = 0, shutdown = 0; int opt; char *lxcpath = NULL, *name = NULL, *logpriority = NULL; while ((opt = getopt_long(argc, argv, "n:l:qP:", options, NULL)) != -1) { switch(opt) { case 'n': name = optarg; break; case 'l': logpriority = optarg; break; case 'q': quiet = 1; break; case 'P': lxcpath = optarg; break; default: /* '?' */ usage(); exit(EXIT_FAILURE); } } if (lxc_caps_init()) exit(EXIT_FAILURE); err = lxc_log_init(name, name ? NULL : "none", logpriority, basename(argv[0]), quiet, lxcpath); if (err < 0) exit(EXIT_FAILURE); lxc_log_options_no_override(); if (!argv[optind]) { ERROR("missing command to launch"); exit(EXIT_FAILURE); } aargv = &argv[optind]; /* * mask all the signals so we are safe to install a * signal handler and to fork */ if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || sigprocmask(SIG_SETMASK, &mask, &omask)) { SYSERROR("failed to set signal mask"); exit(EXIT_FAILURE); } for (i = 1; i < NSIG; i++) { struct sigaction act; /* Exclude some signals: ILL, SEGV and BUS are likely to * reveal a bug and we want a core. STOP and KILL cannot be * handled anyway: they're here for documentation. */ if (i == SIGILL || i == SIGSEGV || i == SIGBUS || i == SIGSTOP || i == SIGKILL || i == 32 || i == 33) continue; if (sigfillset(&act.sa_mask) || sigdelset(&act.sa_mask, SIGILL) || sigdelset(&act.sa_mask, SIGSEGV) || sigdelset(&act.sa_mask, SIGBUS) || sigdelset(&act.sa_mask, SIGSTOP) || sigdelset(&act.sa_mask, SIGKILL)) { ERROR("failed to set signal"); exit(EXIT_FAILURE); } act.sa_flags = 0; act.sa_handler = interrupt_handler; if (sigaction(i, &act, NULL) && errno != EINVAL) { SYSERROR("failed to sigaction"); exit(EXIT_FAILURE); } } lxc_setup_fs(); if (lxc_caps_reset()) exit(EXIT_FAILURE); pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (!pid) { /* restore default signal handlers */ for (i = 1; i < NSIG; i++) signal(i, SIG_DFL); if (sigprocmask(SIG_SETMASK, &omask, NULL)) { SYSERROR("failed to set signal mask"); exit(EXIT_FAILURE); } NOTICE("about to exec '%s'", aargv[0]); execvp(aargv[0], aargv); ERROR("failed to exec: '%s' : %m", aargv[0]); exit(err); } /* let's process the signals now */ if (sigdelset(&omask, SIGALRM) || sigprocmask(SIG_SETMASK, &omask, NULL)) { SYSERROR("failed to set signal mask"); exit(EXIT_FAILURE); } /* no need of other inherited fds but stderr */ close(fileno(stdin)); close(fileno(stdout)); err = EXIT_SUCCESS; for (;;) { int status; pid_t waited_pid; switch (was_interrupted) { case 0: break; case SIGTERM: if (!shutdown) { shutdown = 1; kill(-1, SIGTERM); alarm(1); } break; case SIGALRM: kill(-1, SIGKILL); break; default: kill(pid, was_interrupted); break; } was_interrupted = 0; waited_pid = wait(&status); if (waited_pid < 0) { if (errno == ECHILD) goto out; if (errno == EINTR) continue; ERROR("failed to wait child : %s", strerror(errno)); goto out; } /* reset timer each time a process exited */ if (shutdown) alarm(1); /* * keep the exit code of started application * (not wrapped pid) and continue to wait for * the end of the orphan group. */ if (waited_pid == pid && !have_status) { err = lxc_error_set_and_log(waited_pid, status); have_status = 1; } } out: return err; }
int main(int argc, char *argv[]) { int ret, pipefd; char logpath[PATH_MAX]; sigset_t mask; char *lxcpath = argv[1]; bool mainloop_opened = false; bool monitord_created = false; struct lxc_log log; if (argc != 3) { fprintf(stderr, "Usage: lxc-monitord lxcpath sync-pipe-fd\n\n" "NOTE: lxc-monitord is intended for use by lxc internally\n" " and does not need to be run by hand\n\n"); exit(EXIT_FAILURE); } ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log", (strcmp(LXCPATH, lxcpath) ? lxcpath : LOGPATH)); if (ret < 0 || ret >= sizeof(logpath)) exit(EXIT_FAILURE); log.name = NULL; log.file = logpath; log.level = "DEBUG"; log.prefix = "lxc-monitord"; log.quiet = 0; log.lxcpath = lxcpath; ret = lxc_log_init(&log); if (ret) INFO("Failed to open log file %s, log will be lost", lxcpath); lxc_log_options_no_override(); if (lxc_safe_int(argv[2], &pipefd) < 0) exit(EXIT_FAILURE); if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || sigdelset(&mask, SIGTERM) || pthread_sigmask(SIG_BLOCK, &mask, NULL)) { SYSERROR("Failed to set signal mask"); exit(EXIT_FAILURE); } signal(SIGILL, lxc_monitord_sig_handler); signal(SIGSEGV, lxc_monitord_sig_handler); signal(SIGBUS, lxc_monitord_sig_handler); signal(SIGTERM, lxc_monitord_sig_handler); if (sigsetjmp(mark, 1) != 0) goto on_signal; ret = EXIT_FAILURE; memset(&mon, 0, sizeof(mon)); mon.lxcpath = lxcpath; if (lxc_mainloop_open(&mon.descr)) { ERROR("Failed to create mainloop"); goto on_error; } mainloop_opened = true; if (lxc_monitord_create(&mon)) goto on_error; monitord_created = true; /* sync with parent, we're ignoring the return from write * because regardless if it works or not, the following * close will sync us with the parent process. the * if-empty-statement construct is to quiet the * warn-unused-result warning. */ if (lxc_write_nointr(pipefd, "S", 1)) ; close(pipefd); if (lxc_monitord_mainloop_add(&mon)) { ERROR("Failed to add mainloop handlers"); goto on_error; } NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s", lxc_raw_getpid(), mon.lxcpath); for (;;) { ret = lxc_mainloop(&mon.descr, 1000 * 30); if (ret) { ERROR("mainloop returned an error"); break; } if (mon.clientfds_cnt <= 0) { NOTICE("No remaining clients. lxc-monitord is exiting"); break; } if (quit == LXC_MAINLOOP_CLOSE) { NOTICE("Got quit command. lxc-monitord is exitting"); break; } } on_signal: ret = EXIT_SUCCESS; on_error: if (monitord_created) lxc_monitord_cleanup(); if (mainloop_opened) lxc_mainloop_close(&mon.descr); exit(ret); }
int main(int argc, char *argv[]) { struct lxc_container *c; bool s; int ret = 1; if (lxc_arguments_parse(&my_args, argc, argv)) return 1; if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet, my_args.lxcpath[0])) return 1; lxc_log_options_no_override(); /* Set default timeout */ if (my_args.timeout == -2) { if (my_args.hardstop) { my_args.timeout = 0; } else { my_args.timeout = 60; } } if (my_args.nowait) { my_args.timeout = 0; } /* some checks */ if (!my_args.hardstop && my_args.timeout < -1) { fprintf(stderr, "invalid timeout\n"); return 1; } if (my_args.hardstop && my_args.nokill) { fprintf(stderr, "-k can't be used with --nokill\n"); return 1; } if (my_args.hardstop && my_args.reboot) { fprintf(stderr, "-k can't be used with -r\n"); return 1; } if (my_args.hardstop && my_args.timeout) { fprintf(stderr, "-k doesn't allow timeouts\n"); return 1; } if (my_args.nolock && !my_args.hardstop) { fprintf(stderr, "--nolock may only be used with -k\n"); return 1; } /* shortcut - if locking is bogus, we should be able to kill * containers at least */ if (my_args.nolock) return lxc_cmd_stop(my_args.name, my_args.lxcpath[0]); c = lxc_container_new(my_args.name, my_args.lxcpath[0]); if (!c) { fprintf(stderr, "Error opening container\n"); goto out; } if (!c->may_control(c)) { fprintf(stderr, "Insufficent privileges to control %s\n", c->name); goto out; } if (!c->is_running(c)) { fprintf(stderr, "%s is not running\n", c->name); ret = 2; goto out; } /* kill */ if (my_args.hardstop) { ret = c->stop(c) ? 0 : 1; goto out; } /* reboot */ if (my_args.reboot) { ret = do_reboot_and_check(&my_args, c); goto out; } /* shutdown */ s = c->shutdown(c, my_args.timeout); if (!s) { if (my_args.timeout == 0) ret = 0; else if (my_args.nokill) ret = 1; else ret = c->stop(c) ? 0 : 1; } else ret = 0; out: lxc_container_put(c); return ret; }