[libvirt] [PATCH 0/4] Couple of LXC fixes

After Dan's eff95ac8fce in which he's fixing the build on RHEL-6, I've realized we can do better. We don't need to copy our code around. Michal Privoznik (4): util: Allow virProcessSetNamespaces() to have sparse FD list libvirt_lxc: Claim success for --help lxc_container: Turn lxcAttachNS into calling virProcessSetNamespaces Revert "lxc: ensure setns() syscall is defined" src/lxc/lxc_container.c | 56 +++--------------------------------------------- src/lxc/lxc_controller.c | 1 + src/util/virprocess.c | 3 +++ 3 files changed, 7 insertions(+), 53 deletions(-) -- 2.4.6

So far, the virProcessSetNamespaces() takes an array of FDs that it tries to set namespace on. However, in the very next commit this array may be sparse, having some -1's in it. Teach the function to cope with that. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/util/virprocess.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 77a038a..e6b78ef 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -705,6 +705,9 @@ int virProcessSetNamespaces(size_t nfdlist, return -1; } for (i = 0; i < nfdlist; i++) { + if (fdlist[i] < 0) + continue; + /* We get EINVAL if new NS is same as the current * NS, or if the fd namespace doesn't match the * type passed to setns()'s second param. Since we -- 2.4.6

On Thu, Aug 27, 2015 at 03:06:51AM +0200, Michal Privoznik wrote:
So far, the virProcessSetNamespaces() takes an array of FDs that it tries to set namespace on. However, in the very next commit this array may be sparse, having some -1's in it. Teach the function to cope with that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/util/virprocess.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 77a038a..e6b78ef 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -705,6 +705,9 @@ int virProcessSetNamespaces(size_t nfdlist, return -1; } for (i = 0; i < nfdlist; i++) { + if (fdlist[i] < 0) + continue; + /* We get EINVAL if new NS is same as the current * NS, or if the fd namespace doesn't match the * type passed to setns()'s second param. Since we
ACK Regards, 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 :|

So far, if libvirt_lxc binary (usually to be found under /usr/libexec/) is run with --help, due to a missing line and our usual functions pattern, an 'uknown' error is returned. Yeah, the help is printed out, but we should not claim error. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_controller.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index a94e819..d36bc9b 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -2613,6 +2613,7 @@ int main(int argc, char *argv[]) fprintf(stderr, " -U FD, --share-uts FD\n"); fprintf(stderr, " -h, --help\n"); fprintf(stderr, "\n"); + rc = 0; goto cleanup; } } -- 2.4.6

On Thu, Aug 27, 2015 at 03:06:52AM +0200, Michal Privoznik wrote:
So far, if libvirt_lxc binary (usually to be found under /usr/libexec/) is run with --help, due to a missing line and our usual functions pattern, an 'uknown' error is returned. Yeah, the help is printed out, but we should not claim error.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_controller.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index a94e819..d36bc9b 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -2613,6 +2613,7 @@ int main(int argc, char *argv[]) fprintf(stderr, " -U FD, --share-uts FD\n"); fprintf(stderr, " -h, --help\n"); fprintf(stderr, "\n"); + rc = 0; goto cleanup; } }
ACK Regards, 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 :|

Now that virProcessSetNamespaces() does accept FD list in the correct format, we can simply turn lxcAttachNS into calling virProcessSetNamespaces(). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_container.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index feb8fad..eb7cad6 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -2184,25 +2184,9 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED, */ static int lxcAttachNS(int *ns_fd) { - size_t i; - if (ns_fd) - for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) { - if (ns_fd[i] < 0) - continue; - VIR_DEBUG("Setting into namespace\n"); - /* We get EINVAL if new NS is same as the current - * NS, or if the fd namespace doesn't match the - * type passed to setns()'s second param. Since we - * pass 0, we know the EINVAL is harmless - */ - if (setns(ns_fd[i], 0) < 0 && - errno != EINVAL) { - virReportSystemError(errno, _("failed to set namespace '%s'"), - virLXCDomainNamespaceTypeToString(i)); - return -1; - } - VIR_FORCE_CLOSE(ns_fd[i]); - } + if (ns_fd && + virProcessSetNamespaces(VIR_LXC_DOMAIN_NAMESPACE_LAST, ns_fd) < 0) + return -1; return 0; } -- 2.4.6

On Thu, Aug 27, 2015 at 03:06:53AM +0200, Michal Privoznik wrote:
Now that virProcessSetNamespaces() does accept FD list in the correct format, we can simply turn lxcAttachNS into calling virProcessSetNamespaces().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_container.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index feb8fad..eb7cad6 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -2184,25 +2184,9 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED, */ static int lxcAttachNS(int *ns_fd) { - size_t i; - if (ns_fd) - for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) { - if (ns_fd[i] < 0) - continue; - VIR_DEBUG("Setting into namespace\n"); - /* We get EINVAL if new NS is same as the current - * NS, or if the fd namespace doesn't match the - * type passed to setns()'s second param. Since we - * pass 0, we know the EINVAL is harmless - */ - if (setns(ns_fd[i], 0) < 0 && - errno != EINVAL) { - virReportSystemError(errno, _("failed to set namespace '%s'"), - virLXCDomainNamespaceTypeToString(i)); - return -1; - } - VIR_FORCE_CLOSE(ns_fd[i]); - } + if (ns_fd && + virProcessSetNamespaces(VIR_LXC_DOMAIN_NAMESPACE_LAST, ns_fd) < 0) + return -1; return 0; }
ACK, or we could just inline this call and get rid fo the lxcAttachNS method entirely Regards, 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 :|

On 08/26/2015 09:06 PM, Michal Privoznik wrote:
Now that virProcessSetNamespaces() does accept FD list in the correct format, we can simply turn lxcAttachNS into calling virProcessSetNamespaces().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_container.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index feb8fad..eb7cad6 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -2184,25 +2184,9 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED, */ static int lxcAttachNS(int *ns_fd) { - size_t i; - if (ns_fd) - for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) { - if (ns_fd[i] < 0) - continue; - VIR_DEBUG("Setting into namespace\n"); - /* We get EINVAL if new NS is same as the current - * NS, or if the fd namespace doesn't match the - * type passed to setns()'s second param. Since we - * pass 0, we know the EINVAL is harmless - */ - if (setns(ns_fd[i], 0) < 0 && - errno != EINVAL) { - virReportSystemError(errno, _("failed to set namespace '%s'"), - virLXCDomainNamespaceTypeToString(i)); - return -1; - } - VIR_FORCE_CLOSE(ns_fd[i]); - } + if (ns_fd && + virProcessSetNamespaces(VIR_LXC_DOMAIN_NAMESPACE_LAST, ns_fd) < 0)
Coverity wasn't very happy with this one - I got: (1) Event suspicious_sizeof: Passing argument "ns_fd" of type "int *" and argument "VIR_LXC_DOMAIN_NAMESPACE_LAST" to function "virProcessSetNamespaces" is suspicious because a multiple of "sizeof (int)" /*4*/ is expected. Changing 'arg1' to virProcessSetNamespaces from size_t to unsigned int cleared the error - whether that's "right" or not, I'm not sure. I do note the only other caller virDomainLxcEnterNamespace passes an 'unsigned int' which is why I tried that first. John
+ return -1; return 0; }

On Fri, Aug 28, 2015 at 06:40:39AM -0400, John Ferlan wrote:
On 08/26/2015 09:06 PM, Michal Privoznik wrote:
Now that virProcessSetNamespaces() does accept FD list in the correct format, we can simply turn lxcAttachNS into calling virProcessSetNamespaces().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_container.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index feb8fad..eb7cad6 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -2184,25 +2184,9 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED, */ static int lxcAttachNS(int *ns_fd) { - size_t i; - if (ns_fd) - for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) { - if (ns_fd[i] < 0) - continue; - VIR_DEBUG("Setting into namespace\n"); - /* We get EINVAL if new NS is same as the current - * NS, or if the fd namespace doesn't match the - * type passed to setns()'s second param. Since we - * pass 0, we know the EINVAL is harmless - */ - if (setns(ns_fd[i], 0) < 0 && - errno != EINVAL) { - virReportSystemError(errno, _("failed to set namespace '%s'"), - virLXCDomainNamespaceTypeToString(i)); - return -1; - } - VIR_FORCE_CLOSE(ns_fd[i]); - } + if (ns_fd && + virProcessSetNamespaces(VIR_LXC_DOMAIN_NAMESPACE_LAST, ns_fd) < 0)
Coverity wasn't very happy with this one - I got:
(1) Event suspicious_sizeof: Passing argument "ns_fd" of type "int *" and argument "VIR_LXC_DOMAIN_NAMESPACE_LAST" to function "virProcessSetNamespaces" is suspicious because a multiple of "sizeof (int)" /*4*/ is expected.
IIUC, coverity is saying here that 'size_t nfdlist' is supposed to be a multiple of sizeof(int), which is clearly wrong. it is the number of int elements in the array, so sizeof() doesn't apply. I don't see any code change required here at all, I think coverity is simply wrong. Regards, 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 :|

After my previous commit this commit is no longer needed. This reverts commit eff95ac8fce8af47c0948a1c8a654b210633a350. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_container.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index eb7cad6..b621d1d 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -95,40 +95,6 @@ VIR_LOG_INIT("lxc.lxc_container"); # define CLONE_NEWNET 0x40000000 /* New network namespace */ #endif -/* - * Workaround older glibc. While kernel may support the setns - * syscall, the glibc wrapper might not exist. If that's the - * case, use our own. - */ -#ifndef __NR_setns -# if defined(__x86_64__) -# define __NR_setns 308 -# elif defined(__i386__) -# define __NR_setns 346 -# elif defined(__arm__) -# define __NR_setns 375 -# elif defined(__aarch64__) -# define __NR_setns 375 -# elif defined(__powerpc__) -# define __NR_setns 350 -# elif defined(__s390__) -# define __NR_setns 339 -# endif -#endif - -#ifndef HAVE_SETNS -# if defined(__NR_setns) -# include <sys/syscall.h> - -static inline int setns(int fd, int nstype) -{ - return syscall(__NR_setns, fd, nstype); -} -# else /* !__NR_setns */ -# error Please determine the syscall number for setns on your architecture -# endif -#endif - /* messages between parent and container */ typedef char lxc_message_t; #define LXC_CONTINUE_MSG 'c' -- 2.4.6

On Thu, Aug 27, 2015 at 03:06:54AM +0200, Michal Privoznik wrote:
After my previous commit this commit is no longer needed.
This reverts commit eff95ac8fce8af47c0948a1c8a654b210633a350.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/lxc/lxc_container.c | 34 ---------------------------------- 1 file changed, 34 deletions(-)
ACK Regards, 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 :|

On Thu, Aug 27, 2015 at 03:06:50AM +0200, Michal Privoznik wrote:
After Dan's eff95ac8fce in which he's fixing the build on RHEL-6, I've realized we can do better. We don't need to copy our code around.
Yep, nicely done. Safe for freeze too IMHO
Michal Privoznik (4): util: Allow virProcessSetNamespaces() to have sparse FD list libvirt_lxc: Claim success for --help lxc_container: Turn lxcAttachNS into calling virProcessSetNamespaces Revert "lxc: ensure setns() syscall is defined"
src/lxc/lxc_container.c | 56 +++--------------------------------------------- src/lxc/lxc_controller.c | 1 + src/util/virprocess.c | 3 +++ 3 files changed, 7 insertions(+), 53 deletions(-)
Regards, 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 :|
participants (3)
-
Daniel P. Berrange
-
John Ferlan
-
Michal Privoznik