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

* qemud/protocol.h: add the protocol for virtual networks

        * qemud/dispatch.c: implement the protocol

        * qemud/driver.[ch]: add stubs for the driver

        * qemud/internal.h: add struct qemud_network

        * src/qemu_internal.c: add a virtual networks driver
This commit is contained in:
Mark McLoughlin 2007-02-14 15:54:10 +00:00
parent fbc08f063c
commit f391be00e9
7 changed files with 813 additions and 8 deletions

View File

@ -1,4 +1,86 @@
Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com
Tue Feb 14 15:52:34 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/protocol.h: add the protocol for virtual networks
* qemud/dispatch.c: implement the protocol
* qemud/driver.[ch]: add stubs for the driver
* qemud/internal.h: add struct qemud_network
* src/qemu_internal.c: add a virtual networks driver
Tue Feb 14 15:43:28 EST 2007 Mark McLoughlin <markmc@redhat.com>
* src/virsh.c: add the net-* commands.
Tue Feb 14 15:37:17 EST 2007 Mark McLoughlin <markmc@redhat.com>
Note: potential ABI break here, but people should
only really be using virError structs returned from
libvirt itself.
* include/libvirt/virterror.h: add virNetwork
to virError
* src/internal.h, src/virterror.c: add network param
to __virRaiseError()
* src/conf.c, src/hash.c, src/libvirt.c, src/proxy_internal.c,
src/qemu_internal.c, src/sexpr.c, src/test.c, src/xen_internal.c,
src/xend_internal.c, src/xm_internal.c, src/xml.c, src/xmlrpc.c,
src/xs_internal.c: update.
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:
@ -8,25 +90,25 @@ Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com
- split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs
Tue Feb 14 14:50:22 EST 2007 Mark McLoughlin <markmc@redhat.com
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
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
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
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
@ -35,7 +117,7 @@ Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com
* driver.c, qemud.c: upd.
Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com
Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
* autogen.sh: run autoheader

View File

@ -462,6 +462,243 @@ static int qemudDispatchDomainUndefine(struct qemud_server *server, struct qemud
return 0;
}
static int qemudDispatchNumNetworks(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != 0)
return -1;
int nnetworks = qemudNumNetworks(server);
if (nnetworks < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NUM_NETWORKS;
out->header.dataSize = sizeof(out->data.numNetworksReply);
out->data.numNetworksReply.numNetworks = nnetworks;
}
return 0;
}
static int qemudDispatchListNetworks(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
char **names;
int i;
if (in->header.dataSize != 0)
return -1;
if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_NETWORKS)))
return -1;
for (i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i++) {
names[i] = out->data.listNetworksReply.networks[i];
}
int nnetworks = qemudListNetworks(server,
names,
QEMUD_MAX_NUM_NETWORKS);
free(names);
if (nnetworks < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_LIST_NETWORKS;
out->header.dataSize = sizeof(out->data.listNetworksReply);
out->data.listNetworksReply.numNetworks = nnetworks;
}
return 0;
}
static int qemudDispatchNumDefinedNetworks(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != 0)
return -1;
int nnetworks = qemudNumDefinedNetworks(server);
if (nnetworks < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NUM_DEFINED_NETWORKS;
out->header.dataSize = sizeof(out->data.numDefinedNetworksReply);
out->data.numDefinedNetworksReply.numNetworks = nnetworks;
}
return 0;
}
static int qemudDispatchListDefinedNetworks(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
char **names;
int i;
if (in->header.dataSize != 0)
return -1;
if (!(names = malloc(sizeof(char *)*QEMUD_MAX_NUM_NETWORKS)))
return -1;
for (i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i++) {
names[i] = out->data.listDefinedNetworksReply.networks[i];
}
int nnetworks = qemudListDefinedNetworks(server,
names,
QEMUD_MAX_NUM_NETWORKS);
free(names);
if (nnetworks < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_LIST_DEFINED_NETWORKS;
out->header.dataSize = sizeof(out->data.listDefinedNetworksReply);
out->data.listDefinedNetworksReply.numNetworks = nnetworks;
}
return 0;
}
static int qemudDispatchNetworkLookupByName(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkLookupByNameRequest))
return -1;
/* Paranoia NULL termination */
in->data.networkLookupByNameRequest.name[QEMUD_MAX_NAME_LEN-1] = '\0';
struct qemud_network *network = qemudFindNetworkByName(server, in->data.networkLookupByNameRequest.name);
if (!network) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_NAME;
out->header.dataSize = sizeof(out->data.networkLookupByNameReply);
memcpy(out->data.networkLookupByNameReply.uuid, network->def.uuid, QEMUD_UUID_RAW_LEN);
}
return 0;
}
static int qemudDispatchNetworkLookupByUUID(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkLookupByUUIDRequest))
return -1;
struct qemud_network *network = qemudFindNetworkByUUID(server, in->data.networkLookupByUUIDRequest.uuid);
if (!network) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID;
out->header.dataSize = sizeof(out->data.networkLookupByUUIDReply);
strncpy(out->data.networkLookupByUUIDReply.name, network->def.name, QEMUD_MAX_NAME_LEN-1);
out->data.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
}
return 0;
}
static int qemudDispatchNetworkCreate(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkCreateRequest))
return -1;
in->data.networkCreateRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0';
struct qemud_network *network = qemudNetworkCreate(server, in->data.networkCreateRequest.xml);
if (!network) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_CREATE;
out->header.dataSize = sizeof(out->data.networkCreateReply);
memcpy(out->data.networkCreateReply.uuid, network->def.uuid, QEMUD_UUID_RAW_LEN);
strncpy(out->data.networkCreateReply.name, network->def.name, QEMUD_MAX_NAME_LEN-1);
out->data.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
}
return 0;
}
static int qemudDispatchNetworkDefine(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkDefineRequest))
return -1;
in->data.networkDefineRequest.xml[QEMUD_MAX_XML_LEN-1] ='\0';
struct qemud_network *network = qemudNetworkDefine(server, in->data.networkDefineRequest.xml);
if (!network) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_DEFINE;
out->header.dataSize = sizeof(out->data.networkDefineReply);
memcpy(out->data.networkDefineReply.uuid, network->def.uuid, QEMUD_UUID_RAW_LEN);
strncpy(out->data.networkDefineReply.name, network->def.name, QEMUD_MAX_NAME_LEN-1);
out->data.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
}
return 0;
}
static int qemudDispatchNetworkUndefine(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkUndefineRequest))
return -1;
int ret = qemudNetworkUndefine(server, in->data.networkUndefineRequest.uuid);
if (ret < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_UNDEFINE;
out->header.dataSize = 0;
}
return 0;
}
static int qemudDispatchNetworkStart(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkStartRequest))
return -1;
struct qemud_network *network = qemudFindNetworkByUUID(server, in->data.networkStartRequest.uuid);
if (!network || qemudNetworkStart(server, network) < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_START;
out->header.dataSize = 0;
}
return 0;
}
static int qemudDispatchNetworkDestroy(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkDestroyRequest))
return -1;
int ret = qemudNetworkDestroy(server, in->data.networkDestroyRequest.uuid);
if (ret < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_DESTROY;
out->header.dataSize = 0;
}
return 0;
}
static int qemudDispatchNetworkDumpXML(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out) {
if (in->header.dataSize != sizeof(in->data.networkDumpXMLRequest))
return -1;
int ret = qemudNetworkDumpXML(server,
in->data.networkDumpXMLRequest.uuid,
out->data.networkDumpXMLReply.xml, QEMUD_MAX_XML_LEN);
if (ret < 0) {
if (qemudDispatchFailure(server, client, out) < 0)
return -1;
} else {
out->header.type = QEMUD_PKT_NETWORK_DUMP_XML;
out->header.dataSize = sizeof(out->data.networkDumpXMLReply);
}
return 0;
}
typedef int (*clientFunc)(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out);
@ -490,7 +727,19 @@ clientFunc funcsTransmitRW[QEMUD_PKT_MAX] = {
qemudDispatchNumDefinedDomains,
qemudDispatchDomainStart,
qemudDispatchDomainDefine,
qemudDispatchDomainUndefine
qemudDispatchDomainUndefine,
qemudDispatchNumNetworks,
qemudDispatchListNetworks,
qemudDispatchNumDefinedNetworks,
qemudDispatchListDefinedNetworks,
qemudDispatchNetworkLookupByUUID,
qemudDispatchNetworkLookupByName,
qemudDispatchNetworkCreate,
qemudDispatchNetworkDefine,
qemudDispatchNetworkUndefine,
qemudDispatchNetworkStart,
qemudDispatchNetworkDestroy,
qemudDispatchNetworkDumpXML,
};
clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
@ -515,6 +764,18 @@ clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
NULL,
NULL,
NULL,
qemudDispatchNumNetworks,
qemudDispatchListNetworks,
qemudDispatchNumDefinedNetworks,
qemudDispatchListDefinedNetworks,
qemudDispatchNetworkLookupByUUID,
qemudDispatchNetworkLookupByName,
NULL,
NULL,
NULL,
NULL,
NULL,
qemudDispatchNetworkDumpXML,
};
/*

View File

@ -545,6 +545,70 @@ int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid)
return 0;
}
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
const unsigned char *uuid) {
server = NULL; uuid = NULL;
return NULL;
}
struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server,
const char *name) {
server = NULL; name = NULL;
return NULL;
}
int qemudNumNetworks(struct qemud_server *server) {
server = NULL;
return 0;
}
int qemudListNetworks(struct qemud_server *server, char *const*names, int nnames) {
server = NULL; names = NULL; nnames = 0;
return 0;
}
int qemudNumDefinedNetworks(struct qemud_server *server) {
server = NULL;
return 0;
}
int qemudListDefinedNetworks(struct qemud_server *server, char *const*names, int nnames) {
server = NULL; names = NULL; nnames = 0;
return 0;
}
struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
server = NULL; xml = NULL;
return NULL;
}
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
server = NULL; xml = NULL;
return NULL;
}
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
uuid = NULL;
return -1;
}
int qemudNetworkStart(struct qemud_server *server, struct qemud_network *network) {
server = NULL; network = NULL;
return 1;
}
int qemudNetworkDestroy(struct qemud_server *server, const unsigned char *uuid) {
uuid = NULL;
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
return -1;
}
int qemudNetworkDumpXML(struct qemud_server *server, const unsigned char *uuid, char *xml, int xmllen) {
qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
uuid = NULL; xml = NULL; xmllen = 0;
return -1;
}
/*
* Local variables:

View File

@ -86,6 +86,34 @@ struct qemud_vm *qemudDomainDefine(struct qemud_server *server,
int qemudDomainUndefine(struct qemud_server *server,
const unsigned char *uuid);
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
const unsigned char *uuid);
struct qemud_network *qemudFindNetworkByName(const struct qemud_server *server,
const char *name);
int qemudNumNetworks(struct qemud_server *server);
int qemudListNetworks(struct qemud_server *server,
char *const*names,
int nnames);
int qemudNumDefinedNetworks(struct qemud_server *server);
int qemudListDefinedNetworks(struct qemud_server *server,
char *const*names,
int nnames);
struct qemud_network *qemudNetworkCreate(struct qemud_server *server,
const char *xml);
struct qemud_network *qemudNetworkDefine(struct qemud_server *server,
const char *xml);
int qemudNetworkUndefine(struct qemud_server *server,
const unsigned char *uuid);
int qemudNetworkStart(struct qemud_server *server,
struct qemud_network *network);
int qemudNetworkDestroy(struct qemud_server *server,
const unsigned char *uuid);
int qemudNetworkDumpXML(struct qemud_server *server,
const unsigned char *uuid,
char *xml,
int xmllen);
#endif

View File

@ -199,6 +199,18 @@ struct qemud_vm {
struct qemud_vm *next;
};
/* Virtual Network main configuration */
struct qemud_network_def {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
char name[QEMUD_MAX_NAME_LEN];
};
/* Virtual Network runtime state */
struct qemud_network {
struct qemud_network_def def;
struct qemud_network *next;
};
/* Stores the per-client connection state */
struct qemud_client {
int fd;

View File

@ -50,6 +50,18 @@ enum {
QEMUD_PKT_DOMAIN_START,
QEMUD_PKT_DOMAIN_DEFINE,
QEMUD_PKT_DOMAIN_UNDEFINE,
QEMUD_PKT_NUM_NETWORKS,
QEMUD_PKT_LIST_NETWORKS,
QEMUD_PKT_NUM_DEFINED_NETWORKS,
QEMUD_PKT_LIST_DEFINED_NETWORKS,
QEMUD_PKT_NETWORK_LOOKUP_BY_UUID,
QEMUD_PKT_NETWORK_LOOKUP_BY_NAME,
QEMUD_PKT_NETWORK_CREATE,
QEMUD_PKT_NETWORK_DEFINE,
QEMUD_PKT_NETWORK_UNDEFINE,
QEMUD_PKT_NETWORK_START,
QEMUD_PKT_NETWORK_DESTROY,
QEMUD_PKT_NETWORK_DUMP_XML,
QEMUD_PKT_MAX,
} qemud_packet_type;
@ -62,6 +74,7 @@ enum {
#define QEMUD_MAX_NAME_LEN 50
#define QEMUD_MAX_XML_LEN 4096
#define QEMUD_MAX_NUM_DOMAINS 100
#define QEMUD_MAX_NUM_NETWORKS 100
#define QEMUD_MAX_ERROR_LEN 1024
/* Possible guest VM states */
@ -200,6 +213,63 @@ union qemud_packet_data {
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} domainUndefineRequest;
struct {
int32_t numNetworks;
} numNetworksReply;
struct {
int32_t numNetworks;
char networks[QEMUD_MAX_NUM_NETWORKS][QEMUD_MAX_NAME_LEN];
} listNetworksReply;
struct {
int32_t numNetworks;
} numDefinedNetworksReply;
struct {
int32_t numNetworks;
char networks[QEMUD_MAX_NUM_NETWORKS][QEMUD_MAX_NAME_LEN];
} listDefinedNetworksReply;
struct {
char name[QEMUD_MAX_NAME_LEN];
} networkLookupByNameRequest;
struct {
int32_t id;
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} networkLookupByNameReply;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} networkLookupByUUIDRequest;
struct {
int32_t id;
char name[QEMUD_MAX_NAME_LEN];
} networkLookupByUUIDReply;
struct {
char xml[QEMUD_MAX_XML_LEN];
} networkCreateRequest;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
char name[QEMUD_MAX_NAME_LEN];
} networkCreateReply;
struct {
char xml[QEMUD_MAX_XML_LEN];
} networkDefineRequest;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
char name[QEMUD_MAX_NAME_LEN];
} networkDefineReply;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} networkUndefineRequest;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} networkStartRequest;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} networkDestroyRequest;
struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
} networkDumpXMLRequest;
struct {
char xml[QEMUD_MAX_XML_LEN];
} networkDumpXMLReply;
};
/* Each packet has header & data */

View File

@ -61,7 +61,7 @@ qemuError(virConnectPtr con,
return;
errmsg = __virErrorMsg(error, info);
__virRaiseError(con, dom, VIR_FROM_QEMU, error, VIR_ERR_ERROR,
__virRaiseError(con, dom, NULL, VIR_FROM_QEMU, error, VIR_ERR_ERROR,
errmsg, info, NULL, 0, 0, errmsg, info, 0);
}
@ -806,6 +806,276 @@ static int qemuUndefine(virDomainPtr dom) {
return ret;
}
static int qemuNetworkOpen(virConnectPtr conn,
const char *name,
int flags) {
xmlURIPtr uri = NULL;
int ret = -1;
if (conn->qemud_fd == -1)
return 0;
if (name)
uri = xmlParseURI(name);
if (uri && !strcmp(uri->scheme, "qemu"))
ret = qemuOpen(conn, name, flags);
else if (geteuid() == 0)
ret = qemuOpen(conn, "qemu:///system", flags);
else
ret = qemuOpen(conn, "qemu:///session", flags);
if (uri)
xmlFreeURI(uri);
return ret;
}
static int qemuNumOfNetworks(virConnectPtr conn) {
struct qemud_packet req, reply;
req.header.type = QEMUD_PKT_NUM_NETWORKS;
req.header.dataSize = 0;
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return -1;
}
return reply.data.numNetworksReply.numNetworks;
}
static int qemuListNetworks(virConnectPtr conn,
const char **names,
int maxnames) {
struct qemud_packet req, reply;
int i, nNetworks;
req.header.type = QEMUD_PKT_LIST_NETWORKS;
req.header.dataSize = 0;
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return -1;
}
nNetworks = reply.data.listNetworksReply.numNetworks;
if (nNetworks > maxnames)
return -1;
for (i = 0 ; i < nNetworks ; i++) {
reply.data.listNetworksReply.networks[i][QEMUD_MAX_NAME_LEN-1] = '\0';
names[i] = strdup(reply.data.listNetworksReply.networks[i]);
}
return nNetworks;
}
static int qemuNumOfDefinedNetworks(virConnectPtr conn) {
struct qemud_packet req, reply;
req.header.type = QEMUD_PKT_NUM_DEFINED_NETWORKS;
req.header.dataSize = 0;
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return -1;
}
return reply.data.numDefinedNetworksReply.numNetworks;
}
static int qemuListDefinedNetworks(virConnectPtr conn,
const char **names,
int maxnames) {
struct qemud_packet req, reply;
int i, nNetworks;
req.header.type = QEMUD_PKT_LIST_DEFINED_NETWORKS;
req.header.dataSize = 0;
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return -1;
}
nNetworks = reply.data.listDefinedNetworksReply.numNetworks;
if (nNetworks > maxnames)
return -1;
for (i = 0 ; i < nNetworks ; i++) {
reply.data.listDefinedNetworksReply.networks[i][QEMUD_MAX_NAME_LEN-1] = '\0';
names[i] = strdup(reply.data.listDefinedNetworksReply.networks[i]);
}
return nNetworks;
}
static virNetworkPtr qemuNetworkLookupByUUID(virConnectPtr conn,
const unsigned char *uuid) {
struct qemud_packet req, reply;
virNetworkPtr network;
req.header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID;
req.header.dataSize = sizeof(req.data.networkLookupByUUIDRequest);
memmove(req.data.networkLookupByUUIDRequest.uuid, uuid, QEMUD_UUID_RAW_LEN);
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return NULL;
}
reply.data.networkLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
if (!(network = virGetNetwork(conn,
reply.data.networkLookupByUUIDReply.name,
uuid)))
return NULL;
return network;
}
static virNetworkPtr qemuNetworkLookupByName(virConnectPtr conn,
const char *name) {
struct qemud_packet req, reply;
virNetworkPtr network;
if (strlen(name) > (QEMUD_MAX_NAME_LEN-1))
return NULL;
req.header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_NAME;
req.header.dataSize = sizeof(req.data.networkLookupByNameRequest);
strcpy(req.data.networkLookupByNameRequest.name, name);
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return NULL;
}
if (!(network = virGetNetwork(conn,
name,
reply.data.networkLookupByNameReply.uuid)))
return NULL;
return network;
}
static virNetworkPtr qemuNetworkCreateXML(virConnectPtr conn,
const char *xmlDesc) {
struct qemud_packet req, reply;
virNetworkPtr network;
int len = strlen(xmlDesc);
if (len > (QEMUD_MAX_XML_LEN-1)) {
return NULL;
}
req.header.type = QEMUD_PKT_NETWORK_CREATE;
req.header.dataSize = sizeof(req.data.networkCreateRequest);
strcpy(req.data.networkCreateRequest.xml, xmlDesc);
req.data.networkCreateRequest.xml[QEMUD_MAX_XML_LEN-1] = '\0';
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return NULL;
}
reply.data.networkCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
if (!(network = virGetNetwork(conn,
reply.data.networkCreateReply.name,
reply.data.networkCreateReply.uuid)))
return NULL;
return network;
}
static virNetworkPtr qemuNetworkDefineXML(virConnectPtr conn,
const char *xml) {
struct qemud_packet req, reply;
virNetworkPtr network;
int len = strlen(xml);
if (len > (QEMUD_MAX_XML_LEN-1)) {
return NULL;
}
req.header.type = QEMUD_PKT_NETWORK_DEFINE;
req.header.dataSize = sizeof(req.data.networkDefineRequest);
strcpy(req.data.networkDefineRequest.xml, xml);
req.data.networkDefineRequest.xml[QEMUD_MAX_XML_LEN-1] = '\0';
if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
return NULL;
}
reply.data.networkDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
if (!(network = virGetNetwork(conn,
reply.data.networkDefineReply.name,
reply.data.networkDefineReply.uuid)))
return NULL;
return network;
}
static int qemuNetworkUndefine(virNetworkPtr network) {
struct qemud_packet req, reply;
int ret = 0;
req.header.type = QEMUD_PKT_NETWORK_UNDEFINE;
req.header.dataSize = sizeof(req.data.networkUndefineRequest);
memcpy(req.data.networkUndefineRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
ret = -1;
goto cleanup;
}
cleanup:
if (virFreeNetwork(network->conn, network) < 0)
ret = -1;
return ret;
}
static int qemuNetworkCreate(virNetworkPtr network) {
struct qemud_packet req, reply;
req.header.type = QEMUD_PKT_NETWORK_START;
req.header.dataSize = sizeof(req.data.networkStartRequest);
memcpy(req.data.networkStartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
return -1;
}
return 0;
}
static int qemuNetworkDestroy(virNetworkPtr network) {
struct qemud_packet req, reply;
req.header.type = QEMUD_PKT_NETWORK_DESTROY;
req.header.dataSize = sizeof(req.data.networkDestroyRequest);
memcpy(req.data.networkDestroyRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
return -1;
}
return 0;
}
static char * qemuNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
struct qemud_packet req, reply;
req.header.type = QEMUD_PKT_NETWORK_DUMP_XML;
req.header.dataSize = sizeof(req.data.networkDumpXMLRequest);
memmove(req.data.networkDumpXMLRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
return NULL;
}
reply.data.networkDumpXMLReply.xml[QEMUD_MAX_XML_LEN-1] = '\0';
return strdup(reply.data.networkDumpXMLReply.xml);
}
static virDriver qemuDriver = {
VIR_DRV_QEMU,
@ -849,8 +1119,26 @@ static virDriver qemuDriver = {
NULL, /* domainDetachDevice */
};
static virNetworkDriver qemuNetworkDriver = {
qemuNetworkOpen, /* open */
qemuClose, /* close */
qemuNumOfNetworks, /* numOfNetworks */
qemuListNetworks, /* listNetworks */
qemuNumOfDefinedNetworks, /* numOfDefinedNetworks */
qemuListDefinedNetworks, /* listDefinedNetworks */
qemuNetworkLookupByUUID, /* networkLookupByUUID */
qemuNetworkLookupByName, /* networkLookupByName */
qemuNetworkCreateXML , /* networkCreateXML */
qemuNetworkDefineXML , /* networkDefineXML */
qemuNetworkUndefine, /* networkUndefine */
qemuNetworkCreate, /* networkCreate */
qemuNetworkDestroy, /* networkDestroy */
qemuNetworkDumpXML, /* networkDumpXML */
};
void qemuRegister(void) {
virRegisterDriver(&qemuDriver);
virRegisterDriver(&qemuNetworkDriver);
}