diff options
Diffstat (limited to 'drivers/net/netconsole.c')
| -rw-r--r-- | drivers/net/netconsole.c | 80 | 
1 files changed, 39 insertions, 41 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index dcb21347c67..ba2f5e710af 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -34,6 +34,8 @@   *   ****************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/mm.h>  #include <linux/init.h>  #include <linux/module.h> @@ -310,6 +312,7 @@ static ssize_t store_enabled(struct netconsole_target *nt,  			     const char *buf,  			     size_t count)  { +	unsigned long flags;  	int enabled;  	int err; @@ -319,14 +322,12 @@ static ssize_t store_enabled(struct netconsole_target *nt,  	if (enabled < 0 || enabled > 1)  		return -EINVAL;  	if (enabled == nt->enabled) { -		printk(KERN_INFO "netconsole: network logging has already %s\n", -				nt->enabled ? "started" : "stopped"); +		pr_info("network logging has already %s\n", +			nt->enabled ? "started" : "stopped");  		return -EINVAL;  	} -	mutex_lock(&nt->mutex);  	if (enabled) {	/* 1 */ -  		/*  		 * Skip netpoll_parse_options() -- all the attributes are  		 * already configured via configfs. Just print them out. @@ -334,19 +335,22 @@ static ssize_t store_enabled(struct netconsole_target *nt,  		netpoll_print_options(&nt->np);  		err = netpoll_setup(&nt->np); -		if (err) { -			mutex_unlock(&nt->mutex); +		if (err)  			return err; -		} - -		printk(KERN_INFO "netconsole: network logging started\n"); +		pr_info("netconsole: network logging started\n");  	} else {	/* 0 */ +		/* We need to disable the netconsole before cleaning it up +		 * otherwise we might end up in write_msg() with +		 * nt->np.dev == NULL and nt->enabled == 1 +		 */ +		spin_lock_irqsave(&target_list_lock, flags); +		nt->enabled = 0; +		spin_unlock_irqrestore(&target_list_lock, flags);  		netpoll_cleanup(&nt->np);  	}  	nt->enabled = enabled; -	mutex_unlock(&nt->mutex);  	return strnlen(buf, count);  } @@ -358,9 +362,8 @@ static ssize_t store_dev_name(struct netconsole_target *nt,  	size_t len;  	if (nt->enabled) { -		printk(KERN_ERR "netconsole: target (%s) is enabled, " -				"disable to update parameters\n", -				config_item_name(&nt->item)); +		pr_err("target (%s) is enabled, disable to update parameters\n", +		       config_item_name(&nt->item));  		return -EINVAL;  	} @@ -381,9 +384,8 @@ static ssize_t store_local_port(struct netconsole_target *nt,  	int rv;  	if (nt->enabled) { -		printk(KERN_ERR "netconsole: target (%s) is enabled, " -				"disable to update parameters\n", -				config_item_name(&nt->item)); +		pr_err("target (%s) is enabled, disable to update parameters\n", +		       config_item_name(&nt->item));  		return -EINVAL;  	} @@ -400,9 +402,8 @@ static ssize_t store_remote_port(struct netconsole_target *nt,  	int rv;  	if (nt->enabled) { -		printk(KERN_ERR "netconsole: target (%s) is enabled, " -				"disable to update parameters\n", -				config_item_name(&nt->item)); +		pr_err("target (%s) is enabled, disable to update parameters\n", +		       config_item_name(&nt->item));  		return -EINVAL;  	} @@ -417,9 +418,8 @@ static ssize_t store_local_ip(struct netconsole_target *nt,  			      size_t count)  {  	if (nt->enabled) { -		printk(KERN_ERR "netconsole: target (%s) is enabled, " -				"disable to update parameters\n", -				config_item_name(&nt->item)); +		pr_err("target (%s) is enabled, disable to update parameters\n", +		       config_item_name(&nt->item));  		return -EINVAL;  	} @@ -427,7 +427,7 @@ static ssize_t store_local_ip(struct netconsole_target *nt,  		const char *end;  		if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {  			if (*end && *end != '\n') { -				printk(KERN_ERR "netconsole: invalid IPv6 address at: <%c>\n", *end); +				pr_err("invalid IPv6 address at: <%c>\n", *end);  				return -EINVAL;  			}  			nt->np.ipv6 = true; @@ -448,9 +448,8 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,  			       size_t count)  {  	if (nt->enabled) { -		printk(KERN_ERR "netconsole: target (%s) is enabled, " -				"disable to update parameters\n", -				config_item_name(&nt->item)); +		pr_err("target (%s) is enabled, disable to update parameters\n", +		       config_item_name(&nt->item));  		return -EINVAL;  	} @@ -458,7 +457,7 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,  		const char *end;  		if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {  			if (*end && *end != '\n') { -				printk(KERN_ERR "netconsole: invalid IPv6 address at: <%c>\n", *end); +				pr_err("invalid IPv6 address at: <%c>\n", *end);  				return -EINVAL;  			}  			nt->np.ipv6 = true; @@ -481,9 +480,8 @@ static ssize_t store_remote_mac(struct netconsole_target *nt,  	u8 remote_mac[ETH_ALEN];  	if (nt->enabled) { -		printk(KERN_ERR "netconsole: target (%s) is enabled, " -				"disable to update parameters\n", -				config_item_name(&nt->item)); +		pr_err("target (%s) is enabled, disable to update parameters\n", +		       config_item_name(&nt->item));  		return -EINVAL;  	} @@ -563,8 +561,10 @@ static ssize_t netconsole_target_attr_store(struct config_item *item,  	struct netconsole_target_attr *na =  		container_of(attr, struct netconsole_target_attr, attr); +	mutex_lock(&nt->mutex);  	if (na->store)  		ret = na->store(nt, buf, count); +	mutex_unlock(&nt->mutex);  	return ret;  } @@ -684,15 +684,12 @@ restart:  			case NETDEV_RELEASE:  			case NETDEV_JOIN:  			case NETDEV_UNREGISTER: -				/* -				 * rtnl_lock already held +				/* rtnl_lock already held  				 * we might sleep in __netpoll_cleanup()  				 */  				spin_unlock_irqrestore(&target_list_lock, flags); -				mutex_lock(&nt->mutex);  				__netpoll_cleanup(&nt->np); -				mutex_unlock(&nt->mutex);  				spin_lock_irqsave(&target_list_lock, flags);  				dev_put(nt->np.dev); @@ -707,19 +704,20 @@ restart:  	}  	spin_unlock_irqrestore(&target_list_lock, flags);  	if (stopped) { -		printk(KERN_INFO "netconsole: network logging stopped on " -		       "interface %s as it ", dev->name); +		const char *msg = "had an event";  		switch (event) {  		case NETDEV_UNREGISTER: -			printk(KERN_CONT "unregistered\n"); +			msg = "unregistered";  			break;  		case NETDEV_RELEASE: -			printk(KERN_CONT "released slaves\n"); +			msg = "released slaves";  			break;  		case NETDEV_JOIN: -			printk(KERN_CONT "is joining a master device\n"); +			msg = "is joining a master device";  			break;  		} +		pr_info("network logging stopped on interface %s as it %s\n", +			dev->name, msg);  	}  done: @@ -805,7 +803,7 @@ static int __init init_netconsole(void)  		goto undonotifier;  	register_console(&netconsole); -	printk(KERN_INFO "netconsole: network logging started\n"); +	pr_info("network logging started\n");  	return err; @@ -813,7 +811,7 @@ undonotifier:  	unregister_netdevice_notifier(&netconsole_netdev_notifier);  fail: -	printk(KERN_ERR "netconsole: cleaning up\n"); +	pr_err("cleaning up\n");  	/*  	 * Remove all targets and destroy them (only targets created  | 
