From 08c9bf5e22ecf06e36cf128416a62214704da411 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Tue, 3 Nov 2009 15:30:36 +0000 Subject: [PATCH] Allow callers to disable the recovery process. --- src/generator.ml | 26 +++++++++++++++++++++ src/guestfs.c | 71 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/generator.ml b/src/generator.ml index bbdb330..a06e208 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -835,6 +835,32 @@ The default is disabled."); "\ Return the direct appliance mode flag."); + ("set_recovery_proc", (RErr, [Bool "recoveryproc"]), -1, [FishAlias "recovery-proc"], + [InitNone, Always, TestOutputTrue ( + [["set_recovery_proc"; "true"]; + ["get_recovery_proc"]])], + "enable or disable the recovery process", + "\ +If this is called with the parameter C then +C does not create a recovery process. The +purpose of the recovery process is to stop runaway qemu +processes in the case where the main program aborts abruptly. + +This only has any effect if called before C, +and the default is true. + +About the only time when you would want to disable this is +if the main process will fork itself into the background +(\"daemonize\" itself). In this case the recovery process +thinks that the main program has disappeared and so kills +qemu, which is not very helpful."); + + ("get_recovery_proc", (RBool "recoveryproc", []), -1, [], + [], + "get recovery process enabled flag", + "\ +Return the recovery process enabled flag."); + ] (* daemon_functions are any functions which cause some action diff --git a/src/guestfs.c b/src/guestfs.c index a25e9e7..f7df27e 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -120,6 +120,7 @@ struct guestfs_h int trace; int autosync; int direct; + int recovery_proc; char *path; /* Path to kernel, initrd. */ char *qemu; /* Qemu binary. */ @@ -169,6 +170,8 @@ guestfs_create (void) g->error_cb = default_error_cb; g->error_cb_data = NULL; + g->recovery_proc = 1; + str = getenv ("LIBGUESTFS_DEBUG"); g->verbose = str != NULL && strcmp (str, "1") == 0; @@ -665,6 +668,19 @@ guestfs__get_direct (guestfs_h *g) return g->direct; } +int +guestfs__set_recovery_proc (guestfs_h *g, int f) +{ + g->recovery_proc = !!f; + return 0; +} + +int +guestfs__get_recovery_proc (guestfs_h *g) +{ + return g->recovery_proc; +} + /* Add a string to the current command line. */ static void incr_cmdline_size (guestfs_h *g) @@ -1213,36 +1229,39 @@ guestfs__launch (guestfs_h *g) /* Fork the recovery process off which will kill qemu if the parent * process fails to do so (eg. if the parent segfaults). */ - r = fork (); - if (r == 0) { - pid_t qemu_pid = g->pid; - pid_t parent_pid = getppid (); - - /* Writing to argv is hideously complicated and error prone. See: - * http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/misc/ps_status.c?rev=1.33.2.1;content-type=text%2Fplain - */ + g->recoverypid = -1; + if (g->recovery_proc) { + r = fork (); + if (r == 0) { + pid_t qemu_pid = g->pid; + pid_t parent_pid = getppid (); + + /* Writing to argv is hideously complicated and error prone. See: + * http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/misc/ps_status.c?rev=1.33.2.1;content-type=text%2Fplain + */ - /* Loop around waiting for one or both of the other processes to - * disappear. It's fair to say this is very hairy. The PIDs that - * we are looking at might be reused by another process. We are - * effectively polling. Is the cure worse than the disease? - */ - for (;;) { - if (kill (qemu_pid, 0) == -1) /* qemu's gone away, we aren't needed */ - _exit (0); - if (kill (parent_pid, 0) == -1) { - /* Parent's gone away, qemu still around, so kill qemu. */ - kill (qemu_pid, 9); - _exit (0); + /* Loop around waiting for one or both of the other processes to + * disappear. It's fair to say this is very hairy. The PIDs that + * we are looking at might be reused by another process. We are + * effectively polling. Is the cure worse than the disease? + */ + for (;;) { + if (kill (qemu_pid, 0) == -1) /* qemu's gone away, we aren't needed */ + _exit (0); + if (kill (parent_pid, 0) == -1) { + /* Parent's gone away, qemu still around, so kill qemu. */ + kill (qemu_pid, 9); + _exit (0); + } + sleep (2); } - sleep (2); } - } - /* Don't worry, if the fork failed, this will be -1. The recovery - * process isn't essential. - */ - g->recoverypid = r; + /* Don't worry, if the fork failed, this will be -1. The recovery + * process isn't essential. + */ + g->recoverypid = r; + } /* Start the clock ... */ time (&g->start_t); -- 1.8.3.1