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 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