Daniel P. Berrange 206300
commit 570fd656d1b67e5d02f52e107946930257e811a7
Daniel P. Berrange 206300
Author: Daniel Veillard <veillard@redhat.com>
Daniel P. Berrange 206300
Date:   Thu Mar 13 09:17:45 2008 +0000
Daniel P. Berrange 206300
Daniel P. Berrange 206300
    * src/qemu_conf.c src/qemu_driver.c: patch from Cole Robinson
Daniel P. Berrange 206300
      fixing CD Rom change on live QEmu/KVM domains.
Daniel P. Berrange 206300
    Daniel
Daniel P. Berrange 206300
Daniel P. Berrange 206300
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
Daniel P. Berrange 206300
index e54da5b..ebbd251 100644
Daniel P. Berrange 206300
--- a/src/qemu_conf.c
Daniel P. Berrange 206300
+++ b/src/qemu_conf.c
Daniel P. Berrange 206300
@@ -594,9 +594,16 @@ static int qemudParseDiskXML(virConnectPtr conn,
Daniel P. Berrange 206300
     }
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
     if (source == NULL) {
Daniel P. Berrange 206300
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target);
Daniel P. Berrange 206300
-        goto error;
Daniel P. Berrange 206300
+        /* There is a case without the source
Daniel P. Berrange 206300
+         * to the CD-ROM device
Daniel P. Berrange 206300
+         */
Daniel P. Berrange 206300
+        if (!device || STRNEQ((const char *) device, "cdrom")) {
Daniel P. Berrange 206300
+            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SOURCE,
Daniel P. Berrange 206300
+                             target ? "%s" : NULL, target);
Daniel P. Berrange 206300
+            goto error;
Daniel P. Berrange 206300
+        }
Daniel P. Berrange 206300
     }
Daniel P. Berrange 206300
+
Daniel P. Berrange 206300
     if (target == NULL) {
Daniel P. Berrange 206300
         qemudReportError(conn, NULL, NULL, VIR_ERR_NO_TARGET, source ? "%s" : NULL, source);
Daniel P. Berrange 206300
         goto error;
Daniel P. Berrange 206300
@@ -630,7 +637,7 @@ static int qemudParseDiskXML(virConnectPtr conn,
Daniel P. Berrange 206300
         goto error;
Daniel P. Berrange 206300
     }
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
-    strncpy(disk->src, (const char *)source, NAME_MAX-1);
Daniel P. Berrange 206300
+    strncpy(disk->src, (source ? (const char *) source : "\0"), NAME_MAX-1);
Daniel P. Berrange 206300
     disk->src[NAME_MAX-1] = '\0';
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
     strncpy(disk->dst, (const char *)target, NAME_MAX-1);
Daniel P. Berrange 206300
@@ -1747,9 +1754,15 @@ int qemudBuildCommandLine(virConnectPtr conn,
Daniel P. Berrange 206300
         char dev[NAME_MAX];
Daniel P. Berrange 206300
         char file[PATH_MAX];
Daniel P. Berrange 206300
         if (!strcmp(disk->dst, "hdc") &&
Daniel P. Berrange 206300
-            disk->device == QEMUD_DISK_CDROM)
Daniel P. Berrange 206300
-            snprintf(dev, NAME_MAX, "-%s", "cdrom");
Daniel P. Berrange 206300
-        else
Daniel P. Berrange 206300
+            disk->device == QEMUD_DISK_CDROM) {
Daniel P. Berrange 206300
+            if (disk->src[0])
Daniel P. Berrange 206300
+                snprintf(dev, NAME_MAX, "-%s", "cdrom");
Daniel P. Berrange 206300
+            else {
Daniel P. Berrange 206300
+                /* Don't put anything on the cmdline for an empty cdrom*/
Daniel P. Berrange 206300
+                disk = disk->next;
Daniel P. Berrange 206300
+                continue;
Daniel P. Berrange 206300
+            }
Daniel P. Berrange 206300
+        } else
Daniel P. Berrange 206300
             snprintf(dev, NAME_MAX, "-%s", disk->dst);
Daniel P. Berrange 206300
         snprintf(file, PATH_MAX, "%s", disk->src);
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
@@ -2906,8 +2919,10 @@ char *qemudGenerateXML(virConnectPtr conn,
Daniel P. Berrange 206300
                               types[disk->type], devices[disk->device]) < 0)
Daniel P. Berrange 206300
             goto no_memory;
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
-        if (virBufferVSprintf(buf, "      <source %s='%s'/>\n", typeAttrs[disk->type], disk->src) < 0)
Daniel P. Berrange 206300
-            goto no_memory;
Daniel P. Berrange 206300
+        if (disk->src[0])
Daniel P. Berrange 206300
+            if (virBufferVSprintf(buf, "      <source %s='%s'/>\n",
Daniel P. Berrange 206300
+                                  typeAttrs[disk->type], disk->src) < 0)
Daniel P. Berrange 206300
+                goto no_memory;
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
         if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", disk->dst) < 0)
Daniel P. Berrange 206300
             goto no_memory;
Daniel P. Berrange 206300
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
Daniel P. Berrange 206300
index 21f0fed..2b4c2a6 100644
Daniel P. Berrange 206300
--- a/src/qemu_driver.c
Daniel P. Berrange 206300
+++ b/src/qemu_driver.c
Daniel P. Berrange 206300
@@ -2223,23 +2223,29 @@ static int qemudDomainChangeCDROM(virDomainPtr dom,
Daniel P. Berrange 206300
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
Daniel P. Berrange 206300
     char *cmd, *reply, *safe_path;
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
-    /* Migrate to file */
Daniel P. Berrange 206300
-    safe_path = qemudEscapeMonitorArg(newdisk->src);
Daniel P. Berrange 206300
-    if (!safe_path) {
Daniel P. Berrange 206300
-        qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
Daniel P. Berrange 206300
-                         "out of memory");
Daniel P. Berrange 206300
-        return -1;
Daniel P. Berrange 206300
-    }
Daniel P. Berrange 206300
-    if (asprintf (&cmd, "change %s \"%s\"",
Daniel P. Berrange 206300
-                  /* XXX qemu may support multiple CDROM in future */
Daniel P. Berrange 206300
-                  /* olddisk->dst */ "cdrom",
Daniel P. Berrange 206300
-                  safe_path) == -1) {
Daniel P. Berrange 206300
+    if (newdisk->src[0]) {
Daniel P. Berrange 206300
+        safe_path = qemudEscapeMonitorArg(newdisk->src);
Daniel P. Berrange 206300
+        if (!safe_path) {
Daniel P. Berrange 206300
+            qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
Daniel P. Berrange 206300
+                             "out of memory");
Daniel P. Berrange 206300
+            return -1;
Daniel P. Berrange 206300
+        }
Daniel P. Berrange 206300
+        if (asprintf (&cmd, "change %s \"%s\"",
Daniel P. Berrange 206300
+                      /* XXX qemu may support multiple CDROM in future */
Daniel P. Berrange 206300
+                      /* olddisk->dst */ "cdrom",
Daniel P. Berrange 206300
+                      safe_path) == -1) {
Daniel P. Berrange 206300
+            qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
Daniel P. Berrange 206300
+                             "out of memory");
Daniel P. Berrange 206300
+            free(safe_path);
Daniel P. Berrange 206300
+            return -1;
Daniel P. Berrange 206300
+        }
Daniel P. Berrange 206300
+        free(safe_path);
Daniel P. Berrange 206300
+
Daniel P. Berrange 206300
+    } else if (asprintf(&cmd, "eject cdrom") == -1) {
Daniel P. Berrange 206300
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
Daniel P. Berrange 206300
                          "out of memory");
Daniel P. Berrange 206300
-        free(safe_path);
Daniel P. Berrange 206300
         return -1;
Daniel P. Berrange 206300
     }
Daniel P. Berrange 206300
-    free(safe_path);
Daniel P. Berrange 206300
 
Daniel P. Berrange 206300
     if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
Daniel P. Berrange 206300
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, "cannot change cdrom media");
Daniel P. Berrange 206300
@@ -2248,7 +2254,7 @@ static int qemudDomainChangeCDROM(virDomainPtr dom,
Daniel P. Berrange 206300
     }
Daniel P. Berrange 206300
     free(reply);
Daniel P. Berrange 206300
     free(cmd);
Daniel P. Berrange 206300
-    strcpy(olddisk->dst, newdisk->dst);
Daniel P. Berrange 206300
+    strcpy(olddisk->src, newdisk->src);
Daniel P. Berrange 206300
     olddisk->type = newdisk->type;
Daniel P. Berrange 206300
     return 0;
Daniel P. Berrange 206300
 }