virGetDomain/Network require non-NULL name & UUID

This commit is contained in:
Daniel P. Berrange 2007-03-06 22:06:14 +00:00
parent d6db609d74
commit ab1649d367
2 changed files with 163 additions and 4 deletions

View File

@ -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> 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 * include/libvirt/libvirt.h.in, python/libvir.c, src/driver.h

View File

@ -617,7 +617,7 @@ virHashError(virConnectPtr conn, virErrorNumber error, const char *info)
return; return;
errmsg = __virErrorMsg(error, info); 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); errmsg, info, NULL, 0, 0, errmsg, info);
} }
@ -636,6 +636,20 @@ virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
return (virDomainFree(domain)); 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: * virGetConnect:
* *
@ -660,6 +674,9 @@ virGetConnect(void) {
ret->domains = virHashCreate(20); ret->domains = virHashCreate(20);
if (ret->domains == NULL) if (ret->domains == NULL)
goto failed; goto failed;
ret->networks = virHashCreate(20);
if (ret->networks == NULL)
goto failed;
ret->hashes_mux = xmlNewMutex(); ret->hashes_mux = xmlNewMutex();
if (ret->hashes_mux == NULL) if (ret->hashes_mux == NULL)
goto failed; goto failed;
@ -671,6 +688,8 @@ failed:
if (ret != NULL) { if (ret != NULL) {
if (ret->domains != NULL) if (ret->domains != NULL)
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName); virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->networks != NULL)
virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
if (ret->hashes_mux != NULL) if (ret->hashes_mux != NULL)
xmlFreeMutex(ret->hashes_mux); xmlFreeMutex(ret->hashes_mux);
free(ret); free(ret);
@ -705,6 +724,8 @@ virFreeConnect(virConnectPtr conn) {
if (conn->domains != NULL) if (conn->domains != NULL)
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName); virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->networks != NULL)
virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
if (conn->hashes_mux != NULL) if (conn->hashes_mux != NULL)
xmlFreeMutex(conn->hashes_mux); xmlFreeMutex(conn->hashes_mux);
free(conn); free(conn);
@ -714,8 +735,8 @@ virFreeConnect(virConnectPtr conn) {
/** /**
* virGetDomain: * virGetDomain:
* @conn: the hypervisor connection * @conn: the hypervisor connection
* @name: pointer to the domain name or NULL * @name: pointer to the domain name
* @uuid: pointer to the uuid or NULL * @uuid: pointer to the uuid
* *
* Lookup if the domain is already registered for that connection, * Lookup if the domain is already registered for that connection,
* if yes return a new pointer to it, if no allocate a new structure, * 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) { virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
virDomainPtr ret = NULL; 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)) { (conn->hashes_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL); return(NULL);
@ -893,6 +914,139 @@ done:
xmlMutexUnlock(conn->hashes_mux); xmlMutexUnlock(conn->hashes_mux);
return(ret); 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: * Local variables:
* indent-tabs-mode: nil * indent-tabs-mode: nil