ctdb-daemon: Add ctdb_vfork_exec()
authorAmitay Isaacs <amitay@gmail.com>
Wed, 30 Nov 2016 01:15:11 +0000 (12:15 +1100)
committerMartin Schwenke <martins@samba.org>
Mon, 5 Dec 2016 07:09:23 +0000 (08:09 +0100)
This will replace ctdb_vfork_with_logging().

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/include/ctdb_private.h
ctdb/server/ctdb_fork.c

index 022c10a4e70be69e0231904bac7970c291bcc172..e3085d0e6ee265883833ece310539371f7967dc7 100644 (file)
@@ -606,6 +606,9 @@ int switch_from_server_to_client(struct ctdb_context *ctdb);
 void ctdb_track_child(struct ctdb_context *ctdb, pid_t pid);
 
 pid_t ctdb_fork(struct ctdb_context *ctdb);
+pid_t ctdb_vfork_exec(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
+                     const char *helper, int helper_argc,
+                     const char **helper_argv);
 
 struct tevent_signal *ctdb_init_sigchld(struct ctdb_context *ctdb);
 
index 97dff0088babeb6647e479c8488b3cac52b749ce..1065423199dcae48759cabfbb8ac9756c1be2e4c 100644 (file)
@@ -102,6 +102,52 @@ pid_t ctdb_fork(struct ctdb_context *ctdb)
        return pid;
 }
 
+/*
+ * vfork + exec
+ */
+pid_t ctdb_vfork_exec(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
+                     const char *helper, int helper_argc,
+                     const char **helper_argv)
+{
+       pid_t pid;
+       struct timeval before;
+       double delta_t;
+       char **argv;
+       int i;
+
+       argv = talloc_array(mem_ctx, char *, helper_argc + 1);
+       if (argv == NULL) {
+               DEBUG(DEBUG_ERR, ("Memory allocation error\n"));
+               return -1;
+       }
+
+       argv[0] = discard_const(helper);
+       for (i=0; i<helper_argc; i++) {
+               argv[i+1] = discard_const(helper_argv[i]);
+       }
+
+       before = timeval_current();
+
+       pid = vfork();
+       if (pid == -1) {
+               DEBUG(DEBUG_ERR, ("vfork() failed (%s)\n", strerror(errno)));
+               return -1;
+       }
+
+       if (pid == 0) {
+               execv(helper, argv);
+               _exit(1);
+       }
+
+       delta_t = timeval_elapsed(&before);
+       if (delta_t > 3.0) {
+               DEBUG(DEBUG_WARNING, ("vfork() took %lf seconds\n", delta_t));
+       }
+
+       ctdb_track_child(ctdb, pid);
+       return pid;
+}
+
 static void ctdb_sigchld_handler(struct tevent_context *ev,
        struct tevent_signal *te, int signum, int count,
        void *dont_care,