From nobody Sun Feb 8 05:41:09 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 1548335862696654.2447434863496; Thu, 24 Jan 2019 05:17:42 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3B868C09942B; Thu, 24 Jan 2019 13:17:40 +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 04047BA9E; Thu, 24 Jan 2019 13:17:40 +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 9F8DD18033A3; Thu, 24 Jan 2019 13:17:39 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x0ODHF7F016793 for ; Thu, 24 Jan 2019 08:17:15 -0500 Received: by smtp.corp.redhat.com (Postfix) id C3F1426DFC; Thu, 24 Jan 2019 13:17:15 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-61.ams2.redhat.com [10.36.112.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id E908326332; Thu, 24 Jan 2019 13:17:14 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Thu, 24 Jan 2019 13:17:02 +0000 Message-Id: <20190124131707.17976-4-berrange@redhat.com> In-Reply-To: <20190124131707.17976-1-berrange@redhat.com> References: <20190124131707.17976-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Subject: [libvirt] [go PATCH 3/8] Change typedParamsPackNew to use a C allocated array 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.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 24 Jan 2019 13:17:41 +0000 (UTC) Stop mixing Go allocated memory with C operations for typed parameters and exclusively rely on C allocated memory. This greatly reduces the number of type casts giving clearer code. Signed-off-by: Daniel P. Berrang=C3=A9 --- domain.go | 28 ++++----- typedparams.go | 87 ++++++++++++++------------ typedparams_test.go | 8 ++- typedparams_wrapper.go | 139 +++++++++++++++++++++++++++++++++++++++++ typedparams_wrapper.h | 82 ++++++++++++++++++++++++ 5 files changed, 285 insertions(+), 59 deletions(-) create mode 100644 typedparams_wrapper.go create mode 100644 typedparams_wrapper.h diff --git a/domain.go b/domain.go index b39de47..8f7f030 100644 --- a/domain.go +++ b/domain.go @@ -2104,16 +2104,15 @@ func (d *Domain) BlockCopy(disk string, destxml str= ing, params *DomainBlockCopyP =20 info :=3D getBlockCopyParameterFieldInfo(params) =20 - cparams, gerr :=3D typedParamsPackNew(info) + cparams, cnparams, gerr :=3D typedParamsPackNew(info) if gerr !=3D nil { return gerr } - nparams :=3D len(*cparams) =20 - defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cpar= ams)[0])), C.int(nparams)) + defer C.virTypedParamsFree(cparams, cnparams) =20 var err C.virError - ret :=3D C.virDomainBlockCopyWrapper(d.ptr, cdisk, cdestxml, (*C.virTyped= Parameter)(unsafe.Pointer(&(*cparams)[0])), C.int(nparams), C.uint(flags), = &err) + ret :=3D C.virDomainBlockCopyWrapper(d.ptr, cdisk, cdestxml, cparams, cnp= arams, C.uint(flags), &err) if ret =3D=3D -1 { return makeError(&err) } @@ -2375,16 +2374,15 @@ func getMigrateParameterFieldInfo(params *DomainMig= rateParameters) map[string]ty func (d *Domain) Migrate3(dconn *Connect, params *DomainMigrateParameters,= flags DomainMigrateFlags) (*Domain, error) { =20 info :=3D getMigrateParameterFieldInfo(params) - cparams, gerr :=3D typedParamsPackNew(info) + cparams, cnparams, gerr :=3D typedParamsPackNew(info) if gerr !=3D nil { return nil, gerr } - nparams :=3D len(*cparams) =20 - defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cpar= ams)[0])), C.int(nparams)) + defer C.virTypedParamsFree(cparams, cnparams) =20 var err C.virError - ret :=3D C.virDomainMigrate3Wrapper(d.ptr, dconn.ptr, (*C.virTypedParamet= er)(unsafe.Pointer(&(*cparams)[0])), C.uint(nparams), C.uint(flags), &err) + ret :=3D C.virDomainMigrate3Wrapper(d.ptr, dconn.ptr, cparams, C.uint(cnp= arams), C.uint(flags), &err) if ret =3D=3D nil { return nil, makeError(&err) } @@ -2455,16 +2453,15 @@ func (d *Domain) MigrateToURI3(dconnuri string, par= ams *DomainMigrateParameters, } =20 info :=3D getMigrateParameterFieldInfo(params) - cparams, gerr :=3D typedParamsPackNew(info) + cparams, cnparams, gerr :=3D typedParamsPackNew(info) if gerr !=3D nil { return gerr } - nparams :=3D len(*cparams) =20 - defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cpar= ams)[0])), C.int(nparams)) + defer C.virTypedParamsFree(cparams, cnparams) =20 var err C.virError - ret :=3D C.virDomainMigrateToURI3Wrapper(d.ptr, cdconnuri, (*C.virTypedPa= rameter)(unsafe.Pointer(&(*cparams)[0])), C.uint(nparams), C.uint(flags), &= err) + ret :=3D C.virDomainMigrateToURI3Wrapper(d.ptr, cdconnuri, cparams, C.uin= t(cnparams), C.uint(flags), &err) if ret =3D=3D -1 { return makeError(&err) } @@ -4272,16 +4269,15 @@ func (d *Domain) SetIOThreadParams(iothreadid uint,= params *DomainSetIOThreadPar } info :=3D getSetIOThreadParamsFieldInfo(params) =20 - cparams, gerr :=3D typedParamsPackNew(info) + cparams, cnparams, gerr :=3D typedParamsPackNew(info) if gerr !=3D nil { return gerr } - nparams :=3D len(*cparams) =20 - defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cpar= ams)[0])), C.int(nparams)) + defer C.virTypedParamsFree(cparams, cnparams) =20 var err C.virError - ret :=3D C.virDomainSetIOThreadParamsWrapper(d.ptr, C.uint(iothreadid), (= *C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.int(nparams), C.ui= nt(flags), &err) + ret :=3D C.virDomainSetIOThreadParamsWrapper(d.ptr, C.uint(iothreadid), c= params, cnparams, C.uint(flags), &err) if ret =3D=3D -1 { return makeError(&err) } diff --git a/typedparams.go b/typedparams.go index e8ceae0..a1bdffd 100644 --- a/typedparams.go +++ b/typedparams.go @@ -32,6 +32,7 @@ package libvirt #include #include #include +#include "typedparams_wrapper.h" */ import "C" =20 @@ -197,66 +198,70 @@ func typedParamsPack(cparams []C.virTypedParameter, i= nfomap map[string]typedPara return typedParamsPackLen(&cparams[0], len(cparams), infomap) } =20 -func typedParamsPackNew(infomap map[string]typedParamsFieldInfo) (*[]C.vir= TypedParameter, error) { - nparams :=3D 0 - for _, value :=3D range infomap { - if !*value.set { - continue - } +func typedParamsPackNew(infomap map[string]typedParamsFieldInfo) (*C.virTy= pedParameter, C.int, error) { + var cparams C.virTypedParameterPtr + var nparams C.int + var maxparams C.int =20 - if value.sl !=3D nil { - nparams +=3D len(*value.sl) - } else { - nparams++ - } - } + defer C.virTypedParamsFree(cparams, nparams) =20 - cparams :=3D make([]C.virTypedParameter, nparams) - nparams =3D 0 - for key, value :=3D range infomap { + for name, value :=3D range infomap { if !*value.set { continue } =20 - cfield :=3D C.CString(key) - defer C.free(unsafe.Pointer(cfield)) - clen :=3D len(key) + 1 - if clen > C.VIR_TYPED_PARAM_FIELD_LENGTH { - clen =3D C.VIR_TYPED_PARAM_FIELD_LENGTH - } + cname :=3D C.CString(name) + defer C.free(unsafe.Pointer(cname)) if value.sl !=3D nil { + /* We're not actually using virTypedParamsAddStringList, as it is + * easier to avoid creating a 'char **' in Go to hold all the strings. + * We none the less do a version check, because earlier libvirts + * would not expect to see multiple string values in a typed params + * list with the same field name + */ + if C.LIBVIR_VERSION_NUMBER < 1002017 { + return nil, 0, makeNotImplementedError("virTypedParamsAddStringList") + } for i :=3D 0; i < len(*value.sl); i++ { - cparam :=3D &cparams[nparams] - cparam._type =3D C.VIR_TYPED_PARAM_STRING - C.memcpy(unsafe.Pointer(&cparam.field[0]), unsafe.Pointer(cfield), C.s= ize_t(clen)) - nparams++ + cvalue :=3D C.CString((*value.sl)[i]) + defer C.free(unsafe.Pointer(cvalue)) + var err C.virError + ret :=3D C.virTypedParamsAddStringWrapper(&cparams, &nparams, &maxpara= ms, cname, cvalue, &err) + if ret < 0 { + return nil, 0, makeError(&err) + } } } else { - cparam :=3D &cparams[nparams] + var err C.virError + var ret C.int if value.i !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_INT + ret =3D C.virTypedParamsAddIntWrapper(&cparams, &nparams, &maxparams, = cname, C.int(*value.i), &err) } else if value.ui !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_UINT + ret =3D C.virTypedParamsAddUIntWrapper(&cparams, &nparams, &maxparams,= cname, C.uint(*value.ui), &err) } else if value.l !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_LLONG + ret =3D C.virTypedParamsAddLLongWrapper(&cparams, &nparams, &maxparams= , cname, C.longlong(*value.l), &err) } else if value.ul !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_ULLONG + ret =3D C.virTypedParamsAddULLongWrapper(&cparams, &nparams, &maxparam= s, cname, C.ulonglong(*value.ul), &err) } else if value.b !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_BOOLEAN + v :=3D 0 + if *value.b { + v =3D 1 + } + ret =3D C.virTypedParamsAddBooleanWrapper(&cparams, &nparams, &maxpara= ms, cname, C.int(v), &err) } else if value.d !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_DOUBLE + ret =3D C.virTypedParamsAddDoubleWrapper(&cparams, &nparams, &maxparam= s, cname, C.double(*value.i), &err) } else if value.s !=3D nil { - cparam._type =3D C.VIR_TYPED_PARAM_STRING + cvalue :=3D C.CString(*value.s) + defer C.free(unsafe.Pointer(cvalue)) + ret =3D C.virTypedParamsAddStringWrapper(&cparams, &nparams, &maxparam= s, cname, cvalue, &err) + } else { + return nil, 0, fmt.Errorf("No typed parameter value set for field '%s'= ", name) + } + if ret < 0 { + return nil, 0, makeError(&err) } - C.memcpy(unsafe.Pointer(&cparam.field[0]), unsafe.Pointer(cfield), C.si= ze_t(clen)) - nparams++ } } =20 - err :=3D typedParamsPack(cparams, infomap) - if err !=3D nil { - C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])= ), C.int(nparams)) - return nil, err - } - return &cparams, nil + return cparams, nparams, nil } diff --git a/typedparams_test.go b/typedparams_test.go index 8bc980a..ff3783b 100644 --- a/typedparams_test.go +++ b/typedparams_test.go @@ -77,12 +77,16 @@ func TestPackUnpack(t *testing.T) { sl: &got3, } =20 - params, err :=3D typedParamsPackNew(infoin) + params, nparams, err :=3D typedParamsPackNew(infoin) if err !=3D nil { + lverr, ok :=3D err.(Error) + if ok && lverr.Code =3D=3D ERR_NO_SUPPORT { + return + } t.Fatal(err) } =20 - nout, err :=3D typedParamsUnpack(*params, infoout) + nout, err :=3D typedParamsUnpackLen(params, int(nparams), infoout) if err !=3D nil { t.Fatal(err) } diff --git a/typedparams_wrapper.go b/typedparams_wrapper.go new file mode 100644 index 0000000..c0248ce --- /dev/null +++ b/typedparams_wrapper.go @@ -0,0 +1,139 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + * + * Copyright (C) 2019 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include "typedparams_wrapper.h" + +int +virTypedParamsAddIntWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddInt(params, nparams, maxparams, name, val= ue); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +int +virTypedParamsAddUIntWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + unsigned int value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddUInt(params, nparams, maxparams, name, va= lue); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +int +virTypedParamsAddLLongWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + long long value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddLLong(params, nparams, maxparams, name, v= alue); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +int +virTypedParamsAddULLongWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + unsigned long long value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddULLong(params, nparams, maxparams, name, = value); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +int +virTypedParamsAddDoubleWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + double value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddDouble(params, nparams, maxparams, name, = value); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +int +virTypedParamsAddBooleanWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddBoolean(params, nparams, maxparams, name,= value); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +int +virTypedParamsAddStringWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + const char *value, + virErrorPtr err) +{ + int ret =3D virTypedParamsAddString(params, nparams, maxparams, name, = value); + if (ret < 0) { + virCopyLastError(err); + } + return ret; +} + +*/ +import "C" diff --git a/typedparams_wrapper.h b/typedparams_wrapper.h new file mode 100644 index 0000000..d2ef7d6 --- /dev/null +++ b/typedparams_wrapper.h @@ -0,0 +1,82 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL= THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + * + * Copyright (C) 2019 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_TYPEDPARAMS_WRAPPER_H__ +#define LIBVIRT_GO_TYPEDPARAMS_WRAPPER_H__ + +#include +#include + +int +virTypedParamsAddIntWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int value, + virErrorPtr err); +int +virTypedParamsAddUIntWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + unsigned int value, + virErrorPtr err); +int +virTypedParamsAddLLongWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + long long value, + virErrorPtr err); +int +virTypedParamsAddULLongWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + unsigned long long value, + virErrorPtr err); +int +virTypedParamsAddDoubleWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + double value, + virErrorPtr err); +int +virTypedParamsAddBooleanWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int value, + virErrorPtr err); +int +virTypedParamsAddStringWrapper(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + const char *value, + virErrorPtr err); + +#endif /* LIBVIRT_GO_TYPEDPARAMS_WRAPPER_H__ */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list