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: * 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() - split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs 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, * qemud/conf.c: handle an unspecified MAC address,
fix the argv freeing code in qemudBuildCommandLine() fix the argv freeing code in qemudBuildCommandLine()
and fix copy and paste error in qemudGenerateXML() 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 * src/internal.h: add virConnect->qemud_fd so that
xen and qemu don't share the handle member. xen and qemu don't share the handle member.
* src/hash.c, src/qemu_internal.c: update * 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/conf.c, qemud/dispatch.c, qemud/driver.c,
qemud/qemud.c: include autoconf's config.h 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 * conf.[ch]: rename from config.[ch] so we can use
autoconf's config.h 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. * 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 * autogen.sh: run autoheader

View File

@ -462,6 +462,243 @@ static int qemudDispatchDomainUndefine(struct qemud_server *server, struct qemud
return 0; 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, typedef int (*clientFunc)(struct qemud_server *server, struct qemud_client *client,
struct qemud_packet *in, struct qemud_packet *out); struct qemud_packet *in, struct qemud_packet *out);
@ -490,7 +727,19 @@ clientFunc funcsTransmitRW[QEMUD_PKT_MAX] = {
qemudDispatchNumDefinedDomains, qemudDispatchNumDefinedDomains,
qemudDispatchDomainStart, qemudDispatchDomainStart,
qemudDispatchDomainDefine, qemudDispatchDomainDefine,
qemudDispatchDomainUndefine qemudDispatchDomainUndefine,
qemudDispatchNumNetworks,
qemudDispatchListNetworks,
qemudDispatchNumDefinedNetworks,
qemudDispatchListDefinedNetworks,
qemudDispatchNetworkLookupByUUID,
qemudDispatchNetworkLookupByName,
qemudDispatchNetworkCreate,
qemudDispatchNetworkDefine,
qemudDispatchNetworkUndefine,
qemudDispatchNetworkStart,
qemudDispatchNetworkDestroy,
qemudDispatchNetworkDumpXML,
}; };
clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = { clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
@ -515,6 +764,18 @@ clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
NULL, NULL,
NULL, 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; 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: * Local variables:

View File

@ -86,6 +86,34 @@ struct qemud_vm *qemudDomainDefine(struct qemud_server *server,
int qemudDomainUndefine(struct qemud_server *server, int qemudDomainUndefine(struct qemud_server *server,
const unsigned char *uuid); 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 #endif

View File

@ -199,6 +199,18 @@ struct qemud_vm {
struct qemud_vm *next; 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 */ /* Stores the per-client connection state */
struct qemud_client { struct qemud_client {
int fd; int fd;

View File

@ -50,6 +50,18 @@ enum {
QEMUD_PKT_DOMAIN_START, QEMUD_PKT_DOMAIN_START,
QEMUD_PKT_DOMAIN_DEFINE, QEMUD_PKT_DOMAIN_DEFINE,
QEMUD_PKT_DOMAIN_UNDEFINE, 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_PKT_MAX,
} qemud_packet_type; } qemud_packet_type;
@ -62,6 +74,7 @@ enum {
#define QEMUD_MAX_NAME_LEN 50 #define QEMUD_MAX_NAME_LEN 50
#define QEMUD_MAX_XML_LEN 4096 #define QEMUD_MAX_XML_LEN 4096
#define QEMUD_MAX_NUM_DOMAINS 100 #define QEMUD_MAX_NUM_DOMAINS 100
#define QEMUD_MAX_NUM_NETWORKS 100
#define QEMUD_MAX_ERROR_LEN 1024 #define QEMUD_MAX_ERROR_LEN 1024
/* Possible guest VM states */ /* Possible guest VM states */
@ -200,6 +213,63 @@ union qemud_packet_data {
struct { struct {
unsigned char uuid[QEMUD_UUID_RAW_LEN]; unsigned char uuid[QEMUD_UUID_RAW_LEN];
} domainUndefineRequest; } 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 */ /* Each packet has header & data */

View File

@ -61,7 +61,7 @@ qemuError(virConnectPtr con,
return; return;
errmsg = __virErrorMsg(error, info); 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); errmsg, info, NULL, 0, 0, errmsg, info, 0);
} }
@ -806,6 +806,276 @@ static int qemuUndefine(virDomainPtr dom) {
return ret; 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 = { static virDriver qemuDriver = {
VIR_DRV_QEMU, VIR_DRV_QEMU,
@ -849,8 +1119,26 @@ static virDriver qemuDriver = {
NULL, /* domainDetachDevice */ 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) { void qemuRegister(void) {
virRegisterDriver(&qemuDriver); virRegisterDriver(&qemuDriver);
virRegisterDriver(&qemuNetworkDriver);
} }