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

Reply via email to