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(a)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