X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Flaunch.c;h=0b15ce98d79fac55032a7e93788f62d0011e8c34;hp=8074d1319bd33692ace2c07a9368d1ee8ba9a082;hb=7a091a11d7aeddc170e4d1b833fd9d7d18c00841;hpb=110bfe1fcc9964b82acf7df6d4d60774471f9157 diff --git a/src/launch.c b/src/launch.c index 8074d13..0b15ce9 100644 --- a/src/launch.c +++ b/src/launch.c @@ -1,5 +1,5 @@ /* libguestfs - * Copyright (C) 2009-2010 Red Hat Inc. + * Copyright (C) 2009-2011 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -71,6 +71,7 @@ #include "guestfs_protocol.h" static int launch_appliance (guestfs_h *g); +static int64_t timeval_diff (const struct timeval *x, const struct timeval *y); static int connect_unix_socket (guestfs_h *g, const char *sock); static int qemu_supports (guestfs_h *g, const char *option); @@ -103,20 +104,20 @@ add_cmdline (guestfs_h *g, const char *str) return 0; } -int +size_t guestfs___checkpoint_cmdline (guestfs_h *g) { return g->cmdline_size; } void -guestfs___rollback_cmdline (guestfs_h *g, int pos) +guestfs___rollback_cmdline (guestfs_h *g, size_t pos) { - int i; + size_t i; assert (g->cmdline_size >= pos); - for (i = g->cmdline_size - 1; i >= pos; --i) + for (i = pos; i < g->cmdline_size; ++i) free (g->cmdline[i]); g->cmdline_size = pos; @@ -126,7 +127,7 @@ guestfs___rollback_cmdline (guestfs_h *g, int pos) char ** guestfs__debug_cmdline (guestfs_h *g) { - int i; + size_t i; char **r; if (g->cmdline == NULL) { @@ -406,12 +407,15 @@ launch_appliance (guestfs_h *g) /* Start the clock ... */ gettimeofday (&g->launch_t, NULL); + guestfs___launch_send_progress (g, 0); /* Locate and/or build the appliance. */ char *kernel = NULL, *initrd = NULL, *appliance = NULL; if (guestfs___build_appliance (g, &kernel, &initrd, &appliance) == -1) return -1; + guestfs___launch_send_progress (g, 3); + if (g->verbose) guestfs___print_timestamped_message (g, "begin testing qemu features"); @@ -483,21 +487,30 @@ launch_appliance (guestfs_h *g) if (qemu_supports (g, "-nodefconfig")) add_cmdline (g, "-nodefconfig"); - /* 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. + /* The qemu -machine option (added 2010-12) is a bit more sane + * since it falls back through various different acceleration + * modes, so try that first (thanks Markus Armbruster). */ - if (qemu_supports (g, "-enable-kvm") && - is_openable (g, "/dev/kvm", O_RDWR)) - add_cmdline (g, "-enable-kvm"); + if (qemu_supports (g, "-machine")) { + add_cmdline (g, "-machine"); + add_cmdline (g, "accel=kvm:tcg"); + } else { + /* 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 @@ -760,6 +773,8 @@ launch_appliance (guestfs_h *g) goto cleanup1; } + guestfs___launch_send_progress (g, 12); + return 0; cleanup1: @@ -861,6 +876,36 @@ connect_unix_socket (guestfs_h *g, const char *sockpath) return -1; } +/* launch (of the ordinary appliance) generates approximate progress + * messages. Currently these are defined as follows: + * + * 0 / 12: launch clock starts + * 3 / 12: appliance created + * 6 / 12: detected that guest kernel started + * 9 / 12: detected that /init script is running + * 12 / 12: launch completed successfully + * + * Notes: + * (1) This is not a documented ABI and the behaviour may be changed + * or removed in future. + * (2) Messages are only sent if more than 5 seconds has elapsed + * since the launch clock started. + * (3) There is a gross hack in proto.c to make this work. + */ +void +guestfs___launch_send_progress (guestfs_h *g, int perdozen) +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + if (timeval_diff (&g->launch_t, &tv) >= 5000) { + guestfs_progress progress_message = + { .proc = 0, .serial = 0, .position = perdozen, .total = 12 }; + + guestfs___progress_message_callback (g, &progress_message); + } +} + /* Return the location of the tmpdir (eg. "/tmp") and allow users * to override it at runtime using $TMPDIR. * http://www.pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES