X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fguestfs.c;h=0e91b96b92dca4873b37475c57dda29a15a6d914;hb=891aac7a0c35eb25f853c3960eadf8f1f22ca60b;hp=1d6d40bf7322edfb98c81108e384412b42ec0860;hpb=214babb060d9e85e72bad4633310a9b4a5fcb9dd;p=libguestfs.git diff --git a/src/guestfs.c b/src/guestfs.c index 1d6d40b..0e91b96 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -748,7 +748,8 @@ guestfs__config (guestfs_h *g, } int -guestfs__add_drive (guestfs_h *g, const char *filename) +guestfs__add_drive_with_if (guestfs_h *g, const char *filename, + const char *drive_if) { size_t len = strlen (filename) + 64; char buf[len]; @@ -771,12 +772,12 @@ guestfs__add_drive (guestfs_h *g, const char *filename) int fd = open (filename, O_RDONLY|O_DIRECT); if (fd >= 0) { close (fd); - snprintf (buf, len, "file=%s,cache=off,if=" DRIVE_IF, filename); + snprintf (buf, len, "file=%s,cache=off,if=%s", filename, drive_if); } else { fd = open (filename, O_RDONLY); if (fd >= 0) { close (fd); - snprintf (buf, len, "file=%s,if=" DRIVE_IF, filename); + snprintf (buf, len, "file=%s,if=%s", filename, drive_if); } else { perrorf (g, "%s", filename); return -1; @@ -787,7 +788,8 @@ guestfs__add_drive (guestfs_h *g, const char *filename) } int -guestfs__add_drive_ro (guestfs_h *g, const char *filename) +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]; @@ -802,12 +804,24 @@ guestfs__add_drive_ro (guestfs_h *g, const char *filename) return -1; } - snprintf (buf, len, "file=%s,snapshot=on,if=%s", filename, DRIVE_IF); + snprintf (buf, len, "file=%s,snapshot=on,if=%s", filename, drive_if); return guestfs__config (g, "-drive", buf); } int +guestfs__add_drive (guestfs_h *g, const char *filename) +{ + return guestfs__add_drive_with_if (g, filename, DRIVE_IF); +} + +int +guestfs__add_drive_ro (guestfs_h *g, const char *filename) +{ + return guestfs__add_drive_ro_with_if (g, filename, DRIVE_IF); +} + +int guestfs__add_cdrom (guestfs_h *g, const char *filename) { if (strchr (filename, ',') != NULL) { @@ -858,6 +872,7 @@ 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); static const char *kernel_name = "vmlinuz." REPO "." host_cpu; @@ -1091,6 +1106,22 @@ guestfs__launch (guestfs_h *g) */ g->cmdline[0] = g->qemu; + /* qemu sometimes needs this option to enable hardware + * virtualization, but some versions of 'qemu-kvm' will use KVM + * regardless (even where this option appears in the help text). + * It is rumoured that there are versions of qemu where supplying + * this option when hardware virtualization is not available will + * cause qemu to fail, so we we have to check at least that + * /dev/kvm is openable. That's not reliable, since /dev/kvm + * might be openable by qemu but not by us (think: SELinux) in + * which case the user would not get hardware virtualization, + * although at least shouldn't fail. A giant clusterfuck with the + * qemu command line, again. + */ + if (qemu_supports (g, "-enable-kvm") && + is_openable (g, "/dev/kvm", O_RDWR)) + add_cmdline (g, "-enable-kvm"); + /* Newer versions of qemu (from around 2009/12) changed the * behaviour of monitors so that an implicit '-monitor stdio' is * assumed if we are in -nographic mode and there is no other @@ -1547,7 +1578,7 @@ print_timestamped_message (guestfs_h *g, const char *fs, ...) va_list args; char *msg; int err; - struct timeval tv, diff; + struct timeval tv; va_start (args, fs); err = vasprintf (&msg, fs, args); @@ -1647,6 +1678,20 @@ qemu_supports (guestfs_h *g, const char *option) return g->qemu_help && strstr (g->qemu_help, option) != NULL; } +/* Check if a file can be opened. */ +static int +is_openable (guestfs_h *g, const char *path, int flags) +{ + int fd = open (path, flags); + if (fd == -1) { + if (g->verbose) + perror (path); + return 0; + } + close (fd); + return 1; +} + /* Check the peer effective UID for a TCP socket. Ideally we'd like * SO_PEERCRED for a loopback TCP socket. This isn't possible on * Linux (but it is on Solaris!) so we read /proc/net/tcp instead. @@ -2588,7 +2633,6 @@ guestfs___recv_file (guestfs_h *g, const char *filename) { void *buf; int fd, r; - size_t len; fd = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666); if (fd == -1) {