On Fri, Dec 20, 2013 at 08:24:41PM +0400, Reco wrote: > Implement virProcessRunInMountNamespace, which runs callback of type > virProcessNamespaceCallback in a container namespace. > > Hope it'll nail it this time. > > --- > 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..e210fd0 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..7bb494e 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(errno, "%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 (virProcessWait(cpid, &status) < 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__ */ ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list