[libvirt] [go PATCH 33/37] lxc: fix error reporting thread safety

Daniel P. Berrangé berrange at redhat.com
Mon Jul 16 13:24:19 UTC 2018


Create wrapper functions for each lxc C API that accepts a
virErrorPtr parameter. This avoids accessing a thread local from a
goroutine which may race with other goroutines doing native API calls in
the same OS thread.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 lxc.go         | 20 ++++++++++-------
 lxc_wrapper.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++---
 lxc_wrapper.h  | 26 +++++++++++++++++++++-
 3 files changed, 92 insertions(+), 12 deletions(-)

diff --git a/lxc.go b/lxc.go
index ec685b8..56ab28a 100644
--- a/lxc.go
+++ b/lxc.go
@@ -47,9 +47,10 @@ import (
 func (d *Domain) LxcOpenNamespace(flags uint32) ([]os.File, error) {
 	var cfdlist *C.int
 
-	ret := C.virDomainLxcOpenNamespace(d.ptr, &cfdlist, C.uint(flags))
+	var err C.virError
+	ret := C.virDomainLxcOpenNamespaceWrapper(d.ptr, &cfdlist, C.uint(flags), &err)
 	if ret == -1 {
-		return []os.File{}, GetLastError()
+		return []os.File{}, makeError(&err)
 	}
 	fdlist := make([]os.File, ret)
 	for i := 0; i < int(ret); i++ {
@@ -69,9 +70,10 @@ func (d *Domain) LxcEnterNamespace(fdlist []os.File, flags uint32) ([]os.File, e
 		cfdlist[i] = C.int(fdlist[i].Fd())
 	}
 
-	ret := C.virDomainLxcEnterNamespace(d.ptr, C.uint(len(fdlist)), &cfdlist[0], &ncoldfdlist, &coldfdlist, C.uint(flags))
+	var err C.virError
+	ret := C.virDomainLxcEnterNamespaceWrapper(d.ptr, C.uint(len(fdlist)), &cfdlist[0], &ncoldfdlist, &coldfdlist, C.uint(flags), &err)
 	if ret == -1 {
-		return []os.File{}, GetLastError()
+		return []os.File{}, makeError(&err)
 	}
 	oldfdlist := make([]os.File, ncoldfdlist)
 	for i := 0; i < int(ncoldfdlist); i++ {
@@ -119,9 +121,10 @@ func DomainLxcEnterSecurityLabel(model *NodeSecurityModel, label *SecurityLabel,
 		clabel.enforcing = 0
 	}
 
-	ret := C.virDomainLxcEnterSecurityLabel(&cmodel, &clabel, &coldlabel, C.uint(flags))
+	var err C.virError
+	ret := C.virDomainLxcEnterSecurityLabelWrapper(&cmodel, &clabel, &coldlabel, C.uint(flags), &err)
 	if ret == -1 {
-		return nil, GetLastError()
+		return nil, makeError(&err)
 	}
 
 	var oldlabel SecurityLabel
@@ -141,10 +144,11 @@ func (d *Domain) DomainLxcEnterCGroup(flags uint32) error {
 		return GetNotImplementedError("virDomainLxcEnterCGroup")
 	}
 
-	ret := C.virDomainLxcEnterCGroupWrapper(d.ptr, C.uint(flags))
+	var err C.virError
+	ret := C.virDomainLxcEnterCGroupWrapper(d.ptr, C.uint(flags), &err)
 
 	if ret == -1 {
-		return GetLastError()
+		return makeError(&err)
 	}
 
 	return nil
diff --git a/lxc_wrapper.go b/lxc_wrapper.go
index 0968870..fa3d910 100644
--- a/lxc_wrapper.go
+++ b/lxc_wrapper.go
@@ -34,16 +34,68 @@ package libvirt
 #include <assert.h>
 #include "lxc_wrapper.h"
 
-int virDomainLxcEnterCGroupWrapper(virDomainPtr domain,
-				  unsigned int flags)
+int
+virDomainLxcEnterCGroupWrapper(virDomainPtr domain,
+                               unsigned int flags,
+                               virErrorPtr err)
 {
 #if LIBVIR_VERSION_NUMBER < 2000000
     assert(0); // Caller should have checked version
 #else
-    return virDomainLxcEnterCGroup(domain, flags);
+    int ret = virDomainLxcEnterCGroup(domain, flags);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
 #endif
 }
 
 
+int
+virDomainLxcEnterNamespaceWrapper(virDomainPtr domain,
+                                  unsigned int nfdlist,
+                                  int *fdlist,
+                                  unsigned int *noldfdlist,
+                                  int **oldfdlist,
+                                  unsigned int flags,
+                                  virErrorPtr err)
+{
+    int ret = virDomainLxcEnterNamespace(domain, nfdlist, fdlist, noldfdlist, oldfdlist, flags);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virDomainLxcEnterSecurityLabelWrapper(virSecurityModelPtr model,
+                                      virSecurityLabelPtr label,
+                                      virSecurityLabelPtr oldlabel,
+                                      unsigned int flags,
+                                      virErrorPtr err)
+{
+    int ret = virDomainLxcEnterSecurityLabel(model, label, oldlabel, flags);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virDomainLxcOpenNamespaceWrapper(virDomainPtr domain,
+                                 int **fdlist,
+                                 unsigned int flags,
+                                 virErrorPtr err)
+{
+    int ret = virDomainLxcOpenNamespace(domain, fdlist, flags);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
 */
 import "C"
diff --git a/lxc_wrapper.h b/lxc_wrapper.h
index 22f2d55..b3afd6e 100644
--- a/lxc_wrapper.h
+++ b/lxc_wrapper.h
@@ -31,9 +31,33 @@
 #include <libvirt/libvirt-lxc.h>
 #include <libvirt/virterror.h>
 
+
 int
 virDomainLxcEnterCGroupWrapper(virDomainPtr domain,
-                               unsigned int flags);
+                               unsigned int flags,
+                               virErrorPtr err);
+
+int
+virDomainLxcEnterNamespaceWrapper(virDomainPtr domain,
+                                  unsigned int nfdlist,
+                                  int *fdlist,
+                                  unsigned int *noldfdlist,
+                                  int **oldfdlist,
+                                  unsigned int flags,
+                                  virErrorPtr err);
+
+int
+virDomainLxcEnterSecurityLabelWrapper(virSecurityModelPtr model,
+                                      virSecurityLabelPtr label,
+                                      virSecurityLabelPtr oldlabel,
+                                      unsigned int flags,
+                                      virErrorPtr err);
+
+int
+virDomainLxcOpenNamespaceWrapper(virDomainPtr domain,
+                                 int **fdlist,
+                                 unsigned int flags,
+                                 virErrorPtr err);
 
 
 #endif /* LIBVIRT_GO_LXC_COMPAT_H__ */
-- 
2.17.1




More information about the libvir-list mailing list