summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2009-08-12 22:12:20 +0100
committerRichard Jones <rjones@trick.home.annexia.org>2009-08-13 11:03:02 +0100
commitd082a76d679b019784bc0b131028ee74e381f4a2 (patch)
tree74a5e031b099169b8b215ebca188d715cbb7654e /src
parent67a679afb17747b5ec392e56cf6121b085b38a3a (diff)
downloadlibguestfs-d082a76d679b019784bc0b131028ee74e381f4a2.tar.gz
libguestfs-d082a76d679b019784bc0b131028ee74e381f4a2.tar.xz
libguestfs-d082a76d679b019784bc0b131028ee74e381f4a2.zip
add_drive: Don't use cache=off if not supported by underlying filesystem.
If you use the guestfs_add_drive function, then currently it generates a qemu command line element like: -drive ...,cache=off,... This causes qemu to try to open the device with O_DIRECT. Unfortunately some filesystems don't support this flag, notably tmpfs, which means you can't use libguestfs in conjunction with tmpfs. On some systems /tmp is a tmpfs filesystem. This patch fixes this so that if the filesystem doesn't support O_DIRECT, then we omit the cache=off parameter. This seems reasonable from a reliability point of view, because if you're using tmpfs then you probably didn't expect reliability in the case where your system suddenly powers off.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/generator.ml2
-rw-r--r--src/guestfs.c29
2 files changed, 25 insertions, 6 deletions
diff --git a/src/generator.ml b/src/generator.ml
index 3a772029..39faffec 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -454,6 +454,8 @@ image).
This is equivalent to the qemu parameter
C<-drive file=filename,cache=off,if=...>.
+C<cache=off> is omitted in cases where it is not supported by
+the underlying filesystem.
Note that this call checks for the existence of C<filename>. This
stops you from specifying other types of drive which are supported
diff --git a/src/guestfs.c b/src/guestfs.c
index 37869e84..ad3980ff 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -799,14 +799,31 @@ guestfs_add_drive (guestfs_h *g, const char *filename)
return -1;
}
- if (access (filename, F_OK) == -1) {
- perrorf (g, "%s", filename);
- return -1;
+ /* cache=off improves reliability in the event of a host crash.
+ *
+ * However this option causes qemu to try to open the file with
+ * O_DIRECT. This fails on some filesystem types (notably tmpfs).
+ * So we check if we can open the file with or without O_DIRECT,
+ * and use cache=off (or not) accordingly.
+ *
+ * This test also checks for the presence of the file, which
+ * is a documented semantic of this interface.
+ */
+ int fd = open (filename, O_RDONLY|O_DIRECT);
+ if (fd >= 0) {
+ close (fd);
+ snprintf (buf, len, "file=%s,cache=off,if=" DRIVE_IF, filename);
+ } else {
+ fd = open (filename, O_RDONLY);
+ if (fd >= 0) {
+ close (fd);
+ snprintf (buf, len, "file=%s,if=" DRIVE_IF, filename);
+ } else {
+ perrorf (g, "%s", filename);
+ return -1;
+ }
}
- /* cache=off improves reliability in the event of a host crash. */
- snprintf (buf, len, "file=%s,cache=off,if=%s", filename, DRIVE_IF);
-
return guestfs_config (g, "-drive", buf);
}