提交 5be54b40 编写于 作者: M Mark McLoughlin

Tue Feb 14 15:33:05 EST 2007 Mark McLoughlin <markmc@redhat.com>

        * include/libvirt/libvirt.h.in: add the networks APIs

        * include/libvirt/virterror.h: add some error codes

        * src/driver.h: add network driver vtable

        * src/hash.c: add networks hash

        * src/internal.h: add virNetwork

        * src/libvirt.c: hook up the APIs to the network
        driver

        * src/libvirt_sym.version: add the new APIs

        * src/virterror.c: handle the new error codes
上级 24a92945
Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com
Tue Feb 14 15:33:05 EST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add the networks APIs
* include/libvirt/virterror.h: add some error codes
* src/driver.h: add network driver vtable
* src/hash.c: add networks hash
* src/internal.h: add virNetwork
* src/libvirt.c: hook up the APIs to the network
driver
* src/libvirt_sym.version: add the new APIs
* src/virterror.c: handle the new error codes
Tue Feb 14 15:07:26 EST 2007 Mark McLoughlin <markmc@redhat.com>
* src/conf.h: fix merge error - remove the argc argument
from qemudBuildCommandLine()
Tue Feb 14 15:03:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
* src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
to VSH_BYFOO in order to re-use it for the network stuff.
Tue Feb 14 14:58:35 EST 2007 Mark McLoughlin <markmc@redhat.com>
* src/hash.c, src/internal.h: Re-name virConnect->domains_mux
to virConnect->hashes_mux since it will also be used to
protect the networks hash.
Tue Feb 14 14:57:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: qemudSaveConfig() will always report a
more specific error, so we should avoid overwriting
this error.
Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/qemud.c: Re-factor out qemudExec() so that it can
be used to launch dnsmasq.
* qemud/conf.c: don't return argc from qemudBuildCommandLine()
as exec() doesn't need it.
Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: Re-factor bits of conf.c so that:
- qemudMakeConfigPath() can be re-used given another configDir
- split qemudEnsureConfigDir() out of qemudSaveConfig() so
that it may be re-used to create another configDir
- split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs
Tue Feb 14 14:50:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: handle an unspecified MAC address,
fix the argv freeing code in qemudBuildCommandLine()
and fix copy and paste error in qemudGenerateXML()
Tue Feb 14 14:42:38 EST 2007 Mark McLoughlin <markmc@redhat.com>
* src/internal.h: add virConnect->qemud_fd so that
xen and qemu don't share the handle member.
* src/hash.c, src/qemu_internal.c: update
Tue Feb 14 14:40:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c, qemud/dispatch.c, qemud/driver.c,
qemud/qemud.c: include autoconf's config.h
Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com>
* conf.[ch]: rename from config.[ch] so we can use
autoconf's config.h
* Makefile.am: update
* driver.c, qemud.c: upd.
Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
* autogen.sh: run autoheader
......
......@@ -443,6 +443,90 @@ int virDomainGetVcpus (virDomainPtr domain,
int virDomainAttachDevice(virDomainPtr domain, char *xml);
int virDomainDetachDevice(virDomainPtr domain, char *xml);
/*
* Virtual Networks API
*/
/**
* virNetwork:
*
* a virNetwork is a private structure representing a virtual network.
*/
typedef struct _virNetwork virNetwork;
/**
* virNetworkPtr:
*
* a virNetworkPtr is pointer to a virNetwork private structure, this is the
* type used to reference a virtual network in the API.
*/
typedef virNetwork *virNetworkPtr;
/*
* List active networks
*/
int virConnectNumOfNetworks (virConnectPtr conn);
int virConnectListNetworks (virConnectPtr conn,
const char **names,
int maxnames);
/*
* List inactive networks
*/
int virConnectNumOfDefinedNetworks (virConnectPtr conn);
int virConnectListDefinedNetworks (virConnectPtr conn,
const char **names,
int maxnames);
/*
* Lookup network by name or uuid
*/
virNetworkPtr virNetworkLookupByName (virConnectPtr conn,
const char *name);
virNetworkPtr virNetworkLookupByUUID (virConnectPtr conn,
const unsigned char *uuid);
virNetworkPtr virNetworkLookupByUUIDString (virConnectPtr conn,
const char *uuid);
/*
* Create active transient network
*/
virNetworkPtr virNetworkCreateXML (virConnectPtr conn,
const char *xmlDesc);
/*
* Define inactive persistent network
*/
virNetworkPtr virNetworkDefineXML (virConnectPtr conn,
const char *xmlDesc);
/*
* Delete persistent network
*/
int virNetworkUndefine (virNetworkPtr network);
/*
* Activate persistent network
*/
int virNetworkCreate (virNetworkPtr network);
/*
* Network destroy/free
*/
int virNetworkDestroy (virNetworkPtr network);
int virNetworkFree (virNetworkPtr network);
/*
* Network informations
*/
const char* virNetworkGetName (virNetworkPtr network);
int virNetworkGetUUID (virNetworkPtr network,
unsigned char *uuid);
int virNetworkGetUUIDString (virNetworkPtr network,
char *buf);
char * virNetworkGetXMLDesc (virNetworkPtr network,
int flags);
#ifdef __cplusplus
}
#endif
......
......@@ -48,6 +48,7 @@ typedef enum {
VIR_FROM_PROXY, /* Error in the proxy code */
VIR_FROM_CONF, /* Error in the configuration file handling */
VIR_FROM_QEMU, /* Error at the QEMU daemon */
VIR_FROM_NET, /* Error when operating on a network */
} virErrorDomain;
......@@ -114,7 +115,9 @@ typedef enum {
VIR_ERR_PARSE_FAILED, /* failed to parse a conf file */
VIR_ERR_CONF_SYNTAX, /* failed to parse the syntax of a conf file */
VIR_ERR_WRITE_FAILED, /* failed to write a conf file */
VIR_ERR_XML_DETAIL /* detail of an XML error */
VIR_ERR_XML_DETAIL, /* detail of an XML error */
VIR_ERR_INVALID_NETWORK, /* invalid network object */
VIR_ERR_NETWORK_EXIST, /* the network already exist */
} virErrorNumber;
/**
......
......@@ -188,6 +188,65 @@ struct _virDriver {
virDrvDomainDetachDevice domainDetachDevice;
};
typedef int
(*virDrvNumOfNetworks) (virConnectPtr conn);
typedef int
(*virDrvListNetworks) (virConnectPtr conn,
const char **names,
int maxnames);
typedef int
(*virDrvNumOfDefinedNetworks) (virConnectPtr conn);
typedef int
(*virDrvListDefinedNetworks) (virConnectPtr conn,
const char **names,
int maxnames);
typedef virNetworkPtr
(*virDrvNetworkLookupByUUID) (virConnectPtr conn,
const unsigned char *uuid);
typedef virNetworkPtr
(*virDrvNetworkLookupByName) (virConnectPtr conn,
const char *name);
typedef virNetworkPtr
(*virDrvNetworkCreateXML) (virConnectPtr conn,
const char *xmlDesc);
typedef virNetworkPtr
(*virDrvNetworkDefineXML) (virConnectPtr conn, const char *xml);
typedef int
(*virDrvNetworkUndefine) (virNetworkPtr network);
typedef int
(*virDrvNetworkCreate) (virNetworkPtr network);
typedef int
(*virDrvNetworkDestroy) (virNetworkPtr network);
typedef char *
(*virDrvNetworkDumpXML) (virNetworkPtr network,
int flags);
typedef struct _virNetworkDriver virNetworkDriver;
typedef virNetworkDriver *virNetworkDriverPtr;
/**
* _virNetworkDriver:
*
* Structure associated to a network virtualization driver, defining the various
* entry points for it.
*/
struct _virNetworkDriver {
virDrvOpen open;
virDrvClose close;
virDrvNumOfNetworks numOfNetworks;
virDrvListNetworks listNetworks;
virDrvNumOfDefinedNetworks numOfDefinedNetworks;
virDrvListDefinedNetworks listDefinedNetworks;
virDrvNetworkLookupByUUID networkLookupByUUID;
virDrvNetworkLookupByName networkLookupByName;
virDrvNetworkCreateXML networkCreateXML;
virDrvNetworkDefineXML networkDefineXML;
virDrvNetworkUndefine networkUndefine;
virDrvNetworkCreate networkCreate;
virDrvNetworkDestroy networkDestroy;
virDrvNetworkDumpXML networkDumpXML;
};
/*
* Registration
......@@ -195,6 +254,7 @@ struct _virDriver {
* lookup based on the URI given in a virConnectOpen(ReadOnly)
*/
int virRegisterDriver(virDriverPtr);
int virRegisterNetworkDriver(virNetworkDriverPtr);
#ifdef __cplusplus
}
......
......@@ -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:
*
......@@ -655,11 +669,16 @@ virGetConnect(void) {
memset(ret, 0, sizeof(virConnect));
ret->magic = VIR_CONNECT_MAGIC;
ret->nb_drivers = 0;
ret->handle = -1;
ret->qemud_fd = -1;
ret->domains = virHashCreate(20);
if (ret->domains == NULL)
goto failed;
ret->domains_mux = xmlNewMutex();
if (ret->domains_mux == NULL)
ret->networks = virHashCreate(20);
if (ret->networks == NULL)
goto failed;
ret->hashes_mux = xmlNewMutex();
if (ret->hashes_mux == NULL)
goto failed;
ret->uses = 1;
......@@ -669,8 +688,10 @@ failed:
if (ret != NULL) {
if (ret->domains != NULL)
virHashFree(ret->domains, (virHashDeallocator) virDomainFreeName);
if (ret->domains_mux != NULL)
xmlFreeMutex(ret->domains_mux);
if (ret->networks != NULL)
virHashFree(ret->networks, (virHashDeallocator) virNetworkFreeName);
if (ret->hashes_mux != NULL)
xmlFreeMutex(ret->hashes_mux);
free(ret);
}
return(NULL);
......@@ -689,22 +710,24 @@ int
virFreeConnect(virConnectPtr conn) {
int ret;
if ((!VIR_IS_CONNECT(conn)) || (conn->domains_mux == NULL)) {
if ((!VIR_IS_CONNECT(conn)) || (conn->hashes_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
xmlMutexLock(conn->domains_mux);
xmlMutexLock(conn->hashes_mux);
conn->uses--;
ret = conn->uses;
if (ret > 0) {
xmlMutexUnlock(conn->domains_mux);
xmlMutexUnlock(conn->hashes_mux);
return(ret);
}
if (conn->domains != NULL)
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->domains_mux != NULL)
xmlFreeMutex(conn->domains_mux);
if (conn->networks != NULL)
virHashFree(conn->networks, (virHashDeallocator) virNetworkFreeName);
if (conn->hashes_mux != NULL)
xmlFreeMutex(conn->hashes_mux);
free(conn);
return(0);
}
......@@ -727,11 +750,11 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
virDomainPtr ret = NULL;
if ((!VIR_IS_CONNECT(conn)) || ((name == NULL) && (uuid == NULL)) ||
(conn->domains_mux == NULL)) {
(conn->hashes_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
xmlMutexLock(conn->domains_mux);
xmlMutexLock(conn->hashes_mux);
/* TODO search by UUID first as they are better differenciators */
......@@ -769,11 +792,11 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
conn->uses++;
done:
ret->uses++;
xmlMutexUnlock(conn->domains_mux);
xmlMutexUnlock(conn->hashes_mux);
return(ret);
error:
xmlMutexUnlock(conn->domains_mux);
xmlMutexUnlock(conn->hashes_mux);
if (ret != NULL) {
if (ret->name != NULL)
free(ret->name );
......@@ -797,11 +820,11 @@ 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)) {
(domain->conn != conn) || (conn->hashes_mux == NULL)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
xmlMutexLock(conn->domains_mux);
xmlMutexLock(conn->hashes_mux);
/*
* decrement the count for the domain
......@@ -837,13 +860,13 @@ virFreeDomain(virConnectPtr conn, virDomainPtr domain) {
if (conn->domains != NULL)
virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
if (conn->domains_mux != NULL)
xmlFreeMutex(conn->domains_mux);
if (conn->hashes_mux != NULL)
xmlFreeMutex(conn->hashes_mux);
free(conn);
return(0);
done:
xmlMutexUnlock(conn->domains_mux);
xmlMutexUnlock(conn->hashes_mux);
return(ret);
}
......@@ -868,7 +891,7 @@ virGetDomainByID(virConnectPtr conn, int id) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
xmlMutexLock(conn->domains_mux);
xmlMutexLock(conn->hashes_mux);
table = conn->domains;
if ((table == NULL) || (table->nbElems == 0))
......@@ -888,9 +911,142 @@ virGetDomainByID(virConnectPtr conn, int id) {
}
}
done:
xmlMutexUnlock(conn->domains_mux);
xmlMutexUnlock(conn->hashes_mux);
return(ret);
}
/**
* virGetNetwork:
* @conn: the hypervisor connection
* @name: pointer to the network name or NULL
* @uuid: pointer to the uuid or NULL
*
* 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
......
......@@ -84,6 +84,16 @@ extern "C" {
#define VIR_IS_DOMAIN(obj) ((obj) && (obj)->magic==VIR_DOMAIN_MAGIC)
#define VIR_IS_CONNECTED_DOMAIN(obj) (VIR_IS_DOMAIN(obj) && VIR_IS_CONNECT((obj)->conn))
/**
* VIR_NETWORK_MAGIC:
*
* magic value used to protect the API when pointers to network structures
* are passed down by the uers.
*/
#define VIR_NETWORK_MAGIC 0xDEAD1234
#define VIR_IS_NETWORK(obj) ((obj) && (obj)->magic==VIR_NETWORK_MAGIC)
#define VIR_IS_CONNECTED_NETWORK(obj) (VIR_IS_NETWORK(obj) && VIR_IS_CONNECT((obj)->conn))
#define MAX_DRIVERS 10
/*
......@@ -104,6 +114,10 @@ struct _virConnect {
virDriverPtr drivers[MAX_DRIVERS];
int nb_drivers;
/* the list of available network drivers */
virNetworkDriverPtr networkDrivers[MAX_DRIVERS];
int nb_network_drivers;
/* extra data needed by drivers */
int handle; /* internal handle used for hypercall */
struct xs_handle *xshandle;/* handle to talk to the xenstore */
......@@ -117,14 +131,17 @@ struct _virConnect {
struct sockaddr_un addr_un; /* the unix address */
struct sockaddr_in addr_in; /* the inet address */
int qemud_fd; /* connection to qemud */
/* error stuff */
virError err; /* the last error */
virErrorFunc handler; /* associated handlet */
void *userData; /* the user data */
/* misc */
xmlMutexPtr domains_mux;/* a mutex to protect the domain hash table */
xmlMutexPtr hashes_mux;/* a mutex to protect the domain and networks hash tables */
virHashTablePtr domains;/* hash table for known domains */
virHashTablePtr networks;/* hash table for known domains */
int flags; /* a set of connection flags */
};
......@@ -156,6 +173,19 @@ struct _virDomain {
char *xml; /* the XML description for defined domains */
};
/**
* _virNetwork:
*
* Internal structure associated to a domain
*/
struct _virNetwork {
unsigned int magic; /* specific value to check */
int uses; /* reference count */
virConnectPtr conn; /* pointer back to the connection */
char *name; /* the network external name */
unsigned char uuid[VIR_UUID_BUFLEN]; /* the network unique identifier */
};
/*
* Internal routines
*/
......@@ -194,6 +224,11 @@ int virFreeDomain (virConnectPtr conn,
virDomainPtr domain);
virDomainPtr virGetDomainByID(virConnectPtr conn,
int id);
virNetworkPtr virGetNetwork (virConnectPtr conn,
const char *name,
const unsigned char *uuid);
int virFreeNetwork (virConnectPtr conn,
virNetworkPtr domain);
#ifdef __cplusplus
}
......
此差异已折叠。
......@@ -57,5 +57,24 @@
virDomainAttachDevice;
virDomainDetachDevice;
virConnectNumOfNetworks;
virConnectListNetworks;
virConnectNumOfDefinedNetworks;
virConnectListDefinedNetworks;
virNetworkLookupByName;
virNetworkLookupByUUID;
virNetworkLookupByUUIDString;
virNetworkCreateXML;
virNetworkDefineXML;
virNetworkUndefine;
virNetworkCreate;
virNetworkDestroy;
virNetworkFree;
virNetworkGetName;
virNetworkGetUUID;
virNetworkGetUUIDString;
virNetworkGetXMLDesc;
local: *;
};
......@@ -271,6 +271,9 @@ virDefaultErrorFunc(virErrorPtr err)
case VIR_FROM_QEMU:
dom = "QEMU ";
break;
case VIR_FROM_NET:
dom = "Network ";
break;
}
if ((err->dom != NULL) && (err->code != VIR_ERR_INVALID_DOMAIN)) {
domain = err->dom->name;
......@@ -585,6 +588,18 @@ __virErrorMsg(virErrorNumber error, const char *info)
else
errmsg = "%s";
break;
case VIR_ERR_INVALID_NETWORK:
if (info == NULL)
errmsg = _("invalid network pointer in");
else
errmsg = _("invalid network pointer in %s");
break;
case VIR_ERR_NETWORK_EXIST:
if (info == NULL)
errmsg = _("this network exists already");
else
errmsg = _("network %s exists already");
break;
}
return (errmsg);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册