Thread (43 messages) flat view 43 messages, 5 authors, 2007-07-07

Re: [PATCH -mm 9/9] netconsole: Support dynamic reconfiguration using configfs

From: Joel Becker <hidden>
Date: 2007-07-07 06:02:01
Also in: lkml

On Wed, Jul 04, 2007 at 04:38:24PM +0530, Satyam Sharma wrote:
 struct netconsole_target {
 	struct list_head	list;
+	struct config_item	item;
+	int			id;
+	int			enabled;
 	int			dev_status;
 	struct netpoll		np;
 };
	If you're trying to be good with your CONFIG_NETCONSOLE_DYNAMIC
ifdefs, you probably want to ifdef the item.  You'll save space when
NETCONSOLE_DYNAMIC is off.
+#ifdef	CONFIG_NETCONSOLE_DYNAMIC
+
+/*
+ * Targets that were created by parsing the boot/module option string
+ * do not exist in the configfs hierarchy and will never go away (and
+ * have zeroed-out config_item members). So make these a no-op for them.
+ */
+static void netconsole_target_get(struct netconsole_target *nt)
+{
+	static struct config_item empty_item;	/* Zeroed-out config_item */
+
+	if (memcmp(&nt->item, &empty_item, sizeof(struct config_item)))
+		config_item_get(&nt->item);
+}
	I was going to point out that you could merely check
config_item_name(&nt->item) != NULL, because a valid configfs object has
a name and your zeroed object does not.  But your followup email
suggests you'll be removing this code anyway.
	I don't, off the top of my head, see a problem with removing the
_get/_put cycle, because you do have them under the spinlock.  Things
should behave correctly.  However, the _get/_put pair is "cleaner", in
that it expresses the relationship and doesn't add a special case of "I
happen to know this is safe".
+ * Our subsystem hierarchy is:
+ *
+ * /config/netconsole/
+ *		     |
+ *		     <target>/
+ *		     |	     id
+ *		     |	     enabled
	Your configfs bits seem to be pretty straightforward.
+		/*
+		 * Skip netpoll_parse_options() -- all the attributes are
+		 * already configured in nt->np through configfs. But at
+		 * least let's print the useful stuff it used to output :-)
+		 */
+		printk(KERN_INFO "%s: local port %d\n",
+				 np->name, np->local_port);
+		printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
+				 np->name, HIPQUAD(np->local_ip));
+		printk(KERN_INFO "%s: interface %s\n",
+				 np->name, np->dev_name);
+		printk(KERN_INFO "%s: remote port %d\n",
+				 np->name, np->remote_port);
+		printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
+				 np->name, HIPQUAD(np->remote_ip));
+		printk(KERN_INFO "%s: remote ethernet address "
+				 "%02x:%02x:%02x:%02x:%02x:%02x\n",
+				 np->name,
+				 np->remote_mac[0], np->remote_mac[1],
+				 np->remote_mac[2], np->remote_mac[3],
+				 np->remote_mac[4], np->remote_mac[5]);
	Shouldn't you break this out into a function so that both places
can use it?
+#define NETCONSOLE_TARGET_ATTR_RO(_name)				\
+static struct netconsole_target_attr netconsole_target_##_name =	\
+__CONFIGFS_ATTR(_name, S_IRUGO, show_##_name, NULL)
+
+#define NETCONSOLE_TARGET_ATTR_RW(_name)				\
+static struct netconsole_target_attr netconsole_target_##_name =	\
+__CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name)
	Perhaps an indent would be clearer, but that's a tiny nitpick.
 	/*
-	 * Neither the netdev notifier, nor the console have been
-	 * registered so far. Nobody's racing us, so skip the lock.
+	 * Neither the netdev notifier, not the configfs subsystem and
+	 * nor the console have been registered so far. Nobody's racing us,
+	 * so skip the lock.
	Once again, while you know you can skip the lock, it's unclear
without the comment.  Perhaps using the lock makes it explicitly
"correct"?  Food for thought.
quoted hunk ↗ jump to hunk
@@ -251,6 +796,17 @@ static int __init init_netconsole(void)
 	if (err)
 		goto fail;
 
+#ifdef	CONFIG_NETCONSOLE_DYNAMIC
+	config_group_init(&netconsole_subsys.su_group);
+	mutex_init(&netconsole_subsys.su_mtx);
+
+	err = configfs_register_subsystem(&netconsole_subsys);
+	if (err) {
+		unregister_netdevice_notifier(&netconsole_netdev_notifier);
+		goto fail;
+	}
+#endif	/* CONFIG_NETCONSOLE_DYNAMIC */
	I'd abstract this to a dynamic_init() function.
+
+#ifdef	CONFIG_NETCONSOLE_DYNAMIC
+	configfs_unregister_subsystem(&netconsole_subsys);
+#endif	/* CONFIG_NETCONSOLE_DYNAMIC */
+
	and this to an dynamic_fini() function.  Basically, do what you
did with _get()/_put().  This keeps the ifdef up above and out of the
functions themselves.

#ifdef CONFIG_NETCONSOLE_DYNAMIC
static int __init dynamic_netconsole_init(void)
{
	config_group_init(&netconsole_subsys.su_group);
	mutex_init(&netconsole_subsys.su_mtx);
	return configfs_register_subsystem(&netconsole_subsys);
}
#else
static int __init dynamic_netconsole_init(void)
{
	return 0;
}
#endif   


Joel

-- 

Life's Little Instruction Book #3

	"Watch a sunrise at least once a year."

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help