summaryrefslogtreecommitdiffstats
path: root/src/appliance.c
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2011-08-18 17:41:09 +0100
committerRichard W.M. Jones <rjones@redhat.com>2011-08-18 18:02:56 +0100
commit635af5be04265f845186b40e9a9fe7b102ad6909 (patch)
tree500912c27eadeab0fd27a3f090462d3d6b7114cb /src/appliance.c
parent70c033998e0e721dc4f9eb2a20348098b259752c (diff)
downloadlibguestfs-635af5be04265f845186b40e9a9fe7b102ad6909.tar.gz
libguestfs-635af5be04265f845186b40e9a9fe7b102ad6909.tar.xz
libguestfs-635af5be04265f845186b40e9a9fe7b102ad6909.zip
Remove guestfs___print_timestamped_argv.
This function was used to print the qemu and febootstrap-supermin-helper command lines. Unfortunately in the qemu case it was used incorrectly: it called the internal debug function (ie. event API callback) from the forked qemu subprocess, which meant that higher level event callbacks might have been invoked from the child process. To fix this, convert the qemu case into a new function called print_qemu_command line which just prints the command line directly to stderr. This is called after stderr has been redirected into the pipe to the main process. Thus the qemu command line will be marshalled into the event API along with other qemu and appliance output. After fixing this, only one use of guestfs___print_timestamped_argv remained, for printing the febootstrap-supermin-helper command line. This is converted to a local function print_febootstrap_command_line. Also print_febootstrap_command_line is now called before we fork febootstrap-supermin-helper, so that messages no longer overlap.
Diffstat (limited to 'src/appliance.c')
-rw-r--r--src/appliance.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/src/appliance.c b/src/appliance.c
index 56838825..1df8c361 100644
--- a/src/appliance.c
+++ b/src/appliance.c
@@ -55,6 +55,7 @@ static int check_for_cached_appliance (guestfs_h *g, const char *supermin_path,
static int build_supermin_appliance (guestfs_h *g, const char *supermin_path, const char *checksum, uid_t uid, char **kernel, char **initrd, char **appliance);
static int hard_link_to_cached_appliance (guestfs_h *g, const char *cachedir, char **kernel, char **initrd, char **appliance);
static int run_supermin_helper (guestfs_h *g, const char *supermin_path, const char *cachedir, size_t cdlen);
+static void print_febootstrap_command_line (guestfs_h *g, const char *argv[]);
/* Locate or build the appliance.
*
@@ -640,6 +641,9 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
argv[i++] = root;
argv[i++] = NULL;
+ if (g->verbose)
+ print_febootstrap_command_line (g, argv);
+
pid_t pid = fork ();
if (pid == -1) {
perrorf (g, "fork");
@@ -647,9 +651,6 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
}
if (pid > 0) { /* Parent. */
- if (g->verbose)
- guestfs___print_timestamped_argv (g, argv);
-
int status;
if (waitpid (pid, &status, 0) == -1) {
perrorf (g, "waitpid");
@@ -674,6 +675,54 @@ run_supermin_helper (guestfs_h *g, const char *supermin_path,
_exit (EXIT_FAILURE);
}
+static void
+print_febootstrap_command_line (guestfs_h *g, const char *argv[])
+{
+ int i;
+ int needs_quote;
+ char *buf;
+ size_t len;
+
+ /* Calculate length of the buffer needed. This is an overestimate. */
+ len = 0;
+ for (i = 0; argv[i] != NULL; ++i)
+ len += strlen (argv[i]) + 32;
+
+ buf = malloc (len);
+ if (buf == NULL) {
+ warning (g, "malloc: %m");
+ return;
+ }
+
+ len = 0;
+ for (i = 0; argv[i] != NULL; ++i) {
+ if (i > 0) {
+ strcpy (&buf[len], " ");
+ len++;
+ }
+
+ /* Does it need shell quoting? This only deals with simple cases. */
+ needs_quote = strcspn (argv[i], " ") != strlen (argv[i]);
+
+ if (needs_quote) {
+ strcpy (&buf[len], "'");
+ len++;
+ }
+
+ strcpy (&buf[len], argv[i]);
+ len += strlen (argv[i]);
+
+ if (needs_quote) {
+ strcpy (&buf[len], "'");
+ len++;
+ }
+ }
+
+ guestfs___print_timestamped_message (g, "%s", buf);
+
+ free (buf);
+}
+
/* Search elements of g->path, returning the first path element which
* matches the predicate function 'pred'.
*