From 5f271d6d1b0c36f17f90f18a73162d63328caa46 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 8 Mar 2013 23:46:05 +0100 Subject: [PATCH] add preinit handler --- preinit.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 preinit.c diff --git a/preinit.c b/preinit.c new file mode 100644 index 0000000..f322be1 --- /dev/null +++ b/preinit.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 Felix Fietkau + * Copyright (C) 2013 John Crispin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include +#include + +#include "procd.h" +#include "hotplug.h" +#include "watchdog.h" + +static struct uloop_process preinit; + +static void spawn_procd(struct uloop_process *proc, int ret) +{ + char *wdt_fd = watchdog_fd(); + char *argv[] = { "/sbin/procd", NULL }; + + unsetenv("INITRAMFS"); + unsetenv("PREINIT"); + DEBUG(1, "Exec to real procd now\n"); + if (wdt_fd) + setenv("WDTFD", wdt_fd, 1); + execvp(argv[0], argv); +} + +void procd_preinit(void) +{ + char *argv[] = { "/bin/sh", "/etc/preinit", NULL }; + + LOG("- preinit -\n"); + + setenv("PREINIT", "1", 1); + preinit.cb = spawn_procd; + preinit.pid = fork(); + if (!preinit.pid) { + execvp(argv[0], argv); + ERROR("Failed to start preinit\n"); + exit(-1); + } + + if (preinit.pid <= 0) { + ERROR("Failed to start new preinit instance\n"); + return; + } + + uloop_process_add(&preinit); + DEBUG(2, "Launched preinit instance, pid=%d\n", (int) preinit.pid); +} -- 2.11.0