* TODO src/hash.[ch] src/internal.h src/libvirt.c src/xend_internal.c

src/xs_internal.c: implementing domain pointers unification, thread
  safety and reference counting for domain and connections, this was
  the last critical change needed before making further progresses at
  the API level. Still a couple fo things TODO for this, unification
  at the Python level and adding UUID to hash. All domain/connect alloc
  and free routines are now centralized in hash.c
* docs/APIchunk1.html docs/libvirt-api.xml docs/libvirt-refs.xml
  docs/html/libvirt-libvirt.html: regenerated the docs, that doesn't
  change the API.
Daniel
This commit is contained in:
Daniel Veillard 2006-04-09 13:11:22 +00:00
parent 1ea832d65b
commit 572806a99b
12 changed files with 354 additions and 142 deletions

View File

@ -1,3 +1,16 @@
Sun Apr 9 13:10:34 EDT 2006 Daniel Veillard <veillard@redhat.com>
* TODO src/hash.[ch] src/internal.h src/libvirt.c src/xend_internal.c
src/xs_internal.c: implementing domain pointers unification, thread
safety and reference counting for domain and connections, this was
the last critical change needed before making further progresses at
the API level. Still a couple fo things TODO for this, unification
at the Python level and adding UUID to hash. All domain/connect alloc
and free routines are now centralized in hash.c
* docs/APIchunk1.html docs/libvirt-api.xml docs/libvirt-refs.xml
docs/html/libvirt-libvirt.html: regenerated the docs, that doesn't
change the API.
Thu Apr 6 11:32:46 CEST 2006 Karel Zak <kzak@redhat.com> Thu Apr 6 11:32:46 CEST 2006 Karel Zak <kzak@redhat.com>
* src/virsh.c: use stdout for standard outputs, improve * src/virsh.c: use stdout for standard outputs, improve

6
TODO
View File

@ -1,6 +1,3 @@
Absolute TODOs:
- thread protection, reentrancy, refcounting, etc ...
TODO: TODO:
- Create() API, how do we best keep flexibility and allow various - Create() API, how do we best keep flexibility and allow various
specific environment and space for evolution (VMX) specific environment and space for evolution (VMX)
@ -12,6 +9,8 @@ TODO:
to return a non-None object to return a non-None object
- Add uuid to XML format - Add uuid to XML format
- add error handling hooks at the python level - add error handling hooks at the python level
- object unicity for domains at the Python level
- UUID lookup in hash.c
virsh TODO: virsh TODO:
- decide where will be default directory for domains configurations (/etc/xen/domains/* ?) - decide where will be default directory for domains configurations (/etc/xen/domains/* ?)
@ -48,3 +47,4 @@ Done:
- UUID based lookup and naming - UUID based lookup and naming
- Error API similar to libxml2 structured API - Error API similar to libxml2 structured API
- extract error messages from the Xend rpc - extract error messages from the Xend rpc
- thread protection, reentrancy, refcounting, etc ...

View File

@ -145,7 +145,8 @@
<a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br /> <a href="html/libvirt-libvirt.html#virDomainSave">virDomainSave</a><br />
</dd></dl><h2>Letter k:</h2><dl><dt>kept</dt><dd><a href="html/libvirt-libvirt.html#virDomainFree">virDomainFree</a><br /> </dd></dl><h2>Letter k:</h2><dl><dt>kept</dt><dd><a href="html/libvirt-libvirt.html#virDomainFree">virDomainFree</a><br />
</dd><dt>kernel</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br /> </dd><dt>kernel</dt><dd><a href="html/libvirt-libvirt.html#_virDomainKernel">_virDomainKernel</a><br />
</dd><dt>kilobytes</dt><dd><a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br /> </dd><dt>kilobytes</dt><dd><a href="html/libvirt-libvirt.html#_virNodeInfo">_virNodeInfo</a><br />
<a href="html/libvirt-libvirt.html#virDomainGetMaxMemory">virDomainGetMaxMemory</a><br />
<a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br /> <a href="html/libvirt-libvirt.html#virDomainSetMaxMemory">virDomainSetMaxMemory</a><br />
</dd><dt>knowing</dt><dd><a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br /> </dd><dt>knowing</dt><dd><a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
</dd></dl><h2>Letter l:</h2><dl><dt>lack</dt><dd><a href="html/libvirt-libvirt.html#virConnectGetVersion">virConnectGetVersion</a><br /> </dd></dl><h2>Letter l:</h2><dl><dt>lack</dt><dd><a href="html/libvirt-libvirt.html#virConnectGetVersion">virConnectGetVersion</a><br />
@ -196,7 +197,6 @@
<a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br /> <a href="html/libvirt-libvirt.html#virDomainShutdown">virDomainShutdown</a><br />
<a href="html/libvirt-libvirt.html#virDomainSuspend">virDomainSuspend</a><br /> <a href="html/libvirt-libvirt.html#virDomainSuspend">virDomainSuspend</a><br />
<a href="html/libvirt-virterror.html#virGetLastError">virGetLastError</a><br /> <a href="html/libvirt-virterror.html#virGetLastError">virGetLastError</a><br />
</dd><dt>megabytes</dt><dd><a href="html/libvirt-libvirt.html#_virNodeInfo">_virNodeInfo</a><br />
</dd><dt>mem</dt><dd><a href="html/libvirt-libvirt.html#_virNodeInfo">_virNodeInfo</a><br /> </dd><dt>mem</dt><dd><a href="html/libvirt-libvirt.html#_virNodeInfo">_virNodeInfo</a><br />
</dd><dt>memory</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br /> </dd><dt>memory</dt><dd><a href="html/libvirt-libvirt.html#_virDomainInfo">_virDomainInfo</a><br />
<a href="html/libvirt-libvirt.html#_virNodeInfo">_virNodeInfo</a><br /> <a href="html/libvirt-libvirt.html#_virNodeInfo">_virNodeInfo</a><br />

View File

@ -97,7 +97,7 @@ The content of this structure is not made public by the API.
} }
</pre><h3><a name="virNodeInfo" id="virNodeInfo">Structure virNodeInfo</a></h3><pre class="programlisting">Structure virNodeInfo<br />struct _virNodeInfo { </pre><h3><a name="virNodeInfo" id="virNodeInfo">Structure virNodeInfo</a></h3><pre class="programlisting">Structure virNodeInfo<br />struct _virNodeInfo {
charmodel[32] model : string indicating the CPU model charmodel[32] model : string indicating the CPU model
unsigned long memory : memory size in megabytes unsigned long memory : memory size in kilobytes
unsigned int cpus : the number of active CPUs unsigned int cpus : the number of active CPUs
unsigned int mhz : expected CPU frequency unsigned int mhz : expected CPU frequency
unsigned int nodes : the number of NUMA cell, 1 for uniform unsigned int nodes : the number of NUMA cell, 1 for uniform

View File

@ -237,7 +237,7 @@
<typedef name='virErrorPtr' file='virterror' type='virError *'/> <typedef name='virErrorPtr' file='virterror' type='virError *'/>
<struct name='virNodeInfo' file='libvirt' type='struct _virNodeInfo'> <struct name='virNodeInfo' file='libvirt' type='struct _virNodeInfo'>
<field name='model' type='charmodel[32]' info=' string indicating the CPU model'/> <field name='model' type='charmodel[32]' info=' string indicating the CPU model'/>
<field name='memory' type='unsigned long' info=' memory size in megabytes'/> <field name='memory' type='unsigned long' info=' memory size in kilobytes'/>
<field name='cpus' type='unsigned int' info=' the number of active CPUs'/> <field name='cpus' type='unsigned int' info=' the number of active CPUs'/>
<field name='mhz' type='unsigned int' info=' expected CPU frequency'/> <field name='mhz' type='unsigned int' info=' expected CPU frequency'/>
<field name='nodes' type='unsigned int' info=' the number of NUMA cell, 1 for uniform mem access'/> <field name='nodes' type='unsigned int' info=' the number of NUMA cell, 1 for uniform mem access'/>

View File

@ -1232,6 +1232,7 @@
<ref name='_virDomainKernel'/> <ref name='_virDomainKernel'/>
</word> </word>
<word name='kilobytes'> <word name='kilobytes'>
<ref name='_virNodeInfo'/>
<ref name='virDomainGetMaxMemory'/> <ref name='virDomainGetMaxMemory'/>
<ref name='virDomainSetMaxMemory'/> <ref name='virDomainSetMaxMemory'/>
</word> </word>
@ -1320,9 +1321,6 @@
<ref name='virDomainSuspend'/> <ref name='virDomainSuspend'/>
<ref name='virGetLastError'/> <ref name='virGetLastError'/>
</word> </word>
<word name='megabytes'>
<ref name='_virNodeInfo'/>
</word>
<word name='mem'> <word name='mem'>
<ref name='_virNodeInfo'/> <ref name='_virNodeInfo'/>
</word> </word>

View File

@ -1,5 +1,5 @@
/* /*
* hash.c: chained hash tables * hash.c: chained hash tables for domain and domain/connection deallocations
* *
* Reference: Your favorite introductory book on algorithms * Reference: Your favorite introductory book on algorithms
* *
@ -15,10 +15,13 @@
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
* *
* Author: breese@users.sourceforge.net * Author: breese@users.sourceforge.net
* Daniel Veillard <veillard@redhat.com>
*/ */
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <libxml/threads.h>
#include "internal.h"
#include "hash.h" #include "hash.h"
#define MAX_HASH_LEN 8 #define MAX_HASH_LEN 8
@ -469,3 +472,254 @@ virHashRemoveEntry(virHashTablePtr table, const char *name,
return (-1); return (-1);
} }
} }
/************************************************************************
* *
* Domain and Connections allocations *
* *
************************************************************************/
/**
* virHashError:
* @conn: the connection if available
* @error: the error noumber
* @info: extra information string
*
* Handle an error at the connection level
*/
static void
virHashError(virConnectPtr conn, virErrorNumber error, const char *info)
{
const char *errmsg;
if (error == VIR_ERR_OK)
return;
errmsg = __virErrorMsg(error, info);
__virRaiseError(conn, NULL, VIR_FROM_NONE, error, VIR_ERR_ERROR,
errmsg, info, NULL, 0, 0, errmsg, info);
}
/**
* virDomainFreeName:
* @domain: a domain object
*
* Destroy the domain object, this is just used by the domain hash callback.
*
* Returns 0 in case of success and -1 in case of failure.
*/
static int
virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
{
return (virDomainFree(domain));
}
/**
* virGetConnect:
*
* Allocates a new hypervisor connection structure
*
* Returns a new pointer or NULL in case of error.
*/
virConnectPtr
virGetConnect(void) {
virConnectPtr ret;
ret = (virConnectPtr) malloc(sizeof(virConnect));
if (ret == NULL) {
virHashError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection");
goto failed;
}
memset(ret, 0, sizeof(virConnect));
ret->magic = VIR_CONNECT_MAGIC;
ret->nb_drivers = 0;
ret->domains = virHashCreate(20);
if (ret->domains == NULL)
goto failed;
ret->domains_mux = xmlNewMutex();
if (ret->domains_mux == NULL)
goto failed;
ret->uses = 1;
return(ret);
failed:
if (ret != NULL) {
if (ret->domains != NULL)
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->domains_mux != NULL)
xmlFreeMutex(ret->domains_mux);
free(ret);
}
return(NULL);
}
/**
* virFreeConnect:
* @conn: the hypervisor connection
*
* Release the connection. if the use count drops to zero, the structure is
* actually freed.
*
* Returns the reference count or -1 in case of failure.
*/
int
virFreeConnect(virConnectPtr conn) {
int ret;
if ((!VIR_IS_CONNECT(conn)) || (conn->domains_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
xmlMutexLock(conn->domains_mux);
conn->uses--;
ret = conn->uses;
if (ret > 0) {
xmlMutexUnlock(conn->domains_mux);
return(ret);
}
if (conn->domains != NULL)
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->domains_mux != NULL)
xmlFreeMutex(conn->domains_mux);
free(conn);
return(0);
}
/**
* virGetDomain:
* @conn: the hypervisor connection
* @name: pointer to the domain name or NULL
* @uuid: pointer to the uuid or NULL
*
* Lookup if the domain 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
* virFreeDomain() is needed to not leak data.
*
* Returns a pointer to the domain, or NULL in case of failure
*/
virDomainPtr
virGetDomain(virConnectPtr conn, const char *name, const char *uuid) {
virDomainPtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || ((name == NULL) && (uuid == NULL)) ||
(conn->domains_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
xmlMutexLock(conn->domains_mux);
/* TODO search by UUID first as they are better differenciators */
ret = (virDomainPtr) virHashLookup(conn->domains, name);
if (ret != NULL) {
/* TODO check the UUID */
goto done;
}
/*
* not found, allocate a new one
*/
ret = (virDomainPtr) malloc(sizeof(virDomain));
if (ret == NULL) {
virHashError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
goto error;
}
memset(ret, 0, sizeof(virDomain));
ret->name = strdup(name);
if (ret->name == NULL) {
virHashError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
goto error;
}
ret->magic = VIR_DOMAIN_MAGIC;
ret->conn = conn;
if (uuid != NULL)
memcpy(&(ret->uuid[0]), uuid, 16);
if (virHashAddEntry(conn->domains, name, ret) < 0) {
virHashError(conn, VIR_ERR_INTERNAL_ERROR,
"Failed to add domain to connectio hash table");
goto error;
}
conn->uses++;
done:
ret->uses++;
xmlMutexUnlock(conn->domains_mux);
return(ret);
error:
xmlMutexUnlock(conn->domains_mux);
if (ret != NULL) {
if (ret->name != NULL)
free(ret->name );
free(ret);
}
return(NULL);
}
/**
* virFreeDomain:
* @conn: the hypervisor connection
* @domain: the domain to release
*
* Release the given domain, if the reference count drops to zero, then
* the domain is really freed.
*
* Returns the reference count or -1 in case of failure.
*/
int
virFreeDomain(virConnectPtr conn, virDomainPtr domain) {
int ret = 0;
if ((!VIR_IS_CONNECT(conn)) || (!VIR_IS_CONNECTED_DOMAIN(domain)) ||
(domain->conn != conn) || (conn->domains_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
xmlMutexLock(conn->domains_mux);
/*
* decrement the count for the domain
*/
domain->uses--;
ret = domain->uses;
if (ret > 0)
goto done;
/* TODO search by UUID first as they are better differenciators */
if (virHashRemoveEntry(conn->domains, domain->name, NULL) < 0) {
virHashError(conn, VIR_ERR_INTERNAL_ERROR,
"domain missing from connection hash table");
goto done;
}
domain->magic = -1;
domain->handle = -1;
if (domain->path != NULL)
free(domain->path);
if (domain->name)
free(domain->name);
free(domain);
/*
* decrement the count for the connection
*/
conn->uses--;
if (conn->uses > 0)
goto done;
if (conn->domains != NULL)
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->domains_mux != NULL)
xmlFreeMutex(conn->domains_mux);
free(conn);
return(0);
done:
xmlMutexUnlock(conn->domains_mux);
return(ret);
}

View File

@ -1,11 +1,12 @@
/* /*
* Summary: Chained hash tables * Summary: Chained hash tables and domain/connections handling
* Description: This module implements the hash table support used in * Description: This module implements the hash table and allocation and
* various places in the library. * deallocation of domains and connections
* *
* Copy: Copyright (C) 2005 Red Hat, Inc. * Copy: Copyright (C) 2005 Red Hat, Inc.
* *
* Author: Bjorn Reese <bjorn.reese@systematic.dk> * Author: Bjorn Reese <bjorn.reese@systematic.dk>
* Daniel Veillard <veillard@redhat.com>
*/ */
#ifndef __VIR_HASH_H__ #ifndef __VIR_HASH_H__
@ -18,8 +19,8 @@ extern "C" {
/* /*
* The hash table. * The hash table.
*/ */
typedef struct _virHashTable virHashTable; typedef struct _virHashTable virHashTable;
typedef virHashTable *virHashTablePtr; typedef virHashTable *virHashTablePtr;
/* /*
* function types: * function types:
@ -32,35 +33,34 @@ extern "C" {
* *
* Callback to free data from a hash. * Callback to free data from a hash.
*/ */
typedef void (*virHashDeallocator) (void *payload, char *name); typedef void (*virHashDeallocator) (void *payload, char *name);
/* /*
* Constructor and destructor. * Constructor and destructor.
*/ */
virHashTablePtr virHashCreate(int size); virHashTablePtr virHashCreate(int size);
void void virHashFree(virHashTablePtr table, virHashDeallocator f);
virHashFree(virHashTablePtr table, virHashDeallocator f); int virHashSize(virHashTablePtr table);
int virHashSize(virHashTablePtr table);
/* /*
* Add a new entry to the hash table. * Add a new entry to the hash table.
*/ */
int virHashAddEntry(virHashTablePtr table, int virHashAddEntry(virHashTablePtr table,
const char *name, void *userdata); const char *name, void *userdata);
int virHashUpdateEntry(virHashTablePtr table, int virHashUpdateEntry(virHashTablePtr table,
const char *name, const char *name,
void *userdata, virHashDeallocator f); void *userdata, virHashDeallocator f);
/* /*
* Remove an entry from the hash table. * Remove an entry from the hash table.
*/ */
int virHashRemoveEntry(virHashTablePtr table, int virHashRemoveEntry(virHashTablePtr table,
const char *name, virHashDeallocator f); const char *name, virHashDeallocator f);
/* /*
* Retrieve the userdata. * Retrieve the userdata.
*/ */
void *virHashLookup(virHashTablePtr table, const char *name); void *virHashLookup(virHashTablePtr table, const char *name);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -94,6 +94,7 @@ extern "C" {
struct _virConnect { struct _virConnect {
unsigned int magic; /* specific value to check */ unsigned int magic; /* specific value to check */
int uses; /* reference count */
/* the list of available drivers for that connection */ /* the list of available drivers for that connection */
virDriverPtr drivers[MAX_DRIVERS]; virDriverPtr drivers[MAX_DRIVERS];
int nb_drivers; int nb_drivers;
@ -137,6 +138,7 @@ enum {
*/ */
struct _virDomain { struct _virDomain {
unsigned int magic; /* specific value to check */ unsigned int magic; /* specific value to check */
int uses; /* reference count */
virConnectPtr conn; /* pointer back to the connection */ virConnectPtr conn; /* pointer back to the connection */
char *name; /* the domain external name */ char *name; /* the domain external name */
char *path; /* the domain internal path */ char *path; /* the domain internal path */
@ -152,6 +154,11 @@ char *virDomainGetVM(virDomainPtr domain);
char *virDomainGetVMInfo(virDomainPtr domain, char *virDomainGetVMInfo(virDomainPtr domain,
const char *vm, const char *name); const char *vm, const char *name);
/************************************************************************
* *
* API for error handling *
* *
************************************************************************/
void __virRaiseError(virConnectPtr conn, void __virRaiseError(virConnectPtr conn,
virDomainPtr dom, virDomainPtr dom,
int domain, int domain,
@ -163,6 +170,20 @@ void __virRaiseError(virConnectPtr conn,
int int1, int int2, const char *msg, ...); int int1, int int2, const char *msg, ...);
const char *__virErrorMsg(virErrorNumber error, const char *info); const char *__virErrorMsg(virErrorNumber error, const char *info);
/************************************************************************
* *
* API for domain/connections (de)allocations *
* *
************************************************************************/
virConnectPtr virGetConnect (void);
int virFreeConnect (virConnectPtr conn);
virDomainPtr virGetDomain (virConnectPtr conn,
const char *name,
const char *uuid);
int virFreeDomain (virConnectPtr conn,
virDomainPtr domain);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -25,7 +25,6 @@
#include "xen_internal.h" #include "xen_internal.h"
#include "xend_internal.h" #include "xend_internal.h"
#include "xs_internal.h" #include "xs_internal.h"
#include "hash.h"
#include "xml.h" #include "xml.h"
@ -36,8 +35,6 @@
* - memory wrappers for malloc/free ? * - memory wrappers for malloc/free ?
*/ */
static int virDomainFreeName(virDomainPtr domain, const char *name);
static virDriverPtr virDriverTab[MAX_DRIVERS]; static virDriverPtr virDriverTab[MAX_DRIVERS];
static int initialized = 0; static int initialized = 0;
@ -222,14 +219,11 @@ virConnectOpen(const char *name)
if (!initialized) if (!initialized)
virInitialize(); virInitialize();
ret = (virConnectPtr) malloc(sizeof(virConnect)); ret = virGetConnect();
if (ret == NULL) { if (ret == NULL) {
virLibConnError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection"); virLibConnError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection");
goto failed; goto failed;
} }
memset(ret, 0, sizeof(virConnect));
ret->magic = VIR_CONNECT_MAGIC;
ret->nb_drivers = 0;
for (i = 0;i < MAX_DRIVERS;i++) { for (i = 0;i < MAX_DRIVERS;i++) {
if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) { if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) {
@ -252,14 +246,6 @@ virConnectOpen(const char *name)
goto failed; goto failed;
} }
ret->domains = virHashCreate(20);
if (ret->domains == NULL)
goto failed;
ret->domains_mux = xmlNewMutex();
if (ret->domains_mux == NULL)
goto failed;
ret->flags = 0;
return (ret); return (ret);
failed: failed:
@ -268,11 +254,7 @@ failed:
if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL)) if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL))
ret->drivers[i]->close(ret); ret->drivers[i]->close(ret);
} }
if (ret->domains != NULL) virFreeConnect(ret);
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->domains_mux != NULL)
xmlFreeMutex(ret->domains_mux);
free(ret);
} }
return (NULL); return (NULL);
} }
@ -296,14 +278,11 @@ virConnectOpenReadOnly(const char *name)
if (!initialized) if (!initialized)
virInitialize(); virInitialize();
ret = (virConnectPtr) malloc(sizeof(virConnect)); ret = virGetConnect();
if (ret == NULL) { if (ret == NULL) {
virLibConnError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection"); virLibConnError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection");
goto failed; goto failed;
} }
memset(ret, 0, sizeof(virConnect));
ret->magic = VIR_CONNECT_MAGIC;
ret->nb_drivers = 0;
for (i = 0;i < MAX_DRIVERS;i++) { for (i = 0;i < MAX_DRIVERS;i++) {
if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) { if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) {
@ -322,13 +301,6 @@ virConnectOpenReadOnly(const char *name)
virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name); virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
goto failed; goto failed;
} }
ret->domains = virHashCreate(20);
if (ret->domains == NULL)
goto failed;
ret->domains_mux = xmlNewMutex();
if (ret->domains_mux == NULL)
goto failed;
ret->flags = VIR_CONNECT_RO; ret->flags = VIR_CONNECT_RO;
return (ret); return (ret);
@ -339,29 +311,11 @@ failed:
if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL)) if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL))
ret->drivers[i]->close(ret); ret->drivers[i]->close(ret);
} }
if (ret->domains != NULL) virFreeConnect(ret);
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->domains_mux != NULL)
xmlFreeMutex(ret->domains_mux);
free(ret);
} }
return (NULL); return (NULL);
} }
/**
* virDomainFreeName:
* @domain: a domain object
*
* Destroy the domain object, this is just used by the domain hash callback.
*
* Returns 0 in case of success and -1 in case of failure.
*/
static int
virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
{
return (virDomainFree(domain));
}
/** /**
* virConnectClose: * virConnectClose:
* @conn: pointer to the hypervisor connection * @conn: pointer to the hypervisor connection
@ -376,20 +330,10 @@ virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
int int
virConnectClose(virConnectPtr conn) virConnectClose(virConnectPtr conn)
{ {
int i;
if (!VIR_IS_CONNECT(conn)) if (!VIR_IS_CONNECT(conn))
return (-1); return (-1);
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName); if (virFreeConnect(conn) < 0)
conn->domains = NULL; return (-1);
xmlFreeMutex(conn->domains_mux);
conn->domains_mux = NULL;
for (i = 0;i < conn->nb_drivers;i++) {
if ((conn->drivers[i] != NULL) && (conn->drivers[i]->close != NULL))
conn->drivers[i]->close(conn);
}
conn->magic = -1;
free(conn);
return (0); return (0);
} }
@ -663,26 +607,23 @@ virDomainLookupByID(virConnectPtr conn, int id)
} }
free(names); free(names);
} }
if (name == NULL)
goto error;
ret = (virDomainPtr) malloc(sizeof(virDomain)); ret = virGetDomain(conn, name, &uuid[0]);
if (ret == NULL) { if (ret == NULL) {
virLibConnError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
goto error; goto error;
} }
memset(ret, 0, sizeof(virDomain));
ret->magic = VIR_DOMAIN_MAGIC;
ret->conn = conn;
ret->handle = id; ret->handle = id;
ret->path = path; ret->path = path;
ret->name = name; if (name != NULL)
memcpy(&ret->uuid[0], uuid, 16); free(name);
if (ret->name == NULL) {
goto error;
}
return (ret); return (ret);
error: error:
if (ret != NULL) if (name != NULL)
free(ret); free(name);
if (path != NULL) if (path != NULL)
free(path); free(path);
return (NULL); return (NULL);
@ -737,19 +678,13 @@ virDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
if (name == NULL) if (name == NULL)
return (NULL); return (NULL);
ret = (virDomainPtr) malloc(sizeof(virDomain)); ret = virGetDomain(conn, name, &uuid[0]);
if (ret == NULL) { if (ret == NULL) {
if (name != NULL) if (name != NULL)
free(name); free(name);
return (NULL); return (NULL);
} }
memset(ret, 0, sizeof(virDomain));
ret->magic = VIR_DOMAIN_MAGIC;
ret->conn = conn;
ret->handle = id; ret->handle = id;
ret->name = name;
ret->path = 0;
memcpy(ret->uuid, uuid, 16);
return (ret); return (ret);
} }
@ -847,14 +782,9 @@ virDomainFree(virDomainPtr domain)
virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1); return (-1);
} }
domain->magic = -1; if (virFreeDomain(domain->conn, domain) < 0)
domain->handle = -1; return (-1);
if (domain->path != NULL) return(0);
free(domain->path);
if (domain->name)
free(domain->name);
free(domain);
return (0);
} }
/** /**

View File

@ -1586,41 +1586,37 @@ sexpr_to_xend_node_info(struct sexpr *root, virNodeInfoPtr info)
static virDomainPtr static virDomainPtr
sexpr_to_domain(virConnectPtr conn, struct sexpr *root) sexpr_to_domain(virConnectPtr conn, struct sexpr *root)
{ {
virDomainPtr ret; virDomainPtr ret = NULL;
char *dst_uuid = NULL; char *dst_uuid = NULL;
char uuid[16];
const char *name; const char *name;
if ((conn == NULL) || (root == NULL)) if ((conn == NULL) || (root == NULL))
return(NULL); return(NULL);
ret = (virDomainPtr) malloc(sizeof(virDomain)); dst_uuid = (char *) &uuid[0];
if (ret == NULL) {
virXendError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
return(NULL);
}
memset(ret, 0, sizeof(virDomain));
ret->magic = VIR_DOMAIN_MAGIC;
ret->conn = conn;
ret->handle = sexpr_int(root, "domain/domid");
if (ret->handle < 0)
goto error;
dst_uuid = (char *) &(ret->uuid[0]);
if (sexpr_uuid(&dst_uuid, root, "domain/uuid") == NULL) if (sexpr_uuid(&dst_uuid, root, "domain/uuid") == NULL)
goto error; goto error;
name = sexpr_node(root, "domain/name"); name = sexpr_node(root, "domain/name");
if (name == NULL) if (name == NULL)
goto error; goto error;
ret->name = strdup(name);
if (ret->name == NULL) ret = virGetDomain(conn, name, &uuid[0]);
if (ret == NULL) {
virXendError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
return(NULL);
}
ret->handle = sexpr_int(root, "domain/domid");
if (ret->handle < 0)
goto error; goto error;
return (ret); return (ret);
error: error:
virXendError(conn, VIR_ERR_INTERNAL_ERROR, virXendError(conn, VIR_ERR_INTERNAL_ERROR,
"failed to parse Xend domain informations"); "failed to parse Xend domain informations");
if (ret->name != NULL) if (ret != NULL)
free(ret->name ); virFreeDomain(conn, ret);
free(ret);
return(NULL); return(NULL);
} }

View File

@ -556,15 +556,15 @@ xenStoreDomainLookupByName(virConnectPtr conn, const char *name)
if (!found) if (!found)
return(NULL); return(NULL);
ret = (virDomainPtr) malloc(sizeof(virDomain)); ret = virGetDomain(conn, name, NULL);
if (ret == NULL) if (ret == NULL) {
virXenStoreError(conn, VIR_ERR_NO_MEMORY, "Allocating domain");
if (path != NULL)
free(path);
goto done; goto done;
memset(ret, 0, sizeof(virDomain)); }
ret->magic = VIR_DOMAIN_MAGIC;
ret->conn = conn;
ret->handle = id; ret->handle = id;
ret->path = path; ret->path = path;
ret->name = strdup(name);
done: done:
if (xenddomain != NULL) if (xenddomain != NULL)