From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Add some APIs for acquiring namespace file descriptors and switching namespaces Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list