diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-08-15 15:44:18 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-08-15 17:49:48 +0100 |
commit | 5abd7bfc4cd8411efb8c3ad30e8a2b2610a7a1be (patch) | |
tree | 3e56511043c51e6146953fd20d0f4b1ce840ba6d | |
parent | 7f9f2818651860a15a7142d3761e3168e062c357 (diff) | |
download | libguestfs-5abd7bfc4cd8411efb8c3ad30e8a2b2610a7a1be.tar.gz libguestfs-5abd7bfc4cd8411efb8c3ad30e8a2b2610a7a1be.tar.xz libguestfs-5abd7bfc4cd8411efb8c3ad30e8a2b2610a7a1be.zip |
launch: For /dev/null drives, create a temporary disk.
This is a workaround for a bug with virtio-scsi in qemu 1.2:
https://bugzilla.redhat.com/show_bug.cgi?id=847549
-rw-r--r-- | src/launch.c | 70 |
1 files changed, 52 insertions, 18 deletions
diff --git a/src/launch.c b/src/launch.c index 5c023f8c..eaf5caef 100644 --- a/src/launch.c +++ b/src/launch.c @@ -131,6 +131,56 @@ add_drive (guestfs_h *g, const char *path, (*drv)->use_cache_none = use_cache_none; } +/* Traditionally you have been able to use /dev/null as a filename, as + * many times as you like. Ancient KVM (RHEL 5) cannot handle adding + * /dev/null readonly. qemu 1.2 + virtio-scsi segfaults when you use + * any zero-sized file including /dev/null. Therefore, we replace + * /dev/null with a non-zero sized temporary file. This shouldn't + * make any difference since users are not supposed to try and access + * a null drive. + */ +static int +add_null_drive (guestfs_h *g, int readonly, const char *format, + const char *iface, const char *name) +{ + char *tmpfile = NULL; + int fd = -1; + + if (format && STRNEQ (format, "raw")) { + error (g, _("for device '/dev/null', format must be 'raw'")); + return -1; + } + + if (guestfs___lazy_make_tmpdir (g) == -1) + return -1; + + tmpfile = safe_asprintf (g, "%s/devnull%d", g->tmpdir, ++g->unique); + fd = open (tmpfile, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0600); + if (fd == -1) { + perrorf (g, "open: %s", tmpfile); + goto err; + } + if (ftruncate (fd, 4096) == -1) { + perrorf (g, "truncate: %s", tmpfile); + goto err; + } + if (close (fd) == -1) { + perrorf (g, "close: %s", tmpfile); + goto err; + } + + add_drive (g, tmpfile, readonly, format, iface, name, 0); + free (tmpfile); + + return 0; + + err: + free (tmpfile); + if (fd >= 0) + close (fd); + return -1; +} + int guestfs__add_drive_opts (guestfs_h *g, const char *filename, const struct guestfs_add_drive_opts_argv *optargs) @@ -140,7 +190,6 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, const char *iface; const char *name; int use_cache_none; - int is_null; if (strchr (filename, ':') != NULL) { error (g, _("filename cannot contain ':' (colon) character. " @@ -168,23 +217,8 @@ guestfs__add_drive_opts (guestfs_h *g, const char *filename, return -1; } - /* Traditionally you have been able to use /dev/null as a filename, - * as many times as you like. Treat this as a special case, because - * old versions of qemu have some problems. - */ - is_null = STREQ (filename, "/dev/null"); - if (is_null) { - if (format && STRNEQ (format, "raw")) { - error (g, _("for device '/dev/null', format must be 'raw'")); - goto err_out; - } - /* Ancient KVM (RHEL 5) cannot handle the case where we try to add - * a snapshot on top of /dev/null. Modern qemu can handle it OK, - * but the device size is still 0, so it shouldn't matter whether - * or not this is readonly. - */ - readonly = 0; - } + if (STREQ (filename, "/dev/null")) + return add_null_drive (g, readonly, format, iface, name); /* For writable files, see if we can use cache=none. This also * checks for the existence of the file. For readonly we have |