[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] [PATCH] Fix cdrom connect/disconnect for qemu



The attached patch fixes cdrom changing for a live qemu guest. There
were a few issues preventing it from working:

1) It didn't anticipate no <source> block in the xml.
2) No support for ejecting the media
3) Small bug which prevented the running guest xml from being updated.

I've tested this via virt-manager, and now qemu and xen seem
to have parity wrt cdrom connect/disconnect.

Thanks,
Cole


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

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]