Richard W.M. Jones
2011-Apr-01 12:34 UTC
[Libguestfs] [PATCH 0/4] Add progress messages to guestfs_launch function.
These four commits add approximate progress messages to the guestfs_launch function. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://et.redhat.com/~rjones/virt-top
Richard W.M. Jones
2011-Apr-01 12:35 UTC
[Libguestfs] [PATCH 1/4] Add prototype for timeval_diff.
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://et.redhat.com/~rjones/virt-top -------------- next part -------------->From b8fd17fa0b5c91ad657a2dc765864711ed95ef1c Mon Sep 17 00:00:00 2001From: Richard W.M. Jones <rjones at redhat.com> Date: Fri, 1 Apr 2011 13:30:24 +0100 Subject: [PATCH 1/4] Add prototype for timeval_diff. This is just code motion. --- src/launch.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/launch.c b/src/launch.c index 8074d13..367d3ff 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); -- 1.7.4.1
Richard W.M. Jones
2011-Apr-01 12:35 UTC
[Libguestfs] [PATCH 2/4] Shared function to send progress messages.
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://et.redhat.com/~rjones/virt-top -------------- next part -------------->From 21434b17986fe45950bb9cac1bb546ea3cd95de7 Mon Sep 17 00:00:00 2001From: Richard W.M. Jones <rjones at redhat.com> Date: Fri, 1 Apr 2011 12:17:22 +0100 Subject: [PATCH 2/4] Shared function to send progress messages. This is just code motion. --- src/guestfs-internal.h | 4 +++- src/proto.c | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index b5f50c9..2729097 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -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 @@ -266,6 +266,7 @@ struct inspect_fstab_entry { struct guestfs_message_header; struct guestfs_message_error; +struct guestfs_progress; extern void guestfs_error (guestfs_h *g, const char *fs, ...) __attribute__((format (printf,2,3))); @@ -299,6 +300,7 @@ extern int guestfs___recv_file (guestfs_h *g, const char *filename); extern int guestfs___send_to_daemon (guestfs_h *g, const void *v_buf, size_t n); extern int guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn); 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___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); diff --git a/src/proto.c b/src/proto.c index cda731e..39f30ae 100644 --- a/src/proto.c +++ b/src/proto.c @@ -326,8 +326,10 @@ really_read_from_socket (guestfs_h *g, int sock, char *buf, size_t n) return (ssize_t) got; } -static void -send_progress_message (guestfs_h *g, const guestfs_progress *message) +/* Convenient wrapper to generate a progress message callback. */ +void +guestfs___progress_message_callback (guestfs_h *g, + const guestfs_progress *message) { uint64_t array[4]; @@ -384,7 +386,7 @@ check_for_daemon_cancellation_or_eof (guestfs_h *g, int fd) xdr_guestfs_progress (&xdr, &message); xdr_destroy (&xdr); - send_progress_message (g, &message); + guestfs___progress_message_callback (g, &message); } return 0; @@ -674,7 +676,7 @@ guestfs___recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void **buf_rtn) xdr_guestfs_progress (&xdr, &message); xdr_destroy (&xdr); - send_progress_message (g, &message); + guestfs___progress_message_callback (g, &message); } free (*buf_rtn); -- 1.7.4.1
Richard W.M. Jones
2011-Apr-01 12:35 UTC
[Libguestfs] [PATCH 3/4] protocol: Sleep for 1ms before reading log messages.
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones New in Fedora 11: Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 70 libraries supprt'd http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw -------------- next part -------------->From 6962c003785f48b859fedaabc77ebe0dfe85e993 Mon Sep 17 00:00:00 2001From: Richard W.M. Jones <rjones at redhat.com> Date: Fri, 1 Apr 2011 13:29:06 +0100 Subject: [PATCH 3/4] protocol: Sleep for 1ms before reading log messages. As explained in the comment: /* QEMU's console emulates a 16550A serial port. The real 16550A * device has a small FIFO buffer (16 bytes) which means here we see * lots of small reads of 1-16 bytes in length, usually single * bytes. Sleeping here for a very brief period groups reads * together (so we usually get a few lines of output at once) and * improves overall throughput, as well as making the event * interface a bit more sane for callers. With a virtio-serial * based console (not yet implemented) we may be able to remove * this. XXX */ --- src/proto.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/src/proto.c b/src/proto.c index 39f30ae..7cd1d31 100644 --- a/src/proto.c +++ b/src/proto.c @@ -251,8 +251,15 @@ read_log_message_or_eof (guestfs_h *g, int fd, int error_if_eof) /* QEMU's console emulates a 16550A serial port. The real 16550A * device has a small FIFO buffer (16 bytes) which means here we see * lots of small reads of 1-16 bytes in length, usually single - * bytes. + * bytes. Sleeping here for a very brief period groups reads + * together (so we usually get a few lines of output at once) and + * improves overall throughput, as well as making the event + * interface a bit more sane for callers. With a virtio-serial + * based console (not yet implemented) we may be able to remove + * this. XXX */ + usleep (1000); + n = read (fd, buf, sizeof buf); if (n == 0) { /* Hopefully this indicates the qemu child process has died. */ -- 1.7.4.1
Richard W.M. Jones
2011-Apr-01 12:36 UTC
[Libguestfs] [PATCH 4/4] Generate progress messages during launch.
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/ -------------- next part -------------->From ea70a3e0ab34cac40151ebfbddb5a5e03bc7cbc6 Mon Sep 17 00:00:00 2001From: Richard W.M. Jones <rjones at redhat.com> Date: Fri, 1 Apr 2011 13:30:48 +0100 Subject: [PATCH 4/4] 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). --- src/guestfs-internal.h | 1 + src/launch.c | 35 +++++++++++++++++++++++++++++++++++ src/proto.c | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+), 0 deletions(-) diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 2729097..3a63f2e 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 367d3ff..a60ef7b 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 7cd1d31..63aea68 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; } -- 1.7.4.1
Apparently Analagous Threads
- [PATCH 0/8 v2] Complete fix for CVE-2010-3851.
- [PATCH 0/13 v2] Prepare for adding write support to hivex (Windows registry) library
- [PATCH 0/7] Add libvirt domain to core API
- [PATCH 0/8 v2 DISCUSSION ONLY] Connecting to live virtual machines
- [PATCH] Correct checks for dup failure in guestfs_launch