This patch intorduces cmdline netconsole configs to register to configfs
with dynamic netconsole. Satyam Sharma who designed shiny dynamic
reconfiguration for netconsole, mentioned about this issue already.
(http://lkml.org/lkml/2007/7/29/360)
But I think, without separately managing of two kind of netconsole target
objects, it's possible by using config_group instead of
config_item in the netconsole_target and default_groups feature of configfs.
Patch was tested with configuration creation/destruction by kernel and
module.
And it makes possible to enable/disable, modify and review netconsole
target configs from cmdline.
Signed-off-by: Joonwoo Park <[EMAIL PROTECTED]>
---
drivers/net/netconsole.c | 91 --
1 files changed, 72 insertions(+), 19 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 31e047d..63aabbb 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -93,7 +93,7 @@ static DEFINE_SPINLOCK(target_list_lock);
struct netconsole_target {
struct list_headlist;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
- struct config_item item;
+ struct config_group group;
#endif
int enabled;
struct netpoll np;
@@ -103,16 +103,49 @@ struct netconsole_target {
static struct configfs_subsystem netconsole_subsys;
-static int __init dynamic_netconsole_init(void)
+static void netconsole_target_put(struct netconsole_target *nt);
+static struct config_item_type netconsole_target_type;
+
+static int __init dynamic_netconsole_init(int defaults)
{
+ int err;
+ unsigned long flags;
config_group_init(&netconsole_subsys.su_group);
+
+ if (defaults > 0) {
+ struct list_head *pos;
+ struct config_group **groups;
+ int i = 0;
+
+ groups = kcalloc(defaults, sizeof(struct config_group *),
+ GFP_KERNEL);
+ if (!groups)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&target_list_lock, flags);
+ list_for_each(pos, &target_list) {
+ struct netconsole_target *nt;
+ nt = list_entry(pos, struct netconsole_target, list);
+ groups[i] = &nt->group;
+ i++;
+ }
+ spin_unlock_irqrestore(&target_list_lock, flags);
+ netconsole_subsys.su_group.default_groups = groups;
+ }
+
mutex_init(&netconsole_subsys.su_mutex);
- return configfs_register_subsystem(&netconsole_subsys);
+
+ err = configfs_register_subsystem(&netconsole_subsys);
+ if (err)
+ kfree(netconsole_subsys.su_group.default_groups);
+
+ return err;
}
static void __exit dynamic_netconsole_exit(void)
{
configfs_unregister_subsystem(&netconsole_subsys);
+ kfree(netconsole_subsys.su_group.default_groups);
}
/*
@@ -122,14 +155,23 @@ static void __exit dynamic_netconsole_exit(void)
*/
static void netconsole_target_get(struct netconsole_target *nt)
{
- if (config_item_name(&nt->item))
- config_item_get(&nt->item);
+ if (config_item_name(&nt->group.cg_item))
+ config_item_get(&nt->group.cg_item);
}
static void netconsole_target_put(struct netconsole_target *nt)
{
- if (config_item_name(&nt->item))
- config_item_put(&nt->item);
+ if (config_item_name(&nt->group.cg_item))
+ config_item_put(&nt->group.cg_item);
+}
+
+static void dynamic_netconsole_init_type_name(struct netconsole_target *nt,
+ int index)
+{
+ char name[16];
+ snprintf(name, sizeof(name), "netcon%d", index);
+ config_item_init_type_name(&nt->group.cg_item, name,
+ &netconsole_target_type);
}
#else /* !CONFIG_NETCONSOLE_DYNAMIC */
@@ -155,6 +197,11 @@ static void netconsole_target_put(struct netconsole_target
*nt)
{
}
+static void dynamic_netconsole_init_type_name(struct netconsole_target *nt,
+ int index)
+{
+}
+
#endif /* CONFIG_NETCONSOLE_DYNAMIC */
/* Allocate new target (from boot/module param) and setup netpoll for it */
@@ -236,8 +283,8 @@ struct netconsole_target_attr {
static struct netconsole_target *to_target(struct config_item *item)
{
return item ?
- container_of(item, struct netconsole_target, item) :
- NULL;
+ container_of(to_config_group(item), struct netconsole_target,
+ group) : NULL;
}
/*
@@ -370,7 +417,7 @@ static ssize_t store_dev_name(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
-