summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBreno Leitao <leitao@debian.org>2025-06-09 02:46:27 -0700
committerJakub Kicinski <kuba@kernel.org>2025-06-10 14:21:53 -0700
commite99d938f867173937373b1bb08cbc2d102a07d0c (patch)
tree086caae56b98b6180914f451882776825050b0fc
parentbc0cb64db1c765a81f69997d5a28f539e1731bc0 (diff)
netconsole: Add automatic console unregistration on target removal
Add unregister_netcons_consoles() function to automatically unregister console handlers when no targets of the corresponding type remain active. The function iterates through the target list to determine which console types (basic vs extended) are still needed, and unregisters any console handlers that are no longer required. This prevents having registered console handlers without corresponding active targets. The function is called when a target is disabled and moved to the cleanup list, ensuring proper cleanup of unused console registrations. Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20250609-netcons_ext-v3-2-5336fa670326@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/netconsole.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 01baa45221b4..21077aff061c 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -460,6 +460,33 @@ static ssize_t sysdata_release_enabled_show(struct config_item *item,
return sysfs_emit(buf, "%d\n", release_enabled);
}
+/* Iterate in the list of target, and make sure we don't have any console
+ * register without targets of the same type
+ */
+static void unregister_netcons_consoles(void)
+{
+ struct netconsole_target *nt;
+ u32 console_type_needed = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&target_list_lock, flags);
+ list_for_each_entry(nt, &target_list, list) {
+ if (nt->extended)
+ console_type_needed |= CONS_EXTENDED;
+ else
+ console_type_needed |= CONS_BASIC;
+ }
+ spin_unlock_irqrestore(&target_list_lock, flags);
+
+ if (!(console_type_needed & CONS_EXTENDED) &&
+ console_is_registered(&netconsole_ext))
+ unregister_console(&netconsole_ext);
+
+ if (!(console_type_needed & CONS_BASIC) &&
+ console_is_registered(&netconsole))
+ unregister_console(&netconsole);
+}
+
/*
* This one is special -- targets created through the configfs interface
* are not enabled (and the corresponding netpoll activated) by default.
@@ -493,14 +520,18 @@ static ssize_t enabled_store(struct config_item *item,
goto out_unlock;
}
- if (nt->extended && !console_is_registered(&netconsole_ext))
+ if (nt->extended && !console_is_registered(&netconsole_ext)) {
+ netconsole_ext.flags |= CON_ENABLED;
register_console(&netconsole_ext);
+ }
/* User might be enabling the basic format target for the very
* first time, make sure the console is registered.
*/
- if (!nt->extended && !console_is_registered(&netconsole))
+ if (!nt->extended && !console_is_registered(&netconsole)) {
+ netconsole.flags |= CON_ENABLED;
register_console(&netconsole);
+ }
/*
* Skip netpoll_parse_options() -- all the attributes are
@@ -528,6 +559,10 @@ static ssize_t enabled_store(struct config_item *item,
list_move(&nt->list, &target_cleanup_list);
spin_unlock_irqrestore(&target_list_lock, flags);
mutex_unlock(&target_cleanup_list_lock);
+ /* Unregister consoles, whose the last target of that type got
+ * disabled.
+ */
+ unregister_netcons_consoles();
}
ret = strnlen(buf, count);