]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Refactor to allowing changing config of active domains
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 14 Feb 2007 17:05:55 +0000 (17:05 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 14 Feb 2007 17:05:55 +0000 (17:05 +0000)
ChangeLog
qemud/conf.c
qemud/conf.h
qemud/dispatch.c
qemud/driver.c
qemud/internal.h
qemud/qemud.c

index ff9125656eb3af3e8b0be64db59683cd351c2937..bd0e945b331812d5c255d9f650cc61ebf528efa1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Feb 14 11:58:24 EST 2007 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/qemud.c, src/conf.c, src/internal.c, src/driver.c: Change
+       the handling of the internal VM config to allow replacing of the
+       config for a VM which is running.
+
 Tue Feb 14 16:53:25 IST 2007 Mark McLoughlin <markmc@redhat.com>
 
        Fix from Richard W.M. Jones <rjones@redhat.com>
index 90e749e764013e931e9a2e56cb9ae7fcd5cff543..4d5295386ac52b26930331ccda34a9703f01a834 100644 (file)
@@ -93,6 +93,29 @@ static int qemudParseUUID(const char *uuid,
     return -1;
 }
 
+/* Free all memory associated with a struct qemud_vm object */
+void qemudFreeVMDef(struct qemud_vm_def *def) {
+    struct qemud_vm_disk_def *disk = def->disks;
+    struct qemud_vm_net_def *net = def->nets;
+
+    while (disk) {
+        struct qemud_vm_disk_def *prev = disk;
+        disk = disk->next;
+        free(prev);
+    }
+    while (net) {
+        struct qemud_vm_net_def *prev = net;
+        net = net->next;
+        free(prev);
+    }
+}
+
+void qemudFreeVM(struct qemud_vm *vm) {
+    qemudFreeVMDef(vm->def);
+    if (vm->newDef)
+        qemudFreeVMDef(vm->newDef);
+    free(vm);
+}
 
 /* Build up a fully qualfiied path for a config file to be
  * associated with a persistent guest or network */
@@ -482,15 +505,20 @@ static struct qemud_vm_net_def *qemudParseInterfaceXML(struct qemud_server *serv
  * Parses a libvirt XML definition of a guest, and populates the
  * the qemud_vm struct with matching data about the guests config
  */
-static int qemudParseXML(struct qemud_server *server,
-                         xmlDocPtr xml,
-                         struct qemud_vm *vm) {
+static struct qemud_vm_def *qemudParseXML(struct qemud_server *server,
+                                          xmlDocPtr xml) {
     xmlNodePtr root = NULL;
     xmlChar *prop = NULL;
     xmlXPathContextPtr ctxt = NULL;
     xmlXPathObjectPtr obj = NULL;
     char *conv = NULL;
     int i;
+    struct qemud_vm_def *def;
+
+    if (!(def = calloc(1, sizeof(struct qemud_vm_def)))) {
+        qemudReportError(server, VIR_ERR_NO_MEMORY, "xmlXPathContext");
+        return NULL;
+    }
 
     /* Prepare parser / xpath context */
     root = xmlDocGetRootElement(xml);
@@ -513,11 +541,11 @@ static int qemudParseXML(struct qemud_server *server,
     }
 
     if (!strcmp((char *)prop, "qemu"))
-        vm->def.virtType = QEMUD_VIRT_QEMU;
+        def->virtType = QEMUD_VIRT_QEMU;
     else if (!strcmp((char *)prop, "kqemu"))
-        vm->def.virtType = QEMUD_VIRT_KQEMU;
+        def->virtType = QEMUD_VIRT_KQEMU;
     else if (!strcmp((char *)prop, "kvm"))
-        vm->def.virtType = QEMUD_VIRT_KVM;
+        def->virtType = QEMUD_VIRT_KVM;
     else {
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "invalid domain type attribute");
         goto error;
@@ -537,7 +565,7 @@ static int qemudParseXML(struct qemud_server *server,
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "domain name length too long");
         goto error;
     }
-    strcpy(vm->def.name, (const char *)obj->stringval);
+    strcpy(def->name, (const char *)obj->stringval);
     xmlXPathFreeObject(obj);
 
 
@@ -549,7 +577,7 @@ static int qemudParseXML(struct qemud_server *server,
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "missing uuid element");
         goto error;
     }
-    if (qemudParseUUID((const char *)obj->stringval, vm->def.uuid) < 0) {
+    if (qemudParseUUID((const char *)obj->stringval, def->uuid) < 0) {
         qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed uuid element");
         goto error;
     }
@@ -564,7 +592,7 @@ static int qemudParseXML(struct qemud_server *server,
         goto error;
     } else {
         conv = NULL;
-        vm->def.maxmem = strtoll((const char*)obj->stringval, &conv, 10);
+        def->maxmem = strtoll((const char*)obj->stringval, &conv, 10);
         if (conv == (const char*)obj->stringval) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed memory information");
             goto error;
@@ -578,12 +606,12 @@ static int qemudParseXML(struct qemud_server *server,
     obj = xmlXPathEval(BAD_CAST "string(/domain/currentMemory[1])", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_STRING) ||
         (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        vm->def.memory = vm->def.maxmem;
+        def->memory = def->maxmem;
     } else {
         conv = NULL;
-        vm->def.memory = strtoll((const char*)obj->stringval, &conv, 10);
-        if (vm->def.memory > vm->def.maxmem)
-            vm->def.memory = vm->def.maxmem;
+        def->memory = strtoll((const char*)obj->stringval, &conv, 10);
+        if (def->memory > def->maxmem)
+            def->memory = def->maxmem;
         if (conv == (const char*)obj->stringval) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed memory information");
             goto error;
@@ -596,10 +624,10 @@ static int qemudParseXML(struct qemud_server *server,
     obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_STRING) ||
         (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        vm->def.vcpus = 1;
+        def->vcpus = 1;
     } else {
         conv = NULL;
-        vm->def.vcpus = strtoll((const char*)obj->stringval, &conv, 10);
+        def->vcpus = strtoll((const char*)obj->stringval, &conv, 10);
         if (conv == (const char*)obj->stringval) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed vcpu information");
             goto error;
@@ -612,7 +640,7 @@ static int qemudParseXML(struct qemud_server *server,
     obj = xmlXPathEval(BAD_CAST "/domain/features/acpi", ctxt);
     if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
         (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
-        vm->def.features |= QEMUD_FEATURE_ACPI;
+        def->features |= QEMUD_FEATURE_ACPI;
     }
 
     /* Extract OS type info */
@@ -626,7 +654,7 @@ static int qemudParseXML(struct qemud_server *server,
         qemudReportError(server, VIR_ERR_OS_TYPE, "%s", obj->stringval);
         goto error;
     }
-    strcpy(vm->def.os.type, (const char *)obj->stringval);
+    strcpy(def->os.type, (const char *)obj->stringval);
     xmlXPathFreeObject(obj);
 
 
@@ -638,13 +666,13 @@ static int qemudParseXML(struct qemud_server *server,
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "architecture type too long");
             goto error;
         }
-        strcpy(vm->def.os.arch, defaultArch);
+        strcpy(def->os.arch, defaultArch);
     } else {
         if (strlen((const char *)obj->stringval) >= (QEMUD_OS_TYPE_MAX_LEN-1)) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "architecture type too long");
             goto error;
         }
-        strcpy(vm->def.os.arch, (const char *)obj->stringval);
+        strcpy(def->os.arch, (const char *)obj->stringval);
     }
     if (obj)
         xmlXPathFreeObject(obj);
@@ -652,18 +680,18 @@ static int qemudParseXML(struct qemud_server *server,
     obj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1]/@machine)", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_STRING) ||
         (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        const char *defaultMachine = qemudDefaultMachineForArch(vm->def.os.arch);
+        const char *defaultMachine = qemudDefaultMachineForArch(def->os.arch);
         if (strlen(defaultMachine) >= (QEMUD_OS_MACHINE_MAX_LEN-1)) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "machine type too long");
             goto error;
         }
-        strcpy(vm->def.os.machine, defaultMachine);
+        strcpy(def->os.machine, defaultMachine);
     } else {
         if (strlen((const char *)obj->stringval) >= (QEMUD_OS_MACHINE_MAX_LEN-1)) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "architecture type too long");
             goto error;
         }
-        strcpy(vm->def.os.machine, (const char *)obj->stringval);
+        strcpy(def->os.machine, (const char *)obj->stringval);
     }
     if (obj)
         xmlXPathFreeObject(obj);
@@ -676,7 +704,7 @@ static int qemudParseXML(struct qemud_server *server,
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "kernel path too long");
             goto error;
         }
-        strcpy(vm->def.os.kernel, (const char *)obj->stringval);
+        strcpy(def->os.kernel, (const char *)obj->stringval);
     }
     if (obj)
         xmlXPathFreeObject(obj);
@@ -689,7 +717,7 @@ static int qemudParseXML(struct qemud_server *server,
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "initrd path too long");
             goto error;
         }
-        strcpy(vm->def.os.initrd, (const char *)obj->stringval);
+        strcpy(def->os.initrd, (const char *)obj->stringval);
     }
     if (obj)
         xmlXPathFreeObject(obj);
@@ -702,7 +730,7 @@ static int qemudParseXML(struct qemud_server *server,
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "cmdline arguments too long");
             goto error;
         }
-        strcpy(vm->def.os.cmdline, (const char *)obj->stringval);
+        strcpy(def->os.cmdline, (const char *)obj->stringval);
     }
     if (obj)
         xmlXPathFreeObject(obj);
@@ -715,40 +743,40 @@ static int qemudParseXML(struct qemud_server *server,
         for (i = 0; i < obj->nodesetval->nodeNr && i < QEMUD_MAX_BOOT_DEVS ; i++) {
             prop = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "dev");
             if (!strcmp((char *)prop, "hd")) {
-                vm->def.os.bootDevs[vm->def.os.nBootDevs++] = QEMUD_BOOT_DISK;
+                def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_DISK;
             } else if (!strcmp((char *)prop, "fd")) {
-                vm->def.os.bootDevs[vm->def.os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
+                def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_FLOPPY;
             } else if (!strcmp((char *)prop, "cdrom")) {
-                vm->def.os.bootDevs[vm->def.os.nBootDevs++] = QEMUD_BOOT_CDROM;
+                def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_CDROM;
             } else if (!strcmp((char *)prop, "net")) {
-                vm->def.os.bootDevs[vm->def.os.nBootDevs++] = QEMUD_BOOT_NET;
+                def->os.bootDevs[def->os.nBootDevs++] = QEMUD_BOOT_NET;
             } else {
                 goto error;
             }
         }
     }
     xmlXPathFreeObject(obj);
-    if (vm->def.os.nBootDevs == 0) {
-        vm->def.os.nBootDevs = 1;
-        vm->def.os.bootDevs[0] = QEMUD_BOOT_DISK;
+    if (def->os.nBootDevs == 0) {
+        def->os.nBootDevs = 1;
+        def->os.bootDevs[0] = QEMUD_BOOT_DISK;
     }
 
 
     obj = xmlXPathEval(BAD_CAST "string(/domain/devices/emulator[1])", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_STRING) ||
         (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
-        char *tmp = qemudLocateBinaryForArch(server, vm->def.virtType, vm->def.os.arch);
+        char *tmp = qemudLocateBinaryForArch(server, def->virtType, def->os.arch);
         if (!tmp) {
             goto error;
         }
-        strcpy(vm->def.os.binary, tmp);
+        strcpy(def->os.binary, tmp);
         free(tmp);
     } else {
         if (strlen((const char *)obj->stringval) >= (PATH_MAX-1)) {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "emulator path too long");
             goto error;
         }
-        strcpy(vm->def.os.binary, (const char *)obj->stringval);
+        strcpy(def->os.binary, (const char *)obj->stringval);
     }
     if (obj)
         xmlXPathFreeObject(obj);
@@ -756,20 +784,20 @@ static int qemudParseXML(struct qemud_server *server,
     obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
         (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) {
-        vm->def.graphicsType = QEMUD_GRAPHICS_NONE;
+        def->graphicsType = QEMUD_GRAPHICS_NONE;
     } else {
         prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type");
         if (!strcmp((char *)prop, "vnc")) {
-            vm->def.graphicsType = QEMUD_GRAPHICS_VNC;
+            def->graphicsType = QEMUD_GRAPHICS_VNC;
             prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "port");
             if (prop) {
                 conv = NULL;
-                vm->def.vncPort = strtoll((const char*)prop, &conv, 10);
+                def->vncPort = strtoll((const char*)prop, &conv, 10);
             } else {
-                vm->def.vncPort = -1;
+                def->vncPort = -1;
             }
         } else if (!strcmp((char *)prop, "sdl")) {
-            vm->def.graphicsType = QEMUD_GRAPHICS_SDL;
+            def->graphicsType = QEMUD_GRAPHICS_SDL;
         } else {
             qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "Unsupported graphics type %s", prop);
             goto error;
@@ -785,9 +813,9 @@ static int qemudParseXML(struct qemud_server *server,
             if (!(disk = qemudParseDiskXML(server, obj->nodesetval->nodeTab[i]))) {
                 goto error;
             }
-            vm->def.ndisks++;
-            disk->next = vm->def.disks;
-            vm->def.disks = disk;
+            def->ndisks++;
+            disk->next = def->disks;
+            def->disks = disk;
         }
     }
     xmlXPathFreeObject(obj);
@@ -802,15 +830,15 @@ static int qemudParseXML(struct qemud_server *server,
             if (!(net = qemudParseInterfaceXML(server, obj->nodesetval->nodeTab[i]))) {
                 goto error;
             }
-            vm->def.nnets++;
-            net->next = vm->def.nets;
-            vm->def.nets = net;
+            def->nnets++;
+            net->next = def->nets;
+            def->nets = net;
         }
     }
     xmlXPathFreeObject(obj);
     xmlXPathFreeContext(ctxt);
 
-    return 0;
+    return def;
 
  error:
     if (prop)
@@ -819,7 +847,8 @@ static int qemudParseXML(struct qemud_server *server,
         xmlXPathFreeObject(obj);
     if (ctxt)
         xmlXPathFreeContext(ctxt);
-    return -1;
+    qemudFreeVMDef(def);
+    return NULL;
 }
 
 
@@ -904,37 +933,37 @@ int qemudBuildCommandLine(struct qemud_server *server,
     char memory[50];
     char vcpus[50];
     char boot[QEMUD_MAX_BOOT_DEVS+1];
-    struct qemud_vm_disk_def *disk = vm->def.disks;
-    struct qemud_vm_net_def *net = vm->def.nets;
+    struct qemud_vm_disk_def *disk = vm->def->disks;
+    struct qemud_vm_net_def *net = vm->def->nets;
 
     len = 1 + /* qemu */
         2 + /* machine type */
-        (vm->def.virtType == QEMUD_VIRT_QEMU ? 1 : 0) + /* Disable kqemu */
-        2 * vm->def.ndisks + /* disks*/
-        (vm->def.nnets > 0 ? (4 * vm->def.nnets) : 2) + /* networks */
+        (vm->def->virtType == QEMUD_VIRT_QEMU ? 1 : 0) + /* Disable kqemu */
+        2 * vm->def->ndisks + /* disks*/
+        (vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */
         2 + /* memory*/
         2 + /* cpus */
         2 + /* boot device */
         2 + /* monitor */
-        (vm->def.features & QEMUD_FEATURE_ACPI ? 0 : 1) + /* acpi */
-        (vm->def.os.kernel[0] ? 2 : 0) + /* kernel */
-        (vm->def.os.initrd[0] ? 2 : 0) + /* initrd */
-        (vm->def.os.cmdline[0] ? 2 : 0) + /* cmdline */
-        (vm->def.graphicsType == QEMUD_GRAPHICS_VNC ? 2 :
-         (vm->def.graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)); /* graphics */
+        (vm->def->features & QEMUD_FEATURE_ACPI ? 0 : 1) + /* acpi */
+        (vm->def->os.kernel[0] ? 2 : 0) + /* kernel */
+        (vm->def->os.initrd[0] ? 2 : 0) + /* initrd */
+        (vm->def->os.cmdline[0] ? 2 : 0) + /* cmdline */
+        (vm->def->graphicsType == QEMUD_GRAPHICS_VNC ? 2 :
+         (vm->def->graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)); /* graphics */
 
-    sprintf(memory, "%d", vm->def.memory/1024);
-    sprintf(vcpus, "%d", vm->def.vcpus);
+    sprintf(memory, "%d", vm->def->memory/1024);
+    sprintf(vcpus, "%d", vm->def->vcpus);
 
     if (!(*argv = malloc(sizeof(char *) * (len+1))))
         goto no_memory;
-    if (!((*argv)[++n] = strdup(vm->def.os.binary)))
+    if (!((*argv)[++n] = strdup(vm->def->os.binary)))
         goto no_memory;
     if (!((*argv)[++n] = strdup("-M")))
         goto no_memory;
-    if (!((*argv)[++n] = strdup(vm->def.os.machine)))
+    if (!((*argv)[++n] = strdup(vm->def->os.machine)))
         goto no_memory;
-    if (vm->def.virtType == QEMUD_VIRT_QEMU) {
+    if (vm->def->virtType == QEMUD_VIRT_QEMU) {
         if (!((*argv)[++n] = strdup("-no-kqemu")))
         goto no_memory;
     }
@@ -952,13 +981,13 @@ int qemudBuildCommandLine(struct qemud_server *server,
     if (!((*argv)[++n] = strdup("pty")))
         goto no_memory;
 
-    if (!(vm->def.features & QEMUD_FEATURE_ACPI)) {
+    if (!(vm->def->features & QEMUD_FEATURE_ACPI)) {
     if (!((*argv)[++n] = strdup("-no-acpi")))
         goto no_memory;
     }
 
-    for (i = 0 ; i < vm->def.os.nBootDevs ; i++) {
-        switch (vm->def.os.bootDevs[i]) {
+    for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
+        switch (vm->def->os.bootDevs[i]) {
         case QEMUD_BOOT_CDROM:
             boot[i] = 'd';
             break;
@@ -976,28 +1005,28 @@ int qemudBuildCommandLine(struct qemud_server *server,
             break;
         }
     }
-    boot[vm->def.os.nBootDevs] = '\0';
+    boot[vm->def->os.nBootDevs] = '\0';
     if (!((*argv)[++n] = strdup("-boot")))
         goto no_memory;
     if (!((*argv)[++n] = strdup(boot)))
         goto no_memory;
 
-    if (vm->def.os.kernel[0]) {
+    if (vm->def->os.kernel[0]) {
         if (!((*argv)[++n] = strdup("-kernel")))
             goto no_memory;
-        if (!((*argv)[++n] = strdup(vm->def.os.kernel)))
+        if (!((*argv)[++n] = strdup(vm->def->os.kernel)))
             goto no_memory;
     }
-    if (vm->def.os.initrd[0]) {
+    if (vm->def->os.initrd[0]) {
         if (!((*argv)[++n] = strdup("-initrd")))
             goto no_memory;
-        if (!((*argv)[++n] = strdup(vm->def.os.initrd)))
+        if (!((*argv)[++n] = strdup(vm->def->os.initrd)))
             goto no_memory;
     }
-    if (vm->def.os.cmdline[0]) {
+    if (vm->def->os.cmdline[0]) {
         if (!((*argv)[++n] = strdup("-append")))
             goto no_memory;
-        if (!((*argv)[++n] = strdup(vm->def.os.cmdline)))
+        if (!((*argv)[++n] = strdup(vm->def->os.cmdline)))
             goto no_memory;
     }
 
@@ -1058,14 +1087,14 @@ int qemudBuildCommandLine(struct qemud_server *server,
         }
     }
 
-    if (vm->def.graphicsType == QEMUD_GRAPHICS_VNC) {
+    if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) {
         char port[10];
-        snprintf(port, 10, "%d", vm->def.vncActivePort - 5900);
+        snprintf(port, 10, "%d", vm->def->vncActivePort - 5900);
         if (!((*argv)[++n] = strdup("-vnc")))
             goto no_memory;
         if (!((*argv)[++n] = strdup(port)))
             goto no_memory;
-    } else if (vm->def.graphicsType == QEMUD_GRAPHICS_NONE) {
+    } else if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
         if (!((*argv)[++n] = strdup("-nographic")))
             goto no_memory;
     } else {
@@ -1094,24 +1123,6 @@ int qemudBuildCommandLine(struct qemud_server *server,
     return -1;
 }
 
-/* Free all memory associated with a struct qemud_vm object */
-void qemudFreeVM(struct qemud_vm *vm) {
-    struct qemud_vm_disk_def *disk = vm->def.disks;
-    struct qemud_vm_net_def *net = vm->def.nets;
-
-    while (disk) {
-        struct qemud_vm_disk_def *prev = disk;
-        disk = disk->next;
-        free(prev);
-    }
-    while (net) {
-        struct qemud_vm_net_def *prev = net;
-        net = net->next;
-        free(prev);
-    }
-
-    free(vm);
-}
 
 /* Save a guest's config data into a persistent file */
 static int qemudSaveConfig(struct qemud_server *server,
@@ -1120,7 +1131,7 @@ static int qemudSaveConfig(struct qemud_server *server,
     int fd = -1, ret = -1;
     int towrite;
 
-    if (!(xml = qemudGenerateXML(server, vm))) {
+    if (!(xml = qemudGenerateXML(server, vm, 0))) {
         return -1;
     }
 
@@ -1170,8 +1181,10 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
                                     const char *file,
                                     const char *doc,
                                     int save) {
+    struct qemud_vm_def *def = NULL;
     struct qemud_vm *vm = NULL;
     xmlDocPtr xml;
+    int newVM = 0;
 
     if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "domain.xml", NULL,
                            XML_PARSE_NOENT | XML_PARSE_NONET |
@@ -1180,34 +1193,34 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
         return NULL;
     }
 
-    if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
-        qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
-        return NULL;
-    }
-
-    vm->stdout = -1;
-    vm->stderr = -1;
-    vm->monitor = -1;
-    vm->pid = -1;
-    vm->def.id = -1;
-
-    if (qemudParseXML(server, xml, vm) < 0) {
+    if (!(def = qemudParseXML(server, xml))) {
         xmlFreeDoc(xml);
-        qemudFreeVM(vm);
         return NULL;
     }
     xmlFreeDoc(xml);
 
-    if (qemudFindVMByUUID(server, vm->def.uuid)) {
-        qemudReportError(server, VIR_ERR_DOM_EXIST, vm->def.name);
-        qemudFreeVM(vm);
-        return NULL;
-    }
+    if ((vm = qemudFindVMByName(server, def->name))) {
+        if (vm->id == -1) {
+            qemudFreeVMDef(vm->def);
+            vm->def = def;
+        } else {
+            if (vm->newDef)
+                qemudFreeVMDef(vm->newDef);
+            vm->newDef = def;
+        }
+    } else {
+        if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
+            qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
+            return NULL;
+        }
 
-    if (qemudFindVMByName(server, vm->def.name)) {
-        qemudReportError(server, VIR_ERR_DOM_EXIST, vm->def.name);
-        qemudFreeVM(vm);
-        return NULL;
+        vm->stdout = -1;
+        vm->stderr = -1;
+        vm->monitor = -1;
+        vm->pid = -1;
+        vm->id = -1;
+        vm->def = def;
+        newVM = 1;
     }
 
     if (file) {
@@ -1215,7 +1228,7 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
         vm->configFile[PATH_MAX-1] = '\0';
     } else {
         if (save) {
-            if (qemudMakeConfigPath(server->configDir, vm->def.name, ".xml", vm->configFile, PATH_MAX) < 0) {
+            if (qemudMakeConfigPath(server->configDir, vm->def->name, ".xml", vm->configFile, PATH_MAX) < 0) {
                 qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
                                  "cannot construct config file path");
                 qemudFreeVM(vm);
@@ -1231,6 +1244,12 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
         }
     }
 
+    if (newVM) {
+        vm->next = server->inactivevms;
+        server->inactivevms = vm;
+        server->ninactivevms++;
+    }
+
     return vm;
 }
 
@@ -1577,12 +1596,7 @@ static void qemudLoadConfig(struct qemud_server *server,
     xml[st.st_size] = '\0';
 
     if (isGuest) {
-        struct qemud_vm *vm;
-        if ((vm = qemudLoadConfigXML(server, file, xml, 1))) {
-            vm->next = server->inactivevms;
-            server->inactivevms = vm;
-            server->ninactivevms++;
-        }
+        qemudLoadConfigXML(server, file, xml, 1);
     } else {
         struct qemud_network *network;
         if ((network = qemudLoadNetworkConfigXML(server, file, xml, 1))) {
@@ -1591,7 +1605,6 @@ static void qemudLoadConfig(struct qemud_server *server,
             server->ninactivenetworks++;
         }
     }
-  
  cleanup:
     fclose(fh);
 }
@@ -1683,7 +1696,8 @@ int qemudBufferPrintf(struct qemudBuffer *buf,
 }
 
 /* Generate an XML document describing the guest's configuration */
-char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
+char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm, int live) {
+    struct qemud_vm_def *def = live ? vm->def : (vm->newDef ? vm->newDef : vm->def);
     struct qemudBuffer buf;
     unsigned char *uuid;
     struct qemud_vm_disk_def *disk;
@@ -1695,7 +1709,7 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
     buf.used = 0;
     buf.data = malloc(buf.len);
 
-    switch (vm->def.virtType) {
+    switch (def->virtType) {
     case QEMUD_VIRT_QEMU:
         type = "qemu";
         break;
@@ -1707,58 +1721,58 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
         break;
     }
     if (!type) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "unexpected domain type %d", vm->def.virtType);
+        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "unexpected domain type %d", def->virtType);
         goto cleanup;
     }
 
-    if (vm->def.id >= 0) {
-        if (qemudBufferPrintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->def.id) < 0)
+    if (vm->id >= 0) {
+        if (qemudBufferPrintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id) < 0)
             goto no_memory;
     } else {
         if (qemudBufferPrintf(&buf, "<domain type='%s'>\n", type) < 0)
             goto no_memory;
     }
 
-    if (qemudBufferPrintf(&buf, "  <name>%s</name>\n", vm->def.name) < 0)
+    if (qemudBufferPrintf(&buf, "  <name>%s</name>\n", def->name) < 0)
         goto no_memory;
 
-    uuid = vm->def.uuid;
+    uuid = def->uuid;
     if (qemudBufferPrintf(&buf, "  <uuid>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</uuid>\n",
                           uuid[0], uuid[1], uuid[2], uuid[3],
                           uuid[4], uuid[5], uuid[6], uuid[7],
                           uuid[8], uuid[9], uuid[10], uuid[11],
                           uuid[12], uuid[13], uuid[14], uuid[15]) < 0)
         goto no_memory;
-    if (qemudBufferPrintf(&buf, "  <memory>%d</memory>\n", vm->def.maxmem) < 0)
+    if (qemudBufferPrintf(&buf, "  <memory>%d</memory>\n", def->maxmem) < 0)
         goto no_memory;
-    if (qemudBufferPrintf(&buf, "  <currentMemory>%d</currentMemory>\n", vm->def.memory) < 0)
+    if (qemudBufferPrintf(&buf, "  <currentMemory>%d</currentMemory>\n", def->memory) < 0)
         goto no_memory;
-    if (qemudBufferPrintf(&buf, "  <vcpu>%d</vcpu>\n", vm->def.vcpus) < 0)
+    if (qemudBufferPrintf(&buf, "  <vcpu>%d</vcpu>\n", def->vcpus) < 0)
         goto no_memory;
 
     if (qemudBufferAdd(&buf, "  <os>\n") < 0)
         goto no_memory;
 
-    if (vm->def.virtType == QEMUD_VIRT_QEMU) {
+    if (def->virtType == QEMUD_VIRT_QEMU) {
         if (qemudBufferPrintf(&buf, "    <type arch='%s' machine='%s'>%s</type>\n",
-                              vm->def.os.arch, vm->def.os.machine, vm->def.os.type) < 0)
+                              def->os.arch, def->os.machine, def->os.type) < 0)
             goto no_memory;
     } else {
-        if (qemudBufferPrintf(&buf, "    <type>%s</type>\n", vm->def.os.type) < 0)
+        if (qemudBufferPrintf(&buf, "    <type>%s</type>\n", def->os.type) < 0)
             goto no_memory;
     }
 
-    if (vm->def.os.kernel[0])
-        if (qemudBufferPrintf(&buf, "    <kernel>%s</kernel>\n", vm->def.os.kernel) < 0)
+    if (def->os.kernel[0])
+        if (qemudBufferPrintf(&buf, "    <kernel>%s</kernel>\n", def->os.kernel) < 0)
             goto no_memory;
-    if (vm->def.os.initrd[0])
-        if (qemudBufferPrintf(&buf, "    <initrd>%s</initrd>\n", vm->def.os.initrd) < 0)
+    if (def->os.initrd[0])
+        if (qemudBufferPrintf(&buf, "    <initrd>%s</initrd>\n", def->os.initrd) < 0)
             goto no_memory;
-    if (vm->def.os.cmdline[0])
-        if (qemudBufferPrintf(&buf, "    <cmdline>%s</cmdline>\n", vm->def.os.cmdline) < 0)
+    if (def->os.cmdline[0])
+        if (qemudBufferPrintf(&buf, "    <cmdline>%s</cmdline>\n", def->os.cmdline) < 0)
             goto no_memory;
 
-    if (vm->def.features & QEMUD_FEATURE_ACPI) {
+    if (def->features & QEMUD_FEATURE_ACPI) {
         if (qemudBufferAdd(&buf, "  <features>\n") < 0)
             goto no_memory;
         if (qemudBufferAdd(&buf, "    <acpi>\n") < 0)
@@ -1768,9 +1782,9 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
     }
 
 
-    for (n = 0 ; n < vm->def.os.nBootDevs ; n++) {
+    for (n = 0 ; n < def->os.nBootDevs ; n++) {
         const char *boottype = "hd";
-        switch (vm->def.os.bootDevs[n]) {
+        switch (def->os.bootDevs[n]) {
         case QEMUD_BOOT_FLOPPY:
             boottype = "fd";
             break;
@@ -1794,10 +1808,10 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
     if (qemudBufferAdd(&buf, "  <devices>\n") < 0)
         goto no_memory;
 
-    if (qemudBufferPrintf(&buf, "    <emulator>%s</emulator>\n", vm->def.os.binary) < 0)
+    if (qemudBufferPrintf(&buf, "    <emulator>%s</emulator>\n", def->os.binary) < 0)
         goto no_memory;
 
-    disk = vm->def.disks;
+    disk = def->disks;
     while (disk) {
         const char *types[] = {
             "block",
@@ -1832,7 +1846,7 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
         disk = disk->next;
     }
 
-    net = vm->def.nets;
+    net = def->nets;
     while (net) {
         const char *types[] = {
             "user",
@@ -1871,10 +1885,10 @@ char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm) {
         net = net->next;
     }
 
-    if (vm->def.graphicsType == QEMUD_GRAPHICS_VNC) {
-        if (vm->def.vncPort) {
+    if (def->graphicsType == QEMUD_GRAPHICS_VNC) {
+        if (def->vncPort) {
             qemudBufferPrintf(&buf, "    <graphics type='vnc' port='%d'/>\n",
-                              vm->def.id == -1 ? vm->def.vncPort : vm->def.vncActivePort);
+                              vm->id == -1 ? def->vncPort : def->vncActivePort);
         } else {
             qemudBufferPrintf(&buf, "    <graphics type='vnc'/>\n");
         }
index 4c1e96be2faa54eb209b19ed00b7b8466488a094..eebab0d049972a8f89d1e8ae6085ab2443fbc3c9 100644 (file)
@@ -30,18 +30,27 @@ int qemudBuildCommandLine(struct qemud_server *server,
                           struct qemud_vm *vm,
                           char ***argv);
 
+void qemudFreeVMDef(struct qemud_vm_def *vm);
+int qemudScanConfigs(struct qemud_server *server);
+int qemudDeleteConfig(struct qemud_server *server,
+                      const char *configFile,
+                      const char *name);
+
 void qemudFreeVM(struct qemud_vm *vm);
 struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
                                     const char *file,
                                     const char *doc,
                                     int persist);
-int qemudScanConfigs(struct qemud_server *server);
 char *qemudGenerateXML(struct qemud_server *server,
-                       struct qemud_vm *vm);
-
-int qemudDeleteConfigXML(struct qemud_server *server,
-                         struct qemud_vm *vm);
+                       struct qemud_vm *vm, int live);
 
+void qemudFreeNetwork(struct qemud_network *network);
+struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
+                                                const char *file,
+                                                const char *doc,
+                                                int persist);
+char *qemudGenerateNetworkXML(struct qemud_server *server,
+                              struct qemud_network *network);
 
 #endif
 
index 016a5c3627464c3cacf8f0e088a5e4faf7b7ab7b..1643b823f2f987b1f456cf41faa086661d80cdd1 100644 (file)
@@ -154,9 +154,9 @@ static int qemudDispatchDomainCreate(struct qemud_server *server, struct qemud_c
     } else {
         out->header.type = QEMUD_PKT_DOMAIN_CREATE;
         out->header.dataSize = sizeof(out->data.domainCreateReply);
-        out->data.domainCreateReply.id = vm->def.id;
-        memcpy(out->data.domainCreateReply.uuid, vm->def.uuid, QEMUD_UUID_RAW_LEN);
-        strncpy(out->data.domainCreateReply.name, vm->def.name, QEMUD_MAX_NAME_LEN-1);
+        out->data.domainCreateReply.id = vm->id;
+        memcpy(out->data.domainCreateReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
+        strncpy(out->data.domainCreateReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
         out->data.domainCreateReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
     }
     return 0;
@@ -174,8 +174,8 @@ static int qemudDispatchDomainLookupByID(struct qemud_server *server, struct qem
     } else {
         out->header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_ID;
         out->header.dataSize = sizeof(out->data.domainLookupByIDReply);
-        memcpy(out->data.domainLookupByIDReply.uuid, vm->def.uuid, QEMUD_UUID_RAW_LEN);
-        strncpy(out->data.domainLookupByIDReply.name, vm->def.name, QEMUD_MAX_NAME_LEN-1);
+        memcpy(out->data.domainLookupByIDReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
+        strncpy(out->data.domainLookupByIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
         out->data.domainLookupByIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
     }
     return 0;
@@ -193,8 +193,8 @@ static int qemudDispatchDomainLookupByUUID(struct qemud_server *server, struct q
     } else {
         out->header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_UUID;
         out->header.dataSize = sizeof(out->data.domainLookupByUUIDReply);
-        out->data.domainLookupByUUIDReply.id = vm->def.id;
-        strncpy(out->data.domainLookupByUUIDReply.name, vm->def.name, QEMUD_MAX_NAME_LEN-1);
+        out->data.domainLookupByUUIDReply.id = vm->id;
+        strncpy(out->data.domainLookupByUUIDReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
         out->data.domainLookupByUUIDReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
     }
     return 0;
@@ -214,8 +214,8 @@ static int qemudDispatchDomainLookupByName(struct qemud_server *server, struct q
     } else {
         out->header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_NAME;
         out->header.dataSize = sizeof(out->data.domainLookupByNameReply);
-        out->data.domainLookupByNameReply.id = vm->def.id;
-        memcpy(out->data.domainLookupByNameReply.uuid, vm->def.uuid, QEMUD_UUID_RAW_LEN);
+        out->data.domainLookupByNameReply.id = vm->id;
+        memcpy(out->data.domainLookupByNameReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
     }
     return 0;
 }
@@ -420,7 +420,7 @@ static int qemudDispatchDomainStart(struct qemud_server *server, struct qemud_cl
     } else {
         out->header.type = QEMUD_PKT_DOMAIN_START;
         out->header.dataSize = sizeof(out->data.domainStartReply);
-        out->data.domainStartReply.id = vm->def.id;
+        out->data.domainStartReply.id = vm->id;
     }
     return 0;
 }
@@ -439,8 +439,8 @@ static int qemudDispatchDomainDefine(struct qemud_server *server, struct qemud_c
     } else {
         out->header.type = QEMUD_PKT_DOMAIN_DEFINE;
         out->header.dataSize = sizeof(out->data.domainDefineReply);
-        memcpy(out->data.domainDefineReply.uuid, vm->def.uuid, QEMUD_UUID_RAW_LEN);
-        strncpy(out->data.domainDefineReply.name, vm->def.name, QEMUD_MAX_NAME_LEN-1);
+        memcpy(out->data.domainDefineReply.uuid, vm->def->uuid, QEMUD_UUID_RAW_LEN);
+        strncpy(out->data.domainDefineReply.name, vm->def->name, QEMUD_MAX_NAME_LEN-1);
         out->data.domainDefineReply.name[QEMUD_MAX_NAME_LEN-1] = '\0';
     }
     return 0;
index 9d30dd1fbf4d1aff1715eb8c84b2b3b07f04772f..13549fae4ae6a561521af16bb050fc43af0bc3b0 100644 (file)
@@ -225,7 +225,7 @@ struct qemud_vm *qemudFindVMByID(const struct qemud_server *server, int id) {
     struct qemud_vm *vm = server->activevms;
 
     while (vm) {
-        if (vm->def.id == id)
+        if (vm->id == id)
             return vm;
         vm = vm->next;
     }
@@ -238,14 +238,14 @@ struct qemud_vm *qemudFindVMByUUID(const struct qemud_server *server,
     struct qemud_vm *vm = server->activevms;
 
     while (vm) {
-        if (!memcmp(vm->def.uuid, uuid, QEMUD_UUID_RAW_LEN))
+        if (!memcmp(vm->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
             return vm;
         vm = vm->next;
     }
 
     vm = server->inactivevms;
     while (vm) {
-        if (!memcmp(vm->def.uuid, uuid, QEMUD_UUID_RAW_LEN))
+        if (!memcmp(vm->def->uuid, uuid, QEMUD_UUID_RAW_LEN))
             return vm;
         vm = vm->next;
     }
@@ -258,14 +258,14 @@ struct qemud_vm *qemudFindVMByName(const struct qemud_server *server,
     struct qemud_vm *vm = server->activevms;
 
     while (vm) {
-        if (!strcmp(vm->def.name, name))
+        if (!strcmp(vm->def->name, name))
             return vm;
         vm = vm->next;
     }
 
     vm = server->inactivevms;
     while (vm) {
-        if (!strcmp(vm->def.name, name))
+        if (!strcmp(vm->def->name, name))
             return vm;
         vm = vm->next;
     }
@@ -281,7 +281,7 @@ int qemudListDomains(struct qemud_server *server, int *ids, int nids) {
     struct qemud_vm *vm = server->activevms;
     int got = 0;
     while (vm && got < nids) {
-        ids[got] = vm->def.id;
+        ids[got] = vm->id;
         vm = vm->next;
         got++;
     }
@@ -297,16 +297,11 @@ struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml)
         return NULL;
     }
 
-    if (qemudStartVMDaemon(server, vm) < 0) {
+    if (qemudDomainStart(server, vm) < 0) {
         qemudFreeVM(vm);
         return NULL;
     }
 
-    vm->next = server->activevms;
-    server->activevms = vm;
-    server->nactivevms++;
-    server->nvmfds += 2;
-
     return vm;
 }
 
@@ -399,9 +394,9 @@ int qemudDomainGetInfo(struct qemud_server *server, const unsigned char *uuid,
         }
     }
 
-    *maxmem = vm->def.maxmem;
-    *memory = vm->def.memory;
-    *nrVirtCpu = vm->def.vcpus;
+    *maxmem = vm->def->maxmem;
+    *memory = vm->def->memory;
+    *nrVirtCpu = vm->def->vcpus;
     return 0;
 }
 
@@ -437,7 +432,7 @@ int qemudDomainDumpXML(struct qemud_server *server, const unsigned char *uuid, c
         return -1;
     }
 
-    vmxml = qemudGenerateXML(server, vm);
+    vmxml = qemudGenerateXML(server, vm, 1);
     if (!vmxml)
         return -1;
 
@@ -452,7 +447,7 @@ int qemudListDefinedDomains(struct qemud_server *server, char *const*names, int
     struct qemud_vm *vm = server->inactivevms;
     int got = 0;
     while (vm && got < nnames) {
-        strncpy(names[got], vm->def.name, QEMUD_MAX_NAME_LEN-1);
+        strncpy(names[got], vm->def->name, QEMUD_MAX_NAME_LEN-1);
         names[got][QEMUD_MAX_NAME_LEN-1] = '\0';
         vm = vm->next;
         got++;
@@ -501,10 +496,6 @@ struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml)
         return NULL;
     }
 
-    vm->next = server->inactivevms;
-    server->inactivevms = vm;
-    server->ninactivevms++;
-
     return vm;
 }
 
@@ -522,7 +513,7 @@ int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid)
         return -1;
     }
 
-    if (qemudDeleteConfig(server, vm->configFile, vm->def.name) < 0)
+    if (qemudDeleteConfig(server, vm->configFile, vm->def->name) < 0)
         return -1;
 
     vm->configFile[0] = '\0';
index a4764f5e65b5607f45ac93bb84e89fc2a4eafb3f..bc67542a74c98867b61cf9d5f75a4521b3903960 100644 (file)
@@ -169,7 +169,6 @@ struct qemud_vm_os_def {
 
 /* Guest VM main configuration */
 struct qemud_vm_def {
-    int id;
     int virtType;
     unsigned char uuid[QEMUD_UUID_RAW_LEN];
     char name[QEMUD_MAX_NAME_LEN];
@@ -198,13 +197,15 @@ struct qemud_vm {
     int stderr;
     int monitor;
     int pid;
+    int id;
 
     int *tapfds;
     int ntapfds;
 
     char configFile[PATH_MAX];
 
-    struct qemud_vm_def def;
+    struct qemud_vm_def *def; /* The current definition */
+    struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
 
     struct qemud_vm *next;
 };
index d56a61a2fdf43d9de75e945f7819d886cdc4b93c..628c07c310656480a733586d13ce2716d32b3aee 100644 (file)
@@ -438,16 +438,16 @@ int qemudStartVMDaemon(struct qemud_server *server,
     char **argv = NULL;
     int i, ret = -1;
 
-    if (vm->def.vncPort < 0)
-        vm->def.vncActivePort = 5900 + server->nextvmid;
+    if (vm->def->vncPort < 0)
+        vm->def->vncActivePort = 5900 + server->nextvmid;
     else
-        vm->def.vncActivePort = vm->def.vncPort;
+        vm->def->vncActivePort = vm->def->vncPort;
 
     if (qemudBuildCommandLine(server, vm, &argv) < 0)
         return -1;
 
     if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr, vm->tapfds) == 0) {
-        vm->def.id = server->nextvmid++;
+        vm->id = server->nextvmid++;
         ret = 0;
     }
 
@@ -711,7 +711,7 @@ int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
     curr->monitor = -1;
     server->nvmfds -= 2;
 
-    net = vm->def.nets;
+    net = vm->def->nets;
     while (net) {
         if (net->type == QEMUD_NET_NETWORK)
             qemudNetworkIfaceDisconnect(server, vm, net);
@@ -726,7 +726,13 @@ int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
     }
 
     vm->pid = -1;
-    vm->def.id = -1;
+    vm->id = -1;
+
+    if (vm->newDef) {
+        qemudFreeVMDef(vm->def);
+        vm->def = vm->newDef;
+        vm->newDef = NULL;
+    }
 
     return 0;
 }