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);
{ "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, },
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)
{
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)
{
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)
{
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);
}
}
+ /* 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);
}
INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name);
+on_success:
bret = true;
out:
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);