-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:
- 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
* 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
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);
qemudDispatchNumDefinedDomains,
qemudDispatchDomainStart,
qemudDispatchDomainDefine,
- qemudDispatchDomainUndefine
+ qemudDispatchDomainUndefine,
+ qemudDispatchNumNetworks,
+ qemudDispatchListNetworks,
+ qemudDispatchNumDefinedNetworks,
+ qemudDispatchListDefinedNetworks,
+ qemudDispatchNetworkLookupByUUID,
+ qemudDispatchNetworkLookupByName,
+ qemudDispatchNetworkCreate,
+ qemudDispatchNetworkDefine,
+ qemudDispatchNetworkUndefine,
+ qemudDispatchNetworkStart,
+ qemudDispatchNetworkDestroy,
+ qemudDispatchNetworkDumpXML,
};
clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
NULL,
NULL,
NULL,
+ qemudDispatchNumNetworks,
+ qemudDispatchListNetworks,
+ qemudDispatchNumDefinedNetworks,
+ qemudDispatchListDefinedNetworks,
+ qemudDispatchNetworkLookupByUUID,
+ qemudDispatchNetworkLookupByName,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ qemudDispatchNetworkDumpXML,
};
/*
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:
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
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;
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;
#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 */
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 */
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);
}
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,
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);
}