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. > + 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