This will allow to add sysupgrade support via upgraded for failsafe mode. Signed-off-by: Matthias Schiffer <mschif...@universe-factory.net>
Note: obviously, this patch should go into the procd repo when it is actually applied; it is provided like this for now to allow easier testing of the whole series. --- ...pport-for-sysupgrades-triggered-from-prei.patch | 272 +++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 package/system/procd/patches/0005-init-add-support-for-sysupgrades-triggered-from-prei.patch diff --git a/package/system/procd/patches/0005-init-add-support-for-sysupgrades-triggered-from-prei.patch b/package/system/procd/patches/0005-init-add-support-for-sysupgrades-triggered-from-prei.patch new file mode 100644 index 0000000000..bbd7b6dd92 --- /dev/null +++ b/package/system/procd/patches/0005-init-add-support-for-sysupgrades-triggered-from-prei.patch @@ -0,0 +1,272 @@ +From 49970e3f3c5c4ba35b6566e52104cacfc9d3e939 Mon Sep 17 00:00:00 2001 +Message-Id: <49970e3f3c5c4ba35b6566e52104cacfc9d3e939.1492987636.git.mschif...@universe-factory.net> +In-Reply-To: <3462ccc0c91964ec92c1c61cde803a6504b2fb24.1492987636.git.mschif...@universe-factory.net> +References: <3462ccc0c91964ec92c1c61cde803a6504b2fb24.1492987636.git.mschif...@universe-factory.net> +From: Matthias Schiffer <mschif...@universe-factory.net> +Date: Mon, 24 Apr 2017 00:40:27 +0200 +Subject: [PATCH 5/5] init: add support for sysupgrades triggered from preinit + +This will allow to add sysupgrade support via upgraded for failsafe mode. + +Signed-off-by: Matthias Schiffer <mschif...@universe-factory.net> +--- + CMakeLists.txt | 4 ++-- + initd/preinit.c | 46 +++++++++++++++++++++++++++++++++++++++++----- + system.c | 35 ++++------------------------------- + sysupgrade.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ + sysupgrade.h | 15 +++++++++++++++ + watchdog.h | 2 ++ + 6 files changed, 113 insertions(+), 38 deletions(-) + create mode 100644 sysupgrade.c + create mode 100644 sysupgrade.h + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0729459..7d05e97 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -18,7 +18,7 @@ INSTALL(TARGETS setlbf + ) + + +-SET(SOURCES procd.c signal.c state.c inittab.c rcS.c ubus.c system.c ++SET(SOURCES procd.c signal.c state.c inittab.c rcS.c ubus.c system.c sysupgrade.c + service/service.c service/instance.c service/validate.c service/trigger.c service/watch.c + utils/utils.c) + IF(NOT DISABLE_INIT) +@@ -54,7 +54,7 @@ INCLUDE_DIRECTORIES(${ubox_include_dir}) + IF(DISABLE_INIT) + ADD_DEFINITIONS(-DDISABLE_INIT) + ELSE() +-ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c watchdog.c ++ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c sysupgrade.c watchdog.c + utils/utils.c ${SOURCES_ZRAM}) + TARGET_LINK_LIBRARIES(init ${LIBS}) + INSTALL(TARGETS init +diff --git a/initd/preinit.c b/initd/preinit.c +index 729978e..dda6576 100644 +--- a/initd/preinit.c ++++ b/initd/preinit.c +@@ -27,6 +27,7 @@ + + #include "init.h" + #include "../watchdog.h" ++#include "../sysupgrade.h" + + static struct uloop_process preinit_proc; + static struct uloop_process plugd_proc; +@@ -49,23 +50,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); +diff --git a/system.c b/system.c +index dc509ff..8b8cdbc 100644 +--- a/system.c ++++ b/system.c +@@ -28,6 +28,7 @@ + #include <libubox/uloop.h> + + #include "procd.h" ++#include "sysupgrade.h" + #include "watchdog.h" + + static struct blob_buf b; +@@ -346,34 +347,6 @@ static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = { + [SYSUPGRADE_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING }, + }; + +-static void +-procd_exec_upgraded(const char *prefix, char *path, char *command) +-{ +- char *wdt_fd = watchdog_fd(); +- char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL}; +- +- if (chroot(prefix)) { +- fprintf(stderr, "Failed to chroot for upgraded exec.\n"); +- return; +- } +- +- argv[1] = path; +- argv[2] = command; +- +- DEBUG(2, "Exec to upgraded now\n"); +- if (wdt_fd) { +- watchdog_set_cloexec(false); +- setenv("WDTFD", wdt_fd, 1); +- } +- execvp(argv[0], argv); +- +- /* Cleanup on failure */ +- fprintf(stderr, "Failed to exec upgraded.\n"); +- unsetenv("WDTFD"); +- watchdog_set_cloexec(true); +- chroot("."); +-} +- + static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +@@ -387,9 +360,9 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, + if (!tb[SYSUPGRADE_PATH] || !tb[SYSUPGRADE_PREFIX]) + return UBUS_STATUS_INVALID_ARGUMENT; + +- procd_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]), +- blobmsg_get_string(tb[SYSUPGRADE_PATH]), +- tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL); ++ sysupgrade_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]), ++ blobmsg_get_string(tb[SYSUPGRADE_PATH]), ++ tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL); + return 0; + } + +diff --git a/sysupgrade.c b/sysupgrade.c +new file mode 100644 +index 0000000..30f1836 +--- /dev/null ++++ b/sysupgrade.c +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (C) 2013 Felix Fietkau <n...@openwrt.org> ++ * Copyright (C) 2013 John Crispin <blo...@openwrt.org> ++ * Copyright (C) 2017 Matthias Schiffer <mschif...@universe-factory.net> ++ * ++ * 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 "watchdog.h" ++#include "sysupgrade.h" ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <unistd.h> ++ ++ ++void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command) ++{ ++ char *wdt_fd = watchdog_fd(); ++ char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL}; ++ ++ if (chroot(prefix)) { ++ fprintf(stderr, "Failed to chroot for upgraded exec.\n"); ++ return; ++ } ++ ++ argv[1] = path; ++ argv[2] = command; ++ ++ if (wdt_fd) { ++ watchdog_set_cloexec(false); ++ setenv("WDTFD", wdt_fd, 1); ++ } ++ execvp(argv[0], argv); ++ ++ /* Cleanup on failure */ ++ fprintf(stderr, "Failed to exec upgraded.\n"); ++ unsetenv("WDTFD"); ++ watchdog_set_cloexec(true); ++ chroot("."); ++} +diff --git a/sysupgrade.h b/sysupgrade.h +new file mode 100644 +index 0000000..2122f36 +--- /dev/null ++++ b/sysupgrade.h +@@ -0,0 +1,15 @@ ++/* ++ * Copyright (C) 2017 Matthias Schiffer <mschif...@universe-factory.net> ++ * ++ * 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. ++ */ ++ ++ ++void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command); +diff --git a/watchdog.h b/watchdog.h +index 641e7e1..3c4a487 100644 +--- a/watchdog.h ++++ b/watchdog.h +@@ -15,6 +15,8 @@ + #ifndef __PROCD_WATCHDOG_H + #define __PROCD_WATCHDOG_H + ++#include <stdbool.h> ++ + #ifndef DISABLE_INIT + void watchdog_init(int preinit); + char* watchdog_fd(void); +-- +2.12.2 + -- 2.12.2 _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev