]> git.proxmox.com Git - mirror_lxc.git/commitdiff
conf: introduce lxc.rootfs.managed
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 27 Jun 2018 09:37:57 +0000 (11:37 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 31 Jul 2018 20:09:34 +0000 (22:09 +0200)
This introduces a new config key lxc.rootfs.managed which can be used to
indicate whether this LXC instance is managing the container storage. If LXC is
not managing the storage then LXC will not modify the container storage.
For example, an API call to c->destroy(c) will then run any destroy hooks but
will not destroy the actual rootfs (Unless, of course, the hook does so behind
LXC's back.).

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
CC: Wolfgang Bumiller <w.bumiller@proxmox.com>
CC: Stéphane Graber <stgraber@ubuntu.com>
CC: Serge Hallyn <serge@hallyn.com>
CC: 2xsec <dh48.jeong@samsung.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/confile_utils.c
src/lxc/confile_utils.h
src/lxc/lxccontainer.c

index 3cbebfb6ad26ec0c96c160dfdaf5f99fc5ea11ce..ce63d5ba557211229108ce66c5e168c5395b62d8 100644 (file)
@@ -2760,6 +2760,7 @@ struct lxc_conf *lxc_conf_init(void)
                free(new);
                return NULL;
        }
+       new->rootfs.managed = true;
        new->logfd = -1;
        lxc_list_init(&new->cgroup);
        lxc_list_init(&new->cgroup2);
index 2c70303a21c277fbcf80c31302c6da8e89a70cec..6f947f1f35559aa36ea5244f988955edd5f70436 100644 (file)
@@ -154,6 +154,7 @@ struct lxc_tty_info {
  * @options    : mount options
  * @mountflags : the portion of @options that are flags
  * @data       : the porition of @options that are not flags
+ * @managed    : whether it is managed by LXC
  */
 struct lxc_rootfs {
        char *path;
@@ -162,6 +163,7 @@ struct lxc_rootfs {
        char *options;
        unsigned long mountflags;
        char *data;
+       bool managed;
 };
 
 /*
index 326782eac343204b9e832cd0b020787e51a3f0ca..b24fcfe17941e43983793c355c64df6d2f8db7b5 100644 (file)
@@ -141,6 +141,7 @@ lxc_config_define(no_new_privs);
 lxc_config_define(personality);
 lxc_config_define(prlimit);
 lxc_config_define(pty_max);
+lxc_config_define(rootfs_managed);
 lxc_config_define(rootfs_mount);
 lxc_config_define(rootfs_options);
 lxc_config_define(rootfs_path);
@@ -226,6 +227,7 @@ static struct lxc_config_t config[] = {
        { "lxc.no_new_privs",              set_config_no_new_privs,                get_config_no_new_privs,                clr_config_no_new_privs,              },
        { "lxc.prlimit",                   set_config_prlimit,                     get_config_prlimit,                     clr_config_prlimit,                   },
        { "lxc.pty.max",                   set_config_pty_max,                     get_config_pty_max,                     clr_config_pty_max,                   },
+       { "lxc.rootfs.managed",            set_config_rootfs_managed,              get_config_rootfs_managed,              clr_config_rootfs_managed,            },
        { "lxc.rootfs.mount",              set_config_rootfs_mount,                get_config_rootfs_mount,                clr_config_rootfs_mount,              },
        { "lxc.rootfs.options",            set_config_rootfs_options,              get_config_rootfs_options,              clr_config_rootfs_options,            },
        { "lxc.rootfs.path",               set_config_rootfs_path,                 get_config_rootfs_path,                 clr_config_rootfs_path,               },
@@ -2134,6 +2136,31 @@ static int set_config_rootfs_path(const char *key, const char *value,
        return ret;
 }
 
+static int set_config_rootfs_managed(const char *key, const char *value,
+                                    struct lxc_conf *lxc_conf, void *data)
+{
+       unsigned int val = 0;
+
+       if (lxc_config_value_empty(value)) {
+               lxc_conf->rootfs.managed = true;
+               return 0;
+       }
+
+       if (lxc_safe_uint(value, &val) < 0)
+               return -EINVAL;
+
+       switch (val) {
+       case 0:
+               lxc_conf->rootfs.managed = false;
+               return 0;
+       case 1:
+               lxc_conf->rootfs.managed = true;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
 static int set_config_rootfs_mount(const char *key, const char *value,
                                   struct lxc_conf *lxc_conf, void *data)
 {
@@ -3356,6 +3383,12 @@ static int get_config_rootfs_path(const char *key, char *retv, int inlen,
        return lxc_get_conf_str(retv, inlen, c->rootfs.path);
 }
 
+static int get_config_rootfs_managed(const char *key, char *retv, int inlen,
+                                    struct lxc_conf *c, void *data)
+{
+       return lxc_get_conf_bool(c, retv, inlen, c->rootfs.managed);
+}
+
 static int get_config_rootfs_mount(const char *key, char *retv, int inlen,
                                   struct lxc_conf *c, void *data)
 {
@@ -3976,6 +4009,13 @@ static inline int clr_config_rootfs_path(const char *key, struct lxc_conf *c,
        return 0;
 }
 
+static inline int clr_config_rootfs_managed(const char *key, struct lxc_conf *c,
+                                           void *data)
+{
+       c->rootfs.managed = true;
+       return 0;
+}
+
 static inline int clr_config_rootfs_mount(const char *key, struct lxc_conf *c,
                                          void *data)
 {
index 2bb46d17bcce9efa1d93613d6fcb0fbde578141a..a83d4aea927076a994b9e2d8ce6d37bb8f8697fd 100644 (file)
@@ -672,6 +672,21 @@ int lxc_get_conf_str(char *retv, int inlen, const char *value)
        return value_len;
 }
 
+int lxc_get_conf_bool(struct lxc_conf *c, char *retv, int inlen, bool v)
+{
+       int len;
+       int fulllen = 0;
+
+       if (!retv)
+               inlen = 0;
+       else
+               memset(retv, 0, inlen);
+
+       strprint(retv, inlen, "%d", v);
+
+       return fulllen;
+}
+
 int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
 {
        int len;
index b58ce47b2dd2a71754efe3228d767448d3141223..caa2b8849d6b623ee0895aa075f57aa67e8810ac 100644 (file)
@@ -86,6 +86,7 @@ extern bool lxc_config_net_hwaddr(const char *line);
 extern void update_hwaddr(const char *line);
 extern bool new_hwaddr(char *hwaddr);
 extern int lxc_get_conf_str(char *retv, int inlen, const char *value);
+extern int lxc_get_conf_bool(struct lxc_conf *c, char *retv, int inlen, bool v);
 extern int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v);
 extern int lxc_get_conf_size_t(struct lxc_conf *c, char *retv, int inlen, size_t v);
 extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v);
index 1b9c0fb6dd11d8b7342dda3f36569947f3393ef2..4fb063462f58714efddfea3cfcd259d7c0a3e12b 100644 (file)
@@ -2973,6 +2973,10 @@ static bool container_destroy(struct lxc_container *c,
                }
        }
 
+       /* LXC is not managing the storage of the container. */
+       if (conf && !conf->rootfs.managed)
+               goto on_success;
+
        if (conf && conf->rootfs.path && conf->rootfs.mount) {
                if (!do_destroy_container(conf)) {
                        ERROR("Error destroying rootfs for %s", c->name);
@@ -3045,6 +3049,7 @@ static bool container_destroy(struct lxc_container *c,
        }
        INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name);
 
+on_success:
        bret = true;
 
 out:
@@ -3060,14 +3065,16 @@ static bool do_lxcapi_destroy(struct lxc_container *c)
        if (!c || !lxcapi_is_defined(c))
                return false;
 
-       if (has_snapshots(c)) {
-               ERROR("Container %s has snapshots;  not removing", c->name);
-               return false;
-       }
+       if (c->lxc_conf && c->lxc_conf->rootfs.managed) {
+               if (has_snapshots(c)) {
+                       ERROR("Container %s has snapshots;  not removing", c->name);
+                       return false;
+               }
 
-       if (has_fs_snapshots(c)) {
-               ERROR("container %s has snapshots on its rootfs", c->name);
-               return false;
+               if (has_fs_snapshots(c)) {
+                       ERROR("container %s has snapshots on its rootfs", c->name);
+                       return false;
+               }
        }
 
        return container_destroy(c, NULL);