[libvirt] [PATCH 1/2] Implementation deficiency in virInitctlSetRunLevel v3

Reco recoverym4n at gmail.com
Fri Dec 20 15:39:21 UTC 2013


Implement virProcessRunInMountNamespace, which runs callback of type
virProcessNamespaceCallback in a container namespace.

---
 src/libvirt_private.syms |    1 +
 src/util/virprocess.c    |   63 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virprocess.h    |    6 +++++
 3 files changed, 70 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2dbb8f8..3f4b350 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1646,6 +1646,7 @@ virProcessGetNamespaces;
 virProcessGetStartTime;
 virProcessKill;
 virProcessKillPainfully;
+virProcessRunInMountNamespace
 virProcessSetAffinity;
 virProcessSetMaxFiles;
 virProcessSetMaxMemLock;
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 9fc3207..2e8535e 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -31,6 +31,7 @@
 # include <sys/resource.h>
 #endif
 #include <sched.h>
+#include <stdlib.h>
 
 #ifdef __FreeBSD__
 # include <sys/param.h>
@@ -847,3 +848,65 @@ int virProcessGetStartTime(pid_t pid,
     return 0;
 }
 #endif
+
+#ifdef HAVE_SETNS
+int virProcessRunInMountNamespace(pid_t pid,
+                                  virProcessNamespaceCallback cb,
+                                  void *opaque)
+{
+    char* path = NULL;
+    int ret = -1;
+    int cpid = -1;
+    int status = -1;
+    int fd = -1;
+
+    if (virAsprintf(&path, "/proc/%llu/ns/mnt",
+                    (unsigned long long)pid) < 0) {
+        goto cleanup;
+    }
+
+    if ((fd = open(path, O_RDONLY)) < 0) {
+        virReportSystemError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                             _("Kernel does not provide mount namespace"));
+        goto cleanup;
+    }
+
+    switch (cpid = fork()) {
+    case 0:
+        if (setns(fd, 0) == -1) {
+            exit(-1);
+        }
+
+        ret = cb(pid, opaque);
+        exit(ret);
+        break;
+    case -1:
+        virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("Fork failed"));
+        goto cleanup;
+    default:
+        if (waitpid(cpid, &status, 0) < 0 || status < 0) {
+            virReportSystemError(errno,
+                                 _("Callback failed with status %i"),
+                                 status);
+            ret = 1;
+        } else {
+            ret = 0;
+        }
+    }
+
+cleanup:
+    VIR_FREE(path);
+    VIR_FORCE_CLOSE(fd);
+    return ret;
+}
+#else
+int virProcessRunInMountNamespace(pid_t pid ATTRIBUTE_UNUSED,
+                                  virProcessNamespaceCallback cb ATTRIBUTE_UNUSED,
+                                  void *opaque ATTRIBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("Mount namespaces are not available on this platform"));
+    return -1;
+}
+#endif
diff --git a/src/util/virprocess.h b/src/util/virprocess.h
index 9f77bc5..205abf7 100644
--- a/src/util/virprocess.h
+++ b/src/util/virprocess.h
@@ -60,4 +60,10 @@ int virProcessSetNamespaces(size_t nfdlist,
 int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes);
 int virProcessSetMaxProcesses(pid_t pid, unsigned int procs);
 int virProcessSetMaxFiles(pid_t pid, unsigned int files);
+
+typedef int (*virProcessNamespaceCallback)(pid_t pid, void *opaque);
+
+int virProcessRunInMountNamespace(pid_t pid,
+                                  virProcessNamespaceCallback cb,
+                                  void *opaque);
 #endif /* __VIR_PROCESS_H__ */
-- 
1.7.10.4




More information about the libvir-list mailing list