diff mbox series

[1/2] handler: add function to unregister the handler

Message ID 20240315092514.485906-1-stefano.babic@swupdate.org
State Accepted
Headers show
Series [1/2] handler: add function to unregister the handler | expand

Commit Message

Stefano Babic March 15, 2024, 9:25 a.m. UTC
Up now, handlers are instantiated when SWUpdate starts. Add a function
to unregister a handler that was set as temporary (noglobal flag) and
was instantiated during an install transaction.

This is to provide in future a way to add new handlers that are
transferred together with the SWU.

Signed-off-by: Stefano Babic <stefano.babic@swupdate.org>
---
 core/handler.c    | 54 +++++++++++++++++++++++++++++++++++++++++++++--
 include/handler.h | 27 ++++++++++++++++++++----
 2 files changed, 75 insertions(+), 6 deletions(-)

--
2.34.1
diff mbox series

Patch

diff --git a/core/handler.c b/core/handler.c
index d3862a33..74a211ac 100644
--- a/core/handler.c
+++ b/core/handler.c
@@ -21,8 +21,8 @@  struct installer_handler supported_types[MAX_INSTALLER_HANDLER];
 static unsigned long nr_installers = 0;
 static unsigned long handler_index = ULONG_MAX;

-int register_handler(const char *desc,
-		handler installer, HANDLER_MASK mask, void *data)
+static int __register_handler(const char *desc,
+		handler installer, HANDLER_MASK mask, void *data, handler_type_t lifetime)
 {
 	int i;

@@ -43,11 +43,61 @@  int register_handler(const char *desc,
 	supported_types[nr_installers].installer = installer;
 	supported_types[nr_installers].data = data;
 	supported_types[nr_installers].mask = mask;
+	supported_types[nr_installers].noglobal = (lifetime == SESSION_HANDLER);
 	nr_installers++;

 	return 0;
 }

+int register_handler(const char *desc,
+		handler installer, HANDLER_MASK mask, void *data)
+{
+	return __register_handler(desc, installer, mask, data, GLOBAL_HANDLER);
+}
+
+int register_session_handler(const char *desc,
+		handler installer, HANDLER_MASK mask, void *data)
+{
+	return __register_handler(desc, installer, mask, data, SESSION_HANDLER);
+}
+
+int unregister_handler(const char *desc)
+{
+	int i;
+
+	for (i = 0; i < nr_installers; i++) {
+		if ((strlen(desc) == strlen(supported_types[i].desc)) &&
+			IS_STR_EQUAL(desc, supported_types[i].desc)) {
+			break;
+		}
+	}
+
+	/* Not found */
+	if (i == nr_installers)
+		return -1;
+	for (int j = i + 1; j < nr_installers; j++) {
+		strlcpy(supported_types[j - 1].desc, supported_types[j].desc,
+		      sizeof(supported_types[j -1].desc));
+		supported_types[j - 1].installer = supported_types[j].installer;
+		supported_types[j - 1].data = supported_types[j].data;
+		supported_types[j - 1].mask = supported_types[j].mask;
+	}
+	nr_installers--;
+
+	return 0;
+}
+
+void unregister_session_handlers(void)
+{
+	int i;
+
+	for (i = nr_installers - 1; i >= 0; i--) {
+		if (supported_types[i].noglobal) {
+			unregister_handler(supported_types[i].desc);
+		}
+	}
+}
+
 void print_registered_handlers(void)
 {
 	unsigned int i;
diff --git a/include/handler.h b/include/handler.h
index 66529467..e100bd72 100644
--- a/include/handler.h
+++ b/include/handler.h
@@ -8,6 +8,8 @@ 

 #pragma once

+#include <stdbool.h>
+
 struct img_type;

 /*
@@ -36,16 +38,29 @@  typedef enum {
 	NO_DATA_HANDLER = 32
 } HANDLER_MASK;

+/*
+ * Life-cycle for the handler:
+ * GLOBAL : handler is instantiated at startup and available for all updates
+ * SESSION : handler is part of the SWU and available only for the current update
+ */
+
+typedef enum {
+	GLOBAL_HANDLER,
+	SESSION_HANDLER
+} handler_type_t;
+
 #define ANY_HANDLER (IMAGE_HANDLER | FILE_HANDLER | SCRIPT_HANDLER | \
 			BOOTLOADER_HANDLER | PARTITION_HANDLER | \
 			NO_DATA_HANDLER)

 typedef int (*handler)(struct img_type *img, void *data);
 struct installer_handler{
-	char	desc[64];
-	handler installer;
-	void	*data;
-	unsigned int mask;
+	char	desc[64];	/* Name that identifies the handler */
+	handler installer;	/* Handler function */
+	void	*data;		/* Private data for the handler */
+	unsigned int mask;	/* Mask (see HANDLER_MASK) */
+	bool	noglobal;	/* true if handler is not global and
+				   should be removed after install */
 };

 struct script_handler_data {
@@ -59,6 +74,10 @@  struct script_handler_data {

 int register_handler(const char *desc,
 		handler installer, HANDLER_MASK mask, void *data);
+int register_session_handler(const char *desc,
+		handler installer, HANDLER_MASK mask, void *data);
+int unregister_handler(const char *desc);
+void unregister_session_handlers(void);

 struct installer_handler *find_handler(struct img_type *img);
 void print_registered_handlers(void);