Consider the typical 'fork-without-exec' pattern: often, a program wants to do some initialization, acquire some resources, etc, and then background itself by forking and exiting in the parent. We don't have great support for this, as e.g. reference counts on resources created by the parent can keep processes alive when they should die. (cf, `ipconfig` currently, where we acquire a DHCP lease in the foreground before going into a loop in the background to maintain the lease, but the parent process stays in the "DYING" state forever.)
Barret and I discussed this at length. A possible solution is to have a program that invokes the target process in the background and then waits for an event from that process and then itself exits. Note that this requires a protocol between the two: any place where we exit in the child needs to send an event, and the parent needs to get an event or it blocks. I think a generalization of 'wait' where we can send arbitrary messages with payloads, more along the lines of our existing event support but specialized to process control, would be nice but it's more work than what we've got right now. Think of something analogous to 'wait' but that accepts a payload, paired with a 'background' call of some kind that signals to a possibly-waiting parent that we're going off on our own. Change-Id: I531f1be3076786a638d57db1c660f9b768f5545e Signed-off-by: Dan Cross <[email protected]> --- tools/sys-apps/daemonize/Makefile | 31 +++++++++++++++++++++++++++ tools/sys-apps/daemonize/daemonize.c | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tools/sys-apps/daemonize/Makefile create mode 100644 tools/sys-apps/daemonize/daemonize.c diff --git a/tools/sys-apps/daemonize/Makefile b/tools/sys-apps/daemonize/Makefile new file mode 100644 index 0000000..3958122 --- /dev/null +++ b/tools/sys-apps/daemonize/Makefile @@ -0,0 +1,31 @@ +include ../../Makefrag + +SOURCES:= daemonize.c + +XCC:= $(CROSS_COMPILE)gcc + +LIBS:= + +PHONY:= all +all: daemonize + +PHONY+= daemonize +daemonize: $(SOURCES) + @echo " CC daemonize" + $(Q)$(XCC) -O2 -std=gnu99 -o daemonize $(SOURCES) $(LIBS) + +PHONY+= install +install: daemonize + @echo " IN daemonize" + $(Q)cp daemonize $(KFS_ROOT)/bin/daemonize + $(Q)chmod 755 $(KFS_ROOT)/bin/daemonize + +PHONY+= clean +clean: + @echo " RM daemonize" + $(Q)rm -f daemonize + +PHONY+= mrproper +mrproper: clean + +.PHONY: $(PHONY) diff --git a/tools/sys-apps/daemonize/daemonize.c b/tools/sys-apps/daemonize/daemonize.c new file mode 100644 index 0000000..f7422e1 --- /dev/null +++ b/tools/sys-apps/daemonize/daemonize.c @@ -0,0 +1,41 @@ +#include <parlib/event.h> +#include <parlib/parlib.h> +#include <parlib/uthread.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +static void ev_handler(struct event_msg *msg, unsigned int ev_type, void *data) +{ + int rv; + + assert(msg != NULL); + assert(ev_type == EV_USER_IPI); + (void)data; + rv = msg->ev_arg1; + exit(rv); +} + +int main(int argc, char *argv[], char *envp[]) +{ + struct event_queue *evq, *triggered; + pid_t pid; + struct event_msg msg; + + register_ev_handler(EV_USER_IPI, ev_handler, 0); + evq = get_eventq(EV_MBOX_UCQ); + evq->ev_flags |= EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP; + register_kevent_q(evq, EV_USER_IPI); + + pid = create_child_with_stdfds(argv[1], argc - 1, argv + 1, envp); + if (pid < 0) { + perror("child creation failed"); + exit(-1); + } + sys_proc_run(pid); + + uthread_sleep_forever(); + + return -1; +} -- 2.8.0.rc3.226.g39d4020 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
