Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> --- src/lxc/conf.c | 24 ++++++++++++++++++++++++ src/lxc/conf.h | 1 + src/lxc/lxc_destroy.c | 7 ------- src/lxc/lxccontainer.c | 15 ++++++++++++--- 4 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c index a47d4bd..a84c2ad 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2825,6 +2825,30 @@ int chown_mapped_root(char *path, struct lxc_conf *conf) return wait_for_pid(pid); } +int do_mapped_rmdir(char *path, struct lxc_conf *conf) +{ + char buf[4096], *p = buf; + int hostuid = geteuid(), nsuid = find_unmapped_nsuid(conf); + struct lxc_list *it; + + /* lxc-usernsexec -m b:$nsuid:$hostuid <... all container mappings> \ + * rm -rf --one-file-system path */ + p += snprintf(buf, 4095, "lxc-usernsexec -m u:%d:%d:1", nsuid, hostuid); + + lxc_list_for_each(it, &conf->id_map) { + struct id_map *map = it->elem; + p += snprintf(p, p-buf, " -m %c:%d:%d:%d", + map->idtype == ID_TYPE_UID ? 'u' : 'g', + (int)map->nsid, (int)map->hostid, (int)map->range); + } + p += snprintf(p, p-buf, " -- rm -rf --one-file-system %s", path); + if (p - buf >= 4096) { + ERROR("lxc-usernsexec directory removal command too long"); + return -1; + } + return system(buf); +} + int ttys_shift_ids(struct lxc_conf *c) { int i; diff --git a/src/lxc/conf.h b/src/lxc/conf.h index c285950..e3565bd 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -336,5 +336,6 @@ extern uid_t get_mapped_rootid(struct lxc_conf *conf); extern int find_unmapped_nsuid(struct lxc_conf *conf); extern bool hostid_is_mapped(int id, struct lxc_conf *conf); extern int chown_mapped_root(char *path, struct lxc_conf *conf); +extern int do_mapped_rmdir(char *path, struct lxc_conf *conf); extern int ttys_shift_ids(struct lxc_conf *c); #endif diff --git a/src/lxc/lxc_destroy.c b/src/lxc/lxc_destroy.c index 9a1b11f..114c911 100644 --- a/src/lxc/lxc_destroy.c +++ b/src/lxc/lxc_destroy.c @@ -64,13 +64,6 @@ int main(int argc, char *argv[]) { struct lxc_container *c; - /* this is a short term test. We'll probably want to check for - * write access to lxcpath instead */ - if (geteuid()) { - fprintf(stderr, "%s must be run as root\n", argv[0]); - exit(1); - } - if (lxc_arguments_parse(&my_args, argc, argv)) exit(1); diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index ee0b1ff..3dae2b8 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1467,6 +1467,9 @@ static bool lxcapi_destroy(struct lxc_container *c) { struct bdev *r = NULL; bool ret = false; + const char *p1 = lxcapi_get_config_path(c); + char *path = alloca(strlen(p1) + strlen(c->name) + 2); + sprintf(path, "%s/%s", p1, c->name); if (!c || !lxcapi_is_defined(c)) return false; @@ -1480,6 +1483,15 @@ static bool lxcapi_destroy(struct lxc_container *c) goto out; } + if (geteuid() != 0) { + /* + * container is one big dir, and we have to shell out + * to have permission to remove it. So do it in one + * big shot + */ + return do_mapped_rmdir(path, c->lxc_conf) == 0; + } + if (c->lxc_conf && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) r = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL); if (r) { @@ -1489,9 +1501,6 @@ static bool lxcapi_destroy(struct lxc_container *c) } } - const char *p1 = lxcapi_get_config_path(c); - char *path = alloca(strlen(p1) + strlen(c->name) + 2); - sprintf(path, "%s/%s", p1, c->name); if (lxc_rmdir_onedev(path) < 0) { ERROR("Error destroying container directory for %s", c->name); goto out; -- 1.8.3.2 ------------------------------------------------------------------------------ See everything from the browser to the database with AppDynamics Get end-to-end visibility with application monitoring from AppDynamics Isolate bottlenecks and diagnose root cause in seconds. Start your free trial of AppDynamics Pro today! http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel