mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	driver-core: extend dev_printk() to pass structured data
Extends dev_printk() to attach a dictionary with a device identifier
and the driver core subsystem name to logged messages, which makes
dev_prink() reliable machine-readable. In addition to the printed
plain text message, it creates these properties:
    SUBSYSTEM=     - the driver-core subsytem name
    DEVICE=
      b12:8        - block dev_t
      c127:3       - char dev_t
      n8           - netdev ifindex
      +sound:card0 - subsystem:devname
Tested-by: William Douglas <william.douglas@intel.com>
Signed-off-by: Kay Sievers <kay@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									e11fea92e1
								
							
						
					
					
						commit
						c4e00daaa9
					
				
					 1 changed files with 49 additions and 3 deletions
				
			
		| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
#include <linux/mutex.h>
 | 
					#include <linux/mutex.h>
 | 
				
			||||||
#include <linux/async.h>
 | 
					#include <linux/async.h>
 | 
				
			||||||
#include <linux/pm_runtime.h>
 | 
					#include <linux/pm_runtime.h>
 | 
				
			||||||
 | 
					#include <linux/netdevice.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "base.h"
 | 
					#include "base.h"
 | 
				
			||||||
#include "power/power.h"
 | 
					#include "power/power.h"
 | 
				
			||||||
| 
						 | 
					@ -1843,15 +1844,60 @@ void device_shutdown(void)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PRINTK
 | 
					#ifdef CONFIG_PRINTK
 | 
				
			||||||
 | 
					 | 
				
			||||||
int __dev_printk(const char *level, const struct device *dev,
 | 
					int __dev_printk(const char *level, const struct device *dev,
 | 
				
			||||||
		 struct va_format *vaf)
 | 
							 struct va_format *vaf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						char dict[128];
 | 
				
			||||||
 | 
						size_t dictlen = 0;
 | 
				
			||||||
 | 
						const char *subsys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!dev)
 | 
						if (!dev)
 | 
				
			||||||
		return printk("%s(NULL device *): %pV", level, vaf);
 | 
							return printk("%s(NULL device *): %pV", level, vaf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return printk("%s%s %s: %pV",
 | 
						if (dev->class)
 | 
				
			||||||
		      level, dev_driver_string(dev), dev_name(dev), vaf);
 | 
							subsys = dev->class->name;
 | 
				
			||||||
 | 
						else if (dev->bus)
 | 
				
			||||||
 | 
							subsys = dev->bus->name;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							goto skip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
 | 
				
			||||||
 | 
								    "SUBSYSTEM=%s", subsys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Add device identifier DEVICE=:
 | 
				
			||||||
 | 
						 *   b12:8         block dev_t
 | 
				
			||||||
 | 
						 *   c127:3        char dev_t
 | 
				
			||||||
 | 
						 *   n8            netdev ifindex
 | 
				
			||||||
 | 
						 *   +sound:card0  subsystem:devname
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (MAJOR(dev->devt)) {
 | 
				
			||||||
 | 
							char c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (strcmp(subsys, "block") == 0)
 | 
				
			||||||
 | 
								c = 'b';
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								c = 'c';
 | 
				
			||||||
 | 
							dictlen++;
 | 
				
			||||||
 | 
							dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
 | 
				
			||||||
 | 
									   "DEVICE=%c%u:%u",
 | 
				
			||||||
 | 
									   c, MAJOR(dev->devt), MINOR(dev->devt));
 | 
				
			||||||
 | 
						} else if (strcmp(subsys, "net") == 0) {
 | 
				
			||||||
 | 
							struct net_device *net = to_net_dev(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dictlen++;
 | 
				
			||||||
 | 
							dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
 | 
				
			||||||
 | 
									    "DEVICE=n%u", net->ifindex);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							dictlen++;
 | 
				
			||||||
 | 
							dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
 | 
				
			||||||
 | 
									    "DEVICE=+%s:%s", subsys, dev_name(dev));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					skip:
 | 
				
			||||||
 | 
						return printk_emit(0, level[1] - '0',
 | 
				
			||||||
 | 
								   dictlen ? dict : NULL, dictlen,
 | 
				
			||||||
 | 
								   "%s %s: %pV",
 | 
				
			||||||
 | 
								   dev_driver_string(dev), dev_name(dev), vaf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(__dev_printk);
 | 
					EXPORT_SYMBOL(__dev_printk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue