From efe538b7094e66842767aa4dc65704e786165f12 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 23 Feb 2007 09:03:25 +0000
Subject: [PATCH] Fri Feb 23 09:00:13 IST 2007 Mark McLoughlin
 <markmc@redhat.com>

        * qemud/protocol.h: add the (domain/network)(Get/Set)Autostart
        requests and replies to the protocol.

        * src/qemu_internal.c: hookup the qemu driver autostart
        methods

        * qemud/dispatch.c, qemud/driver.[ch], internal.h: add
        the daemon side, but just set an in-memory autostart
        flag for now.
---
 ChangeLog           | 12 ++++++
 qemud/dispatch.c    | 99 +++++++++++++++++++++++++++++++++++++++++++++
 qemud/driver.c      | 70 ++++++++++++++++++++++++++++++++
 qemud/driver.h      | 12 ++++++
 qemud/internal.h    |  3 ++
 qemud/protocol.h    | 24 +++++++++++
 src/qemu_internal.c | 74 +++++++++++++++++++++++++++++++--
 7 files changed, 290 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5584813b53..ed0057ac21 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Fri Feb 23 09:00:13 IST 2007 Mark McLoughlin <markmc@redhat.com>
+
+	* qemud/protocol.h: add the (domain/network)(Get/Set)Autostart
+	requests and replies to the protocol.
+
+	* src/qemu_internal.c: hookup the qemu driver autostart
+	methods
+
+	* qemud/dispatch.c, qemud/driver.[ch], internal.h: add
+	the daemon side, but just set an in-memory autostart
+	flag for now.
+	
 Fri Feb 23 08:51:05 IST 2007 Mark McLoughlin <markmc@redhat.com>
 
 	* src/virsh.c: add "autostart" and "net-autostart" commands
diff --git a/qemud/dispatch.c b/qemud/dispatch.c
index 5d010a3632..79a657dad1 100644
--- a/qemud/dispatch.c
+++ b/qemud/dispatch.c
@@ -717,6 +717,97 @@ static int qemudDispatchNetworkGetBridgeName(struct qemud_server *server, struct
     return 0;
 }
 
+static int qemudDispatchDomainGetAutostart(struct qemud_server *server, struct qemud_client *client,
+                                           struct qemud_packet *in, struct qemud_packet *out)
+{
+    int ret;
+    int autostart;
+
+    if (in->header.dataSize != sizeof(in->data.domainGetAutostartRequest))
+        return -1;
+
+    autostart = 0;
+
+    ret = qemudDomainGetAutostart(server,
+                                  in->data.domainGetAutostartRequest.uuid,
+                                  &autostart);
+    if (ret < 0) {
+        if (qemudDispatchFailure(server, client, out) < 0)
+            return -1;
+    } else {
+        out->header.type = QEMUD_PKT_DOMAIN_GET_AUTOSTART;
+        out->header.dataSize = sizeof(out->data.networkGetAutostartReply);
+        out->data.networkGetAutostartReply.autostart = (autostart != 0);
+    }
+    return 0;
+}
+
+static int qemudDispatchDomainSetAutostart(struct qemud_server *server, struct qemud_client *client,
+                                           struct qemud_packet *in, struct qemud_packet *out)
+{
+    int ret;
+
+    if (in->header.dataSize != sizeof(in->data.domainSetAutostartRequest))
+        return -1;
+
+    ret = qemudDomainSetAutostart(server,
+                                  in->data.domainGetAutostartRequest.uuid,
+                                  in->data.domainSetAutostartRequest.autostart);
+    if (ret < 0) {
+        if (qemudDispatchFailure(server, client, out) < 0)
+            return -1;
+    } else {
+        out->header.type = QEMUD_PKT_DOMAIN_SET_AUTOSTART;
+        out->header.dataSize = 0;
+    }
+    return 0;
+}
+
+static int qemudDispatchNetworkGetAutostart(struct qemud_server *server, struct qemud_client *client,
+                                            struct qemud_packet *in, struct qemud_packet *out)
+{
+    int ret;
+    int autostart;
+
+    if (in->header.dataSize != sizeof(in->data.networkGetAutostartRequest))
+        return -1;
+
+    autostart = 0;
+
+    ret = qemudNetworkGetAutostart(server,
+                                   in->data.networkGetAutostartRequest.uuid,
+                                   &autostart);
+    if (ret < 0) {
+        if (qemudDispatchFailure(server, client, out) < 0)
+            return -1;
+    } else {
+        out->header.type = QEMUD_PKT_NETWORK_GET_AUTOSTART;
+        out->header.dataSize = sizeof(out->data.networkGetAutostartReply);
+        out->data.networkGetAutostartReply.autostart = (autostart != 0);
+    }
+    return 0;
+}
+
+static int qemudDispatchNetworkSetAutostart(struct qemud_server *server, struct qemud_client *client,
+                                            struct qemud_packet *in, struct qemud_packet *out)
+{
+    int ret;
+
+    if (in->header.dataSize != sizeof(in->data.networkSetAutostartRequest))
+        return -1;
+
+    ret = qemudNetworkSetAutostart(server,
+                                   in->data.networkGetAutostartRequest.uuid,
+                                   in->data.networkSetAutostartRequest.autostart);
+    if (ret < 0) {
+        if (qemudDispatchFailure(server, client, out) < 0)
+            return -1;
+    } else {
+        out->header.type = QEMUD_PKT_NETWORK_SET_AUTOSTART;
+        out->header.dataSize = 0;
+    }
+    return 0;
+}
 
 typedef int (*clientFunc)(struct qemud_server *server, struct qemud_client *client,
                           struct qemud_packet *in, struct qemud_packet *out);
@@ -759,6 +850,10 @@ clientFunc funcsTransmitRW[QEMUD_PKT_MAX] = {
     qemudDispatchNetworkDestroy,
     qemudDispatchNetworkDumpXML,
     qemudDispatchNetworkGetBridgeName,
+    qemudDispatchDomainGetAutostart,
+    qemudDispatchDomainSetAutostart,
+    qemudDispatchNetworkGetAutostart,
+    qemudDispatchNetworkSetAutostart,
 };
 
 clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
@@ -796,6 +891,10 @@ clientFunc funcsTransmitRO[QEMUD_PKT_MAX] = {
     NULL,
     qemudDispatchNetworkDumpXML,
     qemudDispatchNetworkGetBridgeName,
+    qemudDispatchDomainGetAutostart,
+    NULL,
+    qemudDispatchNetworkGetAutostart,
+    NULL,
 };
 
 /*
diff --git a/qemud/driver.c b/qemud/driver.c
index aa62910173..8aa049f026 100644
--- a/qemud/driver.c
+++ b/qemud/driver.c
@@ -509,6 +509,41 @@ int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid)
     return 0;
 }
 
+int qemudDomainGetAutostart(struct qemud_server *server,
+                             const unsigned char *uuid,
+                             int *autostart) {
+    struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+
+    if (!vm) {
+        qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
+        return -1;
+    }
+
+    *autostart = vm->autostart;
+
+    return 0;
+}
+
+int qemudDomainSetAutostart(struct qemud_server *server,
+                             const unsigned char *uuid,
+                             int autostart) {
+    struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
+
+    if (!vm) {
+        qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
+        return -1;
+    }
+
+    autostart = (autostart != 0);
+
+    if (vm->autostart == autostart)
+        return 0;
+
+    vm->autostart = autostart;
+
+    return 0;
+}
+
 struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
                                              const unsigned char *uuid) {
     struct qemud_network *network = server->networks;
@@ -685,6 +720,41 @@ int qemudNetworkGetBridgeName(struct qemud_server *server, const unsigned char *
     return 0;
 }
 
+int qemudNetworkGetAutostart(struct qemud_server *server,
+                             const unsigned char *uuid,
+                             int *autostart) {
+    struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+
+    if (!network) {
+        qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
+        return -1;
+    }
+
+    *autostart = network->autostart;
+
+    return 0;
+}
+
+int qemudNetworkSetAutostart(struct qemud_server *server,
+                             const unsigned char *uuid,
+                             int autostart) {
+    struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
+
+    if (!network) {
+        qemudReportError(server, VIR_ERR_INVALID_NETWORK, "no network with matching uuid");
+        return -1;
+    }
+
+    autostart = (autostart != 0);
+
+    if (network->autostart == autostart)
+        return 0;
+
+    network->autostart = autostart;
+
+    return 0;
+}
+
 /*
  * Local variables:
  *  indent-tabs-mode: nil
diff --git a/qemud/driver.h b/qemud/driver.h
index ac67f93ebb..8c6e7c302e 100644
--- a/qemud/driver.h
+++ b/qemud/driver.h
@@ -85,6 +85,12 @@ struct qemud_vm *qemudDomainDefine(struct qemud_server *server,
                                    const char *xml);
 int qemudDomainUndefine(struct qemud_server *server,
                         const unsigned char *uuid);
+int qemudDomainGetAutostart(struct qemud_server *server,
+                            const unsigned char *uuid,
+                            int *autostart);
+int qemudDomainSetAutostart(struct qemud_server *server,
+                            const unsigned char *uuid,
+                            int autostart);
 
 struct qemud_network *qemudFindNetworkByUUID(const struct qemud_server *server,
                                              const unsigned char *uuid);
@@ -117,6 +123,12 @@ int qemudNetworkGetBridgeName(struct qemud_server *server,
                               const unsigned char *uuid,
                               char *ifname,
                               int ifnamelen);
+int qemudNetworkGetAutostart(struct qemud_server *server,
+                             const unsigned char *uuid,
+                             int *autostart);
+int qemudNetworkSetAutostart(struct qemud_server *server,
+                             const unsigned char *uuid,
+                             int autostart);
 
 #endif
 
diff --git a/qemud/internal.h b/qemud/internal.h
index 10e337256b..e575d5bb7c 100644
--- a/qemud/internal.h
+++ b/qemud/internal.h
@@ -209,6 +209,8 @@ struct qemud_vm {
     struct qemud_vm_def *def; /* The current definition */
     struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
 
+    unsigned int autostart : 1;
+
     struct qemud_vm *next;
 };
 
@@ -247,6 +249,7 @@ struct qemud_network {
     int dnsmasqPid;
 
     unsigned int active : 1;
+    unsigned int autostart : 1;
 
     struct qemud_network *next;
 };
diff --git a/qemud/protocol.h b/qemud/protocol.h
index 7e6cc33f0d..07847e36a6 100644
--- a/qemud/protocol.h
+++ b/qemud/protocol.h
@@ -64,6 +64,10 @@ enum {
     QEMUD_PKT_NETWORK_DESTROY,
     QEMUD_PKT_NETWORK_DUMP_XML,
     QEMUD_PKT_NETWORK_GET_BRIDGE_NAME,
+    QEMUD_PKT_DOMAIN_GET_AUTOSTART,
+    QEMUD_PKT_DOMAIN_SET_AUTOSTART,
+    QEMUD_PKT_NETWORK_GET_AUTOSTART,
+    QEMUD_PKT_NETWORK_SET_AUTOSTART,
 
     QEMUD_PKT_MAX,
 } qemud_packet_type;
@@ -279,6 +283,26 @@ union qemud_packet_data {
     struct {
         char ifname[QEMUD_MAX_IFNAME_LEN];
     } networkGetBridgeNameReply;
+    struct {
+        unsigned char uuid[QEMUD_UUID_RAW_LEN];
+    } domainGetAutostartRequest;
+    struct {
+        int autostart;
+    } domainGetAutostartReply;
+    struct {
+        unsigned char uuid[QEMUD_UUID_RAW_LEN];
+        unsigned int autostart : 1;
+    } domainSetAutostartRequest;
+    struct {
+        unsigned char uuid[QEMUD_UUID_RAW_LEN];
+    } networkGetAutostartRequest;
+    struct {
+        unsigned int autostart : 1;
+    } networkGetAutostartReply;
+    struct {
+        unsigned char uuid[QEMUD_UUID_RAW_LEN];
+        unsigned int autostart : 1;
+    } networkSetAutostartRequest;
 };
 
 /* Each packet has header & data */
diff --git a/src/qemu_internal.c b/src/qemu_internal.c
index ba4595506f..19ff45c14d 100644
--- a/src/qemu_internal.c
+++ b/src/qemu_internal.c
@@ -806,6 +806,39 @@ static int qemuUndefine(virDomainPtr dom) {
     return ret;
 }
 
+static int qemuDomainGetAutostart(virDomainPtr dom,
+                                  int *autostart) {
+    struct qemud_packet req, reply;
+
+    req.header.type = QEMUD_PKT_DOMAIN_GET_AUTOSTART;
+    req.header.dataSize = sizeof(req.data.domainGetAutostartRequest);
+    memmove(req.data.domainGetAutostartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
+
+    if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+        return -1;
+    }
+
+    *autostart = reply.data.domainGetAutostartReply.autostart;
+
+    return 0;
+}
+
+static int qemuDomainSetAutostart(virDomainPtr dom,
+                                  int autostart) {
+    struct qemud_packet req, reply;
+
+    req.header.type = QEMUD_PKT_DOMAIN_SET_AUTOSTART;
+    req.header.dataSize = sizeof(req.data.domainSetAutostartRequest);
+    req.data.domainSetAutostartRequest.autostart = (autostart != 0);
+    memmove(req.data.domainSetAutostartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
+
+    if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
 static int qemuNetworkOpen(virConnectPtr conn,
                            const char *name,
                            int flags) {
@@ -1093,6 +1126,39 @@ static char * qemuNetworkGetBridgeName(virNetworkPtr network) {
     return strdup(reply.data.networkGetBridgeNameReply.ifname);
 }
 
+static int qemuNetworkGetAutostart(virNetworkPtr network,
+                                   int *autostart) {
+    struct qemud_packet req, reply;
+
+    req.header.type = QEMUD_PKT_NETWORK_GET_AUTOSTART;
+    req.header.dataSize = sizeof(req.data.networkGetAutostartRequest);
+    memmove(req.data.networkGetAutostartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
+
+    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+        return -1;
+    }
+
+    *autostart = reply.data.networkGetAutostartReply.autostart;
+
+    return 0;
+}
+
+static int qemuNetworkSetAutostart(virNetworkPtr network,
+                                   int autostart) {
+    struct qemud_packet req, reply;
+
+    req.header.type = QEMUD_PKT_NETWORK_SET_AUTOSTART;
+    req.header.dataSize = sizeof(req.data.networkSetAutostartRequest);
+    req.data.networkSetAutostartRequest.autostart = (autostart != 0);
+    memmove(req.data.networkSetAutostartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
+
+    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
 static virDriver qemuDriver = {
     VIR_DRV_QEMU,
     "QEMU",
@@ -1132,8 +1198,8 @@ static virDriver qemuDriver = {
     qemuUndefine, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
-    NULL, /* domainGetAutostart */
-    NULL, /* domainSetAutostart */
+    qemuDomainGetAutostart, /* domainGetAutostart */
+    qemuDomainSetAutostart, /* domainSetAutostart */
 };
 
 static virNetworkDriver qemuNetworkDriver = {
@@ -1152,8 +1218,8 @@ static virNetworkDriver qemuNetworkDriver = {
     qemuNetworkDestroy, /* networkDestroy */
     qemuNetworkDumpXML, /* networkDumpXML */
     qemuNetworkGetBridgeName, /* networkGetBridgeName */
-    NULL, /* networkGetAutostart */
-    NULL, /* networkSetAutostart */
+    qemuNetworkGetAutostart, /* networkGetAutostart */
+    qemuNetworkSetAutostart, /* networkSetAutostart */
 };
 
 void qemuRegister(void) {
-- 
GitLab