New APIs: set-pgroup, get-pgroup
authorRichard W.M. Jones <rjones@redhat.com>
Fri, 15 Jul 2011 10:38:21 +0000 (11:38 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Fri, 15 Jul 2011 11:24:51 +0000 (12:24 +0100)
If the pgroup flag is set in the handle, then the qemu and recovery
subprocesses are placed in separate process groups.  The default is
false.

The purpose for setting up a process group is that ^C will not be
passed from the main process down to these processes (killing them).
This allows ^C and other keyboard events to be caught and handled in
the main process.

generator/generator_actions.ml
src/guestfs-internal.h
src/guestfs.c
src/launch.c

index 1ccacdb..87c934a 100644 (file)
@@ -1526,6 +1526,25 @@ advice before using trademarks in applications.
 
 =back");
 
+  ("set_pgroup", (RErr, [Bool "pgroup"], []), -1, [FishAlias "pgroup"],
+   [],
+   "set process group flag",
+   "\
+If C<pgroup> is true, child processes are placed into
+their own process group.
+
+The practical upshot of this is that signals like C<SIGINT> (from
+users pressing C<^C>) won't be received by the child process.
+
+The default for this flag is false, because usually you want
+C<^C> to kill the subprocess.");
+
+  ("get_pgroup", (RBool "pgroup", [], []), -1, [],
+   [],
+   "get process group flag",
+   "\
+This returns the process group flag.");
+
 ]
 
 (* daemon_functions are any functions which cause some action
index 96f8152..e2ffdf3 100644 (file)
@@ -170,6 +170,8 @@ struct guestfs_h
 
   int selinux;                  /* selinux enabled? */
 
+  int pgroup;                   /* Create process group for children? */
+
   char *last_error;
   int last_errnum;              /* errno, or 0 if there was no errno */
 
index b02bdb9..e2b7159 100644 (file)
@@ -801,6 +801,19 @@ guestfs__get_attach_method (guestfs_h *g)
   return ret;
 }
 
+int
+guestfs__set_pgroup (guestfs_h *g, int v)
+{
+  g->pgroup = !!v;
+  return 0;
+}
+
+int
+guestfs__get_pgroup (guestfs_h *g)
+{
+  return g->pgroup;
+}
+
 /* Note the private data area is allocated lazily, since the vast
  * majority of callers will never use it.  This means g->pda is
  * likely to be NULL.
index 0b15ce9..1a47363 100644 (file)
@@ -643,12 +643,9 @@ launch_appliance (guestfs_h *g)
       close (rfd[1]);
     }
 
-#if 0
-    /* Set up a new process group, so we can signal this process
-     * and all subprocesses (eg. if qemu is really a shell script).
-     */
-    setpgid (0, 0);
-#endif
+    /* Put qemu in a new process group. */
+    if (g->pgroup)
+      setpgid (0, 0);
 
     setenv ("LC_ALL", "C", 1);
 
@@ -677,6 +674,14 @@ launch_appliance (guestfs_h *g)
       pid_t qemu_pid = g->pid;
       pid_t parent_pid = getppid ();
 
+      /* It would be nice to be able to put this in the same process
+       * group as qemu (ie. setpgid (0, qemu_pid)).  However this is
+       * not possible because we don't have any guarantee here that
+       * the qemu process has started yet.
+       */
+      if (g->pgroup)
+        setpgid (0, 0);
+
       /* 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
        */