For the lxc-* C binaries, introduce a -P|--lxcpath command line option to override the system default.
With this, I can lxc-create -t ubuntu -n r1 lxc-create -t ubuntu -n r1 -P /home/ubuntu/lxcbase lxc-start -n r1 -d lxc-start -n r1 -d -P /home/ubuntu/lxcbase lxc-console -n r1 -d -P /home/ubuntu/lxcbase lxc-stop -n r1 all working with the right containers (module cgroup stuff). To do: * lxc monitor needs to be made to handle cgroups. This is another very invasive one. I started doing this as a part of this set, but that gets hairy, so I'm sending this separately. Note that lxc-wait and lxc-monitor don't work without this, and there may be niggles in what I said works above - since start.c is doing lxc_monitor_send_state etc to the shared abstract unix domain socket. * Need to handle the cgroup conflicts. Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> --- doc/common_options.sgml.in | 9 +++++++++ src/lua-lxc/core.c | 3 +-- src/lxc/arguments.c | 4 ++++ src/lxc/arguments.h | 2 ++ src/lxc/commands.c | 4 +--- src/lxc/conf.c | 3 +-- src/lxc/lxc-create.in | 11 +++++++++-- src/lxc/lxc.h | 3 ++- src/lxc/lxc_attach.c | 6 ++---- src/lxc/lxc_console.c | 4 +--- src/lxc/lxc_execute.c | 10 ++-------- src/lxc/lxc_info.c | 6 ++---- src/lxc/lxc_kill.c | 4 +--- src/lxc/lxc_restart.c | 10 ++-------- src/lxc/lxc_start.c | 12 ++---------- src/lxc/lxc_stop.c | 6 ++---- src/lxc/lxc_wait.c | 2 +- src/lxc/lxccontainer.c | 6 +++--- src/lxc/lxccontainer.h | 2 +- src/lxc/restart.c | 5 ++--- src/lxc/state.c | 4 +--- src/lxc/state.h | 2 +- src/lxc/utils.c | 19 ++++++++++--------- src/lxc/utils.h | 2 +- 24 files changed, 63 insertions(+), 76 deletions(-) diff --git a/doc/common_options.sgml.in b/doc/common_options.sgml.in index 32e89ce..f89419f 100644 --- a/doc/common_options.sgml.in +++ b/doc/common_options.sgml.in @@ -58,6 +58,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA </varlistentry> <varlistentry> + <term><option>-P, --lxcpath=<replaceable>PATH</replaceable></option></term> + <listitem> + <para> + Use an alternate container path. The default is @LXCPATH@. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><option>-o, --logfile=<replaceable>FILE</replaceable></option></term> <listitem> <para> diff --git a/src/lua-lxc/core.c b/src/lua-lxc/core.c index c9eaef0..3641786 100644 --- a/src/lua-lxc/core.c +++ b/src/lua-lxc/core.c @@ -366,10 +366,9 @@ static int lxc_version_get(lua_State *L) { } static int lxc_default_config_path_get(lua_State *L) { - char *lxcpath = lxc_get_default_config_path(); + const char *lxcpath = lxc_get_default_config_path(); lua_pushstring(L, lxcpath); - free(lxcpath); return 1; } diff --git a/src/lxc/arguments.c b/src/lxc/arguments.c index 76d8366..ceafb52 100644 --- a/src/lxc/arguments.c +++ b/src/lxc/arguments.c @@ -32,6 +32,7 @@ #include <unistd.h> #include "arguments.h" +#include "utils.h" /*---------------------------------------------------------------------------*/ static int build_shortopts(const struct option *a_options, @@ -136,6 +137,7 @@ Common options :\n\ -o, --logfile=FILE Output log to FILE instead of stderr\n\ -l, --logpriority=LEVEL Set log priority to LEVEL\n\ -q, --quiet Don't produce any output\n\ + -P, --lxcpath=PATH Use specified container path\n\ -?, --help Give this help list\n\ --usage Give a short usage message\n\ \n\ @@ -154,6 +156,7 @@ extern int lxc_arguments_parse(struct lxc_arguments *args, char shortopts[256]; int ret = 0; + args->lxcpath = default_lxc_path(); ret = build_shortopts(args->options, shortopts, sizeof(shortopts)); if (ret < 0) { lxc_error(args, "build_shortopts() failed : %s", @@ -173,6 +176,7 @@ extern int lxc_arguments_parse(struct lxc_arguments *args, case 'l': args->log_priority = optarg; break; case 'c': args->console = optarg; break; case 'q': args->quiet = 1; break; + case 'P': args->lxcpath = optarg; break; case OPT_USAGE: print_usage(args->options, args); case '?': print_help(args, 1); case 'h': print_help(args, 0); diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h index 5f2ecba..69e7b00 100644 --- a/src/lxc/arguments.h +++ b/src/lxc/arguments.h @@ -47,6 +47,7 @@ struct lxc_arguments { const char *console; const char *console_log; const char *pidfile; + const char *lxcpath; /* for lxc-checkpoint/restart */ const char *statefile; @@ -79,6 +80,7 @@ struct lxc_arguments { {"quiet", no_argument, 0, 'q'}, \ {"logfile", required_argument, 0, 'o'}, \ {"logpriority", required_argument, 0, 'l'}, \ + {"lxcpath", required_argument, 0, 'P'}, \ {0, 0, 0, 0} /* option keys for long only options */ diff --git a/src/lxc/commands.c b/src/lxc/commands.c index 2776f03..83e7df1 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -62,7 +62,7 @@ lxc_log_define(lxc_commands, lxc); static int fill_sock_name(char *path, int len, const char *name, const char *inpath) { - char *lxcpath = NULL; + const char *lxcpath = NULL; int ret; if (!inpath) { @@ -73,8 +73,6 @@ static int fill_sock_name(char *path, int len, const char *name, } } ret = snprintf(path, len, "%s/%s/command", lxcpath ? lxcpath : inpath, name); - if (lxcpath) - free(lxcpath); if (ret < 0 || ret >= len) { ERROR("Name too long"); diff --git a/src/lxc/conf.c b/src/lxc/conf.c index bb93189..04ab8b8 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1519,7 +1519,7 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent, unsigned long mntflags; char *mntdata; int r, ret = 0, offset; - char *lxcpath; + const char *lxcpath; if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) { ERROR("failed to parse mount option '%s'", mntent->mnt_opts); @@ -1535,7 +1535,6 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent, /* if rootfs->path is a blockdev path, allow container fstab to * use $lxcpath/CN/rootfs as the target prefix */ r = snprintf(path, MAXPATHLEN, "%s/%s/rootfs", lxcpath, lxc_name); - free(lxcpath); if (r < 0 || r >= MAXPATHLEN) goto skipvarlib; diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in index 26ca580..fec5511 100644 --- a/src/lxc/lxc-create.in +++ b/src/lxc/lxc-create.in @@ -20,9 +20,11 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +. @DATADIR@/lxc/lxc.functions + usage() { echo "usage: $(basename $0) -n NAME [-f CONFIG_FILE] [-t TEMPLATE] [FS_OPTIONS] --" >&2 - echo " [TEMPLATE_OPTIONS]" >&2 + echo " [-P lxcpath] [TEMPLATE_OPTIONS]" >&2 echo >&2 echo "where FS_OPTIONS is one of:" >&2 echo " -B none" >&2 @@ -42,6 +44,7 @@ help() { echo " -f CONFIG_FILE use an existing configuration file" >&2 echo " -t TEMPLATE use an accessible template script" >&2 echo " -B BACKING_STORE alter the container backing store (default: none)" >&2 + echo " --lxcpath path specify an alternate container patch (default: $lxc_path)" >&2 echo " --lvname LV_NAME specify the LVM logical volume name" >&2 echo " (default: container name)" >&2 echo " --dir ROOTFS_DIR specify path for custom rootfs directory location" >&2 @@ -73,7 +76,6 @@ optarg_check() { fi } -. @DATADIR@/lxc/lxc.functions backingstore=_unset fstype=ext4 fssize=500M @@ -98,6 +100,11 @@ while [ $# -gt 0 ]; do lxc_config=$1 shift ;; + -P|--lxcpath) + optarg_check $opt "$1" + lxc_path=$1 + shift + ;; -t|--template) optarg_check $opt "$1" lxc_template=$1 diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h index 0e1ce63..4e770a6 100644 --- a/src/lxc/lxc.h +++ b/src/lxc/lxc.h @@ -171,9 +171,10 @@ extern int lxc_checkpoint(const char *name, int sfd, int flags); * @sfd: fd from which the container is restarted * @conf: lxc_conf structure. * @flags : restart flags (an ORed value) + * @lxcpath: container path * Returns 0 on success, < 0 otherwise */ -extern int lxc_restart(const char *, int, struct lxc_conf *, int); +extern int lxc_restart(const char *, int, struct lxc_conf *, int, const char *); /* * Returns the version number of the library diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c index b4ccf44..370bfbc 100644 --- a/src/lxc/lxc_attach.c +++ b/src/lxc/lxc_attach.c @@ -130,8 +130,6 @@ int main(int argc, char *argv[]) void *cgroup_data = NULL; uid_t uid; char *curdir; - /* TODO: add cmdline arg to set lxcpath */ - const char *lxcpath = NULL; ret = lxc_caps_init(); if (ret) @@ -146,7 +144,7 @@ int main(int argc, char *argv[]) if (ret) return ret; - init_pid = get_init_pid(my_args.name, lxcpath); + init_pid = get_init_pid(my_args.name, my_args.lxcpath); if (init_pid < 0) { ERROR("failed to get the init pid"); return -1; @@ -176,7 +174,7 @@ int main(int argc, char *argv[]) * by asking lxc-start */ if (namespace_flags == -1) { - namespace_flags = lxc_get_clone_flags(my_args.name, lxcpath); + namespace_flags = lxc_get_clone_flags(my_args.name, my_args.lxcpath); /* call failed */ if (namespace_flags == -1) { ERROR("failed to automatically determine the " diff --git a/src/lxc/lxc_console.c b/src/lxc/lxc_console.c index 8ff3f5a..5f2ef0f 100644 --- a/src/lxc/lxc_console.c +++ b/src/lxc/lxc_console.c @@ -182,8 +182,6 @@ int main(int argc, char *argv[]) int err, std_in = 1; struct lxc_epoll_descr descr; struct termios newtios, oldtios; - /* TODO: add cmdline arg to specify lxcpath */ - char *lxcpath = NULL; err = lxc_arguments_parse(&my_args, argc, argv); if (err) @@ -200,7 +198,7 @@ int main(int argc, char *argv[]) return -1; } - err = lxc_console(my_args.name, my_args.ttynum, &master, lxcpath); + err = lxc_console(my_args.name, my_args.ttynum, &master, my_args.lxcpath); if (err) goto out; diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c index 3c76e2e..23631d8 100644 --- a/src/lxc/lxc_execute.c +++ b/src/lxc/lxc_execute.c @@ -109,14 +109,8 @@ int main(int argc, char *argv[]) rcfile = (char *)my_args.rcfile; else { int rc; - char *lxcpath = default_lxc_path(); - if (!lxcpath) { - ERROR("Out of memory"); - return -1; - } - rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name); - free(lxcpath); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return -1; @@ -143,5 +137,5 @@ int main(int argc, char *argv[]) if (lxc_config_define_load(&defines, conf)) return -1; - return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, NULL); + return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath); } diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c index fb37b2f..3b1b63f 100644 --- a/src/lxc/lxc_info.c +++ b/src/lxc/lxc_info.c @@ -74,8 +74,6 @@ Options :\n\ int main(int argc, char *argv[]) { int ret; - /* TODO: add lxcpath cmdline arg */ - const char *lxcpath = NULL; ret = lxc_arguments_parse(&my_args, argc, argv); if (ret) @@ -89,7 +87,7 @@ int main(int argc, char *argv[]) state = pid = true; if (state || test_state) { - ret = lxc_getstate(my_args.name, lxcpath); + ret = lxc_getstate(my_args.name, my_args.lxcpath); if (ret < 0) return 1; if (test_state) @@ -99,7 +97,7 @@ int main(int argc, char *argv[]) } if (pid) - printf("pid:%10d\n", get_init_pid(my_args.name, lxcpath)); + printf("pid:%10d\n", get_init_pid(my_args.name, my_args.lxcpath)); return 0; } diff --git a/src/lxc/lxc_kill.c b/src/lxc/lxc_kill.c index 669f469..40b3eaa 100644 --- a/src/lxc/lxc_kill.c +++ b/src/lxc/lxc_kill.c @@ -56,8 +56,6 @@ int main(int argc, char *argv[], char *envp[]) int ret; pid_t pid; int sig; - /* TODO: add lxcpath cmdline arg */ - const char *lxcpath = NULL; ret = lxc_arguments_parse(&my_args, argc, argv); if (ret) @@ -78,7 +76,7 @@ int main(int argc, char *argv[], char *envp[]) } else sig=SIGKILL; - pid = get_init_pid(my_args.name, lxcpath); + pid = get_init_pid(my_args.name, my_args.lxcpath); if (pid < 0) { ERROR("failed to get the init pid"); return -1; diff --git a/src/lxc/lxc_restart.c b/src/lxc/lxc_restart.c index 7561b1b..55e7c6e 100644 --- a/src/lxc/lxc_restart.c +++ b/src/lxc/lxc_restart.c @@ -132,14 +132,8 @@ int main(int argc, char *argv[]) rcfile = (char *)my_args.rcfile; else { int rc; - char *lxcpath = default_lxc_path(); - if (!lxcpath) { - ERROR("Out of memory"); - return -1; - } - rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name); - free(lxcpath); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return -1; @@ -178,7 +172,7 @@ int main(int argc, char *argv[]) } } - ret = lxc_restart(my_args.name, sfd, conf, my_args.flags); + ret = lxc_restart(my_args.name, sfd, conf, my_args.flags, my_args.lxcpath); if (my_args.statefile) close(sfd); diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index aac7fe7..f1f5f21 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -150,8 +150,6 @@ int main(int argc, char *argv[]) '\0', }; FILE *pid_fp = NULL; - /* TODO: add cmdline arg to specify lxcpath */ - char *lxcpath = NULL; lxc_list_init(&defines); @@ -175,15 +173,9 @@ int main(int argc, char *argv[]) rcfile = (char *)my_args.rcfile; else { int rc; - char *lxcpath = default_lxc_path(); - if (!lxcpath) { - ERROR("Out of memory"); - return -1; - } - rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name); INFO("using rcfile %s", rcfile); - free(lxcpath); if (rc == -1) { SYSERROR("failed to allocate memory"); return err; @@ -260,7 +252,7 @@ int main(int argc, char *argv[]) if (my_args.close_all_fds) conf->close_all_fds = 1; - err = lxc_start(my_args.name, args, conf, lxcpath); + err = lxc_start(my_args.name, args, conf, my_args.lxcpath); /* * exec ourself, that requires to have all opened fd diff --git a/src/lxc/lxc_stop.c b/src/lxc/lxc_stop.c index 703726a..4682d16 100644 --- a/src/lxc/lxc_stop.c +++ b/src/lxc/lxc_stop.c @@ -29,6 +29,7 @@ #include <lxc/log.h> #include "arguments.h" +#include "utils.h" static const struct option my_longopts[] = { LXC_COMMON_OPTIONS @@ -50,9 +51,6 @@ Options :\n\ int main(int argc, char *argv[]) { - /* TODO - make lxcpath a cmdline arg */ - const char *lxcpath = NULL; - if (lxc_arguments_parse(&my_args, argc, argv)) return -1; @@ -60,5 +58,5 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet)) return -1; - return lxc_stop(my_args.name, lxcpath); + return lxc_stop(my_args.name, my_args.lxcpath); } diff --git a/src/lxc/lxc_wait.c b/src/lxc/lxc_wait.c index b0643c7..c2a2fb4 100644 --- a/src/lxc/lxc_wait.c +++ b/src/lxc/lxc_wait.c @@ -87,5 +87,5 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet)) return -1; - return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout); + return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout, my_args.lxcpath); } diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 3633047..1e257c0 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -272,7 +272,7 @@ static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout) if (!c) return false; - ret = lxc_wait(c->name, state, timeout); + ret = lxc_wait(c->name, state, timeout, c->config_path); return ret == 0; } @@ -987,7 +987,7 @@ out: return ret; } -char *lxc_get_default_config_path(void) +const char *lxc_get_default_config_path(void) { return default_lxc_path(); } @@ -1006,7 +1006,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath if (configpath) c->config_path = strdup(configpath); else - c->config_path = default_lxc_path(); + c->config_path = strdup(default_lxc_path()); if (!c->config_path) { fprintf(stderr, "Out of memory"); diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 46c46c5..f0c4565 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -86,7 +86,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath int lxc_container_get(struct lxc_container *c); int lxc_container_put(struct lxc_container *c); int lxc_get_wait_states(const char **states); -char *lxc_get_default_config_path(void); +const char *lxc_get_default_config_path(void); #if 0 char ** lxc_get_valid_keys(); diff --git a/src/lxc/restart.c b/src/lxc/restart.c index d0b8fa8..03ae384 100644 --- a/src/lxc/restart.c +++ b/src/lxc/restart.c @@ -64,14 +64,13 @@ static struct lxc_operations restart_ops = { .post_start = post_restart }; -int lxc_restart(const char *name, int sfd, struct lxc_conf *conf, int flags) +int lxc_restart(const char *name, int sfd, struct lxc_conf *conf, int flags, + const char *lxcpath) { struct restart_args restart_arg = { .sfd = sfd, .flags = flags }; - /* TODO - make lxcpath a cmdline arg */ - const char *lxcpath = NULL; if (lxc_check_inherited(conf, sfd)) return -1; diff --git a/src/lxc/state.c b/src/lxc/state.c index 8552522..7d6c0d5 100644 --- a/src/lxc/state.c +++ b/src/lxc/state.c @@ -191,13 +191,11 @@ static int fillwaitedstates(const char *strstates, int *states) return 0; } -extern int lxc_wait(const char *lxcname, const char *states, int timeout) +extern int lxc_wait(const char *lxcname, const char *states, int timeout, const char *lxcpath) { struct lxc_msg msg; int state, ret; int s[MAX_STATE] = { }, fd; - /* TODO: add cmdline arg to specify lxcpath */ - char *lxcpath = NULL; if (fillwaitedstates(states, s)) return -1; diff --git a/src/lxc/state.h b/src/lxc/state.h index c995e55..beeed18 100644 --- a/src/lxc/state.h +++ b/src/lxc/state.h @@ -33,6 +33,6 @@ extern lxc_state_t lxc_getstate(const char *name, const char *lxcpath); extern lxc_state_t lxc_str2state(const char *state); extern const char *lxc_state2str(lxc_state_t state); -extern int lxc_wait(const char *lxcname, const char *states, int timeout); +extern int lxc_wait(const char *lxcname, const char *states, int timeout, const char *lxcpath); #endif diff --git a/src/lxc/utils.c b/src/lxc/utils.c index b9e6ffc..e38acab 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -212,11 +212,16 @@ static char *copypath(char *p) return retbuf; } -char *default_lxc_path(void) +char *default_lxcpath; + +const char *default_lxc_path(void) { - char buf[1024], *p, *retbuf; + char buf[1024], *p; FILE *fin; + if (default_lxcpath) + return default_lxcpath; + fin = fopen(LXC_GLOBAL_CONF, "r"); if (fin) { while (fgets(buf, 1024, fin)) { @@ -232,20 +237,16 @@ char *default_lxc_path(void) while (*p && (*p == ' ' || *p == '\t')) p++; if (!*p) continue; - retbuf = copypath(p); + default_lxcpath = copypath(p); goto out; } } /* we couldn't open the file, or didn't find a lxcpath * entry there. Return @LXCPATH@ */ - retbuf = malloc(strlen(LXCPATH)+1); - if (!retbuf) - goto out; - strcpy(retbuf, LXCPATH); + default_lxcpath = LXCPATH; out: if (fin) fclose(fin); - INFO("returning %s", (retbuf ? retbuf : "null")); - return retbuf; + return default_lxcpath; } diff --git a/src/lxc/utils.h b/src/lxc/utils.h index b24c8fa..a6bf067 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -31,6 +31,6 @@ extern int mkdir_p(const char *dir, mode_t mode); * Return a newly allocated buffer containing the default container * path. Caller must free this buffer. */ -extern char *default_lxc_path(void); +extern const char *default_lxc_path(void); #endif -- 1.8.1.2 ------------------------------------------------------------------------------ Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel