From nobody Sun Feb 8 01:33:13 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 1545663673174180.802012659684; Mon, 24 Dec 2018 07:01:13 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA81925ECD; Mon, 24 Dec 2018 15:01:09 +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 6638460BE2; Mon, 24 Dec 2018 15:01:09 +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 F271518433AF; Mon, 24 Dec 2018 15:01:08 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBOF14f0001427 for ; Mon, 24 Dec 2018 10:01:04 -0500 Received: by smtp.corp.redhat.com (Postfix) id B68F260C68; Mon, 24 Dec 2018 15:01:04 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-27.ams2.redhat.com [10.36.112.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id CD3C660C73; Mon, 24 Dec 2018 15:01:00 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Mon, 24 Dec 2018 14:59:13 +0000 Message-Id: <20181224145915.8700-26-berrange@redhat.com> In-Reply-To: <20181224145915.8700-1-berrange@redhat.com> References: <20181224145915.8700-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 25/27] conf: support recording ports against virNetworkObjPtr 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.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 24 Dec 2018 15:01:11 +0000 (UTC) The virNetworkObjPtr state will need to maintain a record of all virNetworkPortDefPtr objects associated with the network. Record these in a hash and add APIs for manipulating them. Signed-off-by: Daniel P. Berrang=C3=A9 --- src/conf/virnetworkobj.c | 303 +++++++++++++++++++++++++++++++++++++++ src/conf/virnetworkobj.h | 30 ++++ src/libvirt_private.syms | 5 + 3 files changed, 338 insertions(+) diff --git a/src/conf/virnetworkobj.c b/src/conf/virnetworkobj.c index e6b01388f5..935edcea57 100644 --- a/src/conf/virnetworkobj.c +++ b/src/conf/virnetworkobj.c @@ -58,6 +58,8 @@ struct _virNetworkObj { =20 /* Immutable pointer, self locking APIs */ virMacMapPtr macmap; + + virHashTablePtr ports; /* uuid -> virNetworkPortDefPtr */ }; =20 struct _virNetworkObjList { @@ -86,6 +88,17 @@ virNetworkObjOnceInit(void) =20 VIR_ONCE_GLOBAL_INIT(virNetworkObj) =20 +static int +virNetworkObjLoadAllPorts(virNetworkObjPtr net, + const char *stateDir); + + +static void +virNetworkObjPortFree(void *val, const void *key ATTRIBUTE_UNUSED) +{ + virNetworkPortDefFree(val); +} + virNetworkObjPtr virNetworkObjNew(void) { @@ -106,6 +119,10 @@ virNetworkObjNew(void) virBitmapSetBitExpand(obj->classIdMap, 2) < 0) goto error; =20 + if (!(obj->ports =3D virHashCreate(10, + virNetworkObjPortFree))) + goto error; + virObjectLock(obj); =20 return obj; @@ -458,6 +475,7 @@ virNetworkObjDispose(void *opaque) { virNetworkObjPtr obj =3D opaque; =20 + virHashFree(obj->ports); virNetworkDefFree(obj->def); virNetworkDefFree(obj->newDef); virBitmapFree(obj->classIdMap); @@ -1073,9 +1091,16 @@ virNetworkObjLoadAllState(virNetworkObjListPtr nets, continue; =20 obj =3D virNetworkLoadState(nets, stateDir, entry->d_name); + + if (obj && + virNetworkObjLoadAllPorts(obj, stateDir) < 0) { + virNetworkObjEndAPI(&obj); + goto cleanup; + } virNetworkObjEndAPI(&obj); } =20 + cleanup: VIR_DIR_CLOSE(dir); return ret; } @@ -1585,3 +1610,281 @@ virNetworkObjListPrune(virNetworkObjListPtr nets, virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, &data); virObjectRWUnlock(nets); } + + +static char * +virNetworkObjGetPortStatusDir(virNetworkObjPtr net, + const char *stateDir) +{ + char *ret; + ignore_value(virAsprintf(&ret, "%s/%s/ports", stateDir, net->def->name= )); + return ret; +} + +int +virNetworkObjAddPort(virNetworkObjPtr net, + virNetworkPortDefPtr portdef, + const char *stateDir) +{ + int ret =3D -1; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *dir =3D NULL; + + virUUIDFormat(portdef->uuid, uuidstr); + + if (virHashLookup(net->ports, uuidstr)) { + virReportError(VIR_ERR_NETWORK_PORT_EXIST, + _("Network port with UUID %s already exists"), + uuidstr); + goto cleanup; + } + + if (!(dir =3D virNetworkObjGetPortStatusDir(net, stateDir))) + goto cleanup; + + if (virHashAddEntry(net->ports, uuidstr, portdef) < 0) + goto cleanup; + + if (virNetworkPortDefSaveStatus(portdef, dir) < 0) { + virHashRemoveEntry(net->ports, uuidstr); + goto cleanup; + } + + ret =3D 0; + + cleanup: + return ret; +} + + +virNetworkPortDefPtr +virNetworkObjLookupPort(virNetworkObjPtr net, + const unsigned char *uuid) +{ + virNetworkPortDefPtr ret =3D NULL; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + virUUIDFormat(uuid, uuidstr); + + if (!(ret =3D virHashLookup(net->ports, uuidstr))) { + virReportError(VIR_ERR_NO_NETWORK_PORT, + _("Network port with UUID %s does not exist"), + uuidstr); + goto cleanup; + } + + cleanup: + return ret; +} + + +int +virNetworkObjDeletePort(virNetworkObjPtr net, + const unsigned char *uuid, + const char *stateDir) +{ + int ret =3D -1; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *dir =3D NULL; + virNetworkPortDefPtr portdef; + + virUUIDFormat(uuid, uuidstr); + + if (!(portdef =3D virHashLookup(net->ports, uuidstr))) { + virReportError(VIR_ERR_NO_NETWORK_PORT, + _("Network port with UUID %s does not exist"), + uuidstr); + goto cleanup; + } + + if (!(dir =3D virNetworkObjGetPortStatusDir(net, stateDir))) + goto cleanup; + + if (virNetworkPortDefDeleteStatus(portdef, dir) < 0) + goto cleanup; + + if (virHashRemoveEntry(net->ports, uuidstr) < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + VIR_FREE(dir); + return ret; +} + + +int +virNetworkObjDeleteAllPorts(virNetworkObjPtr net, + const char *stateDir) +{ + char *dir; + DIR *dh; + struct dirent *de; + int rc; + int ret =3D -1; + + if (!(dir =3D virNetworkObjGetPortStatusDir(net, stateDir))) + goto cleanup; + + if ((rc =3D virDirOpenIfExists(&dh, dir)) <=3D 0) { + ret =3D rc; + goto cleanup; + } + + while ((rc =3D virDirRead(dh, &de, dir)) > 0) { + char *file =3D NULL; + + if (!virFileStripSuffix(de->d_name, ".xml")) + continue; + + if (virAsprintf(&file, "%s/%s.xml", dir, de->d_name) < 0) + goto cleanup; + + if (unlink(file) < 0 && errno !=3D ENOENT) + VIR_WARN("Unable to delete %s", file); + + VIR_FREE(file); + } + + virHashRemoveAll(net->ports); + + ret =3D 0; + cleanup: + return ret; +} + + +typedef struct _virNetworkObjPortListExportData virNetworkObjPortListExpor= tData; +typedef virNetworkObjPortListExportData *virNetworkObjPortListExportDataPt= r; +struct _virNetworkObjPortListExportData { + virNetworkPtr net; + virNetworkDefPtr def; + virNetworkPortPtr *ports; + virNetworkPortListFilter filter; + int nports; + bool error; +}; + +static int +virNetworkObjPortListExportCallback(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virNetworkObjPortListExportDataPtr data =3D opaque; + virNetworkPortDefPtr def =3D payload; + virNetworkPortPtr port; + + if (data->error) + return 0; + + if (data->filter && + !data->filter(data->net->conn, data->def, def)) + goto cleanup; + + if (!data->ports) { + data->nports++; + goto cleanup; + } + + if (!(port =3D virGetNetworkPort(data->net, def->uuid))) { + data->error =3D true; + goto cleanup; + } + + data->ports[data->nports++] =3D port; + + cleanup: + return 0; +} + + +int +virNetworkObjPortListExport(virNetworkPtr net, + virNetworkObjPtr obj, + virNetworkPortPtr **ports, + virNetworkPortListFilter filter) +{ + virNetworkObjPortListExportData data =3D { + net, obj->def, NULL, filter, 0, false, + }; + int ret =3D -1; + + *ports =3D NULL; + + if (ports && VIR_ALLOC_N(data.ports, virHashSize(obj->ports) + 1) < 0) + goto cleanup; + + virHashForEach(obj->ports, virNetworkObjPortListExportCallback, &data); + + if (data.error) + goto cleanup; + + if (data.ports) { + /* trim the array to the final size */ + ignore_value(VIR_REALLOC_N(data.ports, data.nports + 1)); + *ports =3D data.ports; + data.ports =3D NULL; + } + + ret =3D data.nports; + cleanup: + while (data.ports && data.nports) + virObjectUnref(data.ports[--data.nports]); + + VIR_FREE(data.ports); + return ret; +} + + +static int +virNetworkObjLoadAllPorts(virNetworkObjPtr net, + const char *stateDir) +{ + char *dir; + DIR *dh =3D NULL; + struct dirent *de; + int ret =3D -1; + int rc; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virNetworkPortDefPtr portdef =3D NULL; + + if (!(dir =3D virNetworkObjGetPortStatusDir(net, stateDir))) + goto cleanup; + + if ((rc =3D virDirOpenIfExists(&dh, dir)) <=3D 0) { + ret =3D rc; + goto cleanup; + } + + while ((rc =3D virDirRead(dh, &de, dir)) > 0) { + char *file =3D NULL; + + if (!virFileStripSuffix(de->d_name, ".xml")) + continue; + + if (virAsprintf(&file, "%s/%s.xml", dir, de->d_name) < 0) + goto cleanup; + + portdef =3D virNetworkPortDefParseFile(file); + VIR_FREE(file); + file =3D NULL; + + if (!portdef) { + VIR_WARN("Cannot parse port %s", file); + continue; + } + + virUUIDFormat(portdef->uuid, uuidstr); + if (virHashAddEntry(net->ports, uuidstr, portdef) < 0) + goto cleanup; + + portdef =3D NULL; + } + + ret =3D 0; + cleanup: + VIR_DIR_CLOSE(dh); + virNetworkPortDefFree(portdef); + return ret; +} diff --git a/src/conf/virnetworkobj.h b/src/conf/virnetworkobj.h index 9c8f141cd9..6ee2550959 100644 --- a/src/conf/virnetworkobj.h +++ b/src/conf/virnetworkobj.h @@ -23,6 +23,7 @@ # include "internal.h" =20 # include "network_conf.h" +# include "virnetworkportdef.h" =20 typedef struct _virNetworkObj virNetworkObj; typedef virNetworkObj *virNetworkObjPtr; @@ -156,6 +157,35 @@ void virNetworkObjRemoveInactive(virNetworkObjListPtr nets, virNetworkObjPtr net); =20 +int +virNetworkObjAddPort(virNetworkObjPtr net, + virNetworkPortDefPtr portdef, + const char *stateDir); + +virNetworkPortDefPtr +virNetworkObjLookupPort(virNetworkObjPtr net, + const unsigned char *uuid); + +int +virNetworkObjDeletePort(virNetworkObjPtr net, + const unsigned char *uuid, + const char *stateDir); + +int +virNetworkObjDeleteAllPorts(virNetworkObjPtr net, + const char *stateDir); + +typedef bool +(*virNetworkPortListFilter)(virConnectPtr conn, + virNetworkDefPtr def, + virNetworkPortDefPtr portdef); + +int +virNetworkObjPortListExport(virNetworkPtr net, + virNetworkObjPtr obj, + virNetworkPortPtr **ports, + virNetworkPortListFilter filter); + int virNetworkObjSaveStatus(const char *statusDir, virNetworkObjPtr net) ATTRIBUTE_RETURN_CHECK; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5a7d19f6d7..16ab01ca38 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -991,9 +991,12 @@ virInterfaceObjSetActive; =20 =20 # conf/virnetworkobj.h +virNetworkObjAddPort; virNetworkObjAssignDef; virNetworkObjBridgeInUse; +virNetworkObjDeleteAllPorts; virNetworkObjDeleteConfig; +virNetworkObjDeletePort; virNetworkObjEndAPI; virNetworkObjFindByName; virNetworkObjFindByUUID; @@ -1016,9 +1019,11 @@ virNetworkObjListNumOfNetworks; virNetworkObjListPrune; virNetworkObjLoadAllConfigs; virNetworkObjLoadAllState; +virNetworkObjLookupPort; virNetworkObjMacMgrAdd; virNetworkObjMacMgrDel; virNetworkObjNew; +virNetworkObjPortListExport; virNetworkObjRemoveInactive; virNetworkObjReplacePersistentDef; virNetworkObjSaveStatus; --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list