From bf68366f3d9fb56e78d5d649b748af3a9685da88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=82=88?= Date: Mon, 26 Oct 2015 19:55:15 +0800 Subject: [PATCH 1/4] add option --exec for commands run after the container is ready --- src/cmdline.ggo | 2 ++ src/pflask.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/cmdline.ggo b/src/cmdline.ggo index 252b98a..d43b8e6 100644 --- a/src/cmdline.ggo +++ b/src/cmdline.ggo @@ -11,6 +11,8 @@ option "mount" m "Create a new mount point inside the container" string optional multiple option "netif" n "Disconnect the container networking from the host" string optional argoptional multiple +option "exec" E "Execute commands when the container is ready" + string optional multiple option "user" u "Run the command under the specified user" string default="root" optional option "user-map" e "Map container users to host users" diff --git a/src/pflask.c b/src/pflask.c index b9f8cd6..639d43a 100644 --- a/src/pflask.c +++ b/src/pflask.c @@ -299,6 +299,15 @@ int main(int argc, char *argv[]) { sync_wake_child(sync, SYNC_DONE); sync_close(sync); + + for (unsigned int i = 0; i < args.exec_given; i++) { + int status = system(args.exec_arg[i]); + if(status == 0){ + ok_printf("Success: %s", args.exec_arg[i]); + }else{ + err_printf("Fail: %s", args.exec_arg[i]); + } + } if (args.detach_flag) serve_pty(master_fd); From 84275a64bc63dcf56b757c556e5298fbaecfa2dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=82=88?= Date: Mon, 26 Oct 2015 20:01:22 +0800 Subject: [PATCH 2/4] add the generated cmdline.* --- src/cmdline.c | 62 ++++++++++++++++++++++++++++++++++++++------------- src/cmdline.h | 6 +++++ 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/cmdline.c b/src/cmdline.c index 7b54d12..97ba571 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -41,6 +41,7 @@ const char *gengetopt_args_info_help[] = { " -t, --hostname=STRING Set the container hostname", " -m, --mount=STRING Create a new mount point inside the container", " -n, --netif[=STRING] Disconnect the container networking from the host", + " -E, --exec=STRING Execute commands when the container is ready", " -u, --user=STRING Run the command under the specified user\n (default=`root')", " -e, --user-map=STRING Map container users to host users", " -w, --ephemeral Discard changes to / (default=off)", @@ -90,6 +91,7 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->hostname_given = 0 ; args_info->mount_given = 0 ; args_info->netif_given = 0 ; + args_info->exec_given = 0 ; args_info->user_given = 0 ; args_info->user_map_given = 0 ; args_info->ephemeral_given = 0 ; @@ -121,6 +123,8 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->mount_orig = NULL; args_info->netif_arg = NULL; args_info->netif_orig = NULL; + args_info->exec_arg = NULL; + args_info->exec_orig = NULL; args_info->user_arg = gengetopt_strdup ("root"); args_info->user_orig = NULL; args_info->user_map_arg = NULL; @@ -160,29 +164,32 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->netif_help = gengetopt_args_info_help[6] ; args_info->netif_min = 0; args_info->netif_max = 0; - args_info->user_help = gengetopt_args_info_help[7] ; - args_info->user_map_help = gengetopt_args_info_help[8] ; + args_info->exec_help = gengetopt_args_info_help[7] ; + args_info->exec_min = 0; + args_info->exec_max = 0; + args_info->user_help = gengetopt_args_info_help[8] ; + args_info->user_map_help = gengetopt_args_info_help[9] ; args_info->user_map_min = 0; args_info->user_map_max = 0; - args_info->ephemeral_help = gengetopt_args_info_help[9] ; - args_info->cgroup_help = gengetopt_args_info_help[10] ; + args_info->ephemeral_help = gengetopt_args_info_help[10] ; + args_info->cgroup_help = gengetopt_args_info_help[11] ; args_info->cgroup_min = 0; args_info->cgroup_max = 0; - args_info->caps_help = gengetopt_args_info_help[11] ; + args_info->caps_help = gengetopt_args_info_help[12] ; args_info->caps_min = 0; args_info->caps_max = 0; - args_info->detach_help = gengetopt_args_info_help[12] ; - args_info->attach_help = gengetopt_args_info_help[13] ; - args_info->setenv_help = gengetopt_args_info_help[14] ; + args_info->detach_help = gengetopt_args_info_help[13] ; + args_info->attach_help = gengetopt_args_info_help[14] ; + args_info->setenv_help = gengetopt_args_info_help[15] ; args_info->setenv_min = 0; args_info->setenv_max = 0; - args_info->keepenv_help = gengetopt_args_info_help[15] ; - args_info->no_userns_help = gengetopt_args_info_help[16] ; - args_info->no_mountns_help = gengetopt_args_info_help[17] ; - args_info->no_netns_help = gengetopt_args_info_help[18] ; - args_info->no_ipcns_help = gengetopt_args_info_help[19] ; - args_info->no_utsns_help = gengetopt_args_info_help[20] ; - args_info->no_pidns_help = gengetopt_args_info_help[21] ; + args_info->keepenv_help = gengetopt_args_info_help[16] ; + args_info->no_userns_help = gengetopt_args_info_help[17] ; + args_info->no_mountns_help = gengetopt_args_info_help[18] ; + args_info->no_netns_help = gengetopt_args_info_help[19] ; + args_info->no_ipcns_help = gengetopt_args_info_help[20] ; + args_info->no_utsns_help = gengetopt_args_info_help[21] ; + args_info->no_pidns_help = gengetopt_args_info_help[22] ; } @@ -319,6 +326,7 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->hostname_orig)); free_multiple_string_field (args_info->mount_given, &(args_info->mount_arg), &(args_info->mount_orig)); free_multiple_string_field (args_info->netif_given, &(args_info->netif_arg), &(args_info->netif_orig)); + free_multiple_string_field (args_info->exec_given, &(args_info->exec_arg), &(args_info->exec_orig)); free_string_field (&(args_info->user_arg)); free_string_field (&(args_info->user_orig)); free_multiple_string_field (args_info->user_map_given, &(args_info->user_map_arg), &(args_info->user_map_orig)); @@ -376,6 +384,7 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "hostname", args_info->hostname_orig, 0); write_multiple_into_file(outfile, args_info->mount_given, "mount", args_info->mount_orig, 0); write_multiple_into_file(outfile, args_info->netif_given, "netif", args_info->netif_orig, 0); + write_multiple_into_file(outfile, args_info->exec_given, "exec", args_info->exec_orig, 0); if (args_info->user_given) write_into_file(outfile, "user", args_info->user_orig, 0); write_multiple_into_file(outfile, args_info->user_map_given, "user-map", args_info->user_map_orig, 0); @@ -659,6 +668,9 @@ cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *pro if (check_multiple_option_occurrences(prog_name, args_info->netif_given, args_info->netif_min, args_info->netif_max, "'--netif' ('-n')")) error_occurred = 1; + if (check_multiple_option_occurrences(prog_name, args_info->exec_given, args_info->exec_min, args_info->exec_max, "'--exec' ('-E')")) + error_occurred = 1; + if (check_multiple_option_occurrences(prog_name, args_info->user_map_given, args_info->user_map_min, args_info->user_map_max, "'--user-map' ('-e')")) error_occurred = 1; @@ -940,6 +952,7 @@ cmdline_parser_internal ( struct generic_list * mount_list = NULL; struct generic_list * netif_list = NULL; + struct generic_list * exec_list = NULL; struct generic_list * user_map_list = NULL; struct generic_list * cgroup_list = NULL; struct generic_list * caps_list = NULL; @@ -981,6 +994,7 @@ cmdline_parser_internal ( { "hostname", 1, NULL, 't' }, { "mount", 1, NULL, 'm' }, { "netif", 2, NULL, 'n' }, + { "exec", 1, NULL, 'E' }, { "user", 1, NULL, 'u' }, { "user-map", 1, NULL, 'e' }, { "ephemeral", 0, NULL, 'w' }, @@ -999,7 +1013,7 @@ cmdline_parser_internal ( { 0, 0, 0, 0 } }; - c = getopt_long (argc, argv, "hVr:c:t:m:n::u:e:wg:b:da:s:kUMNIHP", long_options, &option_index); + c = getopt_long (argc, argv, "hVr:c:t:m:n::E:u:e:wg:b:da:s:kUMNIHP", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -1068,6 +1082,15 @@ cmdline_parser_internal ( additional_error)) goto failure; + break; + case 'E': /* Execute commands when the container is ready. */ + + if (update_multiple_arg_temp(&exec_list, + &(local_args_info.exec_given), optarg, 0, 0, ARG_STRING, + "exec", 'E', + additional_error)) + goto failure; + break; case 'u': /* Run the command under the specified user. */ @@ -1240,6 +1263,10 @@ cmdline_parser_internal ( &(args_info->netif_orig), args_info->netif_given, local_args_info.netif_given, 0, ARG_STRING, netif_list); + update_multiple_arg((void *)&(args_info->exec_arg), + &(args_info->exec_orig), args_info->exec_given, + local_args_info.exec_given, 0, + ARG_STRING, exec_list); update_multiple_arg((void *)&(args_info->user_map_arg), &(args_info->user_map_orig), args_info->user_map_given, local_args_info.user_map_given, 0, @@ -1262,6 +1289,8 @@ cmdline_parser_internal ( local_args_info.mount_given = 0; args_info->netif_given += local_args_info.netif_given; local_args_info.netif_given = 0; + args_info->exec_given += local_args_info.exec_given; + local_args_info.exec_given = 0; args_info->user_map_given += local_args_info.user_map_given; local_args_info.user_map_given = 0; args_info->cgroup_given += local_args_info.cgroup_given; @@ -1286,6 +1315,7 @@ cmdline_parser_internal ( failure: free_list (mount_list, 1 ); free_list (netif_list, 1 ); + free_list (exec_list, 1 ); free_list (user_map_list, 1 ); free_list (cgroup_list, 1 ); free_list (caps_list, 1 ); diff --git a/src/cmdline.h b/src/cmdline.h index 0010e73..01e28b3 100644 --- a/src/cmdline.h +++ b/src/cmdline.h @@ -58,6 +58,11 @@ struct gengetopt_args_info unsigned int netif_min; /**< @brief Disconnect the container networking from the host's minimum occurreces */ unsigned int netif_max; /**< @brief Disconnect the container networking from the host's maximum occurreces */ const char *netif_help; /**< @brief Disconnect the container networking from the host help description. */ + char ** exec_arg; /**< @brief Execute commands when the container is ready. */ + char ** exec_orig; /**< @brief Execute commands when the container is ready original value given at command line. */ + unsigned int exec_min; /**< @brief Execute commands when the container is ready's minimum occurreces */ + unsigned int exec_max; /**< @brief Execute commands when the container is ready's maximum occurreces */ + const char *exec_help; /**< @brief Execute commands when the container is ready help description. */ char * user_arg; /**< @brief Run the command under the specified user (default='root'). */ char * user_orig; /**< @brief Run the command under the specified user original value given at command line. */ const char *user_help; /**< @brief Run the command under the specified user help description. */ @@ -110,6 +115,7 @@ struct gengetopt_args_info unsigned int hostname_given ; /**< @brief Whether hostname was given. */ unsigned int mount_given ; /**< @brief Whether mount was given. */ unsigned int netif_given ; /**< @brief Whether netif was given. */ + unsigned int exec_given ; /**< @brief Whether exec was given. */ unsigned int user_given ; /**< @brief Whether user was given. */ unsigned int user_map_given ; /**< @brief Whether user-map was given. */ unsigned int ephemeral_given ; /**< @brief Whether ephemeral was given. */ From 5bcbad43a594f404d1cd438b5909d49d552fad2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=82=88?= Date: Mon, 26 Oct 2015 20:07:09 +0800 Subject: [PATCH 3/4] add --no-dev for not touching /dev, because sometimes we are able to create some dev nodes in advance --- src/cmdline.ggo | 2 ++ src/mount.c | 14 ++++++++------ src/mount.h | 2 +- src/pflask.c | 15 +++++++++------ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/cmdline.ggo b/src/cmdline.ggo index d43b8e6..9371505 100644 --- a/src/cmdline.ggo +++ b/src/cmdline.ggo @@ -44,3 +44,5 @@ option "no-utsns" H "Disable UTS namespace support" flag off option "no-pidns" P "Disable PID namespace support" flag off +option "no-dev" D "Do not create nodes in /dev" + flag off diff --git a/src/mount.c b/src/mount.c index 84ae303..d2f196d 100644 --- a/src/mount.c +++ b/src/mount.c @@ -135,7 +135,7 @@ void mount_add_from_spec(struct mount **mounts, const char *spec) { } } -void setup_mount(struct mount *mounts, const char *dest, const char *ephemeral_dir) { +void setup_mount(struct mount *mounts, const char *dest, const char *ephemeral_dir, int no_dev_flag) { int rc; struct mount *sys_mounts = NULL; @@ -184,12 +184,14 @@ void setup_mount(struct mount *mounts, const char *dest, const char *ephemeral_d mount_add(&sys_mounts, "sysfs", "/sys", "sysfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_RDONLY, NULL); - mount_add(&sys_mounts, "tmpfs", "/dev", "tmpfs", - MS_NOSUID | MS_STRICTATIME, "mode=755"); + if(! no_dev_flag){ + mount_add(&sys_mounts, "tmpfs", "/dev", "tmpfs", + MS_NOSUID | MS_STRICTATIME, "mode=755"); - mount_add(&sys_mounts, "devpts", "/dev/pts", "devpts", - MS_NOSUID | MS_NOEXEC, - "newinstance,ptmxmode=0666,mode=0620,gid=5"); + mount_add(&sys_mounts, "devpts", "/dev/pts", "devpts", + MS_NOSUID | MS_NOEXEC, + "newinstance,ptmxmode=0666,mode=0620,gid=5"); + } mount_add(&sys_mounts, "tmpfs", "/dev/shm", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_NODEV, "mode=1777"); diff --git a/src/mount.h b/src/mount.h index 19bdb2f..36d7dd4 100644 --- a/src/mount.h +++ b/src/mount.h @@ -35,4 +35,4 @@ void mount_add(struct mount **mounts, const char *src, const char *dst, void mount_add_from_spec(struct mount **mounts, const char *spec); -void setup_mount(struct mount *mounts, const char *dest, const char *ephemeral_dir); +void setup_mount(struct mount *mounts, const char *dest, const char *ephemeral_dir, int no_dev_flag); diff --git a/src/pflask.c b/src/pflask.c index 639d43a..2fb6a03 100644 --- a/src/pflask.c +++ b/src/pflask.c @@ -101,7 +101,6 @@ int main(int argc, char *argv[]) { for (unsigned int i = 0; i < args.netif_given; i++) { clone_flags |= CLONE_NEWNET; - if (args.netif_arg != NULL) { validate_optlist("--netif", args.netif_arg[i]); netif_add_from_spec(&netifs, args.netif_arg[i]); @@ -225,16 +224,20 @@ int main(int argc, char *argv[]) { } setup_mount(mounts, args.chroot_arg, args.ephemeral_flag ? - ephemeral_dir : NULL); + ephemeral_dir : NULL, + args.no_dev_flag); if (args.chroot_given) { - setup_nodes(args.chroot_arg); + if (! args.no_dev_flag) { + + setup_nodes(args.chroot_arg); - setup_ptmx(args.chroot_arg); + setup_ptmx(args.chroot_arg); - setup_symlinks(args.chroot_arg); + setup_symlinks(args.chroot_arg); - setup_console(args.chroot_arg, master); + setup_console(args.chroot_arg, master); + } do_chroot(args.chroot_arg); } From 2a9c4694513e5ac2ce2c6fb8b4d1a95c1f5d7330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=82=88?= Date: Mon, 26 Oct 2015 20:08:05 +0800 Subject: [PATCH 4/4] add cmdline.* generated --- src/cmdline.c | 19 ++++++++++++++++++- src/cmdline.h | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/cmdline.c b/src/cmdline.c index 97ba571..15daca5 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -57,6 +57,7 @@ const char *gengetopt_args_info_help[] = { " -I, --no-ipcns Disable IPC namespace support (default=off)", " -H, --no-utsns Disable UTS namespace support (default=off)", " -P, --no-pidns Disable PID namespace support (default=off)", + " -D, --no-dev Do not create nodes in /dev (default=off)", 0 }; @@ -107,6 +108,7 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->no_ipcns_given = 0 ; args_info->no_utsns_given = 0 ; args_info->no_pidns_given = 0 ; + args_info->no_dev_given = 0 ; } static @@ -145,6 +147,7 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->no_ipcns_flag = 0; args_info->no_utsns_flag = 0; args_info->no_pidns_flag = 0; + args_info->no_dev_flag = 0; } @@ -190,6 +193,7 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->no_ipcns_help = gengetopt_args_info_help[20] ; args_info->no_utsns_help = gengetopt_args_info_help[21] ; args_info->no_pidns_help = gengetopt_args_info_help[22] ; + args_info->no_dev_help = gengetopt_args_info_help[23] ; } @@ -411,6 +415,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "no-utsns", 0, 0 ); if (args_info->no_pidns_given) write_into_file(outfile, "no-pidns", 0, 0 ); + if (args_info->no_dev_given) + write_into_file(outfile, "no-dev", 0, 0 ); i = EXIT_SUCCESS; @@ -1010,10 +1016,11 @@ cmdline_parser_internal ( { "no-ipcns", 0, NULL, 'I' }, { "no-utsns", 0, NULL, 'H' }, { "no-pidns", 0, NULL, 'P' }, + { "no-dev", 0, NULL, 'D' }, { 0, 0, 0, 0 } }; - c = getopt_long (argc, argv, "hVr:c:t:m:n::E:u:e:wg:b:da:s:kUMNIHP", long_options, &option_index); + c = getopt_long (argc, argv, "hVr:c:t:m:n::E:u:e:wg:b:da:s:kUMNIHPD", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -1242,6 +1249,16 @@ cmdline_parser_internal ( goto failure; break; + case 'D': /* Do not create nodes in /dev. */ + + + if (update_arg((void *)&(args_info->no_dev_flag), 0, &(args_info->no_dev_given), + &(local_args_info.no_dev_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "no-dev", 'D', + additional_error)) + goto failure; + + break; case 0: /* Long option with no short option */ case '?': /* Invalid option. */ diff --git a/src/cmdline.h b/src/cmdline.h index 01e28b3..d0d7b2a 100644 --- a/src/cmdline.h +++ b/src/cmdline.h @@ -107,6 +107,8 @@ struct gengetopt_args_info const char *no_utsns_help; /**< @brief Disable UTS namespace support help description. */ int no_pidns_flag; /**< @brief Disable PID namespace support (default=off). */ const char *no_pidns_help; /**< @brief Disable PID namespace support help description. */ + int no_dev_flag; /**< @brief Do not create nodes in /dev (default=off). */ + const char *no_dev_help; /**< @brief Do not create nodes in /dev help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ @@ -131,6 +133,7 @@ struct gengetopt_args_info unsigned int no_ipcns_given ; /**< @brief Whether no-ipcns was given. */ unsigned int no_utsns_given ; /**< @brief Whether no-utsns was given. */ unsigned int no_pidns_given ; /**< @brief Whether no-pidns was given. */ + unsigned int no_dev_given ; /**< @brief Whether no-dev was given. */ } ;