/* This is called from the forked subprocess just before vmlinux runs, * so it can just print the message straight to stderr, where it will * be picked up and funnelled through the usual appliance event API. */ static void print_vmlinux_command_line (guestfs_h *g, char **argv) { size_t i = 0; int needs_quote; struct timeval tv; gettimeofday (&tv, NULL); fprintf (stderr, "[%05" PRIi64 "ms] ", guestfs_int_timeval_diff (&g->launch_t, &tv)); while (argv[i]) { if (i > 0) fputc (' ', stderr); /* Does it need shell quoting? This only deals with simple cases. */ needs_quote = strcspn (argv[i], " ") != strlen (argv[i]); if (needs_quote) fputc ('\'', stderr); fprintf (stderr, "%s", argv[i]); if (needs_quote) fputc ('\'', stderr); i++; } fputc ('\n', stderr); }
/** * This function sends a launch progress message. * * Launching the 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: * * =over 4 * * =item 1. * * This is not a documented ABI and the behaviour may be changed * or removed in future. * * =item 2. * * Messages are only sent if more than 5 seconds has elapsed * since the launch clock started. * * =item 3. * * There is a hack in F<src/proto.c> to make this work. * * =back */ void guestfs_int_launch_send_progress (guestfs_h *g, int perdozen) { struct timeval tv; gettimeofday (&tv, NULL); if (guestfs_int_timeval_diff (&g->launch_t, &tv) >= 5000) { guestfs_progress progress_message = { .proc = 0, .serial = 0, .position = perdozen, .total = 12 }; guestfs_int_progress_message_callback (g, &progress_message); } }
/** * Test C<guestfs_int_timeval_diff>. */ static void test_timeval_diff (void) { struct timeval x, y; int64_t ms; y.tv_sec = 1; y.tv_usec = 0; x.tv_sec = 0; x.tv_usec = 0; ms = guestfs_int_timeval_diff (&x, &y); assert (ms == 1000); y.tv_sec = 0; y.tv_usec = 0; x.tv_sec = 1; x.tv_usec = 0; ms = guestfs_int_timeval_diff (&x, &y); assert (ms == -1000); y.tv_sec = 1; y.tv_usec = 0; x.tv_sec = 0; x.tv_usec = 900000; ms = guestfs_int_timeval_diff (&x, &y); assert (ms == 100); y.tv_sec = 0; y.tv_usec = 900000; x.tv_sec = 1; x.tv_usec = 0; ms = guestfs_int_timeval_diff (&x, &y); assert (ms == -100); y.tv_sec = 1; y.tv_usec = 100000; x.tv_sec = 0; x.tv_usec = 900000; ms = guestfs_int_timeval_diff (&x, &y); assert (ms == 200); y.tv_sec = 0; y.tv_usec = 900000; x.tv_sec = 1; x.tv_usec = 100000; ms = guestfs_int_timeval_diff (&x, &y); assert (ms == -200); }