[libvirt] [PATCH 4/9] Add internal APIs for dealing with namespaces

Daniel P. Berrange berrange at redhat.com
Fri Dec 21 17:08:27 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Add some APIs for acquiring namespace file descriptors and
switching namespaces

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/libvirt_private.syms |   2 +
 src/util/virprocess.c    | 118 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virprocess.h    |   7 +++
 3 files changed, 127 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 497d5d3..a422839 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1790,9 +1790,11 @@ virPidFileWritePath;
 # virprocess.h
 virProcessAbort;
 virProcessGetAffinity;
+virProcessGetNamespaces;
 virProcessKill;
 virProcessKillPainfully;
 virProcessSetAffinity;
+virProcessSetNamespaces;
 virProcessTranslateStatus;
 virProcessWait;
 
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 0858553..b6da47a 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -22,6 +22,8 @@
 
 #include <config.h>
 
+#include <dirent.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <errno.h>
 #include <sys/wait.h>
@@ -30,6 +32,7 @@
 #include "virprocess.h"
 #include "virerror.h"
 #include "viralloc.h"
+#include "virfile.h"
 #include "virlog.h"
 #include "virutil.h"
 
@@ -489,3 +492,118 @@ int virProcessGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
     return -1;
 }
 #endif /* HAVE_SCHED_GETAFFINITY */
+
+
+#if HAVE_SETNS
+int virProcessGetNamespaces(pid_t pid,
+                            size_t *nfdlist,
+                            int **fdlist)
+{
+    int ret = -1;
+    DIR *dh = NULL;
+    struct dirent *de;
+    char *nsdir = NULL;
+    char *nsfile = NULL;
+    size_t i;
+
+    *nfdlist = 0;
+    *fdlist = NULL;
+
+    if (virAsprintf(&nsdir, "/proc/%llu/ns",
+                    (unsigned long long)pid) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (!(dh = opendir(nsdir))) {
+        virReportSystemError(errno,
+                             _("Cannot read directory %s"),
+                             nsdir);
+        goto cleanup;
+    }
+
+    while ((de = readdir(dh))) {
+        int fd;
+        if (de->d_name[0] == '.')
+            continue;
+
+        if (VIR_EXPAND_N(*fdlist, *nfdlist, 1) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        if (virAsprintf(&nsfile, "%s/%s", nsdir, de->d_name) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        if ((fd = open(nsfile, O_RDWR)) < 0) {
+            virReportSystemError(errno,
+                                 _("Unable to open %s"),
+                                 nsfile);
+            goto cleanup;
+        }
+
+        (*fdlist)[(*nfdlist)-1] = fd;
+
+        VIR_FREE(nsfile);
+    }
+
+    ret = 0;
+
+cleanup:
+    if (dh)
+        closedir(dh);
+    VIR_FREE(nsdir);
+    VIR_FREE(nsfile);
+    if (ret < 0) {
+        for (i = 0 ; i < *nfdlist ; i++) {
+            VIR_FORCE_CLOSE((*fdlist)[i]);
+        }
+        VIR_FREE(*fdlist);
+    }
+    return ret;
+}
+
+
+int virProcessSetNamespaces(size_t nfdlist,
+                            int *fdlist)
+{
+    size_t i;
+
+    if (nfdlist == 0) {
+        virReportInvalidArg(nfdlist, "%s",
+                             _("Expected at least one file descriptor"));
+        return -1;
+    }
+    for (i = 0 ; i < nfdlist ; i++) {
+        if (setns(fdlist[i], 0) < 0) {
+            virReportSystemError(errno, "%s",
+                                 _("Unable to join domain namespace"));
+            return -1;
+        }
+    }
+    return 0;
+}
+#else /* ! HAVE_SETNS */
+int virProcessGetNamespaces(pid_t pid,
+                            size_t *nfdlist ATTRIBUTE_UNUSED,
+                            int **fdlist ATTRIBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS,
+                         _("Cannot get namespaces for %llu"),
+                         (unsigned long long)pid);
+    return -1;
+}
+
+
+int virProcessSetNamespaces(pid_t pid,
+                            size_t *nfdlist ATTRIBUTE_UNUSED,
+                            int **fdlist ATTRIBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS,
+                         _("Cannot set namespaces for %llu"),
+                         (unsigned long long)pid);
+    return -1;
+}
+#endif /* ! HAVE_SETNS */
diff --git a/src/util/virprocess.h b/src/util/virprocess.h
index 8724f64..53475d3 100644
--- a/src/util/virprocess.h
+++ b/src/util/virprocess.h
@@ -47,4 +47,11 @@ int virProcessGetAffinity(pid_t pid,
                           virBitmapPtr *map,
                           int maxcpu);
 
+int virProcessGetNamespaces(pid_t pid,
+                            size_t *nfdlist,
+                            int **fdlist);
+
+int virProcessSetNamespaces(size_t nfdlist,
+                            int *fdlist);
+
 #endif /* __VIR_PROCESS_H__ */
-- 
1.7.11.7




More information about the libvir-list mailing list