"\
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<false> then
+C<guestfs_launch> 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<guestfs_launch>,
+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
int trace;
int autosync;
int direct;
+ int recovery_proc;
char *path; /* Path to kernel, initrd. */
char *qemu; /* Qemu binary. */
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;
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)
/* 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);