static int my_parser(struct lxc_arguments* args, int c, char* arg) { int ret; switch (c) { case 'e': ret = lxc_fill_elevated_privileges(arg, &elevated_privileges); if (ret) return -1; break; case 'R': remount_sys_proc = 1; break; case 'a': new_personality = lxc_config_parse_arch(arg); if (new_personality < 0) { lxc_error(args, "invalid architecture specified: %s", arg); return -1; } break; case 's': namespace_flags = 0; ret = lxc_fill_namespace_flags(arg, &namespace_flags); if (ret) return -1; /* -s implies -e */ lxc_fill_elevated_privileges(NULL, &elevated_privileges); break; case 500: /* clear-env */ env_policy = LXC_ATTACH_CLEAR_ENV; break; case 501: /* keep-env */ env_policy = LXC_ATTACH_KEEP_ENV; break; case 502: /* keep-var */ ret = add_to_simple_array(&extra_keep, &extra_keep_size, arg); if (ret < 0) { lxc_error(args, "memory allocation error"); return -1; } break; case 'v': ret = add_to_simple_array(&extra_env, &extra_env_size, arg); if (ret < 0) { lxc_error(args, "memory allocation error"); return -1; } break; } return 0; }
int main(int argc, char *argv[]) { int opt, status; int ret; char *namespaces = NULL; char **args; int flags = 0; int daemonize = 0; uid_t uid = 0; /* valid only if (flags & CLONE_NEWUSER) */ pid_t pid; struct my_iflist *tmpif, *my_iflist = NULL; struct start_arg start_arg = { .args = &args, .uid = &uid, .setuid = false, .flags = &flags, .want_hostname = NULL, .want_default_mounts = 0, }; while ((opt = getopt(argc, argv, "s:u:hH:i:dM")) != -1) { switch (opt) { case 's': namespaces = optarg; break; case 'i': if (!(tmpif = malloc(sizeof(*tmpif)))) { perror("malloc"); exit(1); } tmpif->mi_ifname = optarg; tmpif->mi_next = my_iflist; my_iflist = tmpif; break; case 'd': daemonize = 1; break; case 'M': start_arg.want_default_mounts = 1; break; case 'H': start_arg.want_hostname = optarg; break; case 'h': usage(argv[0]); break; case 'u': if (!lookup_user(optarg, &uid)) return 1; start_arg.setuid = true; } } if (argv[optind] == NULL) { ERROR("a command to execute in the new namespace is required"); return 1; } args = &argv[optind]; ret = lxc_caps_init(); if (ret) return 1; ret = lxc_fill_namespace_flags(namespaces, &flags); if (ret) usage(argv[0]); if (!(flags & CLONE_NEWNET) && my_iflist) { ERROR("-i <interfacename> needs -s NETWORK option"); return 1; } if (!(flags & CLONE_NEWUTS) && start_arg.want_hostname) { ERROR("-H <hostname> needs -s UTSNAME option"); return 1; } if (!(flags & CLONE_NEWNS) && start_arg.want_default_mounts) { ERROR("-M needs -s MOUNT option"); return 1; } pid = lxc_clone(do_start, &start_arg, flags); if (pid < 0) { ERROR("failed to clone"); return 1; } if (my_iflist) { for (tmpif = my_iflist; tmpif; tmpif = tmpif->mi_next) { if (lxc_netdev_move_by_name(tmpif->mi_ifname, pid) < 0) fprintf(stderr,"Could not move interface %s into container %d: %s\n", tmpif->mi_ifname, pid, strerror(errno)); } } if (daemonize) exit(0); if (waitpid(pid, &status, 0) < 0) { ERROR("failed to wait for '%d'", pid); return 1; } return lxc_error_set_and_log(pid, status); }
int main(int argc, char *argv[]) { int opt, status; int ret; char *namespaces = NULL; char **args; int flags = 0; uid_t uid = -1; /* valid only if (flags & CLONE_NEWUSER) */ pid_t pid; struct start_arg start_arg = { .args = &args, .uid = &uid, .flags = &flags, }; while ((opt = getopt(argc, argv, "s:u:h")) != -1) { switch (opt) { case 's': namespaces = optarg; break; case 'h': usage(argv[0]); case 'u': uid = lookup_user(optarg); if (uid == -1) return 1; } } if (argv[optind] == NULL) { ERROR("a command to execute in the new namespace is required"); return 1; } args = &argv[optind]; ret = lxc_caps_init(); if (ret) return ret; ret = lxc_fill_namespace_flags(namespaces, &flags); if (ret) usage(argv[0]); if (!(flags & CLONE_NEWUSER) && uid != -1) { ERROR("-u <uid> needs -s USER option"); return 1; } pid = lxc_clone(do_start, &start_arg, flags); if (pid < 0) { ERROR("failed to clone"); return -1; } if (waitpid(pid, &status, 0) < 0) { ERROR("failed to wait for '%d'", pid); return -1; } return lxc_error_set_and_log(pid, status); }