From nobody Sun Feb 8 12:37:44 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1531747515524413.5590773688532; Mon, 16 Jul 2018 06:25:15 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0B09CBDC0; Mon, 16 Jul 2018 13:25:14 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BB5C31001F5E; Mon, 16 Jul 2018 13:25:13 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5F99D1853DA1; Mon, 16 Jul 2018 13:25:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w6GDOu1s028235 for ; Mon, 16 Jul 2018 09:24:56 -0400 Received: by smtp.corp.redhat.com (Postfix) id ED4422027047; Mon, 16 Jul 2018 13:24:55 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3CAF02026D65; Mon, 16 Jul 2018 13:24:55 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Mon, 16 Jul 2018 14:24:13 +0100 Message-Id: <20180716132423.10354-28-berrange@redhat.com> In-Reply-To: <20180716132423.10354-1-berrange@redhat.com> References: <20180716132423.10354-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Subject: [libvirt] [go PATCH 27/37] network: fix error reporting thread safety X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 16 Jul 2018 13:25:14 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Create wrapper functions for each network 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=C3=A9 --- network.go | 80 +++++++++------- network_wrapper.go | 228 +++++++++++++++++++++++++++++++++++++++++++-- network_wrapper.h | 78 +++++++++++++++- 3 files changed, 347 insertions(+), 39 deletions(-) diff --git a/network.go b/network.go index 015fe5e..d9ec9bf 100644 --- a/network.go +++ b/network.go @@ -121,45 +121,50 @@ type NetworkDHCPLease struct { =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkFree func (n *Network) Free() error { - ret :=3D C.virNetworkFree(n.ptr) + var err C.virError + ret :=3D C.virNetworkFreeWrapper(n.ptr, &err) if ret =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkRef func (c *Network) Ref() error { - ret :=3D C.virNetworkRef(c.ptr) + var err C.virError + ret :=3D C.virNetworkRefWrapper(c.ptr, &err) if ret =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkCreate func (n *Network) Create() error { - result :=3D C.virNetworkCreate(n.ptr) + var err C.virError + result :=3D C.virNetworkCreateWrapper(n.ptr, &err) if result =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkDestroy func (n *Network) Destroy() error { - result :=3D C.virNetworkDestroy(n.ptr) + var err C.virError + result :=3D C.virNetworkDestroyWrapper(n.ptr, &err) if result =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkIsActive func (n *Network) IsActive() (bool, error) { - result :=3D C.virNetworkIsActive(n.ptr) + var err C.virError + result :=3D C.virNetworkIsActiveWrapper(n.ptr, &err) if result =3D=3D -1 { - return false, GetLastError() + return false, makeError(&err) } if result =3D=3D 1 { return true, nil @@ -169,9 +174,10 @@ func (n *Network) IsActive() (bool, error) { =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkIsPersistent func (n *Network) IsPersistent() (bool, error) { - result :=3D C.virNetworkIsPersistent(n.ptr) + var err C.virError + result :=3D C.virNetworkIsPersistentWrapper(n.ptr, &err) if result =3D=3D -1 { - return false, GetLastError() + return false, makeError(&err) } if result =3D=3D 1 { return true, nil @@ -182,9 +188,10 @@ func (n *Network) IsPersistent() (bool, error) { // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkGetAutostart func (n *Network) GetAutostart() (bool, error) { var out C.int - result :=3D C.virNetworkGetAutostart(n.ptr, (*C.int)(unsafe.Pointer(&out)= )) + var err C.virError + result :=3D C.virNetworkGetAutostartWrapper(n.ptr, (*C.int)(unsafe.Pointe= r(&out)), &err) if result =3D=3D -1 { - return false, GetLastError() + return false, makeError(&err) } switch out { case 1: @@ -203,18 +210,20 @@ func (n *Network) SetAutostart(autostart bool) error { default: cAutostart =3D 0 } - result :=3D C.virNetworkSetAutostart(n.ptr, cAutostart) + var err C.virError + result :=3D C.virNetworkSetAutostartWrapper(n.ptr, cAutostart, &err) if result =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkGetName func (n *Network) GetName() (string, error) { - name :=3D C.virNetworkGetName(n.ptr) + var err C.virError + name :=3D C.virNetworkGetNameWrapper(n.ptr, &err) if name =3D=3D nil { - return "", GetLastError() + return "", makeError(&err) } return C.GoString(name), nil } @@ -223,9 +232,10 @@ func (n *Network) GetName() (string, error) { func (n *Network) GetUUID() ([]byte, error) { var cUuid [C.VIR_UUID_BUFLEN](byte) cuidPtr :=3D unsafe.Pointer(&cUuid) - result :=3D C.virNetworkGetUUID(n.ptr, (*C.uchar)(cuidPtr)) + var err C.virError + result :=3D C.virNetworkGetUUIDWrapper(n.ptr, (*C.uchar)(cuidPtr), &err) if result !=3D 0 { - return []byte{}, GetLastError() + return []byte{}, makeError(&err) } return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil } @@ -234,18 +244,20 @@ func (n *Network) GetUUID() ([]byte, error) { func (n *Network) GetUUIDString() (string, error) { var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) cuidPtr :=3D unsafe.Pointer(&cUuid) - result :=3D C.virNetworkGetUUIDString(n.ptr, (*C.char)(cuidPtr)) + var err C.virError + result :=3D C.virNetworkGetUUIDStringWrapper(n.ptr, (*C.char)(cuidPtr), &= err) if result !=3D 0 { - return "", GetLastError() + return "", makeError(&err) } return C.GoString((*C.char)(cuidPtr)), nil } =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkGetBridgeName func (n *Network) GetBridgeName() (string, error) { - result :=3D C.virNetworkGetBridgeName(n.ptr) + var err C.virError + result :=3D C.virNetworkGetBridgeNameWrapper(n.ptr, &err) if result =3D=3D nil { - return "", GetLastError() + return "", makeError(&err) } bridge :=3D C.GoString(result) C.free(unsafe.Pointer(result)) @@ -254,9 +266,10 @@ func (n *Network) GetBridgeName() (string, error) { =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkGetXMLDesc func (n *Network) GetXMLDesc(flags NetworkXMLFlags) (string, error) { - result :=3D C.virNetworkGetXMLDesc(n.ptr, C.uint(flags)) + var err C.virError + result :=3D C.virNetworkGetXMLDescWrapper(n.ptr, C.uint(flags), &err) if result =3D=3D nil { - return "", GetLastError() + return "", makeError(&err) } xml :=3D C.GoString(result) C.free(unsafe.Pointer(result)) @@ -265,9 +278,10 @@ func (n *Network) GetXMLDesc(flags NetworkXMLFlags) (s= tring, error) { =20 // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetwo= rkUndefine func (n *Network) Undefine() error { - result :=3D C.virNetworkUndefine(n.ptr) + var err C.virError + result :=3D C.virNetworkUndefineWrapper(n.ptr, &err) if result =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } @@ -276,9 +290,10 @@ func (n *Network) Undefine() error { func (n *Network) Update(cmd NetworkUpdateCommand, section NetworkUpdateSe= ction, parentIndex int, xml string, flags NetworkUpdateFlags) error { cxml :=3D C.CString(xml) defer C.free(unsafe.Pointer(cxml)) - result :=3D C.virNetworkUpdate(n.ptr, C.uint(cmd), C.uint(section), C.int= (parentIndex), cxml, C.uint(flags)) + var err C.virError + result :=3D C.virNetworkUpdateWrapper(n.ptr, C.uint(cmd), C.uint(section)= , C.int(parentIndex), cxml, C.uint(flags), &err) if result =3D=3D -1 { - return GetLastError() + return makeError(&err) } return nil } @@ -289,9 +304,10 @@ func (n *Network) GetDHCPLeases() ([]NetworkDHCPLease,= error) { return []NetworkDHCPLease{}, GetNotImplementedError("virNetworkGetDHCPLe= ases") } var cLeases *C.virNetworkDHCPLeasePtr - numLeases :=3D C.virNetworkGetDHCPLeasesWrapper(n.ptr, nil, (**C.virNetwo= rkDHCPLeasePtr)(&cLeases), C.uint(0)) + var err C.virError + numLeases :=3D C.virNetworkGetDHCPLeasesWrapper(n.ptr, nil, (**C.virNetwo= rkDHCPLeasePtr)(&cLeases), C.uint(0), &err) if numLeases =3D=3D -1 { - return nil, GetLastError() + return nil, makeError(&err) } hdr :=3D reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(cLeases)), diff --git a/network_wrapper.go b/network_wrapper.go index 5c797e0..2fc443f 100644 --- a/network_wrapper.go +++ b/network_wrapper.go @@ -31,21 +31,237 @@ package libvirt #include #include "network_wrapper.h" =20 -void virNetworkDHCPLeaseFreeWrapper(virNetworkDHCPLeasePtr lease) +int +virNetworkCreateWrapper(virNetworkPtr network, + virErrorPtr err) { + int ret =3D virNetworkCreate(network); + if (ret < 0) { + virCopyLastError(err); + } + return ret; } =20 -int virNetworkGetDHCPLeasesWrapper(virNetworkPtr network, - const char *mac, - virNetworkDHCPLeasePtr **leases, - unsigned int flags) + +void +virNetworkDHCPLeaseFreeWrapper(virNetworkDHCPLeasePtr lease) { #if LIBVIR_VERSION_NUMBER < 1002006 assert(0); // Caller should have checked version #else - return virNetworkGetDHCPLeases(network, mac, leases, flags); + virNetworkDHCPLeaseFree(lease); #endif } =20 + +int +virNetworkDestroyWrapper(virNetworkPtr network, + virErrorPtr err) +{ + int ret =3D virNetworkDestroy(network); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkFreeWrapper(virNetworkPtr network, + virErrorPtr err) +{ + int ret =3D virNetworkFree(network); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkGetAutostartWrapper(virNetworkPtr network, + int *autostart, + virErrorPtr err) +{ + int ret =3D virNetworkGetAutostart(network, autostart); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +char * +virNetworkGetBridgeNameWrapper(virNetworkPtr network, + virErrorPtr err) +{ + char * ret =3D virNetworkGetBridgeName(network); + if (!ret) { + virCopyLastError(err); + } + return ret; +} + + +virConnectPtr +virNetworkGetConnectWrapper(virNetworkPtr net, + virErrorPtr err) +{ + virConnectPtr ret =3D virNetworkGetConnect(net); + if (!ret) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkGetDHCPLeasesWrapper(virNetworkPtr network, + const char *mac, + virNetworkDHCPLeasePtr **leases, + unsigned int flags, + virErrorPtr err) +{ +#if LIBVIR_VERSION_NUMBER < 1002006 + assert(0); // Caller should have checked version +#else + int ret =3D virNetworkGetDHCPLeases(network, mac, leases, flags); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +#endif +} + + +const char * +virNetworkGetNameWrapper(virNetworkPtr network, + virErrorPtr err) +{ + const char * ret =3D virNetworkGetName(network); + if (!ret) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkGetUUIDWrapper(virNetworkPtr network, + unsigned char *uuid, + virErrorPtr err) +{ + int ret =3D virNetworkGetUUID(network, uuid); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkGetUUIDStringWrapper(virNetworkPtr network, + char *buf, + virErrorPtr err) +{ + int ret =3D virNetworkGetUUIDString(network, buf); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +char * +virNetworkGetXMLDescWrapper(virNetworkPtr network, + unsigned int flags, + virErrorPtr err) +{ + char * ret =3D virNetworkGetXMLDesc(network, flags); + if (!ret) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkIsActiveWrapper(virNetworkPtr net, + virErrorPtr err) +{ + int ret =3D virNetworkIsActive(net); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkIsPersistentWrapper(virNetworkPtr net, + virErrorPtr err) +{ + int ret =3D virNetworkIsPersistent(net); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkRefWrapper(virNetworkPtr network, + virErrorPtr err) +{ + int ret =3D virNetworkRef(network); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkSetAutostartWrapper(virNetworkPtr network, + int autostart, + virErrorPtr err) +{ + int ret =3D virNetworkSetAutostart(network, autostart); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkUndefineWrapper(virNetworkPtr network, + virErrorPtr err) +{ + int ret =3D virNetworkUndefine(network); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + +int +virNetworkUpdateWrapper(virNetworkPtr network, + unsigned int command, + unsigned int section, + int parentIndex, + const char *xml, + unsigned int flags, + virErrorPtr err) +{ + int ret =3D virNetworkUpdate(network, command, section, parentIndex, x= ml, flags); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + + */ import "C" diff --git a/network_wrapper.h b/network_wrapper.h index 8a36d13..405bf89 100644 --- a/network_wrapper.h +++ b/network_wrapper.h @@ -31,13 +31,89 @@ #include #include "network_compat.h" =20 +int +virNetworkCreateWrapper(virNetworkPtr network, + virErrorPtr err); + void virNetworkDHCPLeaseFreeWrapper(virNetworkDHCPLeasePtr lease); =20 +int +virNetworkDestroyWrapper(virNetworkPtr network, + virErrorPtr err); + +int +virNetworkFreeWrapper(virNetworkPtr network, + virErrorPtr err); + +int +virNetworkGetAutostartWrapper(virNetworkPtr network, + int *autostart, + virErrorPtr err); + +char * +virNetworkGetBridgeNameWrapper(virNetworkPtr network, + virErrorPtr err); + +virConnectPtr +virNetworkGetConnectWrapper(virNetworkPtr net, + virErrorPtr err); + int virNetworkGetDHCPLeasesWrapper(virNetworkPtr network, const char *mac, virNetworkDHCPLeasePtr **leases, - unsigned int flags); + unsigned int flags, + virErrorPtr err); + +const char * +virNetworkGetNameWrapper(virNetworkPtr network, + virErrorPtr err); + +int +virNetworkGetUUIDWrapper(virNetworkPtr network, + unsigned char *uuid, + virErrorPtr err); + +int +virNetworkGetUUIDStringWrapper(virNetworkPtr network, + char *buf, + virErrorPtr err); + +char * +virNetworkGetXMLDescWrapper(virNetworkPtr network, + unsigned int flags, + virErrorPtr err); + +int +virNetworkIsActiveWrapper(virNetworkPtr net, + virErrorPtr err); + +int +virNetworkIsPersistentWrapper(virNetworkPtr net, + virErrorPtr err); + +int +virNetworkRefWrapper(virNetworkPtr network, + virErrorPtr err); + +int +virNetworkSetAutostartWrapper(virNetworkPtr network, + int autostart, + virErrorPtr err); + +int +virNetworkUndefineWrapper(virNetworkPtr network, + virErrorPtr err); + +int +virNetworkUpdateWrapper(virNetworkPtr network, + unsigned int command, + unsigned int section, + int parentIndex, + const char *xml, + unsigned int flags, + virErrorPtr err); + =20 #endif /* LIBVIRT_GO_NETWORK_WRAPPER_H__ */ --=20 2.17.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list