[libvirt] [go PATCH 23/37] secret: fix error reporting thread safety

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


Create wrapper functions for each secret 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>
---
 secret.go         |  50 +++++++++-------
 secret_wrapper.go | 141 ++++++++++++++++++++++++++++++++++++++++++++++
 secret_wrapper.h  |  53 +++++++++++++++++
 3 files changed, 224 insertions(+), 20 deletions(-)

diff --git a/secret.go b/secret.go
index 9bd8b36..c4ef44b 100644
--- a/secret.go
+++ b/secret.go
@@ -67,27 +67,30 @@ type Secret struct {
 
 // See also https://libvirt.org/html/libvirt-libvirt-secret.html#virSecretFree
 func (s *Secret) Free() error {
-	ret := C.virSecretFree(s.ptr)
+	var err C.virError
+	ret := C.virSecretFreeWrapper(s.ptr, &err)
 	if ret == -1 {
-		return GetLastError()
+		return makeError(&err)
 	}
 	return nil
 }
 
 // See also https://libvirt.org/html/libvirt-libvirt-secret.html#virSecretRef
 func (c *Secret) Ref() error {
-	ret := C.virSecretRef(c.ptr)
+	var err C.virError
+	ret := C.virSecretRefWrapper(c.ptr, &err)
 	if ret == -1 {
-		return GetLastError()
+		return makeError(&err)
 	}
 	return nil
 }
 
 // See also https://libvirt.org/html/libvirt-libvirt-secret.html#virSecretUndefine
 func (s *Secret) Undefine() error {
-	result := C.virSecretUndefine(s.ptr)
+	var err C.virError
+	result := C.virSecretUndefineWrapper(s.ptr, &err)
 	if result == -1 {
-		return GetLastError()
+		return makeError(&err)
 	}
 	return nil
 }
@@ -96,9 +99,10 @@ func (s *Secret) Undefine() error {
 func (s *Secret) GetUUID() ([]byte, error) {
 	var cUuid [C.VIR_UUID_BUFLEN](byte)
 	cuidPtr := unsafe.Pointer(&cUuid)
-	result := C.virSecretGetUUID(s.ptr, (*C.uchar)(cuidPtr))
+	var err C.virError
+	result := C.virSecretGetUUIDWrapper(s.ptr, (*C.uchar)(cuidPtr), &err)
 	if result != 0 {
-		return []byte{}, GetLastError()
+		return []byte{}, makeError(&err)
 	}
 	return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil
 }
@@ -107,36 +111,40 @@ func (s *Secret) GetUUID() ([]byte, error) {
 func (s *Secret) GetUUIDString() (string, error) {
 	var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char)
 	cuidPtr := unsafe.Pointer(&cUuid)
-	result := C.virSecretGetUUIDString(s.ptr, (*C.char)(cuidPtr))
+	var err C.virError
+	result := C.virSecretGetUUIDStringWrapper(s.ptr, (*C.char)(cuidPtr), &err)
 	if result != 0 {
-		return "", GetLastError()
+		return "", makeError(&err)
 	}
 	return C.GoString((*C.char)(cuidPtr)), nil
 }
 
 // See also https://libvirt.org/html/libvirt-libvirt-secret.html#virSecretGetUsageID
 func (s *Secret) GetUsageID() (string, error) {
-	result := C.virSecretGetUsageID(s.ptr)
+	var err C.virError
+	result := C.virSecretGetUsageIDWrapper(s.ptr, &err)
 	if result == nil {
-		return "", GetLastError()
+		return "", makeError(&err)
 	}
 	return C.GoString(result), nil
 }
 
 // See also https://libvirt.org/html/libvirt-libvirt-secret.html#virSecretGetUsageType
 func (s *Secret) GetUsageType() (SecretUsageType, error) {
-	result := SecretUsageType(C.virSecretGetUsageType(s.ptr))
+	var err C.virError
+	result := SecretUsageType(C.virSecretGetUsageTypeWrapper(s.ptr, &err))
 	if result == -1 {
-		return 0, GetLastError()
+		return 0, makeError(&err)
 	}
 	return result, nil
 }
 
 // See also https://libvirt.org/html/libvirt-libvirt-secret.html#virSecretGetXMLDesc
 func (s *Secret) GetXMLDesc(flags uint32) (string, error) {
-	result := C.virSecretGetXMLDesc(s.ptr, C.uint(flags))
+	var err C.virError
+	result := C.virSecretGetXMLDescWrapper(s.ptr, C.uint(flags), &err)
 	if result == nil {
-		return "", GetLastError()
+		return "", makeError(&err)
 	}
 	xml := C.GoString(result)
 	C.free(unsafe.Pointer(result))
@@ -147,9 +155,10 @@ func (s *Secret) GetXMLDesc(flags uint32) (string, error) {
 func (s *Secret) GetValue(flags uint32) ([]byte, error) {
 	var cvalue_size C.size_t
 
-	cvalue := C.virSecretGetValue(s.ptr, &cvalue_size, C.uint(flags))
+	var err C.virError
+	cvalue := C.virSecretGetValueWrapper(s.ptr, &cvalue_size, C.uint(flags), &err)
 	if cvalue == nil {
-		return nil, GetLastError()
+		return nil, makeError(&err)
 	}
 	defer C.free(unsafe.Pointer(cvalue))
 	ret := C.GoBytes(unsafe.Pointer(cvalue), C.int(cvalue_size))
@@ -164,10 +173,11 @@ func (s *Secret) SetValue(value []byte, flags uint32) error {
 		cvalue[i] = C.uchar(value[i])
 	}
 
-	result := C.virSecretSetValue(s.ptr, &cvalue[0], C.size_t(len(value)), C.uint(flags))
+	var err C.virError
+	result := C.virSecretSetValueWrapper(s.ptr, &cvalue[0], C.size_t(len(value)), C.uint(flags), &err)
 
 	if result == -1 {
-		return GetLastError()
+		return makeError(&err)
 	}
 
 	return nil
diff --git a/secret_wrapper.go b/secret_wrapper.go
index 1bcc74d..96f60f6 100644
--- a/secret_wrapper.go
+++ b/secret_wrapper.go
@@ -30,5 +30,146 @@ package libvirt
 #include <assert.h>
 #include "secret_wrapper.h"
 
+
+int
+virSecretFreeWrapper(virSecretPtr secret,
+                     virErrorPtr err)
+{
+    int ret = virSecretFree(secret);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+virConnectPtr
+virSecretGetConnectWrapper(virSecretPtr secret,
+                           virErrorPtr err)
+{
+    virConnectPtr ret = virSecretGetConnect(secret);
+    if (!ret) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virSecretGetUUIDWrapper(virSecretPtr secret,
+                        unsigned char *uuid,
+                        virErrorPtr err)
+{
+    int ret = virSecretGetUUID(secret, uuid);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virSecretGetUUIDStringWrapper(virSecretPtr secret,
+                              char *buf,
+                              virErrorPtr err)
+{
+    int ret = virSecretGetUUIDString(secret, buf);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+const char *
+virSecretGetUsageIDWrapper(virSecretPtr secret,
+                           virErrorPtr err)
+{
+    const char * ret = virSecretGetUsageID(secret);
+    if (!ret) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virSecretGetUsageTypeWrapper(virSecretPtr secret,
+                             virErrorPtr err)
+{
+    int ret = virSecretGetUsageType(secret);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+unsigned char *
+virSecretGetValueWrapper(virSecretPtr secret,
+                         size_t *value_size,
+                         unsigned int flags,
+                         virErrorPtr err)
+{
+    unsigned char * ret = virSecretGetValue(secret, value_size, flags);
+    if (!ret) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+char *
+virSecretGetXMLDescWrapper(virSecretPtr secret,
+                           unsigned int flags,
+                           virErrorPtr err)
+{
+    char * ret = virSecretGetXMLDesc(secret, flags);
+    if (!ret) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virSecretRefWrapper(virSecretPtr secret,
+                    virErrorPtr err)
+{
+    int ret = virSecretRef(secret);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virSecretSetValueWrapper(virSecretPtr secret,
+                         const unsigned char *value,
+                         size_t value_size,
+                         unsigned int flags,
+                         virErrorPtr err)
+{
+    int ret = virSecretSetValue(secret, value, value_size, flags);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
+int
+virSecretUndefineWrapper(virSecretPtr secret,
+                         virErrorPtr err)
+{
+    int ret = virSecretUndefine(secret);
+    if (ret < 0) {
+        virCopyLastError(err);
+    }
+    return ret;
+}
+
+
 */
 import "C"
diff --git a/secret_wrapper.h b/secret_wrapper.h
index 478c7d4..eca6f0a 100644
--- a/secret_wrapper.h
+++ b/secret_wrapper.h
@@ -30,4 +30,57 @@
 #include <libvirt/virterror.h>
 #include "secret_compat.h"
 
+int
+virSecretFreeWrapper(virSecretPtr secret,
+                     virErrorPtr err);
+
+virConnectPtr
+virSecretGetConnectWrapper(virSecretPtr secret,
+                           virErrorPtr err);
+
+int
+virSecretGetUUIDWrapper(virSecretPtr secret,
+                        unsigned char *uuid,
+                        virErrorPtr err);
+
+int
+virSecretGetUUIDStringWrapper(virSecretPtr secret,
+                              char *buf,
+                              virErrorPtr err);
+
+const char *
+virSecretGetUsageIDWrapper(virSecretPtr secret,
+                           virErrorPtr err);
+
+int
+virSecretGetUsageTypeWrapper(virSecretPtr secret,
+                             virErrorPtr err);
+
+unsigned char *
+virSecretGetValueWrapper(virSecretPtr secret,
+                         size_t *value_size,
+                         unsigned int flags,
+                         virErrorPtr err);
+
+char *
+virSecretGetXMLDescWrapper(virSecretPtr secret,
+                           unsigned int flags,
+                           virErrorPtr err);
+
+int
+virSecretRefWrapper(virSecretPtr secret,
+                    virErrorPtr err);
+
+int
+virSecretSetValueWrapper(virSecretPtr secret,
+                         const unsigned char *value,
+                         size_t value_size,
+                         unsigned int flags,
+                         virErrorPtr err);
+
+int
+virSecretUndefineWrapper(virSecretPtr secret,
+                         virErrorPtr err);
+
+
 #endif /* LIBVIRT_GO_SECRET_WRAPPER_H__ */
-- 
2.17.1




More information about the libvir-list mailing list