Commit c4e00daaa96d3a0786f1f4fe6456281c60ef9a16

Authored by Kay Sievers
Committed by Greg Kroah-Hartman
1 parent e11fea92e1

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>

Showing 1 changed file with 49 additions and 3 deletions Side-by-side Diff

... ... @@ -25,6 +25,7 @@
25 25 #include <linux/mutex.h>
26 26 #include <linux/async.h>
27 27 #include <linux/pm_runtime.h>
  28 +#include <linux/netdevice.h>
28 29  
29 30 #include "base.h"
30 31 #include "power/power.h"
31 32  
32 33  
... ... @@ -1843,15 +1844,60 @@
1843 1844 */
1844 1845  
1845 1846 #ifdef CONFIG_PRINTK
1846   -
1847 1847 int __dev_printk(const char *level, const struct device *dev,
1848 1848 struct va_format *vaf)
1849 1849 {
  1850 + char dict[128];
  1851 + size_t dictlen = 0;
  1852 + const char *subsys;
  1853 +
1850 1854 if (!dev)
1851 1855 return printk("%s(NULL device *): %pV", level, vaf);
1852 1856  
1853   - return printk("%s%s %s: %pV",
1854   - level, dev_driver_string(dev), dev_name(dev), vaf);
  1857 + if (dev->class)
  1858 + subsys = dev->class->name;
  1859 + else if (dev->bus)
  1860 + subsys = dev->bus->name;
  1861 + else
  1862 + goto skip;
  1863 +
  1864 + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
  1865 + "SUBSYSTEM=%s", subsys);
  1866 +
  1867 + /*
  1868 + * Add device identifier DEVICE=:
  1869 + * b12:8 block dev_t
  1870 + * c127:3 char dev_t
  1871 + * n8 netdev ifindex
  1872 + * +sound:card0 subsystem:devname
  1873 + */
  1874 + if (MAJOR(dev->devt)) {
  1875 + char c;
  1876 +
  1877 + if (strcmp(subsys, "block") == 0)
  1878 + c = 'b';
  1879 + else
  1880 + c = 'c';
  1881 + dictlen++;
  1882 + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
  1883 + "DEVICE=%c%u:%u",
  1884 + c, MAJOR(dev->devt), MINOR(dev->devt));
  1885 + } else if (strcmp(subsys, "net") == 0) {
  1886 + struct net_device *net = to_net_dev(dev);
  1887 +
  1888 + dictlen++;
  1889 + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
  1890 + "DEVICE=n%u", net->ifindex);
  1891 + } else {
  1892 + dictlen++;
  1893 + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
  1894 + "DEVICE=+%s:%s", subsys, dev_name(dev));
  1895 + }
  1896 +skip:
  1897 + return printk_emit(0, level[1] - '0',
  1898 + dictlen ? dict : NULL, dictlen,
  1899 + "%s %s: %pV",
  1900 + dev_driver_string(dev), dev_name(dev), vaf);
1855 1901 }
1856 1902 EXPORT_SYMBOL(__dev_printk);
1857 1903