X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=initd%2Fpreinit.c;h=09edb8fb88d0c9a1da8854bae54285b4fcaba59b;hp=fb94527d50c002043d8500d17ebae61886e412c7;hb=7aad9409d22dc38b71ec75d2aafcfa32426b5594;hpb=dc3988c38546c37a02030af8201048272caa7ded diff --git a/initd/preinit.c b/initd/preinit.c index fb94527..09edb8f 100644 --- a/initd/preinit.c +++ b/initd/preinit.c @@ -11,10 +11,12 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ +#define _GNU_SOURCE #include #include #include +#include #include #include @@ -26,6 +28,7 @@ #include "init.h" #include "../watchdog.h" +#include "../sysupgrade.h" static struct uloop_process preinit_proc; static struct uloop_process plugd_proc; @@ -38,7 +41,8 @@ check_dbglvl(void) if (!fp) return; - fscanf(fp, "%d", &lvl); + if (fscanf(fp, "%d", &lvl) == EOF) + ERROR("failed to read debug level\n"); fclose(fp); unlink("/tmp/debug_level"); @@ -47,22 +51,58 @@ check_dbglvl(void) } static void +check_sysupgrade(void) +{ + char *prefix = NULL, *path = NULL, *command = NULL; + size_t n; + + if (chdir("/")) + return; + + FILE *sysupgrade = fopen("/tmp/sysupgrade", "r"); + if (!sysupgrade) + return; + + n = 0; + if (getdelim(&prefix, &n, 0, sysupgrade) < 0) + goto fail; + n = 0; + if (getdelim(&path, &n, 0, sysupgrade) < 0) + goto fail; + n = 0; + if (getdelim(&command, &n, 0, sysupgrade) < 0) + goto fail; + + fclose(sysupgrade); + + sysupgrade_exec_upgraded(prefix, path, command); + + while (true) + sleep(1); + +fail: + fclose(sysupgrade); + free(prefix); + free(path); + free(command); +} + +static void spawn_procd(struct uloop_process *proc, int ret) { char *wdt_fd = watchdog_fd(); char *argv[] = { "/sbin/procd", NULL}; - struct stat s; char dbg[2]; if (plugd_proc.pid > 0) kill(plugd_proc.pid, SIGKILL); - if (!stat("/tmp/sysupgrade", &s)) - while (true) - sleep(1); - unsetenv("INITRAMFS"); unsetenv("PREINIT"); + unlink("/tmp/.preinit"); + + check_sysupgrade(); + DEBUG(2, "Exec to real procd now\n"); if (wdt_fd) setenv("WDTFD", wdt_fd, 1); @@ -86,6 +126,7 @@ preinit(void) { char *init[] = { "/bin/sh", "/etc/preinit", NULL }; char *plug[] = { "/sbin/procd", "-h", "/etc/hotplug-preinit.json", NULL }; + int fd; LOG("- preinit -\n"); @@ -104,6 +145,13 @@ preinit(void) setenv("PREINIT", "1", 1); + fd = creat("/tmp/.preinit", 0600); + + if (fd < 0) + ERROR("Failed to create sentinel file\n"); + else + close(fd); + preinit_proc.cb = spawn_procd; preinit_proc.pid = fork(); if (!preinit_proc.pid) {