Add the obvious parts of the QEMU implementation of the autostart API. Signed-off-by: Mark McLoughlin <markmc@xxxxxxxxxx> Index: libvirt/qemud/dispatch.c =================================================================== --- libvirt.orig/qemud/dispatch.c +++ libvirt/qemud/dispatch.c @@ -717,6 +717,97 @@ static int qemudDispatchNetworkGetBridge 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, }; /* Index: libvirt/qemud/driver.c =================================================================== --- libvirt.orig/qemud/driver.c +++ libvirt/qemud/driver.c @@ -506,6 +506,41 @@ int qemudDomainUndefine(struct qemud_ser 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; @@ -676,6 +711,41 @@ int qemudNetworkGetBridgeName(struct qem 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 Index: libvirt/qemud/driver.h =================================================================== --- libvirt.orig/qemud/driver.h +++ libvirt/qemud/driver.h @@ -85,6 +85,12 @@ struct qemud_vm *qemudDomainDefine(struc 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 qem 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 Index: libvirt/qemud/internal.h =================================================================== --- libvirt.orig/qemud/internal.h +++ libvirt/qemud/internal.h @@ -210,6 +210,7 @@ struct qemud_vm { struct qemud_vm_def *newDef; /* New definition to activate at shutdown */ unsigned int active : 1; + unsigned int autostart : 1; struct qemud_vm *next; }; @@ -249,6 +250,7 @@ struct qemud_network { int dnsmasqPid; unsigned int active : 1; + unsigned int autostart : 1; struct qemud_network *next; }; Index: libvirt/qemud/protocol.h =================================================================== --- libvirt.orig/qemud/protocol.h +++ libvirt/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 */ Index: libvirt/src/qemu_internal.c =================================================================== --- libvirt.orig/src/qemu_internal.c +++ libvirt/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(v 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 qemuNetworkDrive qemuNetworkDestroy, /* networkDestroy */ qemuNetworkDumpXML, /* networkDumpXML */ qemuNetworkGetBridgeName, /* networkGetBridgeName */ - NULL, /* networkGetAutostart */ - NULL, /* networkSetAutostart */ + qemuNetworkGetAutostart, /* networkGetAutostart */ + qemuNetworkSetAutostart, /* networkSetAutostart */ }; void qemuRegister(void) { --