mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
conf: support recording ports against virNetworkObjPtr
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. Reviewed-by: Laine Stump <laine@laine.org> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
c2dd9ddf7b
commit
771b361e5b
@ -58,6 +58,8 @@ struct _virNetworkObj {
|
||||
|
||||
/* Immutable pointer, self locking APIs */
|
||||
virMacMapPtr macmap;
|
||||
|
||||
virHashTablePtr ports; /* uuid -> virNetworkPortDefPtr */
|
||||
};
|
||||
|
||||
struct _virNetworkObjList {
|
||||
@ -86,6 +88,17 @@ virNetworkObjOnceInit(void)
|
||||
|
||||
VIR_ONCE_GLOBAL_INIT(virNetworkObj);
|
||||
|
||||
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;
|
||||
|
||||
if (!(obj->ports = virHashCreate(10,
|
||||
virNetworkObjPortFree)))
|
||||
goto error;
|
||||
|
||||
virObjectLock(obj);
|
||||
|
||||
return obj;
|
||||
@ -458,6 +475,7 @@ virNetworkObjDispose(void *opaque)
|
||||
{
|
||||
virNetworkObjPtr obj = opaque;
|
||||
|
||||
virHashFree(obj->ports);
|
||||
virNetworkDefFree(obj->def);
|
||||
virNetworkDefFree(obj->newDef);
|
||||
virBitmapFree(obj->classIdMap);
|
||||
@ -1072,9 +1090,16 @@ virNetworkObjLoadAllState(virNetworkObjListPtr nets,
|
||||
continue;
|
||||
|
||||
obj = virNetworkLoadState(nets, stateDir, entry->d_name);
|
||||
|
||||
if (obj &&
|
||||
virNetworkObjLoadAllPorts(obj, stateDir) < 0) {
|
||||
virNetworkObjEndAPI(&obj);
|
||||
goto cleanup;
|
||||
}
|
||||
virNetworkObjEndAPI(&obj);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_DIR_CLOSE(dir);
|
||||
return ret;
|
||||
}
|
||||
@ -1584,3 +1609,281 @@ virNetworkObjListPrune(virNetworkObjListPtr nets,
|
||||
virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, &data);
|
||||
virObjectRWUnlock(nets);
|
||||
}
|
||||
|
||||
|
||||
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 = -1;
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
char *dir = 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 = 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 = 0;
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
virNetworkPortDefPtr
|
||||
virNetworkObjLookupPort(virNetworkObjPtr net,
|
||||
const unsigned char *uuid)
|
||||
{
|
||||
virNetworkPortDefPtr ret = NULL;
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
|
||||
virUUIDFormat(uuid, uuidstr);
|
||||
|
||||
if (!(ret = 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 = -1;
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
char *dir = NULL;
|
||||
virNetworkPortDefPtr portdef;
|
||||
|
||||
virUUIDFormat(uuid, uuidstr);
|
||||
|
||||
if (!(portdef = virHashLookup(net->ports, uuidstr))) {
|
||||
virReportError(VIR_ERR_NO_NETWORK_PORT,
|
||||
_("Network port with UUID %s does not exist"),
|
||||
uuidstr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(dir = virNetworkObjGetPortStatusDir(net, stateDir)))
|
||||
goto cleanup;
|
||||
|
||||
if (virNetworkPortDefDeleteStatus(portdef, dir) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virHashRemoveEntry(net->ports, uuidstr) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 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 = -1;
|
||||
|
||||
if (!(dir = virNetworkObjGetPortStatusDir(net, stateDir)))
|
||||
goto cleanup;
|
||||
|
||||
if ((rc = virDirOpenIfExists(&dh, dir)) <= 0) {
|
||||
ret = rc;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while ((rc = virDirRead(dh, &de, dir)) > 0) {
|
||||
char *file = NULL;
|
||||
|
||||
if (!virStringStripSuffix(de->d_name, ".xml"))
|
||||
continue;
|
||||
|
||||
if (virAsprintf(&file, "%s/%s.xml", dir, de->d_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (unlink(file) < 0 && errno != ENOENT)
|
||||
VIR_WARN("Unable to delete %s", file);
|
||||
|
||||
VIR_FREE(file);
|
||||
}
|
||||
|
||||
virHashRemoveAll(net->ports);
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _virNetworkObjPortListExportData virNetworkObjPortListExportData;
|
||||
typedef virNetworkObjPortListExportData *virNetworkObjPortListExportDataPtr;
|
||||
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 = opaque;
|
||||
virNetworkPortDefPtr def = 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 = virGetNetworkPort(data->net, def->uuid))) {
|
||||
data->error = true;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
data->ports[data->nports++] = port;
|
||||
|
||||
cleanup:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virNetworkObjPortListExport(virNetworkPtr net,
|
||||
virNetworkObjPtr obj,
|
||||
virNetworkPortPtr **ports,
|
||||
virNetworkPortListFilter filter)
|
||||
{
|
||||
virNetworkObjPortListExportData data = {
|
||||
net, obj->def, NULL, filter, 0, false,
|
||||
};
|
||||
int ret = -1;
|
||||
|
||||
*ports = 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 = data.ports;
|
||||
data.ports = NULL;
|
||||
}
|
||||
|
||||
ret = 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 = NULL;
|
||||
struct dirent *de;
|
||||
int ret = -1;
|
||||
int rc;
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virNetworkPortDefPtr portdef = NULL;
|
||||
|
||||
if (!(dir = virNetworkObjGetPortStatusDir(net, stateDir)))
|
||||
goto cleanup;
|
||||
|
||||
if ((rc = virDirOpenIfExists(&dh, dir)) <= 0) {
|
||||
ret = rc;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while ((rc = virDirRead(dh, &de, dir)) > 0) {
|
||||
char *file = NULL;
|
||||
|
||||
if (!virStringStripSuffix(de->d_name, ".xml"))
|
||||
continue;
|
||||
|
||||
if (virAsprintf(&file, "%s/%s.xml", dir, de->d_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
portdef = virNetworkPortDefParseFile(file);
|
||||
VIR_FREE(file);
|
||||
file = 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 = NULL;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_DIR_CLOSE(dh);
|
||||
virNetworkPortDefFree(portdef);
|
||||
return ret;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "internal.h"
|
||||
|
||||
#include "network_conf.h"
|
||||
#include "virnetworkportdef.h"
|
||||
|
||||
typedef struct _virNetworkObj virNetworkObj;
|
||||
typedef virNetworkObj *virNetworkObjPtr;
|
||||
@ -155,6 +156,39 @@ void
|
||||
virNetworkObjRemoveInactive(virNetworkObjListPtr nets,
|
||||
virNetworkObjPtr net);
|
||||
|
||||
int
|
||||
virNetworkObjAddPort(virNetworkObjPtr net,
|
||||
virNetworkPortDefPtr portdef,
|
||||
const char *stateDir);
|
||||
|
||||
char *
|
||||
virNetworkObjGetPortStatusDir(virNetworkObjPtr net,
|
||||
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;
|
||||
|
@ -1031,9 +1031,12 @@ virInterfaceObjSetActive;
|
||||
|
||||
|
||||
# conf/virnetworkobj.h
|
||||
virNetworkObjAddPort;
|
||||
virNetworkObjAssignDef;
|
||||
virNetworkObjBridgeInUse;
|
||||
virNetworkObjDeleteAllPorts;
|
||||
virNetworkObjDeleteConfig;
|
||||
virNetworkObjDeletePort;
|
||||
virNetworkObjEndAPI;
|
||||
virNetworkObjFindByName;
|
||||
virNetworkObjFindByUUID;
|
||||
@ -1044,6 +1047,7 @@ virNetworkObjGetFloorSum;
|
||||
virNetworkObjGetMacMap;
|
||||
virNetworkObjGetNewDef;
|
||||
virNetworkObjGetPersistentDef;
|
||||
virNetworkObjGetPortStatusDir;
|
||||
virNetworkObjGetRadvdPid;
|
||||
virNetworkObjIsActive;
|
||||
virNetworkObjIsAutostart;
|
||||
@ -1056,9 +1060,11 @@ virNetworkObjListNumOfNetworks;
|
||||
virNetworkObjListPrune;
|
||||
virNetworkObjLoadAllConfigs;
|
||||
virNetworkObjLoadAllState;
|
||||
virNetworkObjLookupPort;
|
||||
virNetworkObjMacMgrAdd;
|
||||
virNetworkObjMacMgrDel;
|
||||
virNetworkObjNew;
|
||||
virNetworkObjPortListExport;
|
||||
virNetworkObjRemoveInactive;
|
||||
virNetworkObjReplacePersistentDef;
|
||||
virNetworkObjSaveStatus;
|
||||
|
Loading…
Reference in New Issue
Block a user