diff --git a/patches/openwrt/0104-procd-clean-up-trailing-whitespace-in-nand.sh.patch b/patches/openwrt/0104-procd-clean-up-trailing-whitespace-in-nand.sh.patch new file mode 100644 index 00000000..4b66f8b4 --- /dev/null +++ b/patches/openwrt/0104-procd-clean-up-trailing-whitespace-in-nand.sh.patch @@ -0,0 +1,28 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 08:27:40 +0200 +Subject: procd: clean up trailing whitespace in nand.sh + +Signed-off-by: Matthias Schiffer + +diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh +index 0ed1b632d5a3ecc0299d3f8da853191c453d3bb4..e0d3f2dfdb1e04e17ccf6fea60b0f2af617206f3 100644 +--- a/package/system/procd/files/nand.sh ++++ b/package/system/procd/files/nand.sh +@@ -194,7 +194,7 @@ nand_upgrade_prepare_ubi() { + + nand_do_upgrade_success() { + local conf_tar="/tmp/sysupgrade.tgz" +- ++ + sync + [ -f "$conf_tar" ] && nand_restore_config "$conf_tar" + echo "sysupgrade successful" +@@ -229,7 +229,7 @@ nand_upgrade_ubifs() { + local rootfs_length=`(cat $1 | wc -c) 2> /dev/null` + + nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0" +- ++ + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + local root_ubivol="$(nand_find_volume $ubidev rootfs)" + ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1 diff --git a/patches/openwrt/0105-procd-prepare-NAND-sysupgrade-for-making-upgraded-dynamically-linked.patch b/patches/openwrt/0105-procd-prepare-NAND-sysupgrade-for-making-upgraded-dynamically-linked.patch new file mode 100644 index 00000000..eefd848a --- /dev/null +++ b/patches/openwrt/0105-procd-prepare-NAND-sysupgrade-for-making-upgraded-dynamically-linked.patch @@ -0,0 +1,32 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 08:28:05 +0200 +Subject: procd: prepare NAND sysupgrade for making upgraded dynamically linked + +Use install_bin to copy upgraded with all dependencies. The old name +/tmp/upgraded is temporarily retained as a symlink to avoid breaking +things. + +Signed-off-by: Matthias Schiffer + +diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh +index e0d3f2dfdb1e04e17ccf6fea60b0f2af617206f3..ec2a014a00461ca897d521e2d065f5399f1f8c48 100644 +--- a/package/system/procd/files/nand.sh ++++ b/package/system/procd/files/nand.sh +@@ -318,7 +318,7 @@ nand_upgrade_stage1() { + [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] && + rm $CONF_TAR + +- ubus call system nandupgrade "{\"path\": \"$path\" }" ++ ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }" + exit 0 + } + } +@@ -359,6 +359,7 @@ nand_do_platform_check() { + # $(1): file to be used for upgrade + nand_do_upgrade() { + echo -n $1 > /tmp/sysupgrade-nand-path +- cp /sbin/upgraded /tmp/ ++ install_bin /sbin/upgraded ++ ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded + nand_upgrade_stage1 + } diff --git a/patches/openwrt/0106-procd-add-universal-staged-sysupgrade-patches.patch b/patches/openwrt/0106-procd-add-universal-staged-sysupgrade-patches.patch new file mode 100644 index 00000000..6e588eff --- /dev/null +++ b/patches/openwrt/0106-procd-add-universal-staged-sysupgrade-patches.patch @@ -0,0 +1,1116 @@ +From: Matthias Schiffer +Date: Thu, 1 Jun 2017 22:42:04 +0200 +Subject: procd: add universal staged sysupgrade patches + +diff --git a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch +deleted file mode 100644 +index bc2434200364b46f1db4c2eec22c4e8b973844d5..0000000000000000000000000000000000000000 +--- a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch ++++ /dev/null +@@ -1,97 +0,0 @@ +-From 03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d Mon Sep 17 00:00:00 2001 +-Message-Id: <03a2bc70e4260ec9f669391c47b9a7a9ecd0b75d.1407329621.git.mschiffer@universe-factory.net> +-From: Matthias Schiffer +-Date: Wed, 6 Aug 2014 14:51:49 +0200 +-Subject: [PATCH] Add support for alternative rc.d directories +- +---- +- initd/preinit.c | 38 ++++++++++++++++++++++++++++++++++++++ +- rcS.c | 2 +- +- 2 files changed, 39 insertions(+), 1 deletion(-) +- +-diff --git a/initd/preinit.c b/initd/preinit.c +-index fb94527..8b832a7 100644 +---- a/initd/preinit.c +-+++ b/initd/preinit.c +-@@ -12,6 +12,8 @@ +- * GNU General Public License for more details. +- */ +- +-+#define _GNU_SOURCE +-+ +- #include +- #include +- #include +-@@ -46,6 +48,35 @@ check_dbglvl(void) +- debug = lvl; +- } +- +-+static char* +-+get_rc_d(void) +-+{ +-+ size_t n = 0; +-+ ssize_t len; +-+ char *ret = NULL; +-+ +-+ FILE *fp = fopen("/tmp/rc_d_path", "r"); +-+ +-+ if (!fp) +-+ return NULL; +-+ +-+ len = getline(&ret, &n, fp); +-+ +-+ fclose(fp); +-+ +-+ unlink("/tmp/rc_d_path"); +-+ +-+ if (len <= 0) { +-+ free(ret); +-+ return NULL; +-+ } +-+ +-+ if (ret[len-1] == '\n') +-+ ret[len-1] = 0; +-+ +-+ return ret; +-+} +-+ +- static void +- spawn_procd(struct uloop_process *proc, int ret) +- { +-@@ -53,6 +84,7 @@ spawn_procd(struct uloop_process *proc, int ret) +- char *argv[] = { "/sbin/procd", NULL}; +- struct stat s; +- char dbg[2]; +-+ char *rc_d_path; +- +- if (plugd_proc.pid > 0) +- kill(plugd_proc.pid, SIGKILL); +-@@ -72,6 +104,12 @@ spawn_procd(struct uloop_process *proc, int ret) +- setenv("DBGLVL", dbg, 1); +- } +- +-+ rc_d_path = get_rc_d(); +-+ if (rc_d_path) { +-+ setenv("RC_D_PATH", rc_d_path, 1); +-+ free(rc_d_path); +-+ } +-+ +- execvp(argv[0], argv); +- } +- +-diff --git a/rcS.c b/rcS.c +-index 0e1b0ba..1b00831 100644 +---- a/rcS.c +-+++ b/rcS.c +-@@ -150,7 +150,7 @@ int rcS(char *pattern, char *param, void (*q_empty)(struct runqueue *)) +- q.empty_cb = q_empty; +- q.max_running_tasks = 1; +- +-- return _rc(&q, "/etc/rc.d", pattern, "*", param); +-+ return _rc(&q, getenv("RC_D_PATH") ?: "/etc/rc.d", pattern, "*", param); +- } +- +- int rc(const char *file, char *param) +--- +-2.0.4 +- +diff --git a/package/system/procd/patches/1001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/1001-Add-support-for-alternative-rc.d-directories.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..2d3c24181cef32ae9e15401ff2e4772805ea9551 +--- /dev/null ++++ b/package/system/procd/patches/1001-Add-support-for-alternative-rc.d-directories.patch +@@ -0,0 +1,97 @@ ++From 36673c2a0e409d9c8ea9e1c15363e73bb21ae65b Mon Sep 17 00:00:00 2001 ++Message-Id: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Wed, 6 Aug 2014 14:51:49 +0200 ++Subject: [PATCH 1001/1007] Add support for alternative rc.d directories ++ ++--- ++ initd/preinit.c | 38 ++++++++++++++++++++++++++++++++++++++ ++ rcS.c | 2 +- ++ 2 files changed, 39 insertions(+), 1 deletion(-) ++ ++diff --git a/initd/preinit.c b/initd/preinit.c ++index f38d8ef..acc64e7 100644 ++--- a/initd/preinit.c +++++ b/initd/preinit.c ++@@ -12,6 +12,8 @@ ++ * GNU General Public License for more details. ++ */ ++ +++#define _GNU_SOURCE +++ ++ #include ++ #include ++ #include ++@@ -47,6 +49,35 @@ check_dbglvl(void) ++ debug = lvl; ++ } ++ +++static char* +++get_rc_d(void) +++{ +++ size_t n = 0; +++ ssize_t len; +++ char *ret = NULL; +++ +++ FILE *fp = fopen("/tmp/rc_d_path", "r"); +++ +++ if (!fp) +++ return NULL; +++ +++ len = getline(&ret, &n, fp); +++ +++ fclose(fp); +++ +++ unlink("/tmp/rc_d_path"); +++ +++ if (len <= 0) { +++ free(ret); +++ return NULL; +++ } +++ +++ if (ret[len-1] == '\n') +++ ret[len-1] = 0; +++ +++ return ret; +++} +++ ++ static void ++ spawn_procd(struct uloop_process *proc, int ret) ++ { ++@@ -54,6 +85,7 @@ spawn_procd(struct uloop_process *proc, int ret) ++ char *argv[] = { "/sbin/procd", NULL}; ++ struct stat s; ++ char dbg[2]; +++ char *rc_d_path; ++ ++ if (plugd_proc.pid > 0) ++ kill(plugd_proc.pid, SIGKILL); ++@@ -73,6 +105,12 @@ spawn_procd(struct uloop_process *proc, int ret) ++ setenv("DBGLVL", dbg, 1); ++ } ++ +++ rc_d_path = get_rc_d(); +++ if (rc_d_path) { +++ setenv("RC_D_PATH", rc_d_path, 1); +++ free(rc_d_path); +++ } +++ ++ execvp(argv[0], argv); ++ } ++ ++diff --git a/rcS.c b/rcS.c ++index b3e3c22..e231d71 100644 ++--- a/rcS.c +++++ b/rcS.c ++@@ -162,7 +162,7 @@ int rcS(char *pattern, char *param, void (*q_empty)(struct runqueue *)) ++ q.empty_cb = q_empty; ++ q.max_running_tasks = 1; ++ ++- return _rc(&q, "/etc/rc.d", pattern, "*", param); +++ return _rc(&q, getenv("RC_D_PATH") ?: "/etc/rc.d", pattern, "*", param); ++ } ++ ++ int rc(const char *file, char *param) ++-- ++2.13.0 ++ +diff --git a/package/system/procd/patches/1002-system-always-support-staged-sysupgrade.patch b/package/system/procd/patches/1002-system-always-support-staged-sysupgrade.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..f19a21aed1a5931d609684ff70784fe40b0d1406 +--- /dev/null ++++ b/package/system/procd/patches/1002-system-always-support-staged-sysupgrade.patch +@@ -0,0 +1,114 @@ ++From 7d2c86de79b6bd976f0e37f7c3cbc61a3b3c3bb7 Mon Sep 17 00:00:00 2001 ++Message-Id: <7d2c86de79b6bd976f0e37f7c3cbc61a3b3c3bb7.1496349467.git.mschiffer@universe-factory.net> ++In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Fri, 21 Apr 2017 20:06:59 +0200 ++Subject: [PATCH 1002/1007] system: always support staged sysupgrade ++ ++In preparation for switching all targets to the staged sysupgrade ++mechanism, upgraded is always built, and the "nandupgrade" ubus method is ++renamed to "sysupgrade". ++ ++To make the migration easier, support for the old name "nandupgrade" and ++the "upgrade" method that will become unused with the staged sysupgrade is ++retained for now. ++ ++Signed-off-by: Matthias Schiffer ++--- ++ CMakeLists.txt | 4 +--- ++ system.c | 31 +++++++++++++------------------ ++ 2 files changed, 14 insertions(+), 21 deletions(-) ++ ++diff --git a/CMakeLists.txt b/CMakeLists.txt ++index cc1e4a5..9e378ae 100644 ++--- a/CMakeLists.txt +++++ b/CMakeLists.txt ++@@ -32,9 +32,7 @@ IF(ZRAM_TMPFS) ++ SET(SOURCES_ZRAM initd/zram.c) ++ ENDIF() ++ ++-IF(BUILD_UPGRADED) ++- add_subdirectory(upgraded) ++-ENDIF() +++add_subdirectory(upgraded) ++ ++ ADD_EXECUTABLE(procd ${SOURCES}) ++ TARGET_LINK_LIBRARIES(procd ${LIBS}) ++diff --git a/system.c b/system.c ++index fb7fbe4..701ff35 100644 ++--- a/system.c +++++ b/system.c ++@@ -328,12 +328,12 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj, ++ } ++ ++ enum { ++- NAND_PATH, ++- __NAND_MAX +++ SYSUPGRADE_PATH, +++ __SYSUPGRADE_MAX ++ }; ++ ++-static const struct blobmsg_policy nand_policy[__NAND_MAX] = { ++- [NAND_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, +++static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = { +++ [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, ++ }; ++ ++ static void ++@@ -352,20 +352,20 @@ procd_spawn_upgraded(char *path) ++ execvp(argv[0], argv); ++ } ++ ++-static int nand_set(struct ubus_context *ctx, struct ubus_object *obj, ++- struct ubus_request_data *req, const char *method, ++- struct blob_attr *msg) +++static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, +++ struct ubus_request_data *req, const char *method, +++ struct blob_attr *msg) ++ { ++- struct blob_attr *tb[__NAND_MAX]; +++ struct blob_attr *tb[__SYSUPGRADE_MAX]; ++ ++ if (!msg) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++- blobmsg_parse(nand_policy, __NAND_MAX, tb, blob_data(msg), blob_len(msg)); ++- if (!tb[NAND_PATH]) +++ blobmsg_parse(sysupgrade_policy, __SYSUPGRADE_MAX, tb, blob_data(msg), blob_len(msg)); +++ if (!tb[SYSUPGRADE_PATH]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++- procd_spawn_upgraded(blobmsg_get_string(tb[NAND_PATH])); +++ procd_spawn_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PATH])); ++ fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n"); ++ return 0; ++ } ++@@ -383,9 +383,8 @@ static const struct ubus_method system_methods[] = { ++ UBUS_METHOD_NOARG("upgrade", system_upgrade), ++ UBUS_METHOD("watchdog", watchdog_set, watchdog_policy), ++ UBUS_METHOD("signal", proc_signal, signal_policy), ++- ++- /* must remain at the end as it ia not always loaded */ ++- UBUS_METHOD("nandupgrade", nand_set, nand_policy), +++ UBUS_METHOD("nandupgrade", sysupgrade, sysupgrade_policy), +++ UBUS_METHOD("sysupgrade", sysupgrade, sysupgrade_policy), ++ }; ++ ++ static struct ubus_object_type system_object_type = ++@@ -414,12 +413,8 @@ procd_bcast_event(char *event, struct blob_attr *msg) ++ ++ void ubus_init_system(struct ubus_context *ctx) ++ { ++- struct stat s; ++ int ret; ++ ++- if (stat("/sbin/upgraded", &s)) ++- system_object.n_methods -= 1; ++- ++ _ctx = ctx; ++ ret = ubus_add_object(ctx, &system_object); ++ if (ret) ++-- ++2.13.0 ++ +diff --git a/package/system/procd/patches/1003-upgraded-link-dynamically-chroot-during-exec.patch b/package/system/procd/patches/1003-upgraded-link-dynamically-chroot-during-exec.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..d57cb02fba42894e5d279d4aa4ab00e0619f66f4 +--- /dev/null ++++ b/package/system/procd/patches/1003-upgraded-link-dynamically-chroot-during-exec.patch +@@ -0,0 +1,222 @@ ++From a6f07873f2189dd7b6742c04064c7bbee2c9d28b Mon Sep 17 00:00:00 2001 ++Message-Id: ++In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Sun, 23 Apr 2017 02:28:13 +0200 ++Subject: [PATCH 1003/1007] upgraded: link dynamically, chroot during exec ++ ++The chroot ensures we don't reference anything on the rootfs and is ++reverted after the upgraded exec. While we're at it, also improve error ++handling a bit. ++ ++This change also required changes to sysupgrade, as the dynamically linked ++version is expected at a different location, and libraries need to be made ++available. ++ ++Signed-off-by: Matthias Schiffer ++--- ++ system.c | 25 +++++++++++++++++++------ ++ upgraded/CMakeLists.txt | 10 +--------- ++ upgraded/upgraded.c | 26 +++++++++++++++++++++----- ++ watchdog.c | 9 +++++++-- ++ watchdog.h | 2 +- ++ 5 files changed, 49 insertions(+), 23 deletions(-) ++ ++diff --git a/system.c b/system.c ++index 701ff35..ad71956 100644 ++--- a/system.c +++++ b/system.c ++@@ -329,27 +329,40 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj, ++ ++ enum { ++ SYSUPGRADE_PATH, +++ SYSUPGRADE_PREFIX, ++ __SYSUPGRADE_MAX ++ }; ++ ++ static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = { ++ [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, +++ [SYSUPGRADE_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING }, ++ }; ++ ++ static void ++-procd_spawn_upgraded(char *path) +++procd_exec_upgraded(const char *prefix, char *path) ++ { ++ char *wdt_fd = watchdog_fd(); ++- char *argv[] = { "/tmp/upgraded", NULL, NULL}; +++ char *argv[] = { "/sbin/upgraded", NULL, NULL}; +++ +++ if (chroot(prefix)) { +++ fprintf(stderr, "Failed to chroot for upgraded exec.\n"); +++ return; +++ } ++ ++ argv[1] = path; ++ ++ DEBUG(2, "Exec to upgraded now\n"); ++ if (wdt_fd) { ++- watchdog_no_cloexec(); +++ 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, ++@@ -362,11 +375,11 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ blobmsg_parse(sysupgrade_policy, __SYSUPGRADE_MAX, tb, blob_data(msg), blob_len(msg)); ++- if (!tb[SYSUPGRADE_PATH]) +++ if (!tb[SYSUPGRADE_PATH] || !tb[SYSUPGRADE_PREFIX]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++- procd_spawn_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PATH])); ++- fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n"); +++ procd_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]), +++ blobmsg_get_string(tb[SYSUPGRADE_PATH])); ++ return 0; ++ } ++ ++diff --git a/upgraded/CMakeLists.txt b/upgraded/CMakeLists.txt ++index 093dba2..00d8ce5 100644 ++--- a/upgraded/CMakeLists.txt +++++ b/upgraded/CMakeLists.txt ++@@ -2,16 +2,8 @@ cmake_minimum_required(VERSION 2.6) ++ ++ PROJECT(upgraded C) ++ ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations) ++-set(CMAKE_EXE_LINKER_FLAGS "-static -fPIC") ++-set(CMAKE_FIND_LIBRARY_SUFFIXES .a) ++-set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) ++-set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS) ++-set(CMAKE_SHARED_LIBRARY_C_FLAGS) ++-set(CMAKE_SHARED_LIBRARY_CXX_FLAGS) ++-set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) ++-set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) ++ ADD_EXECUTABLE(upgraded upgraded.c ../watchdog.c) ++-TARGET_LINK_LIBRARIES(upgraded ubox rt -lc -lgcc_pic) +++TARGET_LINK_LIBRARIES(upgraded ubox) ++ INSTALL(TARGETS upgraded ++ RUNTIME DESTINATION sbin ++ ) ++diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c ++index d7433e7..aa0b4ff 100644 ++--- a/upgraded/upgraded.c +++++ b/upgraded/upgraded.c ++@@ -14,6 +14,7 @@ ++ ++ #include ++ +++#include ++ #include ++ #include ++ #include ++@@ -24,6 +25,10 @@ ++ ++ #include "../watchdog.h" ++ +++#ifndef O_PATH +++#define O_PATH 010000000 +++#endif +++ ++ static struct uloop_process upgrade_proc; ++ unsigned int debug = 2; ++ ++@@ -34,7 +39,7 @@ static void upgrade_proc_cb(struct uloop_process *proc, int ret) ++ uloop_end(); ++ } ++ ++-static void sysupgarde(char *folder) +++static void sysupgrade(char *folder) ++ { ++ char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL }; ++ ++@@ -47,7 +52,7 @@ static void sysupgarde(char *folder) ++ exit(-1); ++ } ++ if (upgrade_proc.pid <= 0) { ++- fprintf(stderr, "Failed to start sysupgarde\n"); +++ fprintf(stderr, "Failed to start sysupgrade\n"); ++ uloop_end(); ++ } ++ } ++@@ -60,10 +65,21 @@ int main(int argc, char **argv) ++ fprintf(stderr, "this tool needs to run as pid 1\n"); ++ return -1; ++ } ++- if (chdir("/tmp") == -1) { ++- fprintf(stderr, "failed to chdir to /tmp: %s\n", strerror(errno)); +++ +++ int fd = open("/", O_DIRECTORY|O_PATH); +++ if (fd < 0) { +++ fprintf(stderr, "unable to open prefix directory: %s\n", strerror(errno)); ++ return -1; ++ } +++ +++ chroot("."); +++ +++ if (fchdir(fd) == -1) { +++ fprintf(stderr, "failed to chdir to prefix directory: %s\n", strerror(errno)); +++ return -1; +++ } +++ close(fd); +++ ++ if (argc != 2) { ++ fprintf(stderr, "sysupgrade stage 2 failed, no folder specified\n"); ++ return -1; ++@@ -71,7 +87,7 @@ int main(int argc, char **argv) ++ ++ uloop_init(); ++ watchdog_init(0); ++- sysupgarde(argv[1]); +++ sysupgrade(argv[1]); ++ uloop_run(); ++ ++ reboot(RB_AUTOBOOT); ++diff --git a/watchdog.c b/watchdog.c ++index 592ae7e..780b321 100644 ++--- a/watchdog.c +++++ b/watchdog.c ++@@ -126,10 +126,15 @@ void watchdog_init(int preinit) ++ } ++ ++ ++-void watchdog_no_cloexec(void) +++void watchdog_set_cloexec(bool val) ++ { ++ if (wdt_fd < 0) ++ return; ++ ++- fcntl(wdt_fd, F_SETFD, fcntl(wdt_fd, F_GETFD) & ~FD_CLOEXEC); +++ int flags = fcntl(wdt_fd, F_GETFD); +++ if (val) +++ flags |= FD_CLOEXEC; +++ else +++ flags &= ~FD_CLOEXEC; +++ fcntl(wdt_fd, F_SETFD, flags); ++ } ++diff --git a/watchdog.h b/watchdog.h ++index 015fa93..e857010 100644 ++--- a/watchdog.h +++++ b/watchdog.h ++@@ -21,7 +21,7 @@ int watchdog_timeout(int timeout); ++ int watchdog_frequency(int frequency); ++ void watchdog_set_stopped(bool val); ++ bool watchdog_get_stopped(void); ++-void watchdog_no_cloexec(void); +++void watchdog_set_cloexec(bool val); ++ void watchdog_ping(void); ++ ++ #endif ++-- ++2.13.0 ++ +diff --git a/package/system/procd/patches/1004-upgraded-add-support-for-passing-a-command-argument-.patch b/package/system/procd/patches/1004-upgraded-add-support-for-passing-a-command-argument-.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..ac8c3fe6ee15e773c973c9d340fbe52ce428d6ee +--- /dev/null ++++ b/package/system/procd/patches/1004-upgraded-add-support-for-passing-a-command-argument-.patch +@@ -0,0 +1,104 @@ ++From af1e6d9839a9a8f2c579202597630df9b8f842e6 Mon Sep 17 00:00:00 2001 ++Message-Id: ++In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Sun, 23 Apr 2017 19:04:25 +0200 ++Subject: [PATCH 1004/1007] upgraded: add support for passing a "command" ++ argument to stage2 ++ ++This allows us to make use of upgraded in "snapshot convert" as well. ++ ++Signed-off-by: Matthias Schiffer ++--- ++ system.c | 10 +++++++--- ++ upgraded/upgraded.c | 13 +++++++------ ++ 2 files changed, 14 insertions(+), 9 deletions(-) ++ ++diff --git a/system.c b/system.c ++index ad71956..1e8a06d 100644 ++--- a/system.c +++++ b/system.c ++@@ -330,19 +330,21 @@ static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj, ++ enum { ++ SYSUPGRADE_PATH, ++ SYSUPGRADE_PREFIX, +++ SYSUPGRADE_COMMAND, ++ __SYSUPGRADE_MAX ++ }; ++ ++ static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = { ++ [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, ++ [SYSUPGRADE_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING }, +++ [SYSUPGRADE_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING }, ++ }; ++ ++ static void ++-procd_exec_upgraded(const char *prefix, char *path) +++procd_exec_upgraded(const char *prefix, char *path, char *command) ++ { ++ char *wdt_fd = watchdog_fd(); ++- char *argv[] = { "/sbin/upgraded", NULL, NULL}; +++ char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL}; ++ ++ if (chroot(prefix)) { ++ fprintf(stderr, "Failed to chroot for upgraded exec.\n"); ++@@ -350,6 +352,7 @@ procd_exec_upgraded(const char *prefix, char *path) ++ } ++ ++ argv[1] = path; +++ argv[2] = command; ++ ++ DEBUG(2, "Exec to upgraded now\n"); ++ if (wdt_fd) { ++@@ -379,7 +382,8 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ procd_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]), ++- blobmsg_get_string(tb[SYSUPGRADE_PATH])); +++ blobmsg_get_string(tb[SYSUPGRADE_PATH]), +++ tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL); ++ return 0; ++ } ++ ++diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c ++index aa0b4ff..303edb7 100644 ++--- a/upgraded/upgraded.c +++++ b/upgraded/upgraded.c ++@@ -39,11 +39,12 @@ static void upgrade_proc_cb(struct uloop_process *proc, int ret) ++ uloop_end(); ++ } ++ ++-static void sysupgrade(char *folder) +++static void sysupgrade(char *path, char *command) ++ { ++- char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL }; +++ char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL, NULL }; ++ ++- args[2] = folder; +++ args[2] = path; +++ args[3] = command; ++ upgrade_proc.cb = upgrade_proc_cb; ++ upgrade_proc.pid = fork(); ++ if (!upgrade_proc.pid) { ++@@ -80,14 +81,14 @@ int main(int argc, char **argv) ++ } ++ close(fd); ++ ++- if (argc != 2) { ++- fprintf(stderr, "sysupgrade stage 2 failed, no folder specified\n"); +++ if (argc != 2 && argc != 3) { +++ fprintf(stderr, "sysupgrade stage 2 failed, invalid command line\n"); ++ return -1; ++ } ++ ++ uloop_init(); ++ watchdog_init(0); ++- sysupgrade(argv[1]); +++ sysupgrade(argv[1], (argc == 3) ? argv[2] : NULL); ++ uloop_run(); ++ ++ reboot(RB_AUTOBOOT); ++-- ++2.13.0 ++ +diff --git a/package/system/procd/patches/1005-Remove-code-that-has-become-unnecessary-after-sysupg.patch b/package/system/procd/patches/1005-Remove-code-that-has-become-unnecessary-after-sysupg.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..0be544bce113b920556bc6a9889041227fc42e07 +--- /dev/null ++++ b/package/system/procd/patches/1005-Remove-code-that-has-become-unnecessary-after-sysupg.patch +@@ -0,0 +1,119 @@ ++From 45bd440ec30f777b3619dcd0e7db330cc29a7850 Mon Sep 17 00:00:00 2001 ++Message-Id: <45bd440ec30f777b3619dcd0e7db330cc29a7850.1496349467.git.mschiffer@universe-factory.net> ++In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Sun, 23 Apr 2017 19:06:12 +0200 ++Subject: [PATCH 1005/1007] Remove code that has become unnecessary after ++ sysupgrade changes ++ ++Signed-off-by: Matthias Schiffer ++--- ++ procd.h | 1 - ++ service/instance.c | 2 -- ++ system.c | 12 ------------ ++ upgraded/upgraded.c | 10 +++++----- ++ 4 files changed, 5 insertions(+), 20 deletions(-) ++ ++diff --git a/procd.h b/procd.h ++index 66d183c..796e524 100644 ++--- a/procd.h +++++ b/procd.h ++@@ -27,7 +27,6 @@ ++ #define __init __attribute__((constructor)) ++ ++ extern char *ubus_socket; ++-extern int upgrade_running; ++ ++ void procd_connect_ubus(void); ++ void procd_reconnect_ubus(int reconnect); ++diff --git a/service/instance.c b/service/instance.c ++index 40ff021..f33eae9 100644 ++--- a/service/instance.c +++++ b/service/instance.c ++@@ -453,8 +453,6 @@ instance_exit(struct uloop_process *p, int ret) ++ runtime = tp.tv_sec - in->start.tv_sec; ++ ++ DEBUG(2, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime); ++- if (upgrade_running) ++- return; ++ ++ uloop_timeout_cancel(&in->timeout); ++ if (in->halt) { ++diff --git a/system.c b/system.c ++index 1e8a06d..80205da 100644 ++--- a/system.c +++++ b/system.c ++@@ -31,8 +31,6 @@ static struct blob_buf b; ++ static int notify; ++ static struct ubus_context *_ctx; ++ ++-int upgrade_running = 0; ++- ++ static int system_board(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++@@ -227,14 +225,6 @@ static int system_info(struct ubus_context *ctx, struct ubus_object *obj, ++ return UBUS_STATUS_OK; ++ } ++ ++-static int system_upgrade(struct ubus_context *ctx, struct ubus_object *obj, ++- struct ubus_request_data *req, const char *method, ++- struct blob_attr *msg) ++-{ ++- upgrade_running = 1; ++- return 0; ++-} ++- ++ enum { ++ WDT_FREQUENCY, ++ WDT_TIMEOUT, ++@@ -397,10 +387,8 @@ procd_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) ++ static const struct ubus_method system_methods[] = { ++ UBUS_METHOD_NOARG("board", system_board), ++ UBUS_METHOD_NOARG("info", system_info), ++- UBUS_METHOD_NOARG("upgrade", system_upgrade), ++ UBUS_METHOD("watchdog", watchdog_set, watchdog_policy), ++ UBUS_METHOD("signal", proc_signal, signal_policy), ++- UBUS_METHOD("nandupgrade", sysupgrade, sysupgrade_policy), ++ UBUS_METHOD("sysupgrade", sysupgrade, sysupgrade_policy), ++ }; ++ ++diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c ++index 303edb7..79ebd37 100644 ++--- a/upgraded/upgraded.c +++++ b/upgraded/upgraded.c ++@@ -41,10 +41,10 @@ static void upgrade_proc_cb(struct uloop_process *proc, int ret) ++ ++ static void sysupgrade(char *path, char *command) ++ { ++- char *args[] = { "/sbin/sysupgrade", "nand", NULL, NULL, NULL }; +++ char *args[] = { "/lib/upgrade/stage2", NULL, NULL, NULL }; ++ ++- args[2] = path; ++- args[3] = command; +++ args[1] = path; +++ args[2] = command; ++ upgrade_proc.cb = upgrade_proc_cb; ++ upgrade_proc.pid = fork(); ++ if (!upgrade_proc.pid) { ++@@ -81,14 +81,14 @@ int main(int argc, char **argv) ++ } ++ close(fd); ++ ++- if (argc != 2 && argc != 3) { +++ if (argc != 3) { ++ fprintf(stderr, "sysupgrade stage 2 failed, invalid command line\n"); ++ return -1; ++ } ++ ++ uloop_init(); ++ watchdog_init(0); ++- sysupgrade(argv[1], (argc == 3) ? argv[2] : NULL); +++ sysupgrade(argv[1], argv[2]); ++ uloop_run(); ++ ++ reboot(RB_AUTOBOOT); ++-- ++2.13.0 ++ +diff --git a/package/system/procd/patches/1006-init-add-support-for-sysupgrades-triggered-from-prei.patch b/package/system/procd/patches/1006-init-add-support-for-sysupgrades-triggered-from-prei.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..872846be3e3984f6177512a7adbf0886b78d2677 +--- /dev/null ++++ b/package/system/procd/patches/1006-init-add-support-for-sysupgrades-triggered-from-prei.patch +@@ -0,0 +1,280 @@ ++From f4e6df8848e54d83bac0ab7451312a9db5b59143 Mon Sep 17 00:00:00 2001 ++Message-Id: ++In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Mon, 24 Apr 2017 00:40:27 +0200 ++Subject: [PATCH 1006/1007] init: add support for sysupgrades triggered from ++ preinit ++ ++This will allow to add support for sysupgrades via upgraded from failsafe ++mode. ++ ++Signed-off-by: Matthias Schiffer ++--- ++ CMakeLists.txt | 4 ++-- ++ initd/preinit.c | 46 +++++++++++++++++++++++++++++++++++++++++----- ++ system.c | 35 ++++------------------------------- ++ sysupgrade.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ ++ sysupgrade.h | 21 +++++++++++++++++++++ ++ watchdog.h | 2 ++ ++ 6 files changed, 119 insertions(+), 38 deletions(-) ++ create mode 100644 sysupgrade.c ++ create mode 100644 sysupgrade.h ++ ++diff --git a/CMakeLists.txt b/CMakeLists.txt ++index 9e378ae..441216b 100644 ++--- a/CMakeLists.txt +++++ b/CMakeLists.txt ++@@ -17,7 +17,7 @@ INSTALL(TARGETS setlbf ++ ) ++ ++ ++-SET(SOURCES procd.c signal.c watchdog.c state.c inittab.c rcS.c ubus.c system.c +++SET(SOURCES procd.c signal.c watchdog.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 ++ plug/coldplug.c plug/hotplug.c utils/utils.c) ++ ++@@ -41,7 +41,7 @@ INSTALL(TARGETS procd ++ ) ++ ++ ++-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 acc64e7..3a606e4 100644 ++--- a/initd/preinit.c +++++ b/initd/preinit.c ++@@ -28,6 +28,7 @@ ++ ++ #include "init.h" ++ #include "../watchdog.h" +++#include "../sysupgrade.h" ++ ++ static struct uloop_process preinit_proc; ++ static struct uloop_process plugd_proc; ++@@ -79,23 +80,58 @@ get_rc_d(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]; ++ char *rc_d_path; ++ ++ if (plugd_proc.pid > 0) ++ kill(plugd_proc.pid, SIGKILL); ++ ++- if (!stat("/tmp/sysupgrade", &s)) ++- while (true) ++- sleep(1); ++- ++ unsetenv("INITRAMFS"); ++ unsetenv("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 80205da..700530d 100644 ++--- a/system.c +++++ b/system.c ++@@ -25,6 +25,7 @@ ++ #include ++ ++ #include "procd.h" +++#include "sysupgrade.h" ++ #include "watchdog.h" ++ ++ static struct blob_buf b; ++@@ -330,34 +331,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) ++@@ -371,9 +344,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 +++ * Copyright (C) 2013 John Crispin +++ * Copyright (C) 2017 Matthias Schiffer +++ * +++ * 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 +++#include +++#include +++ +++ +++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..8c09fc9 ++--- /dev/null +++++ b/sysupgrade.h ++@@ -0,0 +1,21 @@ +++/* +++ * Copyright (C) 2017 Matthias Schiffer +++ * +++ * 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. +++ */ +++ +++#ifndef __PROCD_SYSUPGRADE_H +++#define __PROCD_SYSUPGRADE_H +++ +++ +++void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command); +++ +++ +++#endif ++diff --git a/watchdog.h b/watchdog.h ++index e857010..06ce5e5 100644 ++--- a/watchdog.h +++++ b/watchdog.h ++@@ -15,6 +15,8 @@ ++ #ifndef __PROCD_WATCHDOG_H ++ #define __PROCD_WATCHDOG_H ++ +++#include +++ ++ void watchdog_init(int preinit); ++ char* watchdog_fd(void); ++ int watchdog_timeout(int timeout); ++-- ++2.13.0 ++ +diff --git a/package/system/procd/patches/1007-upgraded-define-__GNU_SOURCE.patch b/package/system/procd/patches/1007-upgraded-define-__GNU_SOURCE.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..c98cb9baa4371b64d6b1297fc0a9921d580947be +--- /dev/null ++++ b/package/system/procd/patches/1007-upgraded-define-__GNU_SOURCE.patch +@@ -0,0 +1,31 @@ ++From 8137d283c7f858ca658fa556b95eb62e35ae980d Mon Sep 17 00:00:00 2001 ++Message-Id: <8137d283c7f858ca658fa556b95eb62e35ae980d.1496349467.git.mschiffer@universe-factory.net> ++In-Reply-To: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++References: <36673c2a0e409d9c8ea9e1c15363e73bb21ae65b.1496349467.git.mschiffer@universe-factory.net> ++From: Matthias Schiffer ++Date: Tue, 30 May 2017 07:23:57 +0200 ++Subject: [PATCH 1007/1007] upgraded: define __GNU_SOURCE ++ ++It is required on non-musl libcs for O_DIRECTORY. ++ ++Signed-off-by: Matthias Schiffer ++--- ++ upgraded/upgraded.c | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++diff --git a/upgraded/upgraded.c b/upgraded/upgraded.c ++index 79ebd37..e70f92d 100644 ++--- a/upgraded/upgraded.c +++++ b/upgraded/upgraded.c ++@@ -12,6 +12,8 @@ ++ * GNU General Public License for more details. ++ */ ++ +++#define _GNU_SOURCE +++ ++ #include ++ ++ #include ++-- ++2.13.0 ++ diff --git a/patches/openwrt/0107-procd-remove-procd-nand-package.patch b/patches/openwrt/0107-procd-remove-procd-nand-package.patch new file mode 100644 index 00000000..32ce7069 --- /dev/null +++ b/patches/openwrt/0107-procd-remove-procd-nand-package.patch @@ -0,0 +1,897 @@ +From: Matthias Schiffer +Date: Fri, 21 Apr 2017 20:37:58 +0200 +Subject: procd: remove procd-nand package + +We always want to support staged upgrades now, so it's better to include +upgraded into the main package. /lib/upgrade/nand.sh is moved to +base-files. + +The procd-nand-firstboot package is removed for now, it may return later +as a separate package. + +Signed-off-by: Matthias Schiffer + +diff --git a/package/base-files/Makefile b/package/base-files/Makefile +index 9f6810f4d8bad89eb11db1023693ad59f7369d57..3e27e43c92af01b6cac212e77cde3d1db916ba6f 100644 +--- a/package/base-files/Makefile ++++ b/package/base-files/Makefile +@@ -31,7 +31,7 @@ endif + define Package/base-files + SECTION:=base + CATEGORY:=Base system +- DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign ++ DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +NAND_SUPPORT:ubi-utils + TITLE:=Base filesystem for OpenWrt + URL:=http://openwrt.org/ + VERSION:=$(PKG_RELEASE)-$(REVISION) +@@ -103,9 +103,16 @@ ifdef CONFIG_SIGNED_PACKAGES + endef + endif + ++ifeq ($(CONFIG_NAND_SUPPORT),) ++ define Package/base-files/nand-support ++ rm -f $(1)/lib/upgrade/nand.sh ++ endef ++endif ++ + define Package/base-files/install + $(CP) ./files/* $(1)/ + $(Package/base-files/install-key) ++ $(Package/base-files/nand-support) + if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \ + $(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \ + fi +diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh +new file mode 100644 +index 0000000000000000000000000000000000000000..ec2a014a00461ca897d521e2d065f5399f1f8c48 +--- /dev/null ++++ b/package/base-files/files/lib/upgrade/nand.sh +@@ -0,0 +1,365 @@ ++#!/bin/sh ++# Copyright (C) 2014 OpenWrt.org ++# ++ ++. /lib/functions.sh ++ ++# 'kernel' partition on NAND contains the kernel ++CI_KERNPART="kernel" ++ ++# 'ubi' partition on NAND contains UBI ++CI_UBIPART="ubi" ++ ++ubi_mknod() { ++ local dir="$1" ++ local dev="/dev/$(basename $dir)" ++ ++ [ -e "$dev" ] && return 0 ++ ++ local devid="$(cat $dir/dev)" ++ local major="${devid%%:*}" ++ local minor="${devid##*:}" ++ mknod "$dev" c $major $minor ++} ++ ++nand_find_volume() { ++ local ubidevdir ubivoldir ++ ubidevdir="/sys/devices/virtual/ubi/$1" ++ [ ! -d "$ubidevdir" ] && return 1 ++ for ubivoldir in $ubidevdir/${1}_*; do ++ [ ! -d "$ubivoldir" ] && continue ++ if [ "$( cat $ubivoldir/name )" = "$2" ]; then ++ basename $ubivoldir ++ ubi_mknod "$ubivoldir" ++ return 0 ++ fi ++ done ++} ++ ++nand_find_ubi() { ++ local ubidevdir ubidev mtdnum ++ mtdnum="$( find_mtd_index $1 )" ++ [ ! "$mtdnum" ] && return 1 ++ for ubidevdir in /sys/devices/virtual/ubi/ubi*; do ++ [ ! -d "$ubidevdir" ] && continue ++ cmtdnum="$( cat $ubidevdir/mtd_num )" ++ [ ! "$mtdnum" ] && continue ++ if [ "$mtdnum" = "$cmtdnum" ]; then ++ ubidev=$( basename $ubidevdir ) ++ ubi_mknod "$ubidevdir" ++ echo $ubidev ++ return 0 ++ fi ++ done ++} ++ ++nand_get_magic_long() { ++ dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' ++} ++ ++get_magic_long_tar() { ++ ( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null ++} ++ ++identify_magic() { ++ local magic=$1 ++ case "$magic" in ++ "55424923") ++ echo "ubi" ++ ;; ++ "31181006") ++ echo "ubifs" ++ ;; ++ "68737173") ++ echo "squashfs" ++ ;; ++ "d00dfeed") ++ echo "fit" ++ ;; ++ "4349"*) ++ echo "combined" ++ ;; ++ *) ++ echo "unknown $magic" ++ ;; ++ esac ++} ++ ++ ++identify() { ++ identify_magic $(nand_get_magic_long "$1" "${2:-0}") ++} ++ ++identify_tar() { ++ identify_magic $(get_magic_long_tar "$1" "$2") ++} ++ ++nand_restore_config() { ++ sync ++ local ubidev=$( nand_find_ubi $CI_UBIPART ) ++ local ubivol="$( nand_find_volume $ubidev rootfs_data )" ++ [ ! "$ubivol" ] && ++ ubivol="$( nand_find_volume $ubidev rootfs )" ++ mkdir /tmp/new_root ++ if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then ++ echo "mounting ubifs $ubivol failed" ++ rmdir /tmp/new_root ++ return 1 ++ fi ++ mv "$1" "/tmp/new_root/sysupgrade.tgz" ++ umount /tmp/new_root ++ sync ++ rmdir /tmp/new_root ++} ++ ++nand_upgrade_prepare_ubi() { ++ local rootfs_length="$1" ++ local rootfs_type="$2" ++ local has_kernel="${3:-0}" ++ local has_env="${4:-0}" ++ ++ local mtdnum="$( find_mtd_index "$CI_UBIPART" )" ++ if [ ! "$mtdnum" ]; then ++ echo "cannot find ubi mtd partition $CI_UBIPART" ++ return 1 ++ fi ++ ++ local ubidev="$( nand_find_ubi "$CI_UBIPART" )" ++ if [ ! "$ubidev" ]; then ++ ubiattach -m "$mtdnum" ++ sync ++ ubidev="$( nand_find_ubi "$CI_UBIPART" )" ++ fi ++ ++ if [ ! "$ubidev" ]; then ++ ubiformat /dev/mtd$mtdnum -y ++ ubiattach -m "$mtdnum" ++ sync ++ ubidev="$( nand_find_ubi "$CI_UBIPART" )" ++ [ "$has_env" -gt 0 ] && { ++ ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB ++ ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB ++ } ++ fi ++ ++ local kern_ubivol="$( nand_find_volume $ubidev kernel )" ++ local root_ubivol="$( nand_find_volume $ubidev rootfs )" ++ local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" ++ ++ # remove ubiblock device of rootfs ++ local root_ubiblk="ubiblock${root_ubivol:3}" ++ if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then ++ echo "removing $root_ubiblk" ++ if ! ubiblock -r /dev/$root_ubivol; then ++ echo "cannot remove $root_ubiblk" ++ return 1; ++ fi ++ fi ++ ++ # kill volumes ++ [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N kernel || true ++ [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs || true ++ [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true ++ ++ # update kernel ++ if [ "$has_kernel" = "1" ]; then ++ if ! ubimkvol /dev/$ubidev -N kernel -s $kernel_length; then ++ echo "cannot create kernel volume" ++ return 1; ++ fi ++ fi ++ ++ # update rootfs ++ local root_size_param ++ if [ "$rootfs_type" = "ubifs" ]; then ++ root_size_param="-m" ++ else ++ root_size_param="-s $rootfs_length" ++ fi ++ if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then ++ echo "cannot create rootfs volume" ++ return 1; ++ fi ++ ++ # create rootfs_data for non-ubifs rootfs ++ if [ "$rootfs_type" != "ubifs" ]; then ++ if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then ++ echo "cannot initialize rootfs_data volume" ++ return 1 ++ fi ++ fi ++ sync ++ return 0 ++} ++ ++nand_do_upgrade_success() { ++ local conf_tar="/tmp/sysupgrade.tgz" ++ ++ sync ++ [ -f "$conf_tar" ] && nand_restore_config "$conf_tar" ++ echo "sysupgrade successful" ++ reboot -f ++} ++ ++# Flash the UBI image to MTD partition ++nand_upgrade_ubinized() { ++ local ubi_file="$1" ++ local mtdnum="$(find_mtd_index "$CI_UBIPART")" ++ ++ [ ! "$mtdnum" ] && { ++ CI_UBIPART="rootfs" ++ mtdnum="$(find_mtd_index "$CI_UBIPART")" ++ } ++ ++ if [ ! "$mtdnum" ]; then ++ echo "cannot find mtd device $CI_UBIPART" ++ reboot -f ++ fi ++ ++ local mtddev="/dev/mtd${mtdnum}" ++ ubidetach -p "${mtddev}" || true ++ sync ++ ubiformat "${mtddev}" -y -f "${ubi_file}" ++ ubiattach -p "${mtddev}" ++ nand_do_upgrade_success ++} ++ ++# Write the UBIFS image to UBI volume ++nand_upgrade_ubifs() { ++ local rootfs_length=`(cat $1 | wc -c) 2> /dev/null` ++ ++ nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0" ++ ++ local ubidev="$( nand_find_ubi "$CI_UBIPART" )" ++ local root_ubivol="$(nand_find_volume $ubidev rootfs)" ++ ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1 ++ ++ nand_do_upgrade_success ++} ++ ++nand_upgrade_tar() { ++ local tar_file="$1" ++ local board_name="$(cat /tmp/sysinfo/board_name)" ++ local kernel_mtd="$(find_mtd_index $CI_KERNPART)" ++ ++ local kernel_length=`(tar xf $tar_file sysupgrade-$board_name/kernel -O | wc -c) 2> /dev/null` ++ local rootfs_length=`(tar xf $tar_file sysupgrade-$board_name/root -O | wc -c) 2> /dev/null` ++ ++ local rootfs_type="$(identify_tar "$tar_file" sysupgrade-$board_name/root)" ++ ++ local has_kernel=1 ++ local has_env=0 ++ ++ [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && { ++ tar xf $tar_file sysupgrade-$board_name/kernel -O | mtd write - $CI_KERNPART ++ } ++ [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0 ++ ++ nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env" ++ ++ local ubidev="$( nand_find_ubi "$CI_UBIPART" )" ++ [ "$has_kernel" = "1" ] && { ++ local kern_ubivol="$(nand_find_volume $ubidev kernel)" ++ tar xf $tar_file sysupgrade-$board_name/kernel -O | \ ++ ubiupdatevol /dev/$kern_ubivol -s $kernel_length - ++ } ++ ++ local root_ubivol="$(nand_find_volume $ubidev rootfs)" ++ tar xf $tar_file sysupgrade-$board_name/root -O | \ ++ ubiupdatevol /dev/$root_ubivol -s $rootfs_length - ++ ++ nand_do_upgrade_success ++} ++ ++# Recognize type of passed file and start the upgrade process ++nand_do_upgrade_stage2() { ++ local file_type=$(identify $1) ++ ++ [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs" ++ ++ case "$file_type" in ++ "ubi") nand_upgrade_ubinized $1;; ++ "ubifs") nand_upgrade_ubifs $1;; ++ *) nand_upgrade_tar $1;; ++ esac ++} ++ ++nand_upgrade_stage2() { ++ [ $1 = "nand" ] && { ++ [ -f "$2" ] && { ++ touch /tmp/sysupgrade ++ ++ killall -9 telnetd ++ killall -9 dropbear ++ killall -9 ash ++ ++ kill_remaining TERM ++ sleep 3 ++ kill_remaining KILL ++ ++ sleep 1 ++ ++ if [ -n "$(rootfs_type)" ]; then ++ v "Switching to ramdisk..." ++ run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2" ++ else ++ nand_do_upgrade_stage2 $2 ++ fi ++ return 0 ++ } ++ echo "Nand upgrade failed" ++ exit 1 ++ } ++} ++ ++nand_upgrade_stage1() { ++ [ -f /tmp/sysupgrade-nand-path ] && { ++ path="$(cat /tmp/sysupgrade-nand-path)" ++ [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] && ++ rm $CONF_TAR ++ ++ ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }" ++ exit 0 ++ } ++} ++append sysupgrade_pre_upgrade nand_upgrade_stage1 ++ ++# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts ++# 3 types of files: ++# 1) UBI - should contain an ubinized image, header is checked for the proper ++# MAGIC ++# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume, ++# header is checked for the proper MAGIC ++# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty ++# "CONTROL" file (at this point its content isn't verified) ++# ++# You usually want to call this function in platform_check_image. ++# ++# $(1): board name, used in case of passing TAR file ++# $(2): file to be checked ++nand_do_platform_check() { ++ local board_name="$1" ++ local tar_file="$2" ++ local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null` ++ local file_type="$(identify $2)" ++ ++ [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && { ++ echo "Invalid sysupgrade file." ++ return 1 ++ } ++ ++ echo -n $2 > /tmp/sysupgrade-nand-path ++ cp /sbin/upgraded /tmp/ ++ ++ return 0 ++} ++ ++# Start NAND upgrade process ++# ++# $(1): file to be used for upgrade ++nand_do_upgrade() { ++ echo -n $1 > /tmp/sysupgrade-nand-path ++ install_bin /sbin/upgraded ++ ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded ++ nand_upgrade_stage1 ++} +diff --git a/package/system/procd/Makefile b/package/system/procd/Makefile +index d343f7481f3bb627b3e7ad79f45864de82a42371..b95ef64b727f6f07c8f92c9caf027c21dbb30863 100644 +--- a/package/system/procd/Makefile ++++ b/package/system/procd/Makefile +@@ -24,7 +24,7 @@ PKG_LICENSE_FILES:= + + PKG_MAINTAINER:=John Crispin + +-PKG_CONFIG_DEPENDS:= CONFIG_KERNEL_SECCOMP CONFIG_NAND_SUPPORT CONFIG_PROCD_SHOW_BOOT CONFIG_PROCD_ZRAM_TMPFS \ ++PKG_CONFIG_DEPENDS:= CONFIG_KERNEL_SECCOMP CONFIG_PROCD_SHOW_BOOT CONFIG_PROCD_ZRAM_TMPFS \ + CONFIG_KERNEL_NAMESPACES CONFIG_PACKAGE_procd-ujail CONFIG_PACKAGE_procd-seccomp + + include $(INCLUDE_DIR)/package.mk +@@ -35,7 +35,7 @@ TARGET_LDFLAGS += $(if $(CONFIG_USE_GLIBC),-lrt) + define Package/procd + SECTION:=base + CATEGORY:=Base system +- DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus +NAND_SUPPORT:procd-nand ++ DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus + TITLE:=OpenWrt system process manager + endef + +@@ -53,20 +53,6 @@ define Package/procd-seccomp + TITLE:=OpenWrt process seccomp helper + utrace + endef + +-define Package/procd-nand +- SECTION:=utils +- CATEGORY:=Utilities +- DEPENDS:=@NAND_SUPPORT +ubi-utils +- TITLE:=OpenWrt sysupgrade nand helper +-endef +- +-define Package/procd-nand-firstboot +- SECTION:=utils +- CATEGORY:=Utilities +- DEPENDS:=procd-nand +- TITLE:=OpenWrt firstboot nand helper +-endef +- + define Package/procd/config + menu "Configuration" + depends on PACKAGE_procd +@@ -84,10 +70,6 @@ endmenu + endef + + +-ifeq ($(CONFIG_NAND_SUPPORT),y) +- CMAKE_OPTIONS += -DBUILD_UPGRADED=1 +-endif +- + ifeq ($(CONFIG_PROCD_SHOW_BOOT),y) + CMAKE_OPTIONS += -DSHOW_BOOT_ON_CONSOLE=1 + endif +@@ -107,7 +89,7 @@ endif + define Package/procd/install + $(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions + +- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger} $(1)/sbin/ ++ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger,upgraded} $(1)/sbin/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libsetlbf.so $(1)/lib + $(INSTALL_BIN) ./files/reload_config $(1)/sbin/ + $(INSTALL_DATA) ./files/hotplug*.json $(1)/etc/ +@@ -126,21 +108,6 @@ define Package/procd-seccomp/install + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libpreload-trace.so $(1)/lib + endef + +-define Package/procd-nand/install +- $(INSTALL_DIR) $(1)/sbin $(1)/lib/upgrade +- +- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upgraded $(1)/sbin/ +- $(INSTALL_DATA) ./files/nand.sh $(1)/lib/upgrade/ +-endef +- +-define Package/procd-nand-firstboot/install +- $(INSTALL_DIR) $(1)/lib/preinit +- +- $(INSTALL_DATA) ./files/nand-preinit.sh $(1)/lib/preinit/60-nand-firstboot.sh +-endef +- + $(eval $(call BuildPackage,procd)) + $(eval $(call BuildPackage,procd-ujail)) + $(eval $(call BuildPackage,procd-seccomp)) +-$(eval $(call BuildPackage,procd-nand)) +-$(eval $(call BuildPackage,procd-nand-firstboot)) +diff --git a/package/system/procd/files/nand-preinit.sh b/package/system/procd/files/nand-preinit.sh +deleted file mode 100644 +index cf596246d1f2891cbeb7b5c7cac4bb6e002b13fb..0000000000000000000000000000000000000000 +--- a/package/system/procd/files/nand-preinit.sh ++++ /dev/null +@@ -1,21 +0,0 @@ +-#!/bin/sh +-# Copyright (C) 2014 OpenWrt.org +- +-nand_takeover() { +- . /lib/upgrade/nand.sh +- mtd=$(find_mtd_index "$CI_UBIPART") +- esize=$(cat /proc/mtd | grep mtd$mtd |cut -d" " -f 3) +- [ -z "$esize" ] && return 1 +- esize=$(printf "%d" 0x$esize) +- for a in `seq 0 64`; do +- mtd -o $((a * esize)) -l 400 dump /dev/mtd$mtd > /tmp/takeover.hdr +- MAGIC=$(dd if=/tmp/takeover.hdr bs=1 skip=261 count=5 2> /dev/null) +- SIZE=$(printf "%d" 0x$(dd if=/tmp/takeover.hdr bs=4 count=1 2> /dev/null | hexdump -v -n 4 -e '1/1 "%02x"')) +- [ "$MAGIC" = "ustar" ] && { +- mtd -o $((a * esize)) -l $((SIZE + 4)) dump /dev/mtd$mtd | dd bs=1 skip=4 of=/tmp/sysupgrade.tar +- nand_do_upgrade_stage2 /tmp/sysupgrade.tar +- } +- done +-} +- +-boot_hook_add initramfs nand_takeover +diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh +deleted file mode 100644 +index ec2a014a00461ca897d521e2d065f5399f1f8c48..0000000000000000000000000000000000000000 +--- a/package/system/procd/files/nand.sh ++++ /dev/null +@@ -1,365 +0,0 @@ +-#!/bin/sh +-# Copyright (C) 2014 OpenWrt.org +-# +- +-. /lib/functions.sh +- +-# 'kernel' partition on NAND contains the kernel +-CI_KERNPART="kernel" +- +-# 'ubi' partition on NAND contains UBI +-CI_UBIPART="ubi" +- +-ubi_mknod() { +- local dir="$1" +- local dev="/dev/$(basename $dir)" +- +- [ -e "$dev" ] && return 0 +- +- local devid="$(cat $dir/dev)" +- local major="${devid%%:*}" +- local minor="${devid##*:}" +- mknod "$dev" c $major $minor +-} +- +-nand_find_volume() { +- local ubidevdir ubivoldir +- ubidevdir="/sys/devices/virtual/ubi/$1" +- [ ! -d "$ubidevdir" ] && return 1 +- for ubivoldir in $ubidevdir/${1}_*; do +- [ ! -d "$ubivoldir" ] && continue +- if [ "$( cat $ubivoldir/name )" = "$2" ]; then +- basename $ubivoldir +- ubi_mknod "$ubivoldir" +- return 0 +- fi +- done +-} +- +-nand_find_ubi() { +- local ubidevdir ubidev mtdnum +- mtdnum="$( find_mtd_index $1 )" +- [ ! "$mtdnum" ] && return 1 +- for ubidevdir in /sys/devices/virtual/ubi/ubi*; do +- [ ! -d "$ubidevdir" ] && continue +- cmtdnum="$( cat $ubidevdir/mtd_num )" +- [ ! "$mtdnum" ] && continue +- if [ "$mtdnum" = "$cmtdnum" ]; then +- ubidev=$( basename $ubidevdir ) +- ubi_mknod "$ubidevdir" +- echo $ubidev +- return 0 +- fi +- done +-} +- +-nand_get_magic_long() { +- dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' +-} +- +-get_magic_long_tar() { +- ( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null +-} +- +-identify_magic() { +- local magic=$1 +- case "$magic" in +- "55424923") +- echo "ubi" +- ;; +- "31181006") +- echo "ubifs" +- ;; +- "68737173") +- echo "squashfs" +- ;; +- "d00dfeed") +- echo "fit" +- ;; +- "4349"*) +- echo "combined" +- ;; +- *) +- echo "unknown $magic" +- ;; +- esac +-} +- +- +-identify() { +- identify_magic $(nand_get_magic_long "$1" "${2:-0}") +-} +- +-identify_tar() { +- identify_magic $(get_magic_long_tar "$1" "$2") +-} +- +-nand_restore_config() { +- sync +- local ubidev=$( nand_find_ubi $CI_UBIPART ) +- local ubivol="$( nand_find_volume $ubidev rootfs_data )" +- [ ! "$ubivol" ] && +- ubivol="$( nand_find_volume $ubidev rootfs )" +- mkdir /tmp/new_root +- if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then +- echo "mounting ubifs $ubivol failed" +- rmdir /tmp/new_root +- return 1 +- fi +- mv "$1" "/tmp/new_root/sysupgrade.tgz" +- umount /tmp/new_root +- sync +- rmdir /tmp/new_root +-} +- +-nand_upgrade_prepare_ubi() { +- local rootfs_length="$1" +- local rootfs_type="$2" +- local has_kernel="${3:-0}" +- local has_env="${4:-0}" +- +- local mtdnum="$( find_mtd_index "$CI_UBIPART" )" +- if [ ! "$mtdnum" ]; then +- echo "cannot find ubi mtd partition $CI_UBIPART" +- return 1 +- fi +- +- local ubidev="$( nand_find_ubi "$CI_UBIPART" )" +- if [ ! "$ubidev" ]; then +- ubiattach -m "$mtdnum" +- sync +- ubidev="$( nand_find_ubi "$CI_UBIPART" )" +- fi +- +- if [ ! "$ubidev" ]; then +- ubiformat /dev/mtd$mtdnum -y +- ubiattach -m "$mtdnum" +- sync +- ubidev="$( nand_find_ubi "$CI_UBIPART" )" +- [ "$has_env" -gt 0 ] && { +- ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB +- ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB +- } +- fi +- +- local kern_ubivol="$( nand_find_volume $ubidev kernel )" +- local root_ubivol="$( nand_find_volume $ubidev rootfs )" +- local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" +- +- # remove ubiblock device of rootfs +- local root_ubiblk="ubiblock${root_ubivol:3}" +- if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then +- echo "removing $root_ubiblk" +- if ! ubiblock -r /dev/$root_ubivol; then +- echo "cannot remove $root_ubiblk" +- return 1; +- fi +- fi +- +- # kill volumes +- [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N kernel || true +- [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs || true +- [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true +- +- # update kernel +- if [ "$has_kernel" = "1" ]; then +- if ! ubimkvol /dev/$ubidev -N kernel -s $kernel_length; then +- echo "cannot create kernel volume" +- return 1; +- fi +- fi +- +- # update rootfs +- local root_size_param +- if [ "$rootfs_type" = "ubifs" ]; then +- root_size_param="-m" +- else +- root_size_param="-s $rootfs_length" +- fi +- if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then +- echo "cannot create rootfs volume" +- return 1; +- fi +- +- # create rootfs_data for non-ubifs rootfs +- if [ "$rootfs_type" != "ubifs" ]; then +- if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then +- echo "cannot initialize rootfs_data volume" +- return 1 +- fi +- fi +- sync +- return 0 +-} +- +-nand_do_upgrade_success() { +- local conf_tar="/tmp/sysupgrade.tgz" +- +- sync +- [ -f "$conf_tar" ] && nand_restore_config "$conf_tar" +- echo "sysupgrade successful" +- reboot -f +-} +- +-# Flash the UBI image to MTD partition +-nand_upgrade_ubinized() { +- local ubi_file="$1" +- local mtdnum="$(find_mtd_index "$CI_UBIPART")" +- +- [ ! "$mtdnum" ] && { +- CI_UBIPART="rootfs" +- mtdnum="$(find_mtd_index "$CI_UBIPART")" +- } +- +- if [ ! "$mtdnum" ]; then +- echo "cannot find mtd device $CI_UBIPART" +- reboot -f +- fi +- +- local mtddev="/dev/mtd${mtdnum}" +- ubidetach -p "${mtddev}" || true +- sync +- ubiformat "${mtddev}" -y -f "${ubi_file}" +- ubiattach -p "${mtddev}" +- nand_do_upgrade_success +-} +- +-# Write the UBIFS image to UBI volume +-nand_upgrade_ubifs() { +- local rootfs_length=`(cat $1 | wc -c) 2> /dev/null` +- +- nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0" +- +- local ubidev="$( nand_find_ubi "$CI_UBIPART" )" +- local root_ubivol="$(nand_find_volume $ubidev rootfs)" +- ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1 +- +- nand_do_upgrade_success +-} +- +-nand_upgrade_tar() { +- local tar_file="$1" +- local board_name="$(cat /tmp/sysinfo/board_name)" +- local kernel_mtd="$(find_mtd_index $CI_KERNPART)" +- +- local kernel_length=`(tar xf $tar_file sysupgrade-$board_name/kernel -O | wc -c) 2> /dev/null` +- local rootfs_length=`(tar xf $tar_file sysupgrade-$board_name/root -O | wc -c) 2> /dev/null` +- +- local rootfs_type="$(identify_tar "$tar_file" sysupgrade-$board_name/root)" +- +- local has_kernel=1 +- local has_env=0 +- +- [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && { +- tar xf $tar_file sysupgrade-$board_name/kernel -O | mtd write - $CI_KERNPART +- } +- [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0 +- +- nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env" +- +- local ubidev="$( nand_find_ubi "$CI_UBIPART" )" +- [ "$has_kernel" = "1" ] && { +- local kern_ubivol="$(nand_find_volume $ubidev kernel)" +- tar xf $tar_file sysupgrade-$board_name/kernel -O | \ +- ubiupdatevol /dev/$kern_ubivol -s $kernel_length - +- } +- +- local root_ubivol="$(nand_find_volume $ubidev rootfs)" +- tar xf $tar_file sysupgrade-$board_name/root -O | \ +- ubiupdatevol /dev/$root_ubivol -s $rootfs_length - +- +- nand_do_upgrade_success +-} +- +-# Recognize type of passed file and start the upgrade process +-nand_do_upgrade_stage2() { +- local file_type=$(identify $1) +- +- [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs" +- +- case "$file_type" in +- "ubi") nand_upgrade_ubinized $1;; +- "ubifs") nand_upgrade_ubifs $1;; +- *) nand_upgrade_tar $1;; +- esac +-} +- +-nand_upgrade_stage2() { +- [ $1 = "nand" ] && { +- [ -f "$2" ] && { +- touch /tmp/sysupgrade +- +- killall -9 telnetd +- killall -9 dropbear +- killall -9 ash +- +- kill_remaining TERM +- sleep 3 +- kill_remaining KILL +- +- sleep 1 +- +- if [ -n "$(rootfs_type)" ]; then +- v "Switching to ramdisk..." +- run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2" +- else +- nand_do_upgrade_stage2 $2 +- fi +- return 0 +- } +- echo "Nand upgrade failed" +- exit 1 +- } +-} +- +-nand_upgrade_stage1() { +- [ -f /tmp/sysupgrade-nand-path ] && { +- path="$(cat /tmp/sysupgrade-nand-path)" +- [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] && +- rm $CONF_TAR +- +- ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }" +- exit 0 +- } +-} +-append sysupgrade_pre_upgrade nand_upgrade_stage1 +- +-# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts +-# 3 types of files: +-# 1) UBI - should contain an ubinized image, header is checked for the proper +-# MAGIC +-# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume, +-# header is checked for the proper MAGIC +-# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty +-# "CONTROL" file (at this point its content isn't verified) +-# +-# You usually want to call this function in platform_check_image. +-# +-# $(1): board name, used in case of passing TAR file +-# $(2): file to be checked +-nand_do_platform_check() { +- local board_name="$1" +- local tar_file="$2" +- local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null` +- local file_type="$(identify $2)" +- +- [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && { +- echo "Invalid sysupgrade file." +- return 1 +- } +- +- echo -n $2 > /tmp/sysupgrade-nand-path +- cp /sbin/upgraded /tmp/ +- +- return 0 +-} +- +-# Start NAND upgrade process +-# +-# $(1): file to be used for upgrade +-nand_do_upgrade() { +- echo -n $1 > /tmp/sysupgrade-nand-path +- install_bin /sbin/upgraded +- ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded +- nand_upgrade_stage1 +-} diff --git a/patches/openwrt/0108-base-files-always-use-staged-sysupgrade.patch b/patches/openwrt/0108-base-files-always-use-staged-sysupgrade.patch new file mode 100644 index 00000000..2e4efe78 --- /dev/null +++ b/patches/openwrt/0108-base-files-always-use-staged-sysupgrade.patch @@ -0,0 +1,468 @@ +From: Matthias Schiffer +Date: Sat, 22 Apr 2017 00:54:50 +0200 +Subject: base-files: always use staged sysupgrade + +Support for the -d and -p options is dropped; it may be added again at some +point by adding these flags to the ubus sysupgrade call. + +A downside of this is that we get a lot less information about the progress +of the upgrade: as soon as the actual upgrade starts, all shell sessions +are killed to allow unmounting the root filesystem. + +Signed-off-by: Matthias Schiffer + +diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh +index 2064adf775c491725dbff5826b94bd6132d8d060..23f18ceb775caac057ee7a757922954f812f77ce 100644 +--- a/package/base-files/files/lib/upgrade/common.sh ++++ b/package/base-files/files/lib/upgrade/common.sh +@@ -92,51 +92,37 @@ run_ramfs() { # [...] + exec /bin/busybox ash -c "$*" + } + +-kill_remaining() { # [ ] ++kill_remaining() { # [ [ ] ] + local sig="${1:-TERM}" ++ local loop="${2:-0}" ++ local run=true ++ local stat ++ + echo -n "Sending $sig to remaining processes ... " + +- local my_pid=$$ +- local my_ppid=$(cut -d' ' -f4 /proc/$my_pid/stat) +- local my_ppisupgraded= +- grep -q upgraded /proc/$my_ppid/cmdline >/dev/null && { +- local my_ppisupgraded=1 +- } +- +- local stat +- for stat in /proc/[0-9]*/stat; do +- [ -f "$stat" ] || continue +- +- local pid name state ppid rest +- read pid name state ppid rest < $stat +- name="${name#(}"; name="${name%)}" +- +- local cmdline +- read cmdline < /proc/$pid/cmdline +- +- # Skip kernel threads +- [ -n "$cmdline" ] || continue +- +- if [ $$ -eq 1 ] || [ $my_ppid -eq 1 ] && [ -n "$my_ppisupgraded" ]; then +- # Running as init process, kill everything except me +- if [ $pid -ne $$ ] && [ $pid -ne $my_ppid ]; then +- echo -n "$name " +- kill -$sig $pid 2>/dev/null +- fi +- else +- case "$name" in +- # Skip essential services +- *procd*|*ash*|*init*|*watchdog*|*ssh*|*dropbear*|*telnet*|*login*|*hostapd*|*wpa_supplicant*|*nas*) : ;; +- +- # Killable process +- *) +- if [ $pid -ne $$ ] && [ $ppid -ne $$ ]; then +- echo -n "$name " +- kill -$sig $pid 2>/dev/null +- fi +- ;; +- esac +- fi ++ while $run; do ++ run=false ++ for stat in /proc/[0-9]*/stat; do ++ [ -f "$stat" ] || continue ++ ++ local pid name state ppid rest ++ read pid name state ppid rest < $stat ++ name="${name#(}"; name="${name%)}" ++ ++ # Skip PID1, ourself and our children ++ [ $pid -ne 1 -a $pid -ne $$ -a $ppid -ne $$ ] || continue ++ ++ local cmdline ++ read cmdline < /proc/$pid/cmdline ++ ++ # Skip kernel threads ++ [ -n "$cmdline" ] || continue ++ ++ echo -n "$name " ++ kill -$sig $pid 2>/dev/null ++ ++ [ $loop -eq 1 ] && run=true ++ done + done + echo "" + } +@@ -171,28 +157,31 @@ v() { + [ "$VERBOSE" -ge 1 ] && echo "$@" + } + ++json_string() { ++ local v="$1" ++ v="${v//\\/\\\\}" ++ v="${v//\"/\\\"}" ++ echo "\"$v\"" ++} ++ + rootfs_type() { + /bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }' + } + + get_image() { # [ ] + local from="$1" +- local conc="$2" +- local cmd +- +- case "$from" in +- http://*|ftp://*) cmd="wget -O- -q";; +- *) cmd="cat";; +- esac +- if [ -z "$conc" ]; then +- local magic="$(eval $cmd \"$from\" 2>/dev/null | dd bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')" ++ local cat="$2" ++ ++ if [ -z "$cat" ]; then ++ local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')" + case "$magic" in +- 1f8b) conc="zcat";; +- 425a) conc="bzcat";; ++ 1f8b) cat="zcat";; ++ 425a) cat="bzcat";; ++ *) cat="cat";; + esac + fi + +- eval "$cmd \"$from\" 2>/dev/null ${conc:+| $conc}" ++ $cat "$from" 2>/dev/null + } + + get_magic_word() { +@@ -316,12 +305,14 @@ default_do_upgrade() { + fi + } + +-do_upgrade() { ++do_upgrade_stage2() { + v "Performing system upgrade..." +- if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then +- platform_do_upgrade "$ARGV" ++ if [ -n "$do_upgrade" ]; then ++ $do_upgrade "$IMAGE" ++ elif type 'platform_do_upgrade' >/dev/null 2>/dev/null; then ++ platform_do_upgrade "$IMAGE" + else +- default_do_upgrade "$ARGV" ++ default_do_upgrade "$IMAGE" + fi + + if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then +@@ -329,11 +320,11 @@ do_upgrade() { + fi + + v "Upgrade completed" +- [ -n "$DELAY" ] && sleep "$DELAY" +- ask_bool 1 "Reboot" && { +- v "Rebooting system..." +- reboot -f +- sleep 5 +- echo b 2>/dev/null >/proc/sysrq-trigger +- } ++ sleep 1 ++ ++ v "Rebooting system..." ++ umount -a ++ reboot -f ++ sleep 5 ++ echo b 2>/dev/null >/proc/sysrq-trigger + } +diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh +index ec2a014a00461ca897d521e2d065f5399f1f8c48..05940e2567e22fe1936fb5afdc7c1df4826570ee 100644 +--- a/package/base-files/files/lib/upgrade/nand.sh ++++ b/package/base-files/files/lib/upgrade/nand.sh +@@ -272,7 +272,16 @@ nand_upgrade_tar() { + } + + # Recognize type of passed file and start the upgrade process +-nand_do_upgrade_stage2() { ++nand_do_upgrade() { ++ if [ -n "$IS_PRE_UPGRADE" ]; then ++ # Previously, nand_do_upgrade was called from the platform_pre_upgrade ++ # hook; this piece of code handles scripts that haven't been ++ # updated. All scripts should gradually move to call nand_do_upgrade ++ # from platform_do_upgrade instead. ++ export do_upgrade=nand_do_upgrade ++ return ++ fi ++ + local file_type=$(identify $1) + + [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs" +@@ -284,46 +293,6 @@ nand_do_upgrade_stage2() { + esac + } + +-nand_upgrade_stage2() { +- [ $1 = "nand" ] && { +- [ -f "$2" ] && { +- touch /tmp/sysupgrade +- +- killall -9 telnetd +- killall -9 dropbear +- killall -9 ash +- +- kill_remaining TERM +- sleep 3 +- kill_remaining KILL +- +- sleep 1 +- +- if [ -n "$(rootfs_type)" ]; then +- v "Switching to ramdisk..." +- run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2" +- else +- nand_do_upgrade_stage2 $2 +- fi +- return 0 +- } +- echo "Nand upgrade failed" +- exit 1 +- } +-} +- +-nand_upgrade_stage1() { +- [ -f /tmp/sysupgrade-nand-path ] && { +- path="$(cat /tmp/sysupgrade-nand-path)" +- [ "$SAVE_CONFIG" != 1 -a -f "$CONF_TAR" ] && +- rm $CONF_TAR +- +- ubus call system nandupgrade "{\"prefix\": \"$RAM_ROOT\", \"path\": \"$path\" }" +- exit 0 +- } +-} +-append sysupgrade_pre_upgrade nand_upgrade_stage1 +- + # Check if passed file is a valid one for NAND sysupgrade. Currently it accepts + # 3 types of files: + # 1) UBI - should contain an ubinized image, header is checked for the proper +@@ -353,13 +322,3 @@ nand_do_platform_check() { + + return 0 + } +- +-# Start NAND upgrade process +-# +-# $(1): file to be used for upgrade +-nand_do_upgrade() { +- echo -n $1 > /tmp/sysupgrade-nand-path +- install_bin /sbin/upgraded +- ln -s "$RAM_ROOT"/sbin/upgraded /tmp/upgraded +- nand_upgrade_stage1 +-} +diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2 +new file mode 100755 +index 0000000000000000000000000000000000000000..4e2aa3a23c3bab07a795762a30a4d4f701081934 +--- /dev/null ++++ b/package/base-files/files/lib/upgrade/stage2 +@@ -0,0 +1,50 @@ ++#!/bin/sh ++ ++. /lib/functions.sh ++. /lib/functions/system.sh ++ ++export IMAGE="$1" ++COMMAND="$2" ++ ++export ARGV="$IMAGE" ++export ARGC=1 ++ ++export SAVE_CONFIG=1 ++export SAVE_PARTITIONS=1 ++ ++export INTERACTIVE=0 ++export VERBOSE=1 ++export CONFFILES=/tmp/sysupgrade.conffiles ++export CONF_TAR=/tmp/sysupgrade.tgz ++ ++ ++[ -f "$CONF_TAR" ] || export SAVE_CONFIG=0 ++[ -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap ] && export SAVE_PARTITIONS=0 ++ ++include /lib/upgrade ++ ++ ++killall -9 telnetd ++killall -9 dropbear ++killall -9 ash ++ ++kill_remaining TERM ++sleep 3 ++kill_remaining KILL 1 ++ ++sleep 1 ++ ++ ++if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then ++ IS_PRE_UPGRADE=1 platform_pre_upgrade "$IMAGE" ++ ++ # Needs to be unset again because of busybox weirdness ... ++ IS_PRE_UPGRADE= ++fi ++ ++if [ -n "$(rootfs_type)" ]; then ++ echo "Switching to ramdisk..." ++ run_ramfs "$COMMAND" ++else ++ exec /bin/busybox ash -c "$COMMAND" ++fi +diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade +index 759c841e131a415c8009995c372cce1f55fb78a0..d48416f6de244b97f426ae0b83d425ac5c1bc5b3 100755 +--- a/package/base-files/files/sbin/sysupgrade ++++ b/package/base-files/files/sbin/sysupgrade +@@ -1,4 +1,7 @@ + #!/bin/sh ++ ++[ "$1" = "nand" ] && exec /lib/upgrade/stage2 "$2" "$3" ++ + . /lib/functions.sh + . /lib/functions/system.sh + +@@ -11,7 +14,6 @@ export VERBOSE=1 + export SAVE_CONFIG=1 + export SAVE_OVERLAY=0 + export SAVE_PARTITIONS=1 +-export DELAY= + export CONF_IMAGE= + export CONF_BACKUP_LIST=0 + export CONF_BACKUP= +@@ -25,7 +27,6 @@ export TEST=0 + while [ -n "$1" ]; do + case "$1" in + -i) export INTERACTIVE=1;; +- -d) export DELAY="$2"; shift;; + -v) export VERBOSE="$(($VERBOSE + 1))";; + -q) export VERBOSE="$(($VERBOSE - 1))";; + -n) export SAVE_CONFIG=0;; +@@ -50,10 +51,9 @@ done + export CONFFILES=/tmp/sysupgrade.conffiles + export CONF_TAR=/tmp/sysupgrade.tgz + +-export ARGV="$*" +-export ARGC="$#" ++IMAGE="$1" + +-[ -z "$ARGV" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && { ++[ -z "$IMAGE" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && { + cat <...] + $0 [-q] [-i] +@@ -90,7 +90,7 @@ EOF + exit 1 + } + +-[ -n "$ARGV" -a -n "$NEED_IMAGE" ] && { ++[ -n "$IMAGE" -a -n "$NEED_IMAGE" ] && { + cat <<-EOF + -b|--create-backup and -r|--restore-backup do not perform a firmware upgrade. + Do not specify both -b|-r and a firmware image. +@@ -134,14 +134,13 @@ sysupgrade_image_check="platform_check_image" + + include /lib/upgrade + +-[ "$1" = "nand" ] && nand_upgrade_stage2 $@ +- + do_save_conffiles() { + local conf_tar="${1:-$CONF_TAR}" + + [ -z "$(rootfs_type)" ] && { + echo "Cannot save config while running from ramdisk." + ask_bool 0 "Abort" && exit ++ rm -f "$conf_tar" + return 0 + } + run_hooks "$CONFFILES" $sysupgrade_init_conffiles +@@ -182,8 +181,33 @@ type platform_check_image >/dev/null 2>/dev/null || { + exit 1 + } + ++case "$IMAGE" in ++ http://*) ++ wget -O/tmp/sysupgrade.img "$IMAGE" ++ IMAGE=/tmp/sysupgrade.img ++ ;; ++esac ++ ++IMAGE="$(readlink -f "$IMAGE")" ++ ++case "$IMAGE" in ++ '') ++ echo "Image file not found." ++ exit 1 ++ ;; ++ /tmp/*) ;; ++ *) ++ v "Image not in /tmp, copying..." ++ cp -f "$IMAGE" /tmp/sysupgrade.img ++ IMAGE=/tmp/sysupgrade.img ++ ;; ++esac ++ ++export ARGV="$IMAGE" ++export ARGC=1 ++ + for check in $sysupgrade_image_check; do +- ( eval "$check \"\$ARGV\"" ) || { ++ ( $check "$IMAGE" ) || { + if [ $FORCE -eq 1 ]; then + echo "Image check '$check' failed but --force given - will update anyway!" + break +@@ -209,6 +233,7 @@ elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then + [ $TEST -eq 1 ] || do_save_conffiles + export SAVE_CONFIG=1 + else ++ [ $TEST -eq 1 ] || rm -f "$CONF_TAR" + export SAVE_CONFIG=0 + fi + +@@ -216,28 +241,18 @@ if [ $TEST -eq 1 ]; then + exit 0 + fi + +-run_hooks "" $sysupgrade_pre_upgrade +- +-# Some platforms/devices may want different sysupgrade process, e.g. without +-# killing processes yet or calling ubus system upgrade method. +-# This is needed e.g. on NAND devices where we just want to trigger stage1 at +-# this point. +-if type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then +- platform_pre_upgrade "$ARGV" ++if [ $SAVE_PARTITIONS -eq 0 ]; then ++ touch /tmp/sysupgrade.always.overwrite.bootdisk.partmap ++else ++ rm -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap + fi + +-ubus call system upgrade +-touch /tmp/sysupgrade +- +-if [ ! -f /tmp/failsafe ] ; then +- kill_remaining TERM +- sleep 3 +- kill_remaining KILL +-fi ++run_hooks "" $sysupgrade_pre_upgrade + +-if [ -n "$(rootfs_type)" ]; then +- v "Switching to ramdisk..." +- run_ramfs '. /lib/functions.sh; include /lib/upgrade; do_upgrade' +-else +- do_upgrade +-fi ++install_bin /sbin/upgraded ++v "Commencing upgrade. All shell sessions will be closed now." ++ubus call system sysupgrade "{ ++ \"prefix\": \"$RAM_ROOT\", ++ \"path\": $(json_string "$IMAGE"), ++ \"command\": \". /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2\" ++}" diff --git a/patches/openwrt/0109-fstools-clean-up-trailing-whitespace-in-snapshot-script.patch b/patches/openwrt/0109-fstools-clean-up-trailing-whitespace-in-snapshot-script.patch new file mode 100644 index 00000000..2011b289 --- /dev/null +++ b/patches/openwrt/0109-fstools-clean-up-trailing-whitespace-in-snapshot-script.patch @@ -0,0 +1,19 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 08:29:24 +0200 +Subject: fstools: clean up trailing whitespace in snapshot script + +Signed-off-by: Matthias Schiffer + +diff --git a/package/system/fstools/files/snapshot b/package/system/fstools/files/snapshot +index a0e0ec0c334ca72086c3e30c62ae988c61ff1bde..eec7214032d1b147d5e989cd305c5c0cd1357a55 100644 +--- a/package/system/fstools/files/snapshot ++++ b/package/system/fstools/files/snapshot +@@ -42,7 +42,7 @@ do_snapshot_upgrade() { + + opkg list-upgradable + [ $? -eq 0 ] || exit 2 +- ++ + UPDATES=`opkg list-upgradable | cut -d" " -f1` + [ -z "${UPDATES}" ] && exit 0 + diff --git a/patches/openwrt/0110-fstools-snapshot-handle-jffs2-conversion-using-upgraded.patch b/patches/openwrt/0110-fstools-snapshot-handle-jffs2-conversion-using-upgraded.patch new file mode 100644 index 00000000..812733ec --- /dev/null +++ b/patches/openwrt/0110-fstools-snapshot-handle-jffs2-conversion-using-upgraded.patch @@ -0,0 +1,36 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 08:29:55 +0200 +Subject: fstools: snapshot: handle jffs2 conversion using upgraded + +We can reuse the kill_remaining and run_ramfs facilities of the stage2 run +by upgraded. + +Signed-off-by: Matthias Schiffer + +diff --git a/package/system/fstools/files/snapshot b/package/system/fstools/files/snapshot +index eec7214032d1b147d5e989cd305c5c0cd1357a55..79be0d24bb68cc9b4ea8ce5b5d6b7558b2f0b0c5 100644 +--- a/package/system/fstools/files/snapshot ++++ b/package/system/fstools/files/snapshot +@@ -64,14 +64,16 @@ do_convert_jffs2() { + do_convert() { + . /lib/functions.sh + . /lib/upgrade/common.sh +- ubus call system upgrade +- touch /tmp/sysupgrade ++ + cd /overlay + tar czf /tmp/snapshot.tar.gz * +- kill_remaining TERM +- sleep 3 +- kill_remaining KILL +- run_ramfs '. /sbin/snapshot; do_convert_jffs2' ++ ++ install_bin /sbin/upgraded ++ ubus call system sysupgrade "{ ++ \"prefix\": \"$RAM_ROOT\", ++ \"path\": \"\", ++ \"command\": \". /sbin/snapshot; do_convert_jffs2\" ++ }" + } + + [ -n "$(cat /proc/mounts|grep /overlay|grep jffs2)" ] && { diff --git a/patches/openwrt/0111-base-files-sysupgrade-cleanup.patch b/patches/openwrt/0111-base-files-sysupgrade-cleanup.patch new file mode 100644 index 00000000..5a7e5044 --- /dev/null +++ b/patches/openwrt/0111-base-files-sysupgrade-cleanup.patch @@ -0,0 +1,255 @@ +From: Matthias Schiffer +Date: Sun, 23 Apr 2017 23:33:14 +0200 +Subject: base-files: sysupgrade cleanup + +Some functions only used by stage2 are moved there from common.sh. + +One piece that could still use more cleanup is platform_pre_upgrade: many +targets reference files from there are aren't available in the ramfs, so +we need to evaluate it before the switch; conversely, flash writes happen +in that function on some targets. Targets that do the latter should be +fixed eventually to use platform_do_upgrade for that purpose. + +Signed-off-by: Matthias Schiffer + +diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh +index 23f18ceb775caac057ee7a757922954f812f77ce..fc59bf2323498d332159b00eb7ab443bfe6b147e 100644 +--- a/package/base-files/files/lib/upgrade/common.sh ++++ b/package/base-files/files/lib/upgrade/common.sh +@@ -30,103 +30,6 @@ install_bin() { # [ ... ] + }; done + } + +-supivot() { # +- /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1 +- mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \ +- /bin/mount -o noatime,move /proc $1/proc && \ +- pivot_root $1 $1$2 || { +- /bin/umount -l $1 $1 +- return 1 +- } +- +- /bin/mount -o noatime,move $2/sys /sys +- /bin/mount -o noatime,move $2/dev /dev +- /bin/mount -o noatime,move $2/tmp /tmp +- /bin/mount -o noatime,move $2/overlay /overlay 2>&- +- return 0 +-} +- +-run_ramfs() { # [...] +- install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \ +- /sbin/pivot_root /usr/bin/wget /sbin/reboot /bin/sync /bin/dd \ +- /bin/grep /bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" \ +- /bin/dd /bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump \ +- /bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \ +- /bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \ +- /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find +- +- install_bin /sbin/mtd +- install_bin /sbin/mount_root +- install_bin /sbin/snapshot +- install_bin /sbin/snapshot_tool +- install_bin /usr/sbin/ubiupdatevol +- install_bin /usr/sbin/ubiattach +- install_bin /usr/sbin/ubiblock +- install_bin /usr/sbin/ubiformat +- install_bin /usr/sbin/ubidetach +- install_bin /usr/sbin/ubirsvol +- install_bin /usr/sbin/ubirmvol +- install_bin /usr/sbin/ubimkvol +- install_bin /usr/sbin/partx +- for file in $RAMFS_COPY_BIN; do +- install_bin ${file//:/ } +- done +- install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA +- +- [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64 +- +- supivot $RAM_ROOT /mnt || { +- echo "Failed to switch over to ramfs. Please reboot." +- exit 1 +- } +- +- /bin/mount -o remount,ro /mnt +- /bin/umount -l /mnt +- +- grep /overlay /proc/mounts > /dev/null && { +- /bin/mount -o noatime,remount,ro /overlay +- /bin/umount -l /overlay +- } +- +- # spawn a new shell from ramdisk to reduce the probability of cache issues +- exec /bin/busybox ash -c "$*" +-} +- +-kill_remaining() { # [ [ ] ] +- local sig="${1:-TERM}" +- local loop="${2:-0}" +- local run=true +- local stat +- +- echo -n "Sending $sig to remaining processes ... " +- +- while $run; do +- run=false +- for stat in /proc/[0-9]*/stat; do +- [ -f "$stat" ] || continue +- +- local pid name state ppid rest +- read pid name state ppid rest < $stat +- name="${name#(}"; name="${name%)}" +- +- # Skip PID1, ourself and our children +- [ $pid -ne 1 -a $pid -ne $$ -a $ppid -ne $$ ] || continue +- +- local cmdline +- read cmdline < /proc/$pid/cmdline +- +- # Skip kernel threads +- [ -n "$cmdline" ] || continue +- +- echo -n "$name " +- kill -$sig $pid 2>/dev/null +- +- [ $loop -eq 1 ] && run=true +- done +- done +- echo "" +-} +- + run_hooks() { + local arg="$1"; shift + for func in "$@"; do +diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2 +index 4e2aa3a23c3bab07a795762a30a4d4f701081934..cc8047d988e39ca9ba27d2588744aad469d1d978 100755 +--- a/package/base-files/files/lib/upgrade/stage2 ++++ b/package/base-files/files/lib/upgrade/stage2 +@@ -24,6 +24,104 @@ export CONF_TAR=/tmp/sysupgrade.tgz + include /lib/upgrade + + ++supivot() { # ++ /bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1 ++ mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \ ++ /bin/mount -o noatime,move /proc $1/proc && \ ++ pivot_root $1 $1$2 || { ++ /bin/umount -l $1 $1 ++ return 1 ++ } ++ ++ /bin/mount -o noatime,move $2/sys /sys ++ /bin/mount -o noatime,move $2/dev /dev ++ /bin/mount -o noatime,move $2/tmp /tmp ++ /bin/mount -o noatime,move $2/overlay /overlay 2>&- ++ return 0 ++} ++ ++switch_to_ramfs() { ++ install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount \ ++ /sbin/pivot_root /sbin/reboot /bin/sync /bin/dd /bin/grep \ ++ /bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" /bin/dd \ ++ /bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump \ ++ /bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \ ++ /bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \ ++ /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \ ++ /bin/mknod ++ ++ install_bin /sbin/mtd ++ install_bin /sbin/mount_root ++ install_bin /sbin/snapshot ++ install_bin /sbin/snapshot_tool ++ install_bin /usr/sbin/ubiupdatevol ++ install_bin /usr/sbin/ubiattach ++ install_bin /usr/sbin/ubiblock ++ install_bin /usr/sbin/ubiformat ++ install_bin /usr/sbin/ubidetach ++ install_bin /usr/sbin/ubirsvol ++ install_bin /usr/sbin/ubirmvol ++ install_bin /usr/sbin/ubimkvol ++ install_bin /usr/sbin/partx ++ install_bin /usr/sbin/losetup ++ install_bin /usr/sbin/mkfs.ext4 ++ for file in $RAMFS_COPY_BIN; do ++ install_bin ${file//:/ } ++ done ++ install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA ++ ++ [ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64 ++ ++ supivot $RAM_ROOT /mnt || { ++ echo "Failed to switch over to ramfs. Please reboot." ++ exit 1 ++ } ++ ++ /bin/mount -o remount,ro /mnt ++ /bin/umount -l /mnt ++ ++ grep /overlay /proc/mounts > /dev/null && { ++ /bin/mount -o noatime,remount,ro /overlay ++ /bin/umount -l /overlay ++ } ++} ++ ++kill_remaining() { # [ [ ] ] ++ local sig="${1:-TERM}" ++ local loop="${2:-0}" ++ local run=true ++ local stat ++ ++ echo -n "Sending $sig to remaining processes ... " ++ ++ while $run; do ++ run=false ++ for stat in /proc/[0-9]*/stat; do ++ [ -f "$stat" ] || continue ++ ++ local pid name state ppid rest ++ read pid name state ppid rest < $stat ++ name="${name#(}"; name="${name%)}" ++ ++ # Skip PID1, ourself and our children ++ [ $pid -ne 1 -a $pid -ne $$ -a $ppid -ne $$ ] || continue ++ ++ local cmdline ++ read cmdline < /proc/$pid/cmdline ++ ++ # Skip kernel threads ++ [ -n "$cmdline" ] || continue ++ ++ echo -n "$name " ++ kill -$sig $pid 2>/dev/null ++ ++ [ $loop -eq 1 ] && run=true ++ done ++ done ++ echo "" ++} ++ ++ + killall -9 telnetd + killall -9 dropbear + killall -9 ash +@@ -44,7 +142,8 @@ fi + + if [ -n "$(rootfs_type)" ]; then + echo "Switching to ramdisk..." +- run_ramfs "$COMMAND" +-else +- exec /bin/busybox ash -c "$COMMAND" ++ switch_to_ramfs + fi ++ ++# Exec new shell from ramfs ++exec /bin/busybox ash -c "$COMMAND" +diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade +index d48416f6de244b97f426ae0b83d425ac5c1bc5b3..2060679e61948e4661a408df009ff3ef3c6faa91 100755 +--- a/package/base-files/files/sbin/sysupgrade ++++ b/package/base-files/files/sbin/sysupgrade +@@ -1,7 +1,5 @@ + #!/bin/sh + +-[ "$1" = "nand" ] && exec /lib/upgrade/stage2 "$2" "$3" +- + . /lib/functions.sh + . /lib/functions/system.sh + diff --git a/patches/openwrt/0112-base-files-add-support-for-staged-sysupgrades-from-failsafe-mode.patch b/patches/openwrt/0112-base-files-add-support-for-staged-sysupgrades-from-failsafe-mode.patch new file mode 100644 index 00000000..7654b066 --- /dev/null +++ b/patches/openwrt/0112-base-files-add-support-for-staged-sysupgrades-from-failsafe-mode.patch @@ -0,0 +1,71 @@ +From: Matthias Schiffer +Date: Mon, 24 Apr 2017 01:31:04 +0200 +Subject: base-files: add support for staged sysupgrades from failsafe mode + +Signed-off-by: Matthias Schiffer + +diff --git a/package/base-files/files/lib/preinit/40_run_failsafe_hook b/package/base-files/files/lib/preinit/40_run_failsafe_hook +index cb43ad39cbae07c533af63d7ff445d41a5b988df..fee0c8f0e19f2bf46771cd23ceaaff2db7af7611 100644 +--- a/package/base-files/files/lib/preinit/40_run_failsafe_hook ++++ b/package/base-files/files/lib/preinit/40_run_failsafe_hook +@@ -4,8 +4,12 @@ + + run_failsafe_hook() { + if [ "$FAILSAFE" = "true" ]; then ++ lock /tmp/.failsafe + boot_run_hook failsafe +- lock -w /tmp/.failsafe ++ while [ ! -e /tmp/sysupgrade ]; do ++ lock -w /tmp/.failsafe ++ done ++ exit + fi + } + +diff --git a/package/base-files/files/lib/preinit/99_10_failsafe_login b/package/base-files/files/lib/preinit/99_10_failsafe_login +index 15dcbd884f1f2ec4fd84c92482a9b656d1a26dd7..96e95b1d99c631536c0b30ee5c2e19b3c63bbc64 100644 +--- a/package/base-files/files/lib/preinit/99_10_failsafe_login ++++ b/package/base-files/files/lib/preinit/99_10_failsafe_login +@@ -7,9 +7,13 @@ failsafe_netlogin () { + } + + failsafe_shell() { +- lock /tmp/.failsafe +- ash --login +- echo "Please reboot system when done with failsafe network logins" ++ local console="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | head -1 | sed -e 's/^console=//' -e 's/,.*//')" ++ [ -n "$console" ] || console=console ++ [ -c "/dev/$console" ] || return 0 ++ while true; do ++ ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console" ++ sleep 1 ++ done & + } + + boot_hook_add failsafe failsafe_netlogin +diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade +index 2060679e61948e4661a408df009ff3ef3c6faa91..853134a2cb8a2ef1d56671bfeee46704892909d8 100755 +--- a/package/base-files/files/sbin/sysupgrade ++++ b/package/base-files/files/sbin/sysupgrade +@@ -249,8 +249,16 @@ run_hooks "" $sysupgrade_pre_upgrade + + install_bin /sbin/upgraded + v "Commencing upgrade. All shell sessions will be closed now." +-ubus call system sysupgrade "{ +- \"prefix\": \"$RAM_ROOT\", +- \"path\": $(json_string "$IMAGE"), +- \"command\": \". /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2\" +-}" ++ ++COMMAND='. /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2' ++ ++if [ -n "$FAILSAFE" ]; then ++ printf '%s\x00%s\x00%s' "$RAM_ROOT" "$IMAGE" "$COMMAND" >/tmp/sysupgrade ++ lock -u /tmp/.failsafe ++else ++ ubus call system sysupgrade "{ ++ \"prefix\": $(json_string "$RAM_ROOT"), ++ \"path\": $(json_string "$IMAGE"), ++ \"command\": $(json_string "$COMMAND") ++ }" ++fi diff --git a/patches/openwrt/0113-x86-sysupgrade-move-partition-table-change-check-to-platform_check_image.patch b/patches/openwrt/0113-x86-sysupgrade-move-partition-table-change-check-to-platform_check_image.patch new file mode 100644 index 00000000..8da5a5d2 --- /dev/null +++ b/patches/openwrt/0113-x86-sysupgrade-move-partition-table-change-check-to-platform_check_image.patch @@ -0,0 +1,62 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 08:57:29 +0200 +Subject: x86: sysupgrade: move partition table change check to platform_check_image + +The staged sysupgrade will prevent us from using ask_bool in +platform_do_upgrade; therefore, the check is moved to platform_check_image. + +Signed-off-by: Matthias Schiffer + +diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh +index d3e9f360aadedad0995da55205364940c9884ba4..81b349a81816033eef9df464b2a70fdb998e5a1d 100644 +--- a/target/linux/x86/base-files/lib/upgrade/platform.sh ++++ b/target/linux/x86/base-files/lib/upgrade/platform.sh +@@ -1,13 +1,37 @@ + platform_check_image() { ++ local diskdev partdev diff + [ "$#" -gt 1 ] && return 1 + + case "$(get_magic_word "$1")" in +- eb48|eb63) return 0;; ++ eb48|eb63) ;; + *) + echo "Invalid image type" + return 1 + ;; + esac ++ ++ export_bootdevice && export_partdevice diskdev 0 || { ++ echo "Unable to determine upgrade device" ++ return 1 ++ } ++ ++ get_partitions "/dev/$diskdev" bootdisk ++ ++ #extract the boot sector from the image ++ get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null ++ ++ get_partitions /tmp/image.bs image ++ ++ #compare tables ++ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" ++ ++ rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image ++ ++ if [ -n "$diff" ]; then ++ echo "Partition layout has changed. Full image will be written." ++ ask_bool 0 "Abort" && exit 1 ++ return 0 ++ fi + } + + platform_copy_config() { +@@ -36,9 +60,6 @@ platform_do_upgrade() { + #compare tables + diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" + if [ -n "$diff" ]; then +- echo "Partition layout is changed. Full image will be written." +- ask_bool 0 "Abort" && exit +- + get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync + return 0 + fi diff --git a/patches/openwrt/0114-x86-sysupgrade-refactor-platform_do_upgrade.patch b/patches/openwrt/0114-x86-sysupgrade-refactor-platform_do_upgrade.patch new file mode 100644 index 00000000..a70f3ad4 --- /dev/null +++ b/patches/openwrt/0114-x86-sysupgrade-refactor-platform_do_upgrade.patch @@ -0,0 +1,90 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 09:05:25 +0200 +Subject: x86: sysupgrade: refactor platform_do_upgrade + +By returning early when no upgrade device can be found and handling the +SAVE_PARTITIONS=0 case differently, we can get rid of two levels of if. + +Signed-off-by: Matthias Schiffer + +diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh +index 81b349a81816033eef9df464b2a70fdb998e5a1d..4fa71999be7be3972676a1019488972dccd57fa2 100644 +--- a/target/linux/x86/base-files/lib/upgrade/platform.sh ++++ b/target/linux/x86/base-files/lib/upgrade/platform.sh +@@ -47,40 +47,43 @@ platform_copy_config() { + platform_do_upgrade() { + local diskdev partdev diff + +- if export_bootdevice && export_partdevice diskdev 0; then +- sync +- if [ "$SAVE_PARTITIONS" = "1" ]; then +- get_partitions "/dev/$diskdev" bootdisk +- +- #extract the boot sector from the image +- get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b +- +- get_partitions /tmp/image.bs image +- +- #compare tables +- diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" +- if [ -n "$diff" ]; then +- get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync +- return 0 +- fi +- +- #iterate over each partition from the image and write it to the boot disk +- while read part start size; do +- if export_partdevice partdev $part; then +- echo "Writing image to /dev/$partdev..." +- get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync +- else +- echo "Unable to find partition $part device, skipped." +- fi +- done < /tmp/partmap.image +- +- #copy partition uuid +- echo "Writing new UUID to /dev/$diskdev..." +- get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync ++ export_bootdevice && export_partdevice diskdev 0 || { ++ echo "Unable to determine upgrade device" ++ return 1 ++ } ++ ++ sync ++ ++ if [ "$SAVE_PARTITIONS" = "1" ]; then ++ get_partitions "/dev/$diskdev" bootdisk ++ ++ #extract the boot sector from the image ++ get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b ++ ++ get_partitions /tmp/image.bs image ++ ++ #compare tables ++ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" ++ else ++ diff=1 ++ fi ++ ++ if [ -n "$diff" ]; then ++ get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync ++ return 0 ++ fi ++ ++ #iterate over each partition from the image and write it to the boot disk ++ while read part start size; do ++ if export_partdevice partdev $part; then ++ echo "Writing image to /dev/$partdev..." ++ get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync + else +- get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync ++ echo "Unable to find partition $part device, skipped." + fi ++ done < /tmp/partmap.image + +- sleep 1 +- fi ++ #copy partition uuid ++ echo "Writing new UUID to /dev/$diskdev..." ++ get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync + } diff --git a/patches/openwrt/0115-x86-sysupgrade-explicitly-rescan-disk-after-writing-partition-table.patch b/patches/openwrt/0115-x86-sysupgrade-explicitly-rescan-disk-after-writing-partition-table.patch new file mode 100644 index 00000000..4e46ce60 --- /dev/null +++ b/patches/openwrt/0115-x86-sysupgrade-explicitly-rescan-disk-after-writing-partition-table.patch @@ -0,0 +1,26 @@ +From: Matthias Schiffer +Date: Wed, 3 May 2017 09:08:29 +0200 +Subject: x86: sysupgrade: explicitly rescan disk after writing partition table + +This should ensure that the kernel partition can be mounted in +platform_copy_config when its size has changed. + +Signed-off-by: Matthias Schiffer + +diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh +index 4fa71999be7be3972676a1019488972dccd57fa2..439ba8f5125d97932248ff966340165a84e1b24a 100644 +--- a/target/linux/x86/base-files/lib/upgrade/platform.sh ++++ b/target/linux/x86/base-files/lib/upgrade/platform.sh +@@ -70,6 +70,12 @@ platform_do_upgrade() { + + if [ -n "$diff" ]; then + get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync ++ ++ # Separate removal and addtion is necessary; otherwise, partition 1 ++ # will be missing if it overlaps with the old partition 2 ++ partx -d - "/dev/$diskdev" ++ partx -a - "/dev/$diskdev" ++ + return 0 + fi + diff --git a/patches/openwrt/0116-mvebu-fix-sysupgrade.patch b/patches/openwrt/0116-mvebu-fix-sysupgrade.patch new file mode 100644 index 00000000..7a345bef --- /dev/null +++ b/patches/openwrt/0116-mvebu-fix-sysupgrade.patch @@ -0,0 +1,85 @@ +From: Matthias Schiffer +Date: Thu, 1 Jun 2017 18:39:12 +0200 +Subject: mvebu: fix sysupgrade + +mvebu was modifying RAMFS_COPY_BIN and RAMFS_COPY_DATA from a +sysupgrade_pre_upgrade hook. As the ramfs is created from stage2, this +did not have an effect anymore after the staged sysupgrade changes. + +As it doesn't really hurt to copy fw_printenv and fw_setenv +unconditionally, simply add them in /lib/upgrade/platform.sh, so stage2 +will see them. + +Config copying is moved to a function called by platform_copy_config, where +it belongs. + +Signed-off-by: Matthias Schiffer +Fixes: FS#821 +Fixes: 30f61a34b4cf "base-files: always use staged sysupgrade" + +diff --git a/package/base-files/files/lib/upgrade/stage2 b/package/base-files/files/lib/upgrade/stage2 +index cc8047d988e39ca9ba27d2588744aad469d1d978..bdbb8926643287f48a4ae62c5d1d4b4a29130859 100755 +--- a/package/base-files/files/lib/upgrade/stage2 ++++ b/package/base-files/files/lib/upgrade/stage2 +@@ -48,7 +48,7 @@ switch_to_ramfs() { + /bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \ + /bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \ + /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \ +- /bin/mknod ++ /bin/mknod /bin/touch + + install_bin /sbin/mtd + install_bin /sbin/mount_root +diff --git a/target/linux/mvebu/base-files/lib/upgrade/linksys.sh b/target/linux/mvebu/base-files/lib/upgrade/linksys.sh +index fc403332bd38fc521a056ab85783abd90629a1cf..63d1cd14a4deed407b217a518ae25a752f62969e 100644 +--- a/target/linux/mvebu/base-files/lib/upgrade/linksys.sh ++++ b/target/linux/mvebu/base-files/lib/upgrade/linksys.sh +@@ -73,14 +73,7 @@ platform_do_upgrade_linksys() { + } + } + +-linksys_preupgrade() { +- export RAMFS_COPY_BIN="${RAMFS_COPY_BIN} /usr/sbin/fw_printenv /usr/sbin/fw_setenv" +- export RAMFS_COPY_BIN="${RAMFS_COPY_BIN} /bin/mkdir /bin/touch" +- export RAMFS_COPY_DATA="${RAMFS_COPY_DATA} /etc/fw_env.config /var/lock/fw_printenv.lock" +- +- [ -f /tmp/sysupgrade.tgz ] && { +- cp /tmp/sysupgrade.tgz /tmp/syscfg/sysupgrade.tgz +- } ++platform_copy_config_linksys() { ++ cp -f /tmp/sysupgrade.tgz /tmp/syscfg/sysupgrade.tgz ++ sync + } +- +-append sysupgrade_pre_upgrade linksys_preupgrade +diff --git a/target/linux/mvebu/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/base-files/lib/upgrade/platform.sh +index 46b84435977b83d002ae766fe37c6459a55177ff..7465f7be7649f778ada62cf90aa94b16c11c7e34 100755 +--- a/target/linux/mvebu/base-files/lib/upgrade/platform.sh ++++ b/target/linux/mvebu/base-files/lib/upgrade/platform.sh +@@ -4,7 +4,8 @@ + + . /lib/mvebu.sh + +-RAMFS_COPY_DATA=/lib/mvebu.sh ++RAMFS_COPY_BIN='/usr/sbin/fw_printenv /usr/sbin/fw_setenv' ++RAMFS_COPY_DATA='/lib/mvebu.sh /etc/fw_env.config /var/lock/fw_printenv.lock' + + platform_check_image() { + local board=$(mvebu_board_name) +@@ -39,6 +40,16 @@ platform_do_upgrade() { + esac + } + ++platform_copy_config() { ++ local board=$(mvebu_board_name) ++ ++ case "$board" in ++ armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-rango|armada-385-linksys-shelby|armada-xp-linksys-mamba) ++ platform_copy_config_linksys ++ ;; ++ esac ++} ++ + disable_watchdog() { + killall watchdog + ( ps | grep -v 'grep' | grep '/dev/watchdog' ) && {