On Fri, Apr 03, 2015 at 09:41:03PM +0000, Serge Hallyn wrote: > Quoting Tycho Andersen (tycho.ander...@canonical.com): > > Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com> > > --- > > src/lxc/conf.c | 18 +++++++++++--- > > src/lxc/conf.h | 2 ++ > > src/lxc/list.h | 11 +++++++++ > > src/lxc/lxccontainer.c | 67 > > +++++++++++++++++++++++++++++++++++++++++++------- > > 4 files changed, 85 insertions(+), 13 deletions(-) > > > > diff --git a/src/lxc/conf.c b/src/lxc/conf.c > > index 2868708..f9c7e37 100644 > > --- a/src/lxc/conf.c > > +++ b/src/lxc/conf.c > > @@ -2040,18 +2040,16 @@ static int setup_mount(const struct lxc_rootfs > > *rootfs, const char *fstab, > > return ret; > > } > > > > -static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct > > lxc_list *mount, > > - const char *lxc_name) > > +FILE *write_mount_file(struct lxc_list *mount) > > { > > FILE *file; > > struct lxc_list *iterator; > > char *mount_entry; > > - int ret; > > > > file = tmpfile(); > > if (!file) { > > ERROR("tmpfile error: %m"); > > - return -1; > > + return NULL; > > } > > > > lxc_list_for_each(iterator, mount) { > > @@ -2060,6 +2058,18 @@ static int setup_mount_entries(const struct > > lxc_rootfs *rootfs, struct lxc_list > > } > > > > rewind(file); > > + return file; > > +} > > + > > +static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct > > lxc_list *mount, > > + const char *lxc_name) > > +{ > > + FILE *file; > > + int ret; > > + > > + file = write_mount_file(mount); > > + if (!file) > > + return -1; > > > > ret = mount_file_entries(rootfs, file, lxc_name); > > > > diff --git a/src/lxc/conf.h b/src/lxc/conf.h > > index 334ea70..4b66045 100644 > > --- a/src/lxc/conf.h > > +++ b/src/lxc/conf.h > > @@ -25,6 +25,7 @@ > > > > #include "config.h" > > > > +#include <stdio.h> > > #include <netinet/in.h> > > #include <net/if.h> > > #include <sys/param.h> > > @@ -422,4 +423,5 @@ extern int parse_mntopts(const char *mntopts, unsigned > > long *mntflags, > > extern void tmp_proc_unmount(struct lxc_conf *lxc_conf); > > void remount_all_slave(void); > > extern void suggest_default_idmap(void); > > +FILE *write_mount_file(struct lxc_list *mount); > > #endif > > diff --git a/src/lxc/list.h b/src/lxc/list.h > > index 0882da0..f16af54 100644 > > --- a/src/lxc/list.h > > +++ b/src/lxc/list.h > > @@ -99,4 +99,15 @@ static inline void lxc_list_del(struct lxc_list *list) > > prev->next = next; > > } > > > > +static inline int lxc_list_len(struct lxc_list *list) > > +{ > > + int i = 0; > > + struct lxc_list *iter; > > + lxc_list_for_each(iter, list) { > > + i++; > > + } > > + > > + return i; > > +} > > + > > #endif > > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c > > index d84543f..7e50372 100644 > > --- a/src/lxc/lxccontainer.c > > +++ b/src/lxc/lxccontainer.c > > @@ -35,6 +35,8 @@ > > #include <libgen.h> > > #include <stdint.h> > > #include <grp.h> > > +#include <stdio.h> > > +#include <mntent.h> > > #include <sys/syscall.h> > > > > #include <lxc/lxccontainer.h> > > @@ -3513,11 +3515,15 @@ struct criu_opts { > > > > static void exec_criu(struct criu_opts *opts) > > { > > - char **argv, log[PATH_MAX], buf[257]; > > + char **argv, log[PATH_MAX]; > > int static_args = 14, argc = 0, i, ret; > > int netnr = 0; > > struct lxc_list *it; > > > > + struct mntent mntent; > > + char buf[4096]; > > + FILE *mnts = NULL; > > + > > /* The command line always looks like: > > * criu $(action) --tcp-established --file-locks --link-remap > > --force-irmap \ > > * --manage-cgroups action-script foo.sh -D $(directory) \ > > @@ -3592,6 +3598,21 @@ static void exec_criu(struct criu_opts *opts) > > if (opts->verbose) > > DECLARE_ARG("-vvvvvv"); > > > > +#define RESIZE_ARGS(additional) > > \ > > This seems to want to be reused, however it doesn't bump argc, > so if it is used twice in a row it wont' have the desired effect.
Right, argc is supposedly where the current pointer is, so it shouldn't bump argc. RESIZE_ARGS has an implicit assumption that you're out of space when you call it, so you shouldn't call it twice in a row. I can re-send a patch with a comment to that effect if you like, or do something else. This whole function is kind of messy now (and long), so it may be time to rethink it. Tycho > > + do { > > \ > > + void *m; > > \ > > + if (additional < 0) { > > \ > > + ERROR("resizing by negative amount"); > > \ > > + goto err; > > \ > > + } else if (additional == 0) > > \ > > + continue; > > \ > > + > > \ > > + m = realloc(argv, (argc + additional + 1) * sizeof(*argv)); > > \ > > + if (!m) > > \ > > + goto err; > > \ > > + argv = m; > > \ > > + } while (0) > > + > > if (strcmp(opts->action, "dump") == 0) { > > char pid[32]; > > > > @@ -3623,9 +3644,10 @@ static void exec_criu(struct criu_opts *opts) > > DECLARE_ARG("--cgroup-root"); > > DECLARE_ARG(opts->cgroup_path); > > > > + RESIZE_ARGS(lxc_list_len(&opts->c->lxc_conf->network) * 2); > > + > > lxc_list_for_each(it, &opts->c->lxc_conf->network) { > > char eth[128], *veth; > > - void *m; > > struct lxc_netdev *n = it->elem; > > > > if (n->name) { > > @@ -3641,18 +3663,42 @@ static void exec_criu(struct criu_opts *opts) > > if (ret < 0 || ret >= sizeof(buf)) > > goto err; > > > > - /* final NULL and --veth-pair eth0=vethASDF */ > > - m = realloc(argv, (argc + 1 + 2) * sizeof(*argv)); > > - if (!m) > > - goto err; > > - argv = m; > > - > > DECLARE_ARG("--veth-pair"); > > DECLARE_ARG(buf); > > - argv[argc] = NULL; > > + } > > + } > > + > > + // CRIU wants to know about any external bind mounts the > > + // container has. > > + mnts = write_mount_file(&opts->c->lxc_conf->mount_list); > > + if (!mnts) > > + goto err; > > + > > + RESIZE_ARGS(lxc_list_len(&opts->c->lxc_conf->mount_list) * 2); > > + > > + while (getmntent_r(mnts, &mntent, buf, sizeof(buf))) { > > + char arg[2048], *key, *val; > > + int ret; > > > > + if (strcmp(opts->action, "dump") == 0) { > > + key = mntent.mnt_fsname; > > + val = mntent.mnt_dir; > > + } else { > > + key = mntent.mnt_dir; > > + val = mntent.mnt_fsname; > > } > > + > > + ret = snprintf(arg, sizeof(arg), "%s:%s", key, val); > > + if (ret < 0 || ret >= sizeof(arg)) { > > + goto err; > > + } > > + > > + DECLARE_ARG("--ext-mount-map"); > > + DECLARE_ARG(arg); > > } > > + fclose(mnts); > > + > > + argv[argc] = NULL; > > > > netnr = 0; > > lxc_list_for_each(it, &opts->c->lxc_conf->network) { > > @@ -3688,8 +3734,11 @@ static void exec_criu(struct criu_opts *opts) > > } > > > > #undef DECLARE_ARG > > +#undef RESIZE_ARGS > > execv(argv[0], argv); > > err: > > + if (mnts) > > + fclose(mnts); > > for (i = 0; argv[i]; i++) > > free(argv[i]); > > free(argv); > > -- > > 2.1.0 > > > > _______________________________________________ > > lxc-devel mailing list > > lxc-devel@lists.linuxcontainers.org > > http://lists.linuxcontainers.org/listinfo/lxc-devel > _______________________________________________ > lxc-devel mailing list > lxc-devel@lists.linuxcontainers.org > http://lists.linuxcontainers.org/listinfo/lxc-devel _______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel