]> git.proxmox.com Git - mirror_lxc.git/commitdiff
lxccontainer: add the umount API function
authorLiza Tretyakova <elizabet.tretyakova@gmail.com>
Sat, 12 May 2018 10:07:41 +0000 (13:07 +0300)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 22 Jul 2018 13:32:42 +0000 (15:32 +0200)
Signed-off-by: Liza Tretyakova <elizabet.tretyakova@gmail.com>
[christian@brauner.io: minor coding-style changes]
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/lxccontainer.c
src/lxc/lxccontainer.h

index b03d049ed65543d420a7fbae4e59f85f3fe1d687..0a70d7f9ab28aa2d657176b8d7c566003f7aba37 100644 (file)
@@ -5025,7 +5025,66 @@ out:
 }
 
 WRAP_API_6(int, lxcapi_mount, const char *, const char *, const char *,
-          unsigned long, const void *, struct lxc_mount*)
+          unsigned long, const void *, struct lxc_mount *)
+
+static int do_lxcapi_umount(struct lxc_container *c, const char *target,
+                           unsigned long mountflags, struct lxc_mount *mnt)
+{
+       pid_t pid, init_pid;
+       int ret = -1;
+
+       if (!c || !c->lxc_conf) {
+               ERROR("Container or configuration is NULL");
+               return -EINVAL;
+       }
+
+       /* Do the fork */
+       pid = fork();
+       if (pid < 0) {
+               SYSERROR("Could not fork");
+               return -1;
+       }
+
+       if (pid == 0) {
+               init_pid = do_lxcapi_init_pid(c);
+               if (init_pid < 0) {
+                       ERROR("Failed to obtain container's init pid");
+                       _exit(EXIT_FAILURE);
+               }
+
+               /* Enter the container namespaces */
+               if (!lxc_list_empty(&c->lxc_conf->id_map)) {
+                       if (!switch_to_ns(init_pid, "user")) {
+                               ERROR("Failed to enter user namespace");
+                               _exit(EXIT_FAILURE);
+                       }
+               }
+
+               if (!switch_to_ns(init_pid, "mnt")) {
+                       ERROR("Failed to enter mount namespace");
+                       _exit(EXIT_FAILURE);
+               }
+
+               /* Do the unmount */
+               ret = umount2(target, mountflags);
+               if (ret < 0) {
+                       SYSERROR("Failed to umount \"%s\"", target);
+                       _exit(EXIT_FAILURE);
+               }
+
+               _exit(EXIT_SUCCESS);
+       }
+
+       ret = wait_for_pid(pid);
+       if (ret < 0) {
+               SYSERROR("Wait for the child with pid %ld failed", (long)pid);
+               return -ret;
+       }
+
+       return 0;
+}
+
+WRAP_API_3(int, lxcapi_umount, const char *, unsigned long, struct lxc_mount*)
 
 static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...)
 {
@@ -5180,6 +5239,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
        c->migrate = lxcapi_migrate;
        c->console_log = lxcapi_console_log;
        c->mount = lxcapi_mount;
+       c->umount = lxcapi_umount;
 
        return c;
 
index c61a1b840d2bc53b4bab82a878a19c6614d50639..3eb62e0d95eb8103ef03f8fb5d31c74b72ff183a 100644 (file)
@@ -859,6 +859,12 @@ struct lxc_container {
                                 const char *source, const char *target,
                                 const char *filesystemtype, unsigned long mountflags,
                                 const void *data, struct lxc_mount *mnt);
+
+       /*!
+        * \brief Unmount the container's path `target`.
+        */
+       int (*umount)(struct lxc_container *c, const char *target,
+                                 unsigned long mountflags, struct lxc_mount *mnt);
 };
 
 /*!