On 06/07/16 06:58, John Crispin wrote: > Hi Philipp > > the thing that i am worried about is this process > > 1) plug a stick > 2) mountd detects the upgrade file > 3) mountd triggers sysupgrade > 4) system reboots > 5) goto 1) > > there is no way to know at what point between 3 and 4 we need to unplug > the usb stick
One possible solution is to write a file, something like ".sysupgrade-applied" or remove the upgrade file before actually doing the upgrade, or during first boot. bruno > John > > On 04/07/2016 18:56, Philipp Deppenwiese wrote: >> Extend the mountd with the ability to apply sysupgrades from mounted devices. >> Upgrade files are identified by filename and executed through the >> commandline sysupgrade utility of LEDE. >> >> Option List: >> >> config mountd 'sysupgrade' >> option check_filename firmware.bin (required) >> option save_config 1 (optional, default disabled) >> option delay 10 (optional, default disabled) >> option preserve_part 1 (optional, default disabled) >> option enabled 1 >> >> The so called "filesearch" is done only in the root of a mounted >> devices. >> >> Signed-off-by: Philipp Deppenwiese <zao...@das-labor.org> >> --- >> CMakeLists.txt | 2 +- >> autofs.c | 19 ++++++- >> include/upgrade.h | 6 ++ >> mount.c | 2 + >> upgrade.c | 162 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 5 files changed, 189 insertions(+), 2 deletions(-) >> create mode 100644 include/upgrade.h >> create mode 100644 upgrade.c >> >> diff --git a/CMakeLists.txt b/CMakeLists.txt >> index 2e712cd..ed3602e 100644 >> --- a/CMakeLists.txt >> +++ b/CMakeLists.txt >> @@ -5,7 +5,7 @@ ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 >> -Wmissing-declarations) >> >> SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") >> >> -ADD_EXECUTABLE(mountd main.c log.c sys.c autofs.c mount.c timer.c signal.c >> ucix.c led.c fs.c ucix.c) >> +ADD_EXECUTABLE(mountd main.c log.c sys.c autofs.c mount.c timer.c signal.c >> ucix.c led.c fs.c ucix.c upgrade.c) >> TARGET_LINK_LIBRARIES(mountd uci ubox) >> >> INSTALL(TARGETS mountd >> diff --git a/autofs.c b/autofs.c >> index 4ad782d..79a3e97 100644 >> --- a/autofs.c >> +++ b/autofs.c >> @@ -37,6 +37,13 @@ dev_t dev; >> time_t uci_timeout; >> char uci_path[32]; >> >> +// Sysupgrade uci options >> +char uci_upgrade_filename[255]; >> +int uci_upgrade_backup; >> +int uci_upgrade_delay; >> +int uci_upgrade_enabled; >> +int uci_upgrade_preserve_partition; >> + >> static void umount_autofs(void) >> { >> system_printf("umount %s 2> /dev/null", "/tmp/run/mountd/"); >> @@ -186,18 +193,28 @@ static void autofs_cleanup_handler(void) >> static void autofs_init(void) >> { >> int kproto_version; >> - char *p; >> + char *p, *filename = NULL; >> struct uci_context *ctx; >> signal_init(autofs_cleanup_handler); >> ctx = ucix_init("mountd"); >> uci_timeout = ucix_get_option_int(ctx, "mountd", "mountd", "timeout", >> 60); >> p = ucix_get_option(ctx, "mountd", "mountd", "path"); >> + filename = ucix_get_option(ctx, "mountd", "sysupgrade", >> "check_filename"); >> + uci_upgrade_backup = ucix_get_option_int(ctx, "mountd", "sysupgrade", >> "save_config", 0); >> + uci_upgrade_delay = ucix_get_option_int(ctx, "mountd", "sysupgrade", >> "delay", 0); >> + uci_upgrade_enabled = ucix_get_option_int(ctx, "mountd", "sysupgrade", >> "enabled", 0); >> + uci_upgrade_preserve_partition = ucix_get_option_int(ctx, "mountd", >> "sysupgrade", "preserve_part", 0); >> ucix_cleanup(ctx); >> if(p) >> snprintf(uci_path, 31, "%s", p); >> else >> snprintf(uci_path, 31, "/tmp/mounts/"); >> uci_path[31] = '\0'; >> + >> + if(filename) { >> + snprintf(uci_upgrade_filename, 255, "%s", filename); >> + } >> + >> mkdir("/tmp/run/", 0555); >> mkdir("/tmp/mounts", 0555); >> system_printf("rm -rf %s*", uci_path); >> diff --git a/include/upgrade.h b/include/upgrade.h >> new file mode 100644 >> index 0000000..6b5ace9 >> --- /dev/null >> +++ b/include/upgrade.h >> @@ -0,0 +1,6 @@ >> +#ifndef _UPGRADE_H__ >> +#define _UPGRADE_H__ >> + >> +int sysupgrade_scan(const char *mount_path); >> + >> +#endif >> diff --git a/mount.c b/mount.c >> index 7cbb8ff..0bec25e 100644 >> --- a/mount.c >> +++ b/mount.c >> @@ -28,6 +28,7 @@ >> #include "include/ucix.h" >> #include "include/fs.h" >> #include "include/mount.h" >> +#include "include/upgrade.h" >> >> int mount_new(char *path, char *dev); >> >> @@ -300,6 +301,7 @@ int mount_new(char *path, char *dev) >> { >> mount->mounted = 1; >> mount_dump_uci_state(); >> + sysupgrade_scan(tmp); >> } else return -1; >> return 0; >> } >> diff --git a/upgrade.c b/upgrade.c >> new file mode 100644 >> index 0000000..6992e65 >> --- /dev/null >> +++ b/upgrade.c >> @@ -0,0 +1,162 @@ >> +/* >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * 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. >> + * >> + * Provided by 9elements GmbH >> + * Copyright (C) 2016 Philipp Deppenwiese >> <philipp.deppenwi...@9elements.com> >> + */ >> + >> +#include <errno.h> >> +#include <linux/limits.h> >> +#include <stdio.h> >> +#include <stdlib.h> >> +#include <stdarg.h> >> +#include <string.h> >> +#include <sys/stat.h> >> +#include <sys/types.h> >> +#include <sys/wait.h> >> +#include <unistd.h> >> + >> +#include "include/upgrade.h" >> +#include "include/log.h" >> + >> +#define SYSUPGRADE_CMD "/sbin/sysupgrade" >> + >> +extern char uci_upgrade_filename[255]; >> +extern int uci_upgrade_backup; >> +extern int uci_upgrade_delay; >> +extern int uci_upgrade_enabled; >> +extern int uci_upgrade_preserve_partition; >> + >> +static unsigned option_index = 0; >> +static char **parameters = NULL; >> + >> +static int execute_sysupgrade() >> +{ >> + pid_t pid; >> + int status; >> + char * const envp[] = { NULL }; >> + >> + if (!parameters) { >> + return 1; >> + } >> + >> + if ((pid = fork()) < 0) { >> + perror("Can't fork child process for command invocation!"); >> + return 1; >> + } else if (pid == 0) { >> + if (execve(SYSUPGRADE_CMD, parameters, envp) < 0) { >> + log_printf("Error was reported on sysupgrade: %s\n", >> strerror(errno)); >> + return 1; >> + } >> + } else { >> + waitpid(pid, &status, 0); >> + } >> + return 0; >> +} >> + >> +static int find_upgrade_filepath(const char *mount_path, char *update_file) >> +{ >> + struct stat file; >> + >> + if (snprintf(update_file, PATH_MAX, "%s/%s", mount_path, >> + uci_upgrade_filename) < 0) { >> + perror(NULL); >> + return 1; >> + } >> + >> + if (stat(update_file, &file) < 0) { >> + log_printf("No upgrade file found for device path: %s! \n", >> mount_path); >> + return 1; >> + } >> + return 0; >> +} >> + >> +static void add_sysupgrade_option(const char *parameter, ...) >> +{ >> + va_list arguments; >> + char *option = NULL; >> + >> + parameters = realloc(parameters, ++option_index * sizeof(char*)); >> + >> + if (parameter) { >> + option = (char*)calloc(PATH_MAX, sizeof(char)); >> + >> + va_start(arguments, parameter); >> + vsnprintf(option, PATH_MAX, parameter, arguments); >> + va_end(arguments); >> + } >> + >> + parameters[option_index - 1] = option; >> +} >> + >> +static void free_all() >> +{ >> + unsigned i; >> + >> + if (!parameters) { >> + return; >> + } >> + >> + for (i = 0; i < option_index; i++) { >> + if (parameters[i]) { >> + free(parameters[i]); >> + } >> + } >> + >> + free(parameters); >> + parameters = NULL; >> + option_index = 0; >> +} >> + >> +int sysupgrade_scan(const char *mount_path) >> +{ >> + char update_file[PATH_MAX]; >> + >> + if (!uci_upgrade_enabled) { >> + log_printf("Sysupgrade via usb device is disabled..\n"); >> + return 0; >> + } >> + >> + if (find_upgrade_filepath(mount_path, update_file)) { >> + log_printf("No upgrade file could be found..\n"); >> + return 0; >> + } >> + >> + log_printf("Starting sysupgrade routine..\n"); >> + >> + add_sysupgrade_option("%s", SYSUPGRADE_CMD); >> + >> + if (uci_upgrade_delay) { >> + add_sysupgrade_option("-d %i", uci_upgrade_delay); >> + } >> + >> + if (uci_upgrade_backup) { >> + add_sysupgrade_option("-c"); >> + } else { >> + add_sysupgrade_option("-n"); >> + } >> + >> + if (uci_upgrade_preserve_partition) { >> + add_sysupgrade_option("-p"); >> + } >> + >> + add_sysupgrade_option("%s", update_file); >> + add_sysupgrade_option(NULL); >> + >> + if (execute_sysupgrade()) { >> + free_all(); >> + log_printf("Try to start sysupgrade but it failed! \n"); >> + return 1; >> + } >> + >> + free_all(); >> + return 0; >> +} >> > > _______________________________________________ > Lede-dev mailing list > Lede-dev@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/lede-dev > _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev