add_drive_ro adds readonly=on option if available.
authorRichard Jones <rjones@redhat.com>
Tue, 16 Mar 2010 21:50:13 +0000 (21:50 +0000)
committerRichard Jones <rjones@redhat.com>
Tue, 16 Mar 2010 21:50:13 +0000 (21:50 +0000)
Change the add_drive_ro call so it adds the readonly=on option
if qemu supports that.

This just means that qemu will not try to open the drive with
O_RDWR, and should not otherwise change the behaviour of qemu or
libguestfs.  (In particular, writes to the read-only drive are
still permitted, and are just discarded when the handle is closed).

However it should alleviate RHBZ#571714 where udev was deciding
to incorrectly relabel a device because we had opened the device
for writing (even though we didn't actually write to it).

src/generator.ml
src/guestfs.c

index 4f569ba..83f307b 100755 (executable)
@@ -544,13 +544,15 @@ handle is closed.  We don't currently have any method to enable
 changes to be committed, although qemu can support this.
 
 This is equivalent to the qemu parameter
 changes to be committed, although qemu can support this.
 
 This is equivalent to the qemu parameter
-C<-drive file=filename,snapshot=on,if=...>.
+C<-drive file=filename,snapshot=on,readonly=on,if=...>.
 
 C<if=...> is set at compile time by the configuration option
 C<./configure --with-drive-if=...>.  In the rare case where you
 might need to change this at run time, use C<guestfs_add_drive_with_if>
 or C<guestfs_add_drive_ro_with_if>.
 
 
 C<if=...> is set at compile time by the configuration option
 C<./configure --with-drive-if=...>.  In the rare case where you
 might need to change this at run time, use C<guestfs_add_drive_with_if>
 or C<guestfs_add_drive_ro_with_if>.
 
+C<readonly=on> is only added where qemu supports this option.
+
 Note that this call checks for the existence of C<filename>.  This
 stops you from specifying other types of drive which are supported
 by qemu such as C<nbd:> and C<http:> URLs.  To specify those, use
 Note that this call checks for the existence of C<filename>.  This
 stops you from specifying other types of drive which are supported
 by qemu such as C<nbd:> and C<http:> URLs.  To specify those, use
index af60699..02d5fdb 100644 (file)
@@ -792,9 +792,6 @@ int
 guestfs__add_drive_ro_with_if (guestfs_h *g, const char *filename,
                                const char *drive_if)
 {
 guestfs__add_drive_ro_with_if (guestfs_h *g, const char *filename,
                                const char *drive_if)
 {
-  size_t len = strlen (filename) + 64;
-  char buf[len];
-
   if (strchr (filename, ',') != NULL) {
     error (g, _("filename cannot contain ',' (comma) character"));
     return -1;
   if (strchr (filename, ',') != NULL) {
     error (g, _("filename cannot contain ',' (comma) character"));
     return -1;
@@ -805,7 +802,24 @@ guestfs__add_drive_ro_with_if (guestfs_h *g, const char *filename,
     return -1;
   }
 
     return -1;
   }
 
-  snprintf (buf, len, "file=%s,snapshot=on,if=%s", filename, drive_if);
+  if (qemu_supports (g, NULL) == -1)
+    return -1;
+
+  /* Only SCSI and virtio drivers support readonly mode.
+   * This is only supported as a QEMU feature since 2010/01.
+   */
+  int supports_ro = 0;
+  if ((STREQ (drive_if, "scsi") || STREQ (drive_if, "virtio")) &&
+      qemu_supports (g, "readonly=on"))
+    supports_ro = 1;
+
+  size_t len = strlen (filename) + 100;
+  char buf[len];
+
+  snprintf (buf, len, "file=%s,snapshot=on,%sif=%s",
+            filename,
+            supports_ro ? "readonly=on," : "",
+            drive_if);
 
   return guestfs__config (g, "-drive", buf);
 }
 
   return guestfs__config (g, "-drive", buf);
 }