]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Tue Feb 14 15:52:34 EST 2007 Mark McLoughlin <markmc@redhat.com>
authorMark McLoughlin <markmc@redhat.com>
Wed, 14 Feb 2007 15:54:10 +0000 (15:54 +0000)
committerMark McLoughlin <markmc@redhat.com>
Wed, 14 Feb 2007 15:54:10 +0000 (15:54 +0000)
        * 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

ChangeLog
qemud/dispatch.c
qemud/driver.c
qemud/driver.h
qemud/internal.h
qemud/protocol.h
src/qemu_internal.c

index eef7640e4d459b257460d14d28424350243edc8d..345f79a54a664d322b7461b6a34531a5255c01b4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
 
index 13d3a263b9d3b70137e6a4990d036afe9431764c..195b3d85c2820e00090ab6134368d895dfea60b1 100644 (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,
 };
 
 /*
index 1ccfceb47becd040732218c905c48cc9d9e00ee7..9b16f3247ddf53ca0a78b6ee0b85863da8e392a4 100644 (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:
index 1b264c3f2473a596fa9b9fe00728a1cfeb0bbcae..3f56bb45c11967bf809149e4dacfe47beb96a53f 100644 (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
 
 
index b308f7c88735d40aacd578e109bb4cbe58164ce8..a52d3895b3e7f75d5319ca38870b840a6f620b7f 100644 (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;
index 85392ba352534bf83743627e1cc5ed433ea82b36..176428c91ffe599d37f51a07a38b545374e0e215 100644 (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 */
index dce3e324413d03af3b77b98befb270e4f8e7ef2c..ca82af48c685934c888481785c64f6b7e4fc30d7 100644 (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);
 }