Commit 6d165861 authored by Daniel P. Berrangé's avatar Daniel P. Berrangé

storage vol: fix error reporting thread safety

Create wrapper functions for each storage volume 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: 's avatarDaniel P. Berrangé <berrange@redhat.com>
parent 66446a81
......@@ -123,27 +123,30 @@ type StorageVolInfo struct {
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolDelete
func (v *StorageVol) Delete(flags StorageVolDeleteFlags) error {
result := C.virStorageVolDelete(v.ptr, C.uint(flags))
var err C.virError
result := C.virStorageVolDeleteWrapper(v.ptr, C.uint(flags), &err)
if result == -1 {
return GetLastError()
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolFree
func (v *StorageVol) Free() error {
ret := C.virStorageVolFree(v.ptr)
var err C.virError
ret := C.virStorageVolFreeWrapper(v.ptr, &err)
if ret == -1 {
return GetLastError()
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolRef
func (c *StorageVol) Ref() error {
ret := C.virStorageVolRef(c.ptr)
var err C.virError
ret := C.virStorageVolRefWrapper(c.ptr, &err)
if ret == -1 {
return GetLastError()
return makeError(&err)
}
return nil
}
......@@ -151,9 +154,10 @@ func (c *StorageVol) Ref() error {
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetInfo
func (v *StorageVol) GetInfo() (*StorageVolInfo, error) {
var cinfo C.virStorageVolInfo
result := C.virStorageVolGetInfo(v.ptr, &cinfo)
var err C.virError
result := C.virStorageVolGetInfoWrapper(v.ptr, &cinfo, &err)
if result == -1 {
return nil, GetLastError()
return nil, makeError(&err)
}
return &StorageVolInfo{
Type: StorageVolType(cinfo._type),
......@@ -169,9 +173,10 @@ func (v *StorageVol) GetInfoFlags(flags StorageVolInfoFlags) (*StorageVolInfo, e
}
var cinfo C.virStorageVolInfo
result := C.virStorageVolGetInfoFlagsWrapper(v.ptr, &cinfo, C.uint(flags))
var err C.virError
result := C.virStorageVolGetInfoFlagsWrapper(v.ptr, &cinfo, C.uint(flags), &err)
if result == -1 {
return nil, GetLastError()
return nil, makeError(&err)
}
return &StorageVolInfo{
Type: StorageVolType(cinfo._type),
......@@ -182,27 +187,30 @@ func (v *StorageVol) GetInfoFlags(flags StorageVolInfoFlags) (*StorageVolInfo, e
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetKey
func (v *StorageVol) GetKey() (string, error) {
key := C.virStorageVolGetKey(v.ptr)
var err C.virError
key := C.virStorageVolGetKeyWrapper(v.ptr, &err)
if key == nil {
return "", GetLastError()
return "", makeError(&err)
}
return C.GoString(key), nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetName
func (v *StorageVol) GetName() (string, error) {
name := C.virStorageVolGetName(v.ptr)
var err C.virError
name := C.virStorageVolGetNameWrapper(v.ptr, &err)
if name == nil {
return "", GetLastError()
return "", makeError(&err)
}
return C.GoString(name), nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetPath
func (v *StorageVol) GetPath() (string, error) {
result := C.virStorageVolGetPath(v.ptr)
var err C.virError
result := C.virStorageVolGetPathWrapper(v.ptr, &err)
if result == nil {
return "", GetLastError()
return "", makeError(&err)
}
path := C.GoString(result)
C.free(unsafe.Pointer(result))
......@@ -211,9 +219,10 @@ func (v *StorageVol) GetPath() (string, error) {
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetXMLDesc
func (v *StorageVol) GetXMLDesc(flags uint32) (string, error) {
result := C.virStorageVolGetXMLDesc(v.ptr, C.uint(flags))
var err C.virError
result := C.virStorageVolGetXMLDescWrapper(v.ptr, C.uint(flags), &err)
if result == nil {
return "", GetLastError()
return "", makeError(&err)
}
xml := C.GoString(result)
C.free(unsafe.Pointer(result))
......@@ -222,54 +231,60 @@ func (v *StorageVol) GetXMLDesc(flags uint32) (string, error) {
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolResize
func (v *StorageVol) Resize(capacity uint64, flags StorageVolResizeFlags) error {
result := C.virStorageVolResize(v.ptr, C.ulonglong(capacity), C.uint(flags))
var err C.virError
result := C.virStorageVolResizeWrapper(v.ptr, C.ulonglong(capacity), C.uint(flags), &err)
if result == -1 {
return GetLastError()
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolWipe
func (v *StorageVol) Wipe(flags uint32) error {
result := C.virStorageVolWipe(v.ptr, C.uint(flags))
var err C.virError
result := C.virStorageVolWipeWrapper(v.ptr, C.uint(flags), &err)
if result == -1 {
return GetLastError()
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolWipePattern
func (v *StorageVol) WipePattern(algorithm StorageVolWipeAlgorithm, flags uint32) error {
result := C.virStorageVolWipePattern(v.ptr, C.uint(algorithm), C.uint(flags))
var err C.virError
result := C.virStorageVolWipePatternWrapper(v.ptr, C.uint(algorithm), C.uint(flags), &err)
if result == -1 {
return GetLastError()
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolUpload
func (v *StorageVol) Upload(stream *Stream, offset, length uint64, flags StorageVolUploadFlags) error {
if C.virStorageVolUpload(v.ptr, stream.ptr, C.ulonglong(offset),
C.ulonglong(length), C.uint(flags)) == -1 {
return GetLastError()
var err C.virError
if C.virStorageVolUploadWrapper(v.ptr, stream.ptr, C.ulonglong(offset),
C.ulonglong(length), C.uint(flags), &err) == -1 {
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolDownload
func (v *StorageVol) Download(stream *Stream, offset, length uint64, flags StorageVolDownloadFlags) error {
if C.virStorageVolDownload(v.ptr, stream.ptr, C.ulonglong(offset),
C.ulonglong(length), C.uint(flags)) == -1 {
return GetLastError()
var err C.virError
if C.virStorageVolDownloadWrapper(v.ptr, stream.ptr, C.ulonglong(offset),
C.ulonglong(length), C.uint(flags), &err) == -1 {
return makeError(&err)
}
return nil
}
// See also https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolLookupByVolume
func (v *StorageVol) LookupPoolByVolume() (*StoragePool, error) {
poolPtr := C.virStoragePoolLookupByVolume(v.ptr)
var err C.virError
poolPtr := C.virStoragePoolLookupByVolumeWrapper(v.ptr, &err)
if poolPtr == nil {
return nil, GetLastError()
return nil, makeError(&err)
}
return &StoragePool{ptr: poolPtr}, nil
}
......@@ -31,16 +31,219 @@ package libvirt
#include <assert.h>
#include "storage_volume_wrapper.h"
int virStorageVolGetInfoFlagsWrapper(virStorageVolPtr vol,
virStorageVolInfoPtr info,
unsigned int flags)
virStoragePoolPtr
virStoragePoolLookupByVolumeWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
virStoragePoolPtr ret = virStoragePoolLookupByVolume(vol);
if (!ret) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolDeleteWrapper(virStorageVolPtr vol,
unsigned int flags,
virErrorPtr err)
{
int ret = virStorageVolDelete(vol, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolDownloadWrapper(virStorageVolPtr vol,
virStreamPtr stream,
unsigned long long offset,
unsigned long long length,
unsigned int flags,
virErrorPtr err)
{
int ret = virStorageVolDownload(vol, stream, offset, length, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolFreeWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
int ret = virStorageVolFree(vol);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
virConnectPtr
virStorageVolGetConnectWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
virConnectPtr ret = virStorageVolGetConnect(vol);
if (!ret) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolGetInfoWrapper(virStorageVolPtr vol,
virStorageVolInfoPtr info,
virErrorPtr err)
{
int ret = virStorageVolGetInfo(vol, info);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolGetInfoFlagsWrapper(virStorageVolPtr vol,
virStorageVolInfoPtr info,
unsigned int flags,
virErrorPtr err)
{
#if LIBVIR_VERSION_NUMBER < 3000000
assert(0); // Caller should have checked version
#else
return virStorageVolGetInfoFlags(vol, info, flags);
int ret = virStorageVolGetInfoFlags(vol, info, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
#endif
}
const char *
virStorageVolGetKeyWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
const char *ret = virStorageVolGetKey(vol);
if (!ret) {
virCopyLastError(err);
}
return ret;
}
const char *
virStorageVolGetNameWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
const char *ret = virStorageVolGetName(vol);
if (!ret) {
virCopyLastError(err);
}
return ret;
}
char *
virStorageVolGetPathWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
char *ret = virStorageVolGetPath(vol);
if (!ret) {
virCopyLastError(err);
}
return ret;
}
char *
virStorageVolGetXMLDescWrapper(virStorageVolPtr vol,
unsigned int flags,
virErrorPtr err)
{
char *ret = virStorageVolGetXMLDesc(vol, flags);
if (!ret) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolRefWrapper(virStorageVolPtr vol,
virErrorPtr err)
{
int ret = virStorageVolRef(vol);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolResizeWrapper(virStorageVolPtr vol,
unsigned long long capacity,
unsigned int flags,
virErrorPtr err)
{
int ret = virStorageVolResize(vol, capacity, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolUploadWrapper(virStorageVolPtr vol,
virStreamPtr stream,
unsigned long long offset,
unsigned long long length,
unsigned int flags,
virErrorPtr err)
{
int ret = virStorageVolUpload(vol, stream, offset, length, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolWipeWrapper(virStorageVolPtr vol,
unsigned int flags,
virErrorPtr err)
{
int ret = virStorageVolWipe(vol, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
int
virStorageVolWipePatternWrapper(virStorageVolPtr vol,
unsigned int algorithm,
unsigned int flags,
virErrorPtr err)
{
int ret = virStorageVolWipePattern(vol, algorithm, flags);
if (ret < 0) {
virCopyLastError(err);
}
return ret;
}
*/
import "C"
......@@ -31,9 +31,86 @@
#include <libvirt/virterror.h>
#include "storage_volume_compat.h"
virStoragePoolPtr
virStoragePoolLookupByVolumeWrapper(virStorageVolPtr vol,
virErrorPtr err);
int
virStorageVolDeleteWrapper(virStorageVolPtr vol,
unsigned int flags,
virErrorPtr err);
int
virStorageVolDownloadWrapper(virStorageVolPtr vol,
virStreamPtr stream,
unsigned long long offset,
unsigned long long length,
unsigned int flags,
virErrorPtr err);
int
virStorageVolFreeWrapper(virStorageVolPtr vol,
virErrorPtr err);
virConnectPtr
virStorageVolGetConnectWrapper(virStorageVolPtr vol,
virErrorPtr err);
int
virStorageVolGetInfoWrapper(virStorageVolPtr vol,
virStorageVolInfoPtr info,
virErrorPtr err);
int
virStorageVolGetInfoFlagsWrapper(virStorageVolPtr vol,
virStorageVolInfoPtr info,
unsigned int flags);
unsigned int flags,
virErrorPtr err);
const char *
virStorageVolGetKeyWrapper(virStorageVolPtr vol,
virErrorPtr err);
const char *
virStorageVolGetNameWrapper(virStorageVolPtr vol,
virErrorPtr err);
char *
virStorageVolGetPathWrapper(virStorageVolPtr vol,
virErrorPtr err);
char *
virStorageVolGetXMLDescWrapper(virStorageVolPtr vol,
unsigned int flags,
virErrorPtr err);
int
virStorageVolRefWrapper(virStorageVolPtr vol,
virErrorPtr err);
int
virStorageVolResizeWrapper(virStorageVolPtr vol,
unsigned long long capacity,
unsigned int flags,
virErrorPtr err);
int
virStorageVolUploadWrapper(virStorageVolPtr vol,
virStreamPtr stream,
unsigned long long offset,
unsigned long long length,
unsigned int flags,
virErrorPtr err);
int
virStorageVolWipeWrapper(virStorageVolPtr vol,
unsigned int flags,
virErrorPtr err);
int
virStorageVolWipePatternWrapper(virStorageVolPtr vol,
unsigned int algorithm,
unsigned int flags,
virErrorPtr err);
#endif /* LIBVIRT_GO_STORAGE_VOLUME_WRAPPER_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment