[v2] swupdate: add pre-update command hook
diff mbox series

Message ID 20190923205500.13832-1-antoine.girard-vallee@savoirfairelinux.com
State Accepted
Headers show
Series
  • [v2] swupdate: add pre-update command hook
Related show

Commit Message

Antoine Girard-Vallée Sept. 23, 2019, 8:55 p.m. UTC
The --preupdate (-P) parameter allows to specify a command to run before
initiating the upgrade.

Signed-off-by: Antoine Girard-Vallée <antoine.girard-vallee@savoirfairelinux.com>
---
Change from v1
	- document -P
	- refactor postupdate and preupdatecmd to both use run_system_cmd()
	- do not run preupdatecmd when doing checks

 core/swupdate.c                     | 16 +++++++++++-
 corelib/installer.c                 | 38 +++++++++++++++++++++--------
 corelib/stream_interface.c          |  4 +++
 doc/source/swupdate.rst             |  2 ++
 examples/configuration/swupdate.cfg |  3 +++
 include/installer.h                 |  1 +
 include/swupdate.h                  |  1 +
 7 files changed, 54 insertions(+), 11 deletions(-)

Patch
diff mbox series

diff --git a/core/swupdate.c b/core/swupdate.c
index 1b5b914..38e5a56 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -108,6 +108,7 @@  static struct option long_options[] = {
 #endif
 	{"check", no_argument, NULL, 'c'},
 	{"postupdate", required_argument, NULL, 'p'},
+	{"preupdate", required_argument, NULL, 'P'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -124,6 +125,7 @@  static void usage(char *programname)
 		" -b, --blacklist <list of mtd>  : MTDs that must not be scanned for UBI\n"
 #endif
 		" -p, --postupdate               : execute post-update command\n"
+		" -P, --preupdate                : execute pre-update command\n"
 		" -e, --select <software>,<mode> : Select software images set and source\n"
 		"                                  Ex.: stable,main\n"
 		" -i, --image <filename>         : Software to be installed\n"
@@ -364,6 +366,12 @@  static int install_from_file(char *fname, int check)
 		exit(EXIT_SUCCESS);
 	}
 
+	ret = preupdatecmd(&swcfg);
+	if (ret) {
+		ERROR("Failed pre-update command!");
+		exit(EXIT_FAILURE);
+	}
+
 #ifdef CONFIG_MTD
 		mtd_cleanup();
 		scan_mtd_devices();
@@ -507,6 +515,8 @@  static int read_globals_settings(void *elem, void *data)
 				"mtd-blacklist", sw->globals.mtdblacklist);
 	GET_FIELD_STRING(LIBCFG_PARSER, elem,
 				"postupdatecmd", sw->globals.postupdatecmd);
+	GET_FIELD_STRING(LIBCFG_PARSER, elem,
+				"preupdatecmd", sw->globals.preupdatecmd);
 	get_field(LIBCFG_PARSER, elem, "verbose", &sw->globals.verbose);
 	get_field(LIBCFG_PARSER, elem, "loglevel", &sw->globals.loglevel);
 	get_field(LIBCFG_PARSER, elem, "syslog", &sw->globals.syslog_enabled);
@@ -610,7 +620,7 @@  int main(int argc, char **argv)
 #endif
 	memset(main_options, 0, sizeof(main_options));
 	memset(image_url, 0, sizeof(image_url));
-	strcpy(main_options, "vhni:e:l:Lcf:p:o:N:R:M");
+	strcpy(main_options, "vhni:e:l:Lcf:p:P:o:N:R:M");
 #ifdef CONFIG_MTD
 	strcat(main_options, "b:");
 #endif
@@ -823,6 +833,10 @@  int main(int argc, char **argv)
 			strncpy(swcfg.globals.postupdatecmd, optarg,
 				sizeof(swcfg.globals.postupdatecmd));
 			break;
+		case 'P':
+			strncpy(swcfg.globals.preupdatecmd, optarg,
+				sizeof(swcfg.globals.preupdatecmd));
+			break;
 		default:
 			usage(argv[0]);
 			exit(EXIT_FAILURE);
diff --git a/corelib/installer.c b/corelib/installer.c
index ff6cb18..b7d1e76 100644
--- a/corelib/installer.c
+++ b/corelib/installer.c
@@ -462,22 +462,40 @@  void cleanup_files(struct swupdate_cfg *software) {
 #endif
 }
 
-int postupdate(struct swupdate_cfg *swcfg, const char *info)
+static int run_system_cmd(const char *cmd, const char *desc)
 {
-	swupdate_progress_done(info);
-
-	if ((swcfg) && (strnlen(swcfg->globals.postupdatecmd,
-		     SWUPDATE_GENERAL_STRING_SIZE) > 0)) {
-		DEBUG("Executing post-update command '%s'",
-		      swcfg->globals.postupdatecmd);
-		int ret = system(swcfg->globals.postupdatecmd);
+	int ret = 0;
+	if ((strnlen(cmd, SWUPDATE_GENERAL_STRING_SIZE) > 0)
+		&& (strnlen(cmd, SWUPDATE_GENERAL_STRING_SIZE) < SWUPDATE_GENERAL_STRING_SIZE)) {
+		DEBUG("Running %s command '%s' ...", desc, cmd);
+		ret = system(cmd);
 		if (WIFEXITED(ret)) {
-			DEBUG("Post-update command returned %d", WEXITSTATUS(ret));
+			DEBUG("%s command returned %d", desc, WEXITSTATUS(ret));
 		} else {
-			ERROR("Post-update command returned %d: '%s'", ret, strerror(errno));
+			ERROR("%s command returned %d: '%s'", desc, ret, strerror(errno));
 			return -1;
 		}
 	}
 
+	return ret;
+}
+
+int preupdatecmd(struct swupdate_cfg *swcfg)
+{
+	if (swcfg) {
+		return run_system_cmd(swcfg->globals.preupdatecmd, "Pre-update");
+	}
+
+	return 0;
+}
+
+int postupdate(struct swupdate_cfg *swcfg, const char *info)
+{
+	swupdate_progress_done(info);
+
+	if ((swcfg) && (run_system_cmd(swcfg->globals.postupdatecmd, "Post-update") == -1)) {
+		return -1;
+	}
+
 	return 0;
 }
diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c
index f51ff68..b65627a 100644
--- a/corelib/stream_interface.c
+++ b/corelib/stream_interface.c
@@ -523,6 +523,10 @@  void *network_initializer(void *data)
 		}
 		close(inst.fd);
 
+		if (ret == 0) {
+			ret = preupdatecmd(software);
+		}
+
 		/* do carry out the installation (flash programming) */
 		if (ret == 0) {
 			TRACE("Valid image found: copying to FLASH");
diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst
index 1ff08ef..c9f30da 100644
--- a/doc/source/swupdate.rst
+++ b/doc/source/swupdate.rst
@@ -488,6 +488,8 @@  Command line parameters
 |             |          | referenced in sw-description are present.  |
 |             |          | Usage: swupdate -c -i <file>               |
 +-------------+----------+--------------------------------------------+
+| -P          | string   | Execute pre-update command.                |
++-------------+----------+--------------------------------------------+
 | -p          | string   | Execute post-update command.               |
 +-------------+----------+--------------------------------------------+
 +-------------+----------+--------------------------------------------+
diff --git a/examples/configuration/swupdate.cfg b/examples/configuration/swupdate.cfg
index 01e6955..632738a 100644
--- a/examples/configuration/swupdate.cfg
+++ b/examples/configuration/swupdate.cfg
@@ -23,6 +23,9 @@ 
 # aes-key-file		: string
 #			  file containing the symmetric key for
 #			  image decryption
+# preupdatecmd		: string
+#			  command to be executed right before the update
+#			  is installed
 # postupdatecmd		: string
 #			  command to be executed after a successful update
 globals :
diff --git a/include/installer.h b/include/installer.h
index 9956d7d..1351603 100644
--- a/include/installer.h
+++ b/include/installer.h
@@ -19,6 +19,7 @@  int check_if_required(struct imglist *list, struct filehdr *pfdh,
 int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile);
 int install_single_image(struct img_type *img, int dry_run);
 int postupdate(struct swupdate_cfg *swcfg, const char *info);
+int preupdatecmd(struct swupdate_cfg *swcfg);
 void cleanup_files(struct swupdate_cfg *software);
 
 #endif
diff --git a/include/swupdate.h b/include/swupdate.h
index 6f5ff22..b28504c 100644
--- a/include/swupdate.h
+++ b/include/swupdate.h
@@ -118,6 +118,7 @@  struct swupdate_global_cfg {
 	char publickeyfname[SWUPDATE_GENERAL_STRING_SIZE];
 	char aeskeyfname[SWUPDATE_GENERAL_STRING_SIZE];
 	char postupdatecmd[SWUPDATE_GENERAL_STRING_SIZE];
+	char preupdatecmd[SWUPDATE_GENERAL_STRING_SIZE];
 	char minimum_version[SWUPDATE_GENERAL_STRING_SIZE];
 	char current_version[SWUPDATE_GENERAL_STRING_SIZE];
 	int cert_purpose;