}
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, ...)
{
c->migrate = lxcapi_migrate;
c->console_log = lxcapi_console_log;
c->mount = lxcapi_mount;
+ c->umount = lxcapi_umount;
return c;
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);
};
/*!