Message ID | 20241108145840.412200-1-oss@braunwarth.dev |
---|---|
State | Changes Requested |
Headers | show |
Series | [RFC] tree-wide: consolidate reboot handling | expand |
Hi,
What about https://groups.google.com/g/swupdate/c/OWwEm0Ciyis as a first
stepping stone to resolve only WebUI support first, then refactor ?
Thanks !
Le vendredi 8 novembre 2024 à 15:59:12 UTC+1, Daniel Braunwarth a écrit :
This patch tries to consolidate the reboot handling of SWUpdate.
Currently, there are multiple places a reboot can be configured. Some use
cases cannot be implemented with the current implementation.
If one wants to differentiate per update if a reboot of the target is
needed, this must be done with the swupdate-progress tool (or any other
mechanism listening to the IPC socket). This eliminates the possibility
to restart the target via the web interface (mongoose). The web
interface triggers the post-update script if one is defined.
Defining the post-update eliminates the use case where an update doesn't
require a reboot of the target, because the post-update command is
executed in any case.
The patch tries to move the reboot handling to one place.
This change has only been roughly tested so far.
I would like to receive some feedback if this something you could
imagine to merge in the future.
If I missed some use cases (or anything else) - please let me know.
Signed-off-by: Daniel Braunwarth <o...@braunwarth.dev
<https://groups.google.com/u/1/>>
---
bindings/lua_swupdate.c | 4 +-
core/install_from_file.c | 5 +--
core/installer.c | 27 ++++++++-----
core/network_thread.c | 7 ++--
core/swupdate.c | 13 ++++---
corelib/downloader.c | 2 +-
doc/source/bindings.rst | 2 +-
doc/source/swupdate-client.rst | 2 -
doc/source/swupdate-ipc-interface.rst | 4 +-
doc/source/swupdate-progress.rst | 3 --
doc/source/swupdate.rst | 2 +-
examples/configuration/swupdate.cfg | 7 +---
include/installer.h | 2 +-
include/network_ipc.h | 4 +-
include/swupdate.h | 2 +-
ipc/network_ipc.c | 4 +-
mongoose/mongoose_interface.c | 13 ++-----
parser/parser.c | 1 -
suricatta/server_hawkbit.c | 4 +-
test/test_server_hawkbit.c | 6 +--
tools/swupdate-client.c | 22 ++++-------
tools/swupdate-progress.c | 55 ---------------------------
22 files changed, 60 insertions(+), 131 deletions(-)
...
Hi Daniel, On 08.11.24 15:58, Daniel Braunwarth wrote: > This patch tries to consolidate the reboot handling of SWUpdate. > > Currently, there are multiple places a reboot can be configured. Some use > cases cannot be implemented with the current implementation. > > If one wants to differentiate per update if a reboot of the target is > needed, this must be done with the swupdate-progress tool (or any other > mechanism listening to the IPC socket). This eliminates the possibility > to restart the target via the web interface (mongoose). The web > interface triggers the post-update script if one is defined. > > Defining the post-update eliminates the use case where an update doesn't > require a reboot of the target, because the post-update command is > executed in any case. > > The patch tries to move the reboot handling to one place. > > This change has only been roughly tested so far. > I would like to receive some feedback if this something you could > imagine to merge in the future. Even if the most used case for postupdate is a reboot, it is not the only use case. In some cases, no tools like swupdate-progress is installed and it is wanted that the SWUpdate daemo is doing everything. So a postupdate is configured, and reason postupdate wasn't called reboot is because some users want to do something else before rebooting, and they attach a string. Nevertheless, the postupdate is outside SWUpdate's state machine, and result of postupdate command has no influence if the update is successful or not. The changes here introduce a backward compatibility because they change how the daemon and tools are called (not a big issue, but well, maybe not necessary to be introduced). The problem with the Website Restart tool is that this is time unrelated with the update. In all other cases (swupdate-progress, postupdate,..) it is known inside SWUpdate or its tool if an update was successful and if reboot is required. But in case of a button, there is no relationship and the update could be executed when a new update is started again, or at any time. So at the moment it is a tradeoff, or SWUpdate should perform the reboot, or the operator is in charge, but not both. To enable the restart, it makes sense to track the state, and enable / disable it just after a successful update, when it is known the device is in agood shape. Best regards, Stefano > > If I missed some use cases (or anything else) - please let me know. > > Signed-off-by: Daniel Braunwarth <oss@braunwarth.dev> > --- > bindings/lua_swupdate.c | 4 +- > core/install_from_file.c | 5 +-- > core/installer.c | 27 ++++++++----- > core/network_thread.c | 7 ++-- > core/swupdate.c | 13 ++++--- > corelib/downloader.c | 2 +- > doc/source/bindings.rst | 2 +- > doc/source/swupdate-client.rst | 2 - > doc/source/swupdate-ipc-interface.rst | 4 +- > doc/source/swupdate-progress.rst | 3 -- > doc/source/swupdate.rst | 2 +- > examples/configuration/swupdate.cfg | 7 +--- > include/installer.h | 2 +- > include/network_ipc.h | 4 +- > include/swupdate.h | 2 +- > ipc/network_ipc.c | 4 +- > mongoose/mongoose_interface.c | 13 ++----- > parser/parser.c | 1 - > suricatta/server_hawkbit.c | 4 +- > test/test_server_hawkbit.c | 6 +-- > tools/swupdate-client.c | 22 ++++------- > tools/swupdate-progress.c | 55 --------------------------- > 22 files changed, 60 insertions(+), 131 deletions(-) > > diff --git a/bindings/lua_swupdate.c b/bindings/lua_swupdate.c > index 0a5dc9f..0f644ee 100644 > --- a/bindings/lua_swupdate.c > +++ b/bindings/lua_swupdate.c > @@ -241,9 +241,9 @@ static int ctrl_close(lua_State *L) { > > ipc_message msg; > msg.data.procmsg.len = 0; > - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { > + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { > lua_pushnil(L); > - lua_pushstring(L, "SWUpdate succeeded but post-update action failed."); > + lua_pushstring(L, "SWUpdate succeeded but reboot failed."); > return 2; > } > > diff --git a/core/install_from_file.c b/core/install_from_file.c > index e222e30..0872cfb 100644 > --- a/core/install_from_file.c > +++ b/core/install_from_file.c > @@ -44,8 +44,7 @@ static int readimage(char **p, int *size) { > > /* > * this is called at the end reporting the status > - * of the upgrade and running any post-update actions > - * if successful > + * of the upgrade and performing a reboot on success if needed > */ > static int endupdate(RECOVERY_STATUS status) > { > @@ -59,7 +58,7 @@ static int endupdate(RECOVERY_STATUS status) > if (status == SUCCESS) { > ipc_message msg; > msg.data.procmsg.len = 0; > - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { > + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { > end_status = EXIT_FAILURE; > } > } > diff --git a/core/installer.c b/core/installer.c > index 0cb06b2..bc0ea14 100644 > --- a/core/installer.c > +++ b/core/installer.c > @@ -595,19 +595,28 @@ int preupdatecmd(struct swupdate_cfg *swcfg) > return 0; > } > > -int postupdate(struct swupdate_cfg *swcfg, const char *info) > +int rebootcmd(struct swupdate_cfg *swcfg, const char *info) > { > + int ret = 0; > + > swupdate_progress_done(info); > > - if (swcfg) { > - if (swcfg->parms.dry_run) { > - DEBUG("Dry run, skipping Post-update command"); > - } else { > - DEBUG("Running Post-update command"); > - return run_system_cmd(swcfg->postupdatecmd); > - } > + if (!swcfg) > + goto finish; > > + if (swcfg->parms.dry_run) { > + DEBUG("Dry run, skipping reboot"); > + goto finish; > } > > - return 0; > + if (!swcfg->reboot_required) { > + INFO("No reboot required for this update"); > + goto finish; > + } > + > + DEBUG("Rebooting the system"); > + ret = run_system_cmd(swcfg->rebootcmd); > + > +finish: > + return ret; > } > diff --git a/core/network_thread.c b/core/network_thread.c > index b70fa12..acf38f8 100644 > --- a/core/network_thread.c > +++ b/core/network_thread.c > @@ -429,14 +429,13 @@ void *network_thread (void *data) > pthread_mutex_lock(&stream_mutex); > if (msg.magic == IPC_MAGIC) { > switch (msg.type) { > - case POST_UPDATE: > - if (postupdate(get_swupdate_cfg(), > + case REBOOT: > + if (rebootcmd(get_swupdate_cfg(), > msg.data.procmsg.len > 0 ? msg.data.procmsg.buf : NULL) == 0) { > msg.type = ACK; > - sprintf(msg.data.msg, "Post-update actions successfully executed."); > } else { > msg.type = NACK; > - sprintf(msg.data.msg, "Post-update actions failed."); > + sprintf(msg.data.msg, "Reboot failed."); > } > break; > case SWUPDATE_SUBPROCESS: > diff --git a/core/swupdate.c b/core/swupdate.c > index 4b98add..d59ee15 100644 > --- a/core/swupdate.c > +++ b/core/swupdate.c > @@ -114,7 +114,7 @@ static struct option long_options[] = { > {"output", required_argument, NULL, 'o'}, > {"gen-swversions", required_argument, NULL, 's'}, > {"preupdate", required_argument, NULL, 'P'}, > - {"postupdate", required_argument, NULL, 'p'}, > + {"rebootcmd", required_argument, NULL, 'r'}, > {"select", required_argument, NULL, 'e'}, > #ifdef CONFIG_SURICATTA > {"suricatta", required_argument, NULL, 'u'}, > @@ -140,7 +140,7 @@ static void usage(char *programname) > " -b, --blacklist <list of mtd> : MTDs that must not be scanned for UBI\n" > #endif > " -B, --bootloader : bootloader interface (default: " PREPROCVALUE(BOOTLOADER_DEFAULT) ")\n" > - " -p, --postupdate : execute post-update command\n" > + " -r, --reboot <command> : execute reboot command\n" > " -P, --preupdate : execute pre-update command\n" > " -e, --select <software>,<mode> : Select software images set and source\n" > " Ex.: stable,main\n" > @@ -274,6 +274,7 @@ static void swupdate_init(struct swupdate_cfg *sw) > LIST_INIT(&sw->bootloader); > LIST_INIT(&sw->extprocs); > sw->cert_purpose = SSL_PURPOSE_DEFAULT; > + sw->reboot_required = true; > > #ifdef CONFIG_MTD > mtd_init(); > @@ -319,7 +320,7 @@ static int read_globals_settings(void *elem, void *data) > GET_FIELD_STRING(LIBCFG_PARSER, elem, > "mtd-blacklist", sw->mtdblacklist); > GET_FIELD_STRING(LIBCFG_PARSER, elem, > - "postupdatecmd", sw->postupdatecmd); > + "rebootcmd", sw->rebootcmd); > GET_FIELD_STRING(LIBCFG_PARSER, elem, > "preupdatecmd", sw->preupdatecmd); > GET_FIELD_STRING(LIBCFG_PARSER, elem, > @@ -761,9 +762,9 @@ int main(int argc, char **argv) > case 'c': > opt_c = true; > break; > - case 'p': > - strlcpy(swcfg.postupdatecmd, optarg, > - sizeof(swcfg.postupdatecmd)); > + case 'r': > + strlcpy(swcfg.rebootcmd, optarg, > + sizeof(swcfg.rebootcmd)); > break; > case 'P': > strlcpy(swcfg.preupdatecmd, optarg, > diff --git a/corelib/downloader.c b/corelib/downloader.c > index 1348f12..b556290 100644 > --- a/corelib/downloader.c > +++ b/corelib/downloader.c > @@ -82,7 +82,7 @@ static RECOVERY_STATUS download_from_url(channel_data_t* channel_data) > if (result != FAILURE) { > ipc_message msg; > msg.data.procmsg.len = 0; > - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { > + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { > result = FAILURE; > } > } > diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst > index 0f9e12b..ded0d70 100644 > --- a/doc/source/bindings.rst > +++ b/doc/source/bindings.rst > @@ -57,7 +57,7 @@ method, returning ``true``, or, in case of errors, ``nil`` plus an error message > > Finally, the ``close()`` method closes the connection to SWUpdate's control > socket after which it waits for SWUpdate to complete the update transaction and > -executes the post-install command, if given. > +executes the reboot command, if given. > > The following example snippet illustrates how to use the control interface binding: > > diff --git a/doc/source/swupdate-client.rst b/doc/source/swupdate-client.rst > index 42b95c7..e0a5ebf 100644 > --- a/doc/source/swupdate-client.rst > +++ b/doc/source/swupdate-client.rst > @@ -27,5 +27,3 @@ DESCRIPTION > go quiet, resets verbosity > -v > go verbose, essentially print upgrade status messages from server > --p > - ask the server to run post-update commands if upgrade succeeds > diff --git a/doc/source/swupdate-ipc-interface.rst b/doc/source/swupdate-ipc-interface.rst > index 3a1d353..e84be4b 100644 > --- a/doc/source/swupdate-ipc-interface.rst > +++ b/doc/source/swupdate-ipc-interface.rst > @@ -53,7 +53,7 @@ Where the fields have the meaning: > > - magic : a magic number as simple proof of the packet > - type : one of REQ_INSTALL, ACK, NACK, > - GET_STATUS, POST_UPDATE, SWUPDATE_SUBPROCESS, SET_AES_KEY > + GET_STATUS, REBOOT, SWUPDATE_SUBPROCESS, SET_AES_KEY > - msgdata : a buffer used by the client to send the image > or by SWUpdate to report back notifications and status. > > @@ -314,7 +314,7 @@ Restart API > > POST /restart > > -If configured (see post update command), this request will restart the device. > +If configured (see reboot command), this request will restart the device. > > > WebSocket API > diff --git a/doc/source/swupdate-progress.rst b/doc/source/swupdate-progress.rst > index 3b57622..62dd9a2 100644 > --- a/doc/source/swupdate-progress.rst > +++ b/doc/source/swupdate-progress.rst > @@ -26,8 +26,6 @@ after an update. > Command to be execute after an update > -p > send percentage to psplash > --r > - optionally reboot the target after a successful update > -s > path to progress IPC socket in case the default is not taken > -w > @@ -36,4 +34,3 @@ after an update. > don't print progress bar > -h > print a help > - > diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst > index fa43071..ef7c926 100644 > --- a/doc/source/swupdate.rst > +++ b/doc/source/swupdate.rst > @@ -521,7 +521,7 @@ Command line parameters > +-------------+----------+--------------------------------------------+ > | -P <cmd> | string | Execute pre-update command. | > +-------------+----------+--------------------------------------------+ > -| -p <cmd> | string | Execute post-update command. | > +| -r <cmd> | string | Execute reboot command. | > +-------------+----------+--------------------------------------------+ > | -q <sel> | string | List for software images set and source | > | | | that are accepted via IPC | > diff --git a/examples/configuration/swupdate.cfg b/examples/configuration/swupdate.cfg > index 2702396..09a1c66 100644 > --- a/examples/configuration/swupdate.cfg > +++ b/examples/configuration/swupdate.cfg > @@ -28,8 +28,8 @@ > # preupdatecmd : string > # command to be executed right before the update > # is installed > -# postupdatecmd : string > -# command to be executed after a successful update > +# rebootcmd : string > +# command to be executed after a successful update to reboot the system > # ca-path : string > # path to the Certificate Authority (PEM) > # no-downgrading : string > @@ -258,9 +258,6 @@ suricatta : > # auth-domain : string > # path to auth-domain, if any > # default = none > -# run-postupdate : boolean (default true) > -# run the postupdate command automatically after > -# a successful update > # timeout : timeout in seconds to monitor the connection > # when an update is started. If no data is received > # during this time, connection is closed by the Webserver > diff --git a/include/installer.h b/include/installer.h > index aad7709..df793ed 100644 > --- a/include/installer.h > +++ b/include/installer.h > @@ -19,7 +19,7 @@ swupdate_file_t check_if_required(struct imglist *list, struct filehdr *pfdh, > int install_images(struct swupdate_cfg *sw); > int install_single_image(struct img_type *img, bool dry_run); > int install_from_file(const char *filename, bool check); > -int postupdate(struct swupdate_cfg *swcfg, const char *info); > +int rebootcmd(struct swupdate_cfg *swcfg, const char *info); > int preupdatecmd(struct swupdate_cfg *swcfg); > int run_prepost_scripts(struct imglist *list, script_fn type); > void cleanup_files(struct swupdate_cfg *software); > diff --git a/include/network_ipc.h b/include/network_ipc.h > index 4d41b7b..3e11e09 100644 > --- a/include/network_ipc.h > +++ b/include/network_ipc.h > @@ -29,7 +29,7 @@ typedef enum { > ACK, > NACK, > GET_STATUS, > - POST_UPDATE, > + REBOOT, > SWUPDATE_SUBPROCESS, > SET_AES_KEY, > SET_UPDATE_STATE, /* set bootloader ustate */ > @@ -143,7 +143,7 @@ int ipc_get_status(ipc_message *msg); > int ipc_get_status_timeout(ipc_message *msg, unsigned int timeout_ms); > int ipc_notify_connect(void); > int ipc_notify_receive(int *connfd, ipc_message *msg); > -int ipc_postupdate(ipc_message *msg); > +int ipc_reboot(ipc_message *msg); > int ipc_send_cmd(ipc_message *msg); > > typedef int (*writedata)(char **buf, int *size); > diff --git a/include/swupdate.h b/include/swupdate.h > index 7cf4210..986a320 100644 > --- a/include/swupdate.h > +++ b/include/swupdate.h > @@ -52,7 +52,7 @@ struct swupdate_cfg { > char output_swversions[SWUPDATE_GENERAL_STRING_SIZE]; > char publickeyfname[SWUPDATE_GENERAL_STRING_SIZE]; > char aeskeyfname[SWUPDATE_GENERAL_STRING_SIZE]; > - char postupdatecmd[SWUPDATE_GENERAL_STRING_SIZE]; > + char rebootcmd[SWUPDATE_GENERAL_STRING_SIZE]; > char preupdatecmd[SWUPDATE_GENERAL_STRING_SIZE]; > char minimum_version[SWUPDATE_GENERAL_STRING_SIZE]; > char maximum_version[SWUPDATE_GENERAL_STRING_SIZE]; > diff --git a/ipc/network_ipc.c b/ipc/network_ipc.c > index e2fff78..d3cf8ac 100644 > --- a/ipc/network_ipc.c > +++ b/ipc/network_ipc.c > @@ -61,7 +61,7 @@ static int prepare_ipc(void) { > return connfd; > } > > -int ipc_postupdate(ipc_message *msg) { > +int ipc_reboot(ipc_message *msg) { > int connfd = prepare_ipc(); > if (connfd < 0) > return -1; > @@ -84,7 +84,7 @@ int ipc_postupdate(ipc_message *msg) { > msg->data.procmsg.len = strnlen(tmpbuf, sizeof(msg->data.procmsg.buf) - 1); > } > msg->magic = IPC_MAGIC; > - msg->type = POST_UPDATE; > + msg->type = REBOOT; > > int result = write(connfd, msg, sizeof(*msg)) != sizeof(*msg) || > read(connfd, msg, sizeof(*msg)) != sizeof(*msg); > diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c > index 1d636cd..027e544 100644 > --- a/mongoose/mongoose_interface.c > +++ b/mongoose/mongoose_interface.c > @@ -69,7 +69,6 @@ struct parent_connection_info { > unsigned long conn_id; > }; > > -static bool run_postupdate; > static unsigned int watchdog_conn = 0; > static struct mg_http_serve_opts s_http_server_opts; > const char *global_auth_domain; > @@ -352,7 +351,7 @@ static void restart_handler(struct mg_connection *nc, void *ev_data) > return; > } > > - int ret = ipc_postupdate(&msg); > + int ret = ipc_reboot(&msg); > if (ret || msg.type != ACK) { > mg_http_reply(nc, 500, "", "%s", "Failed to queue command\n"); > return; > @@ -490,10 +489,10 @@ static void *broadcast_progress_thread(void *data) > broadcast(p, str); > } > > - if (msg.status == SUCCESS && msg.source == SOURCE_WEBSERVER && run_postupdate) { > + if (msg.status == SUCCESS && msg.source == SOURCE_WEBSERVER) { > ipc_message ipc = {}; > > - ipc_postupdate(&ipc); > + ipc_reboot(&ipc); > } > > if (msg.infolen) { > @@ -796,7 +795,6 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat > if (strlen(tmp)) { > opts->auth_domain = strdup(tmp); > } > - GET_FIELD_BOOL(LIBCFG_PARSER, elem, "run-postupdate", &run_postupdate); > > GET_FIELD_INT(LIBCFG_PARSER, elem, "timeout", (int *)&watchdog_conn); > > @@ -855,11 +853,6 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) > /* No listing directory as default */ > opts.listing = false; > > - /* > - * Default value is active > - */ > - run_postupdate = true; > - > /* > * Default no monitor of connection > */ > diff --git a/parser/parser.c b/parser/parser.c > index f5113f9..fbbcd72 100644 > --- a/parser/parser.c > +++ b/parser/parser.c > @@ -215,7 +215,6 @@ static bool get_common_fields(parsertype p, void *cfg, struct swupdate_cfg *swcf > /* > * As default, reboot is initiated > */ > - swcfg->reboot_required = true; > if((setting = find_node(p, cfg, "reboot", swcfg)) != NULL) { > GET_FIELD_BOOL(p, setting, NULL, &swcfg->reboot_required); > } > diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c > index 342670c..6255c67 100644 > --- a/suricatta/server_hawkbit.c > +++ b/suricatta/server_hawkbit.c > @@ -1521,10 +1521,10 @@ cleanup: > ERROR("JSON object should be freed but was not."); > } > if (result == SERVER_OK) { > - INFO("Update successful, executing post-update actions."); > + INFO("Update successful, rebooting the system."); > ipc_message msg; > memset(&msg, 0, sizeof(msg)); > - if (ipc_postupdate(&msg) != 0) { > + if (ipc_reboot(&msg) != 0) { > result = SERVER_EERR; > } else { > result = msg.type == ACK ? SERVER_OK : SERVER_EERR; > diff --git a/test/test_server_hawkbit.c b/test/test_server_hawkbit.c > index fc4bb8f..13117a2 100644 > --- a/test/test_server_hawkbit.c > +++ b/test/test_server_hawkbit.c > @@ -45,9 +45,9 @@ int __wrap_ipc_wait_for_complete(getstatus callback) > return mock_type(RECOVERY_STATUS); > } > > -extern int __real_ipc_postupdate(ipc_message *msg); > -int __wrap_ipc_postupdate(ipc_message *msg); > -int __wrap_ipc_postupdate(ipc_message *msg) { > +extern int __real_ipc_rebootcmd(ipc_message *msg); > +int __wrap_ipc_rebootcmd(ipc_message *msg); > +int __wrap_ipc_rebootcmd(ipc_message *msg) { > msg->type = ACK; > return 0; > } > diff --git a/tools/swupdate-client.c b/tools/swupdate-client.c > index 9ead836..427bd71 100644 > --- a/tools/swupdate-client.c > +++ b/tools/swupdate-client.c > @@ -45,7 +45,6 @@ static void usage(void) { > " -s <path> : path to swupdate IPC socket\n" > " -q : go quiet, resets verbosity\n" > " -v : go verbose, essentially print upgrade status messages from server\n" > - " -p : ask the server to run post-update commands if upgrade succeeds\n" > ); > } > > @@ -53,7 +52,6 @@ char buf[256]; > int fd = STDIN_FILENO; > int verbose = 1; > bool dry_run = false; > -bool run_postupdate = false; > int end_status = EXIT_SUCCESS; > char *software_set = NULL, *running_mode = NULL; > char *socketpath = NULL; > @@ -96,23 +94,21 @@ static int printstatus(ipc_message *msg) > > /* > * this is called at the end reporting the status > - * of the upgrade and running any post-update actions > - * if successful > + * of the upgrade and performing a reboot on success if needed > */ > static int end(RECOVERY_STATUS status) > { > end_status = (status == SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE; > > - fprintf(stdout, "SWUpdate %s\n", > - status == FAILURE ? "*failed* !" : > - "was successful !"); > + if (status == FAILURE) > + ERROR("SWUpdate *failed* !"); > + else > + INFO("SWUpdate was successful !"); > > - if (status == SUCCESS && run_postupdate) { > - fprintf(stdout, "Executing post-update actions.\n"); > + if (status == SUCCESS) { > ipc_message msg; > msg.data.procmsg.len = 0; > - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { > - fprintf(stderr, "Running post-update failed!\n"); > + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { > end_status = EXIT_FAILURE; > } > } > @@ -210,9 +206,6 @@ int main(int argc, char *argv[]) { > software_set = optarg; > running_mode = pos; > break; > - case 'p': > - run_postupdate = true; > - break; > case 's': > socketpath = strdup(optarg); > if(!socketpath) { > @@ -240,4 +233,3 @@ int main(int argc, char *argv[]) { > > cleanup_and_exit(EXIT_SUCCESS); > } > - > diff --git a/tools/swupdate-progress.c b/tools/swupdate-progress.c > index 5e37162..26161db 100644 > --- a/tools/swupdate-progress.c > +++ b/tools/swupdate-progress.c > @@ -18,7 +18,6 @@ > #include <sys/stat.h> > #include <sys/un.h> > #include <sys/select.h> > -#include <sys/reboot.h> > #include <arpa/inet.h> > #include <netinet/in.h> > #include <pthread.h> > @@ -62,7 +61,6 @@ static void textcolor(int attr, int fg, int bg) > static struct option long_options[] = { > {"help", no_argument, NULL, 'h'}, > {"psplash", no_argument, NULL, 'p'}, > - {"reboot", no_argument, NULL, 'r'}, > {"wait", no_argument, NULL, 'w'}, > {"color", no_argument, NULL, 'c'}, > {"socket", required_argument, NULL, 's'}, > @@ -79,7 +77,6 @@ static void usage(char *programname) > fprintf(stdout, > " -c, --color : Use colors to show results\n" > " -e, --exec <script> : call the script with the result of update\n" > - " -r, --reboot : reboot after a successful update\n" > " -w, --wait : wait for a connection with SWUpdate\n" > " -p, --psplash : send info to the psplash process\n" > " -s, --socket <path> : path to progress IPC socket\n" > @@ -189,15 +186,6 @@ static void fill_progress_bar(char *bar, size_t size, unsigned int percent) > memset(&bar[filled_len], '-', remain); > } > > -static void reboot_device(void) > -{ > - sleep(5); > - sync(); > - if (reboot(RB_AUTOBOOT) < 0) { /* Should never happen. */ > - fprintf(stdout, "Please reset the board.\n"); > - } > -} > - > static void run_post_script(char *script, struct progress_msg *msg) > { > char *cmd; > @@ -227,12 +215,10 @@ int main(int argc, char **argv) > char bar[bar_len+1]; > int opt_c = 0; > int opt_w = 0; > - int opt_r = 0; > int opt_p = 0; > int c; > char *script = NULL; > bool wait_update = true; > - bool disable_reboot = false; > bool redirected = false; > > /* Process options with getopt */ > @@ -248,9 +234,6 @@ int main(int argc, char **argv) > case 'p': > opt_p = 1; > break; > - case 'r': > - opt_r = 1; > - break; > case 's': > SOCKET_PROGRESS_PATH = strdup(optarg); > break; > @@ -339,30 +322,11 @@ int main(int argc, char **argv) > * Be sure that string in message are Null terminated > */ > if (msg.infolen > 0) { > - char reboot_mode[20] = { 0 }; > - int n, cause; > - > if (msg.infolen >= sizeof(msg.info) - 1) { > msg.infolen = sizeof(msg.info) - 1; > } > msg.info[msg.infolen] = '\0'; > fprintf(stdout, "INFO : %s\n", msg.info); > - > - /* > - * Check for no-reboot mode > - * Just do a simple parsing for now. If more messages > - * will be added, JSON lib should be linked. > - * NOTE: Until then, the exact string format is imperative! > - */ > - n = sscanf(msg.info, "{\"%d\": { \"reboot-mode\" : \"%19[-a-z]\"}}", > - &cause, reboot_mode); > - if (n == 2) { > - if (cause == CAUSE_REBOOT_MODE) { > - if (!strcmp(reboot_mode, "no-reboot")) { > - disable_reboot = true; > - } > - } > - } > } > msg.cur_image[sizeof(msg.cur_image) - 1] = '\0'; > > @@ -422,22 +386,7 @@ int main(int argc, char **argv) > psplash_progress(psplash_pipe_path, &msg); > psplash_ok = 0; > } > - if (psplash_ok && disable_reboot) { > - fprintf(stdout, > - "\nReboot disabled or waiting for activation.\n"); > - char *buf = alloca(PSPLASH_MSG_SIZE); > - snprintf(buf, PSPLASH_MSG_SIZE - 1, > - "MSG Reboot disabled or waiting for activation."); > - psplash_write_fifo(psplash_pipe_path, buf); > - } > > - if ((msg.status == SUCCESS) && (msg.cur_step > 0) && opt_r && !disable_reboot) { > - reboot_device(); > - } > - /* > - * Reset per update variables after update. > - */ > - disable_reboot = false; > wait_update = true; > break; > case DONE: > @@ -457,10 +406,6 @@ int main(int argc, char **argv) > psplash_progress(psplash_pipe_path, &msg); > psplash_ok = 0; > } > - if (opt_r && strcasestr(msg.info, "firmware")) { > - reboot_device(); > - break; > - } > fprintf(stdout, "\nDon't know how to activate this update, doing nothing.\n"); > } > break;
diff --git a/bindings/lua_swupdate.c b/bindings/lua_swupdate.c index 0a5dc9f..0f644ee 100644 --- a/bindings/lua_swupdate.c +++ b/bindings/lua_swupdate.c @@ -241,9 +241,9 @@ static int ctrl_close(lua_State *L) { ipc_message msg; msg.data.procmsg.len = 0; - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { lua_pushnil(L); - lua_pushstring(L, "SWUpdate succeeded but post-update action failed."); + lua_pushstring(L, "SWUpdate succeeded but reboot failed."); return 2; } diff --git a/core/install_from_file.c b/core/install_from_file.c index e222e30..0872cfb 100644 --- a/core/install_from_file.c +++ b/core/install_from_file.c @@ -44,8 +44,7 @@ static int readimage(char **p, int *size) { /* * this is called at the end reporting the status - * of the upgrade and running any post-update actions - * if successful + * of the upgrade and performing a reboot on success if needed */ static int endupdate(RECOVERY_STATUS status) { @@ -59,7 +58,7 @@ static int endupdate(RECOVERY_STATUS status) if (status == SUCCESS) { ipc_message msg; msg.data.procmsg.len = 0; - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { end_status = EXIT_FAILURE; } } diff --git a/core/installer.c b/core/installer.c index 0cb06b2..bc0ea14 100644 --- a/core/installer.c +++ b/core/installer.c @@ -595,19 +595,28 @@ int preupdatecmd(struct swupdate_cfg *swcfg) return 0; } -int postupdate(struct swupdate_cfg *swcfg, const char *info) +int rebootcmd(struct swupdate_cfg *swcfg, const char *info) { + int ret = 0; + swupdate_progress_done(info); - if (swcfg) { - if (swcfg->parms.dry_run) { - DEBUG("Dry run, skipping Post-update command"); - } else { - DEBUG("Running Post-update command"); - return run_system_cmd(swcfg->postupdatecmd); - } + if (!swcfg) + goto finish; + if (swcfg->parms.dry_run) { + DEBUG("Dry run, skipping reboot"); + goto finish; } - return 0; + if (!swcfg->reboot_required) { + INFO("No reboot required for this update"); + goto finish; + } + + DEBUG("Rebooting the system"); + ret = run_system_cmd(swcfg->rebootcmd); + +finish: + return ret; } diff --git a/core/network_thread.c b/core/network_thread.c index b70fa12..acf38f8 100644 --- a/core/network_thread.c +++ b/core/network_thread.c @@ -429,14 +429,13 @@ void *network_thread (void *data) pthread_mutex_lock(&stream_mutex); if (msg.magic == IPC_MAGIC) { switch (msg.type) { - case POST_UPDATE: - if (postupdate(get_swupdate_cfg(), + case REBOOT: + if (rebootcmd(get_swupdate_cfg(), msg.data.procmsg.len > 0 ? msg.data.procmsg.buf : NULL) == 0) { msg.type = ACK; - sprintf(msg.data.msg, "Post-update actions successfully executed."); } else { msg.type = NACK; - sprintf(msg.data.msg, "Post-update actions failed."); + sprintf(msg.data.msg, "Reboot failed."); } break; case SWUPDATE_SUBPROCESS: diff --git a/core/swupdate.c b/core/swupdate.c index 4b98add..d59ee15 100644 --- a/core/swupdate.c +++ b/core/swupdate.c @@ -114,7 +114,7 @@ static struct option long_options[] = { {"output", required_argument, NULL, 'o'}, {"gen-swversions", required_argument, NULL, 's'}, {"preupdate", required_argument, NULL, 'P'}, - {"postupdate", required_argument, NULL, 'p'}, + {"rebootcmd", required_argument, NULL, 'r'}, {"select", required_argument, NULL, 'e'}, #ifdef CONFIG_SURICATTA {"suricatta", required_argument, NULL, 'u'}, @@ -140,7 +140,7 @@ static void usage(char *programname) " -b, --blacklist <list of mtd> : MTDs that must not be scanned for UBI\n" #endif " -B, --bootloader : bootloader interface (default: " PREPROCVALUE(BOOTLOADER_DEFAULT) ")\n" - " -p, --postupdate : execute post-update command\n" + " -r, --reboot <command> : execute reboot command\n" " -P, --preupdate : execute pre-update command\n" " -e, --select <software>,<mode> : Select software images set and source\n" " Ex.: stable,main\n" @@ -274,6 +274,7 @@ static void swupdate_init(struct swupdate_cfg *sw) LIST_INIT(&sw->bootloader); LIST_INIT(&sw->extprocs); sw->cert_purpose = SSL_PURPOSE_DEFAULT; + sw->reboot_required = true; #ifdef CONFIG_MTD mtd_init(); @@ -319,7 +320,7 @@ static int read_globals_settings(void *elem, void *data) GET_FIELD_STRING(LIBCFG_PARSER, elem, "mtd-blacklist", sw->mtdblacklist); GET_FIELD_STRING(LIBCFG_PARSER, elem, - "postupdatecmd", sw->postupdatecmd); + "rebootcmd", sw->rebootcmd); GET_FIELD_STRING(LIBCFG_PARSER, elem, "preupdatecmd", sw->preupdatecmd); GET_FIELD_STRING(LIBCFG_PARSER, elem, @@ -761,9 +762,9 @@ int main(int argc, char **argv) case 'c': opt_c = true; break; - case 'p': - strlcpy(swcfg.postupdatecmd, optarg, - sizeof(swcfg.postupdatecmd)); + case 'r': + strlcpy(swcfg.rebootcmd, optarg, + sizeof(swcfg.rebootcmd)); break; case 'P': strlcpy(swcfg.preupdatecmd, optarg, diff --git a/corelib/downloader.c b/corelib/downloader.c index 1348f12..b556290 100644 --- a/corelib/downloader.c +++ b/corelib/downloader.c @@ -82,7 +82,7 @@ static RECOVERY_STATUS download_from_url(channel_data_t* channel_data) if (result != FAILURE) { ipc_message msg; msg.data.procmsg.len = 0; - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { result = FAILURE; } } diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 0f9e12b..ded0d70 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -57,7 +57,7 @@ method, returning ``true``, or, in case of errors, ``nil`` plus an error message Finally, the ``close()`` method closes the connection to SWUpdate's control socket after which it waits for SWUpdate to complete the update transaction and -executes the post-install command, if given. +executes the reboot command, if given. The following example snippet illustrates how to use the control interface binding: diff --git a/doc/source/swupdate-client.rst b/doc/source/swupdate-client.rst index 42b95c7..e0a5ebf 100644 --- a/doc/source/swupdate-client.rst +++ b/doc/source/swupdate-client.rst @@ -27,5 +27,3 @@ DESCRIPTION go quiet, resets verbosity -v go verbose, essentially print upgrade status messages from server --p - ask the server to run post-update commands if upgrade succeeds diff --git a/doc/source/swupdate-ipc-interface.rst b/doc/source/swupdate-ipc-interface.rst index 3a1d353..e84be4b 100644 --- a/doc/source/swupdate-ipc-interface.rst +++ b/doc/source/swupdate-ipc-interface.rst @@ -53,7 +53,7 @@ Where the fields have the meaning: - magic : a magic number as simple proof of the packet - type : one of REQ_INSTALL, ACK, NACK, - GET_STATUS, POST_UPDATE, SWUPDATE_SUBPROCESS, SET_AES_KEY + GET_STATUS, REBOOT, SWUPDATE_SUBPROCESS, SET_AES_KEY - msgdata : a buffer used by the client to send the image or by SWUpdate to report back notifications and status. @@ -314,7 +314,7 @@ Restart API POST /restart -If configured (see post update command), this request will restart the device. +If configured (see reboot command), this request will restart the device. WebSocket API diff --git a/doc/source/swupdate-progress.rst b/doc/source/swupdate-progress.rst index 3b57622..62dd9a2 100644 --- a/doc/source/swupdate-progress.rst +++ b/doc/source/swupdate-progress.rst @@ -26,8 +26,6 @@ after an update. Command to be execute after an update -p send percentage to psplash --r - optionally reboot the target after a successful update -s path to progress IPC socket in case the default is not taken -w @@ -36,4 +34,3 @@ after an update. don't print progress bar -h print a help - diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst index fa43071..ef7c926 100644 --- a/doc/source/swupdate.rst +++ b/doc/source/swupdate.rst @@ -521,7 +521,7 @@ Command line parameters +-------------+----------+--------------------------------------------+ | -P <cmd> | string | Execute pre-update command. | +-------------+----------+--------------------------------------------+ -| -p <cmd> | string | Execute post-update command. | +| -r <cmd> | string | Execute reboot command. | +-------------+----------+--------------------------------------------+ | -q <sel> | string | List for software images set and source | | | | that are accepted via IPC | diff --git a/examples/configuration/swupdate.cfg b/examples/configuration/swupdate.cfg index 2702396..09a1c66 100644 --- a/examples/configuration/swupdate.cfg +++ b/examples/configuration/swupdate.cfg @@ -28,8 +28,8 @@ # preupdatecmd : string # command to be executed right before the update # is installed -# postupdatecmd : string -# command to be executed after a successful update +# rebootcmd : string +# command to be executed after a successful update to reboot the system # ca-path : string # path to the Certificate Authority (PEM) # no-downgrading : string @@ -258,9 +258,6 @@ suricatta : # auth-domain : string # path to auth-domain, if any # default = none -# run-postupdate : boolean (default true) -# run the postupdate command automatically after -# a successful update # timeout : timeout in seconds to monitor the connection # when an update is started. If no data is received # during this time, connection is closed by the Webserver diff --git a/include/installer.h b/include/installer.h index aad7709..df793ed 100644 --- a/include/installer.h +++ b/include/installer.h @@ -19,7 +19,7 @@ swupdate_file_t check_if_required(struct imglist *list, struct filehdr *pfdh, int install_images(struct swupdate_cfg *sw); int install_single_image(struct img_type *img, bool dry_run); int install_from_file(const char *filename, bool check); -int postupdate(struct swupdate_cfg *swcfg, const char *info); +int rebootcmd(struct swupdate_cfg *swcfg, const char *info); int preupdatecmd(struct swupdate_cfg *swcfg); int run_prepost_scripts(struct imglist *list, script_fn type); void cleanup_files(struct swupdate_cfg *software); diff --git a/include/network_ipc.h b/include/network_ipc.h index 4d41b7b..3e11e09 100644 --- a/include/network_ipc.h +++ b/include/network_ipc.h @@ -29,7 +29,7 @@ typedef enum { ACK, NACK, GET_STATUS, - POST_UPDATE, + REBOOT, SWUPDATE_SUBPROCESS, SET_AES_KEY, SET_UPDATE_STATE, /* set bootloader ustate */ @@ -143,7 +143,7 @@ int ipc_get_status(ipc_message *msg); int ipc_get_status_timeout(ipc_message *msg, unsigned int timeout_ms); int ipc_notify_connect(void); int ipc_notify_receive(int *connfd, ipc_message *msg); -int ipc_postupdate(ipc_message *msg); +int ipc_reboot(ipc_message *msg); int ipc_send_cmd(ipc_message *msg); typedef int (*writedata)(char **buf, int *size); diff --git a/include/swupdate.h b/include/swupdate.h index 7cf4210..986a320 100644 --- a/include/swupdate.h +++ b/include/swupdate.h @@ -52,7 +52,7 @@ struct swupdate_cfg { char output_swversions[SWUPDATE_GENERAL_STRING_SIZE]; char publickeyfname[SWUPDATE_GENERAL_STRING_SIZE]; char aeskeyfname[SWUPDATE_GENERAL_STRING_SIZE]; - char postupdatecmd[SWUPDATE_GENERAL_STRING_SIZE]; + char rebootcmd[SWUPDATE_GENERAL_STRING_SIZE]; char preupdatecmd[SWUPDATE_GENERAL_STRING_SIZE]; char minimum_version[SWUPDATE_GENERAL_STRING_SIZE]; char maximum_version[SWUPDATE_GENERAL_STRING_SIZE]; diff --git a/ipc/network_ipc.c b/ipc/network_ipc.c index e2fff78..d3cf8ac 100644 --- a/ipc/network_ipc.c +++ b/ipc/network_ipc.c @@ -61,7 +61,7 @@ static int prepare_ipc(void) { return connfd; } -int ipc_postupdate(ipc_message *msg) { +int ipc_reboot(ipc_message *msg) { int connfd = prepare_ipc(); if (connfd < 0) return -1; @@ -84,7 +84,7 @@ int ipc_postupdate(ipc_message *msg) { msg->data.procmsg.len = strnlen(tmpbuf, sizeof(msg->data.procmsg.buf) - 1); } msg->magic = IPC_MAGIC; - msg->type = POST_UPDATE; + msg->type = REBOOT; int result = write(connfd, msg, sizeof(*msg)) != sizeof(*msg) || read(connfd, msg, sizeof(*msg)) != sizeof(*msg); diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c index 1d636cd..027e544 100644 --- a/mongoose/mongoose_interface.c +++ b/mongoose/mongoose_interface.c @@ -69,7 +69,6 @@ struct parent_connection_info { unsigned long conn_id; }; -static bool run_postupdate; static unsigned int watchdog_conn = 0; static struct mg_http_serve_opts s_http_server_opts; const char *global_auth_domain; @@ -352,7 +351,7 @@ static void restart_handler(struct mg_connection *nc, void *ev_data) return; } - int ret = ipc_postupdate(&msg); + int ret = ipc_reboot(&msg); if (ret || msg.type != ACK) { mg_http_reply(nc, 500, "", "%s", "Failed to queue command\n"); return; @@ -490,10 +489,10 @@ static void *broadcast_progress_thread(void *data) broadcast(p, str); } - if (msg.status == SUCCESS && msg.source == SOURCE_WEBSERVER && run_postupdate) { + if (msg.status == SUCCESS && msg.source == SOURCE_WEBSERVER) { ipc_message ipc = {}; - ipc_postupdate(&ipc); + ipc_reboot(&ipc); } if (msg.infolen) { @@ -796,7 +795,6 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat if (strlen(tmp)) { opts->auth_domain = strdup(tmp); } - GET_FIELD_BOOL(LIBCFG_PARSER, elem, "run-postupdate", &run_postupdate); GET_FIELD_INT(LIBCFG_PARSER, elem, "timeout", (int *)&watchdog_conn); @@ -855,11 +853,6 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) /* No listing directory as default */ opts.listing = false; - /* - * Default value is active - */ - run_postupdate = true; - /* * Default no monitor of connection */ diff --git a/parser/parser.c b/parser/parser.c index f5113f9..fbbcd72 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -215,7 +215,6 @@ static bool get_common_fields(parsertype p, void *cfg, struct swupdate_cfg *swcf /* * As default, reboot is initiated */ - swcfg->reboot_required = true; if((setting = find_node(p, cfg, "reboot", swcfg)) != NULL) { GET_FIELD_BOOL(p, setting, NULL, &swcfg->reboot_required); } diff --git a/suricatta/server_hawkbit.c b/suricatta/server_hawkbit.c index 342670c..6255c67 100644 --- a/suricatta/server_hawkbit.c +++ b/suricatta/server_hawkbit.c @@ -1521,10 +1521,10 @@ cleanup: ERROR("JSON object should be freed but was not."); } if (result == SERVER_OK) { - INFO("Update successful, executing post-update actions."); + INFO("Update successful, rebooting the system."); ipc_message msg; memset(&msg, 0, sizeof(msg)); - if (ipc_postupdate(&msg) != 0) { + if (ipc_reboot(&msg) != 0) { result = SERVER_EERR; } else { result = msg.type == ACK ? SERVER_OK : SERVER_EERR; diff --git a/test/test_server_hawkbit.c b/test/test_server_hawkbit.c index fc4bb8f..13117a2 100644 --- a/test/test_server_hawkbit.c +++ b/test/test_server_hawkbit.c @@ -45,9 +45,9 @@ int __wrap_ipc_wait_for_complete(getstatus callback) return mock_type(RECOVERY_STATUS); } -extern int __real_ipc_postupdate(ipc_message *msg); -int __wrap_ipc_postupdate(ipc_message *msg); -int __wrap_ipc_postupdate(ipc_message *msg) { +extern int __real_ipc_rebootcmd(ipc_message *msg); +int __wrap_ipc_rebootcmd(ipc_message *msg); +int __wrap_ipc_rebootcmd(ipc_message *msg) { msg->type = ACK; return 0; } diff --git a/tools/swupdate-client.c b/tools/swupdate-client.c index 9ead836..427bd71 100644 --- a/tools/swupdate-client.c +++ b/tools/swupdate-client.c @@ -45,7 +45,6 @@ static void usage(void) { " -s <path> : path to swupdate IPC socket\n" " -q : go quiet, resets verbosity\n" " -v : go verbose, essentially print upgrade status messages from server\n" - " -p : ask the server to run post-update commands if upgrade succeeds\n" ); } @@ -53,7 +52,6 @@ char buf[256]; int fd = STDIN_FILENO; int verbose = 1; bool dry_run = false; -bool run_postupdate = false; int end_status = EXIT_SUCCESS; char *software_set = NULL, *running_mode = NULL; char *socketpath = NULL; @@ -96,23 +94,21 @@ static int printstatus(ipc_message *msg) /* * this is called at the end reporting the status - * of the upgrade and running any post-update actions - * if successful + * of the upgrade and performing a reboot on success if needed */ static int end(RECOVERY_STATUS status) { end_status = (status == SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE; - fprintf(stdout, "SWUpdate %s\n", - status == FAILURE ? "*failed* !" : - "was successful !"); + if (status == FAILURE) + ERROR("SWUpdate *failed* !"); + else + INFO("SWUpdate was successful !"); - if (status == SUCCESS && run_postupdate) { - fprintf(stdout, "Executing post-update actions.\n"); + if (status == SUCCESS) { ipc_message msg; msg.data.procmsg.len = 0; - if (ipc_postupdate(&msg) != 0 || msg.type != ACK) { - fprintf(stderr, "Running post-update failed!\n"); + if (ipc_reboot(&msg) != 0 || msg.type != ACK) { end_status = EXIT_FAILURE; } } @@ -210,9 +206,6 @@ int main(int argc, char *argv[]) { software_set = optarg; running_mode = pos; break; - case 'p': - run_postupdate = true; - break; case 's': socketpath = strdup(optarg); if(!socketpath) { @@ -240,4 +233,3 @@ int main(int argc, char *argv[]) { cleanup_and_exit(EXIT_SUCCESS); } - diff --git a/tools/swupdate-progress.c b/tools/swupdate-progress.c index 5e37162..26161db 100644 --- a/tools/swupdate-progress.c +++ b/tools/swupdate-progress.c @@ -18,7 +18,6 @@ #include <sys/stat.h> #include <sys/un.h> #include <sys/select.h> -#include <sys/reboot.h> #include <arpa/inet.h> #include <netinet/in.h> #include <pthread.h> @@ -62,7 +61,6 @@ static void textcolor(int attr, int fg, int bg) static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"psplash", no_argument, NULL, 'p'}, - {"reboot", no_argument, NULL, 'r'}, {"wait", no_argument, NULL, 'w'}, {"color", no_argument, NULL, 'c'}, {"socket", required_argument, NULL, 's'}, @@ -79,7 +77,6 @@ static void usage(char *programname) fprintf(stdout, " -c, --color : Use colors to show results\n" " -e, --exec <script> : call the script with the result of update\n" - " -r, --reboot : reboot after a successful update\n" " -w, --wait : wait for a connection with SWUpdate\n" " -p, --psplash : send info to the psplash process\n" " -s, --socket <path> : path to progress IPC socket\n" @@ -189,15 +186,6 @@ static void fill_progress_bar(char *bar, size_t size, unsigned int percent) memset(&bar[filled_len], '-', remain); } -static void reboot_device(void) -{ - sleep(5); - sync(); - if (reboot(RB_AUTOBOOT) < 0) { /* Should never happen. */ - fprintf(stdout, "Please reset the board.\n"); - } -} - static void run_post_script(char *script, struct progress_msg *msg) { char *cmd; @@ -227,12 +215,10 @@ int main(int argc, char **argv) char bar[bar_len+1]; int opt_c = 0; int opt_w = 0; - int opt_r = 0; int opt_p = 0; int c; char *script = NULL; bool wait_update = true; - bool disable_reboot = false; bool redirected = false; /* Process options with getopt */ @@ -248,9 +234,6 @@ int main(int argc, char **argv) case 'p': opt_p = 1; break; - case 'r': - opt_r = 1; - break; case 's': SOCKET_PROGRESS_PATH = strdup(optarg); break; @@ -339,30 +322,11 @@ int main(int argc, char **argv) * Be sure that string in message are Null terminated */ if (msg.infolen > 0) { - char reboot_mode[20] = { 0 }; - int n, cause; - if (msg.infolen >= sizeof(msg.info) - 1) { msg.infolen = sizeof(msg.info) - 1; } msg.info[msg.infolen] = '\0'; fprintf(stdout, "INFO : %s\n", msg.info); - - /* - * Check for no-reboot mode - * Just do a simple parsing for now. If more messages - * will be added, JSON lib should be linked. - * NOTE: Until then, the exact string format is imperative! - */ - n = sscanf(msg.info, "{\"%d\": { \"reboot-mode\" : \"%19[-a-z]\"}}", - &cause, reboot_mode); - if (n == 2) { - if (cause == CAUSE_REBOOT_MODE) { - if (!strcmp(reboot_mode, "no-reboot")) { - disable_reboot = true; - } - } - } } msg.cur_image[sizeof(msg.cur_image) - 1] = '\0'; @@ -422,22 +386,7 @@ int main(int argc, char **argv) psplash_progress(psplash_pipe_path, &msg); psplash_ok = 0; } - if (psplash_ok && disable_reboot) { - fprintf(stdout, - "\nReboot disabled or waiting for activation.\n"); - char *buf = alloca(PSPLASH_MSG_SIZE); - snprintf(buf, PSPLASH_MSG_SIZE - 1, - "MSG Reboot disabled or waiting for activation."); - psplash_write_fifo(psplash_pipe_path, buf); - } - if ((msg.status == SUCCESS) && (msg.cur_step > 0) && opt_r && !disable_reboot) { - reboot_device(); - } - /* - * Reset per update variables after update. - */ - disable_reboot = false; wait_update = true; break; case DONE: @@ -457,10 +406,6 @@ int main(int argc, char **argv) psplash_progress(psplash_pipe_path, &msg); psplash_ok = 0; } - if (opt_r && strcasestr(msg.info, "firmware")) { - reboot_device(); - break; - } fprintf(stdout, "\nDon't know how to activate this update, doing nothing.\n"); } break;
This patch tries to consolidate the reboot handling of SWUpdate. Currently, there are multiple places a reboot can be configured. Some use cases cannot be implemented with the current implementation. If one wants to differentiate per update if a reboot of the target is needed, this must be done with the swupdate-progress tool (or any other mechanism listening to the IPC socket). This eliminates the possibility to restart the target via the web interface (mongoose). The web interface triggers the post-update script if one is defined. Defining the post-update eliminates the use case where an update doesn't require a reboot of the target, because the post-update command is executed in any case. The patch tries to move the reboot handling to one place. This change has only been roughly tested so far. I would like to receive some feedback if this something you could imagine to merge in the future. If I missed some use cases (or anything else) - please let me know. Signed-off-by: Daniel Braunwarth <oss@braunwarth.dev> --- bindings/lua_swupdate.c | 4 +- core/install_from_file.c | 5 +-- core/installer.c | 27 ++++++++----- core/network_thread.c | 7 ++-- core/swupdate.c | 13 ++++--- corelib/downloader.c | 2 +- doc/source/bindings.rst | 2 +- doc/source/swupdate-client.rst | 2 - doc/source/swupdate-ipc-interface.rst | 4 +- doc/source/swupdate-progress.rst | 3 -- doc/source/swupdate.rst | 2 +- examples/configuration/swupdate.cfg | 7 +--- include/installer.h | 2 +- include/network_ipc.h | 4 +- include/swupdate.h | 2 +- ipc/network_ipc.c | 4 +- mongoose/mongoose_interface.c | 13 ++----- parser/parser.c | 1 - suricatta/server_hawkbit.c | 4 +- test/test_server_hawkbit.c | 6 +-- tools/swupdate-client.c | 22 ++++------- tools/swupdate-progress.c | 55 --------------------------- 22 files changed, 60 insertions(+), 131 deletions(-)