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

Reply via email to