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

[Libguestfs] [PATCH for discussion only] add_drive_ro adds readonly=on option if available.

This needs more testing.


Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming blog: http://rwmj.wordpress.com
Fedora now supports 80 OCaml packages (the OPEN alternative to F#)
>From 26161a7a03edcad9cebf6908c052475765250ffb Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones redhat com>
Date: Tue, 16 Mar 2010 20:06:54 +0000
Subject: [PATCH] add_drive_ro adds readonly=on option if available.

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 |    4 +++-
 src/guestfs.c    |   21 ++++++++++++++++-----
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/src/generator.ml b/src/generator.ml
index 486b9d8..38e0706 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -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
-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<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
diff --git a/src/guestfs.c b/src/guestfs.c
index 2ba062c..85f2307 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -91,6 +91,7 @@ static int recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn);
 static int accept_from_daemon (guestfs_h *g);
 static int check_peer_euid (guestfs_h *g, int sock, uid_t *rtn);
 static void close_handles (void);
+static int qemu_supports (guestfs_h *g, const char *option);
 #define UNIX_PATH_MAX 108
@@ -791,9 +792,6 @@ int
 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;
@@ -804,7 +802,21 @@ guestfs__add_drive_ro_with_if (guestfs_h *g, const char *filename,
     return -1;
-  snprintf (buf, len, "file=%s,snapshot=on,if=%s", filename, drive_if);
+  /* 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);
@@ -871,7 +883,6 @@ dir_contains_files (const char *dir, ...)
 static void print_timestamped_message (guestfs_h *g, const char *fs, ...);
 static int build_supermin_appliance (guestfs_h *g, const char *path, char **kernel, char **initrd);
 static int test_qemu (guestfs_h *g);
-static int qemu_supports (guestfs_h *g, const char *option);
 static int is_openable (guestfs_h *g, const char *path, int flags);
 static void print_cmdline (guestfs_h *g);

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