]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add internal APIs for dealing with namespaces
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 21 Dec 2012 16:50:18 +0000 (16:50 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 8 Jan 2013 09:21:08 +0000 (09:21 +0000)
Add some APIs for acquiring namespace file descriptors and
switching namespaces

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
configure.ac
src/libvirt_private.syms
src/util/virprocess.c
src/util/virprocess.h

index 20108c295e1f179e35075d8616d0f1bb5fea7bb3..1c601d277ea1e2ac99db1fb20b87452006a14dff 100644 (file)
@@ -180,7 +180,7 @@ dnl Availability of various common functions (non-fatal if missing),
 dnl and various less common threadsafe functions
 AC_CHECK_FUNCS_ONCE([cfmakeraw geteuid getgid getgrnam_r getmntent_r \
   getpwuid_r getuid initgroups kill mmap newlocale posix_fallocate \
-  posix_memalign regexec sched_getaffinity])
+  posix_memalign regexec sched_getaffinity setns])
 
 dnl Availability of pthread functions (if missing, win32 threading is
 dnl assumed).  Because of $LIB_PTHREAD, we cannot use AC_CHECK_FUNCS_ONCE.
index d9b7c1d86594b5fe9d64275e37e2ca198d974737..d079cc90438489f2566d945d82de6334a4048bae 100644 (file)
@@ -1795,9 +1795,11 @@ virPidFileWritePath;
 # virprocess.h
 virProcessAbort;
 virProcessGetAffinity;
+virProcessGetNamespaces;
 virProcessKill;
 virProcessKillPainfully;
 virProcessSetAffinity;
+virProcessSetNamespaces;
 virProcessTranslateStatus;
 virProcessWait;
 
index 0858553004b1c8fb59617fe8945303f4a2b98956..a492bd11f77103b3bb5f37773010faf1fadadfb6 100644 (file)
@@ -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,116 @@ 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(size_t nfdlist ATTRIBUTE_UNUSED,
+                            int *fdlist ATTRIBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("Cannot set namespaces"));
+    return -1;
+}
+#endif /* ! HAVE_SETNS */
index 8724f649f283e41cb018f7054b55f22ad5fc3978..53475d3cc3ff3410d6c13f6c9cfe0dd427616ba0 100644 (file)
@@ -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__ */