summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2011-04-01 13:30:48 +0100
committerRichard W.M. Jones <rjones@redhat.com>2011-04-01 16:05:30 +0100
commit371eabfae3790588ed97c0017d2882799c7ea871 (patch)
tree0ec9ba15fabe216a0e83bfb5e2e324d92cd1e045
parent02971adc3b0f07f3820d0c5e973fabf16d16deb3 (diff)
downloadlibguestfs-371eabfae3790588ed97c0017d2882799c7ea871.tar.gz
libguestfs-371eabfae3790588ed97c0017d2882799c7ea871.tar.xz
libguestfs-371eabfae3790588ed97c0017d2882799c7ea871.zip
Generate progress messages during launch.
This commit generates approximate progress messages during the guestfs_launch call. Currently this code generates: 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 (Note this is not an ABI and may be changed or removed in a future version). Progress messages are only generated at all if 5 seconds have elapsed since the launch, and they are only generated for the ordinary appliance (not if using attach-method to attach to an existing virtio serial port).
-rw-r--r--generator/generator_actions.ml2
-rw-r--r--src/guestfs-internal.h1
-rw-r--r--src/launch.c35
-rw-r--r--src/proto.c18
4 files changed, 55 insertions, 1 deletions
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 75b1cb3b..a324d997 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -103,7 +103,7 @@ You probably don't want to call this function.")]
*)
let non_daemon_functions = test_functions @ [
- ("launch", (RErr, [], []), -1, [FishAlias "run"],
+ ("launch", (RErr, [], []), -1, [FishAlias "run"; Progress],
[],
"launch the qemu subprocess",
"\
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 27290970..3a63f2e3 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -302,6 +302,7 @@ extern int guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **
extern int guestfs___accept_from_daemon (guestfs_h *g);
extern void guestfs___progress_message_callback (guestfs_h *g, const struct guestfs_progress *message);
extern int guestfs___build_appliance (guestfs_h *g, char **kernel, char **initrd, char **appliance);
+extern void guestfs___launch_send_progress (guestfs_h *g, int perdozen);
extern void guestfs___print_BufferIn (FILE *out, const char *buf, size_t buf_size);
extern void guestfs___print_BufferOut (FILE *out, const char *buf, size_t buf_size);
#ifdef HAVE_PCRE
diff --git a/src/launch.c b/src/launch.c
index 367d3ff8..a60ef7b3 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -407,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");
@@ -761,6 +764,8 @@ launch_appliance (guestfs_h *g)
goto cleanup1;
}
+ guestfs___launch_send_progress (g, 12);
+
return 0;
cleanup1:
@@ -862,6 +867,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
diff --git a/src/proto.c b/src/proto.c
index 7cd1d313..63aea68e 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -285,6 +285,24 @@ read_log_message_or_eof (guestfs_h *g, int fd, int error_if_eof)
/* It's an actual log message, send it upwards if anyone is listening. */
guestfs___call_callbacks_message (g, GUESTFS_EVENT_APPLIANCE, buf, n);
+ /* This is a gross hack. See the comment above
+ * guestfs___launch_send_progress.
+ */
+ if (g->state == LAUNCHING) {
+ const char *sentinel;
+ size_t len;
+
+ sentinel = "Linux version"; /* kernel up */
+ len = strlen (sentinel);
+ if (memmem (buf, n, sentinel, len) != NULL)
+ guestfs___launch_send_progress (g, 6);
+
+ sentinel = "Starting /init script"; /* /init running */
+ len = strlen (sentinel);
+ if (memmem (buf, n, sentinel, len) != NULL)
+ guestfs___launch_send_progress (g, 9);
+ }
+
return 0;
}