diff mbox series

[12/12] Send information to backend in case of on the fly updates

Message ID 20231016165740.1374614-12-stefano.babic@swupdate.org
State Changes Requested
Delegated to: Stefano Babic
Headers show
Series [01/12] Cleanup: use #pragma once in all headers | expand

Commit Message

Stefano Babic Oct. 16, 2023, 4:57 p.m. UTC
Not all updates require a reboot. In many cases, some parts of the
system are updated and a reboot is not necessary (on the fly update).
However, communication with the backend stops because software was
already installed successfully and to close the transaction, SWUpdate
had to be restarted.

To better support on on-the-fly updates, a new attribute "no-reboot" is
added. This is just to inform all processes registered with the progress
interface that a reboot at the end of the update is not necessary.
SWUpdate registers this attribute, and sends via IPC a message to the
suricatta module (currently, only Hawkbit is supported) to inform that
the update was successfully executed and the transaction can be closed.

After that, the suricatta module exits from the wait process and it is
able to receive further updates, too.

Signed-off-by: Stefano Babic <stefano.babic@swupdate.org>
---
 core/stream_interface.c | 41 +++++++++++++++++++++++++++++++++++++++++
 include/swupdate.h      |  1 +
 parser/parser.c         | 13 +++++++++++++
 3 files changed, 55 insertions(+)
diff mbox series

Patch

diff --git a/core/stream_interface.c b/core/stream_interface.c
index d9afa4af..f36319a3 100644
--- a/core/stream_interface.c
+++ b/core/stream_interface.c
@@ -660,6 +660,15 @@  void *network_initializer(void *data)
 			update_transaction_state(software, STATE_IN_PROGRESS);
 
 			notify(RUN, RECOVERY_NO_ERROR, INFOLEVEL, "Installation in progress");
+
+			/*
+			 * if this update is signalled to be without reboot (On the Fly),
+			 * send a notification via progress for processes responsible for booting
+			 */
+			if (!software->reboot_required) {
+				swupdate_progress_info(RUN, CAUSE_REBOOT_MODE , "no-reboot");
+			}
+
 			ret = install_images(software);
 			if (ret != 0) {
 				update_transaction_state(software, STATE_FAILED);
@@ -704,6 +713,38 @@  void *network_initializer(void *data)
 		pthread_mutex_unlock(&stream_mutex);
 		TRACE("Main thread sleep again !");
 		notify(IDLE, RECOVERY_NO_ERROR, INFOLEVEL, "Waiting for requests...");
+
+		/*
+		 * Last step, if no restart is required,
+		 * SWUpdate can send automatically the feedback.
+		 * They are running on separate processes and should first
+		 * know that the update is completed.
+		 * It seems safe enough to wait uncoditionally for some
+		 * time, enough to let all SWUpdate's processes to be scheduled,
+		 * before sending the IPC message
+		 */
+		if (req->source == SOURCE_SURICATTA &&
+		    /*simple check without JSON */ strstr(req->info, "hawkbit") &&
+		    !software->reboot_required) {
+			ipc_message msg;
+			size_t size = sizeof(msg.data.procmsg.buf);
+			char *buf = msg.data.procmsg.buf;
+			memset(&msg, 0, sizeof(msg));
+			msg.magic = IPC_MAGIC;
+			msg.data.procmsg.source = SOURCE_SURICATTA;
+			msg.data.procmsg.cmd = CMD_ACTIVATION;
+			msg.type = SWUPDATE_SUBPROCESS;
+			snprintf(buf, size, "{ \"status\" : \"%s\", \"finished\" : \"%s\" ,\"execution\" : \"%s\" ,\"details\" : [ ]}",
+				"1",
+				inst.last_install == SUCCESS ? "success" : "failure",
+				"closed"
+				 );
+			sleep(2);
+			TRACE("SEND CONCLUSION TO HAWKBIT");
+			ipc_send_cmd(&msg);
+		}
+
+
 	}
 
 	pthread_exit((void *)0);
diff --git a/include/swupdate.h b/include/swupdate.h
index 8f768a72..c1f86b36 100644
--- a/include/swupdate.h
+++ b/include/swupdate.h
@@ -70,6 +70,7 @@  struct swupdate_cfg {
 	bool no_reinstalling;
 	bool no_transaction_marker;
 	bool no_state_marker;
+	bool reboot_required;
 	bool check_max_version;
 	int verbose;
 	int loglevel;
diff --git a/parser/parser.c b/parser/parser.c
index cbb11962..46642a4d 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -214,6 +214,19 @@  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(p, setting, NULL, &swcfg->reboot_required);
+	}
+
+	TRACE("rebot_required %d", swcfg->reboot_required);
+
+	/*
+	 * Check if SWU should be cached
+	 */
 	if ((setting = find_node(p, cfg, "output", swcfg)) != NULL) {
 		if (!strlen(swcfg->output)) {
 			TRACE("Output file set but not enabled with -o, ignored");