mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
virGetDomain/Network require non-NULL name & UUID
This commit is contained in:
parent
d6db609d74
commit
ab1649d367
@ -1,3 +1,8 @@
|
||||
Tue Mar 06 17:02:12 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* src/hash.c: virGetDomain and virGetNetwork require that both
|
||||
name and UUID are non-NULL. (Patch from Rich Jones)
|
||||
|
||||
Tue Mar 06 16:52:12 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* include/libvirt/libvirt.h.in, python/libvir.c, src/driver.h
|
||||
|
162
src/hash.c
162
src/hash.c
@ -617,7 +617,7 @@ virHashError(virConnectPtr conn, virErrorNumber error, const char *info)
|
||||
return;
|
||||
|
||||
errmsg = __virErrorMsg(error, info);
|
||||
__virRaiseError(conn, NULL, VIR_FROM_NONE, error, VIR_ERR_ERROR,
|
||||
__virRaiseError(conn, NULL, NULL, VIR_FROM_NONE, error, VIR_ERR_ERROR,
|
||||
errmsg, info, NULL, 0, 0, errmsg, info);
|
||||
}
|
||||
|
||||
@ -636,6 +636,20 @@ virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
|
||||
return (virDomainFree(domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* virNetworkFreeName:
|
||||
* @network: a network object
|
||||
*
|
||||
* Destroy the network object, this is just used by the network hash callback.
|
||||
*
|
||||
* Returns 0 in case of success and -1 in case of failure.
|
||||
*/
|
||||
static int
|
||||
virNetworkFreeName(virNetworkPtr network, const char *name ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (virNetworkFree(network));
|
||||
}
|
||||
|
||||
/**
|
||||
* virGetConnect:
|
||||
*
|
||||
@ -660,6 +674,9 @@ virGetConnect(void) {
|
||||
ret->domains = virHashCreate(20);
|
||||
if (ret->domains == NULL)
|
||||
goto failed;
|
||||
ret->networks = virHashCreate(20);
|
||||
if (ret->networks == NULL)
|
||||
goto failed;
|
||||
ret->hashes_mux = xmlNewMutex();
|
||||
if (ret->hashes_mux == NULL)
|
||||
goto failed;
|
||||
@ -671,6 +688,8 @@ failed:
|
||||
if (ret != NULL) {
|
||||
if (ret->domains != NULL)
|
||||
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
|
||||
if (ret->networks != NULL)
|
||||
virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
|
||||
if (ret->hashes_mux != NULL)
|
||||
xmlFreeMutex(ret->hashes_mux);
|
||||
free(ret);
|
||||
@ -705,6 +724,8 @@ virFreeConnect(virConnectPtr conn) {
|
||||
|
||||
if (conn->domains != NULL)
|
||||
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
|
||||
if (conn->networks != NULL)
|
||||
virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
|
||||
if (conn->hashes_mux != NULL)
|
||||
xmlFreeMutex(conn->hashes_mux);
|
||||
free(conn);
|
||||
@ -714,8 +735,8 @@ virFreeConnect(virConnectPtr conn) {
|
||||
/**
|
||||
* virGetDomain:
|
||||
* @conn: the hypervisor connection
|
||||
* @name: pointer to the domain name or NULL
|
||||
* @uuid: pointer to the uuid or NULL
|
||||
* @name: pointer to the domain name
|
||||
* @uuid: pointer to the uuid
|
||||
*
|
||||
* Lookup if the domain is already registered for that connection,
|
||||
* if yes return a new pointer to it, if no allocate a new structure,
|
||||
@ -728,7 +749,7 @@ virDomainPtr
|
||||
virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
|
||||
virDomainPtr ret = NULL;
|
||||
|
||||
if ((!VIR_IS_CONNECT(conn)) || ((name == NULL) && (uuid == NULL)) ||
|
||||
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL) ||
|
||||
(conn->hashes_mux == NULL)) {
|
||||
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return(NULL);
|
||||
@ -893,6 +914,139 @@ done:
|
||||
xmlMutexUnlock(conn->hashes_mux);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* virGetNetwork:
|
||||
* @conn: the hypervisor connection
|
||||
* @name: pointer to the network name
|
||||
* @uuid: pointer to the uuid
|
||||
*
|
||||
* Lookup if the network is already registered for that connection,
|
||||
* if yes return a new pointer to it, if no allocate a new structure,
|
||||
* and register it in the table. In any case a corresponding call to
|
||||
* virFreeNetwork() is needed to not leak data.
|
||||
*
|
||||
* Returns a pointer to the network, or NULL in case of failure
|
||||
*/
|
||||
virNetworkPtr
|
||||
virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
|
||||
virNetworkPtr ret = NULL;
|
||||
|
||||
if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || (uuid == NULL) ||
|
||||
(conn->hashes_mux == NULL)) {
|
||||
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return(NULL);
|
||||
}
|
||||
xmlMutexLock(conn->hashes_mux);
|
||||
|
||||
/* TODO search by UUID first as they are better differenciators */
|
||||
|
||||
ret = (virNetworkPtr) virHashLookup(conn->networks, name);
|
||||
if (ret != NULL) {
|
||||
/* TODO check the UUID */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* not found, allocate a new one
|
||||
*/
|
||||
ret = (virNetworkPtr) malloc(sizeof(virNetwork));
|
||||
if (ret == NULL) {
|
||||
virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
|
||||
goto error;
|
||||
}
|
||||
memset(ret, 0, sizeof(virNetwork));
|
||||
ret->name = strdup(name);
|
||||
if (ret->name == NULL) {
|
||||
virHashError(conn, VIR_ERR_NO_MEMORY, _("allocating network"));
|
||||
goto error;
|
||||
}
|
||||
ret->magic = VIR_NETWORK_MAGIC;
|
||||
ret->conn = conn;
|
||||
if (uuid != NULL)
|
||||
memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
|
||||
|
||||
if (virHashAddEntry(conn->networks, name, ret) < 0) {
|
||||
virHashError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed to add network to connection hash table"));
|
||||
goto error;
|
||||
}
|
||||
conn->uses++;
|
||||
done:
|
||||
ret->uses++;
|
||||
xmlMutexUnlock(conn->hashes_mux);
|
||||
return(ret);
|
||||
|
||||
error:
|
||||
xmlMutexUnlock(conn->hashes_mux);
|
||||
if (ret != NULL) {
|
||||
if (ret->name != NULL)
|
||||
free(ret->name );
|
||||
free(ret);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* virFreeNetwork:
|
||||
* @conn: the hypervisor connection
|
||||
* @network: the network to release
|
||||
*
|
||||
* Release the given network, if the reference count drops to zero, then
|
||||
* the network is really freed.
|
||||
*
|
||||
* Returns the reference count or -1 in case of failure.
|
||||
*/
|
||||
int
|
||||
virFreeNetwork(virConnectPtr conn, virNetworkPtr network) {
|
||||
int ret = 0;
|
||||
|
||||
if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_NETWORK(network)) ||
|
||||
(network->conn != conn) || (conn->hashes_mux == NULL)) {
|
||||
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||
return(-1);
|
||||
}
|
||||
xmlMutexLock(conn->hashes_mux);
|
||||
|
||||
/*
|
||||
* decrement the count for the network
|
||||
*/
|
||||
network->uses--;
|
||||
ret = network->uses;
|
||||
if (ret > 0)
|
||||
goto done;
|
||||
|
||||
/* TODO search by UUID first as they are better differenciators */
|
||||
|
||||
if (virHashRemoveEntry(conn->networks, network->name, NULL) < 0) {
|
||||
virHashError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("network missing from connection hash table"));
|
||||
goto done;
|
||||
}
|
||||
network->magic = -1;
|
||||
if (network->name)
|
||||
free(network->name);
|
||||
free(network);
|
||||
|
||||
/*
|
||||
* decrement the count for the connection
|
||||
*/
|
||||
conn->uses--;
|
||||
if (conn->uses > 0)
|
||||
goto done;
|
||||
|
||||
if (conn->networks != NULL)
|
||||
virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
|
||||
if (conn->hashes_mux != NULL)
|
||||
xmlFreeMutex(conn->hashes_mux);
|
||||
free(conn);
|
||||
return(0);
|
||||
|
||||
done:
|
||||
xmlMutexUnlock(conn->hashes_mux);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
|
Loading…
Reference in New Issue
Block a user