/ src / core / nvme.cc
nvme.cc
 1  #include "version.h"
 2  #include "hw.h"
 3  #include "sysfs.h"
 4  #include "osutils.h"
 5  #include "nvme.h"
 6  #include "disk.h"
 7  #include "heuristics.h"
 8  #include "options.h"
 9  
10  #include <vector>
11  #include <iostream>
12  
13  __ID("@(#) $Id$");
14  
15  using namespace std;
16  
17  bool scan_nvme(hwNode & n)
18  {
19    vector < sysfs::entry > entries = sysfs::entries_by_class("nvme");
20  
21    if (entries.empty())
22      return false;
23  
24    for (vector < sysfs::entry >::iterator it = entries.begin();
25        it != entries.end(); ++it)
26    {
27      const sysfs::entry & e = *it;
28  
29      hwNode *device = n.findChildByBusInfo(e.leaf().businfo());
30      if(!device) {
31        device = n.addChild(hwNode(e.name(), hw::storage));
32      }
33  
34      device->claim();
35      device->setLogicalName(e.name());
36      device->setDescription("NVMe device");
37      device->setProduct(e.string_attr("model"));
38      device->setSerial(e.string_attr("serial"));
39      device->setVersion(e.string_attr("firmware_rev"));
40      device->setConfig("nqn",::enabled("output:sanitize")?REMOVED:e.string_attr("subsysnqn"));
41      device->setConfig("state",e.string_attr("state"));
42      device->setModalias(e.modalias());
43  
44      vector < sysfs::entry > namespaces = e.devices();
45      for(vector < sysfs::entry >::iterator i = namespaces.begin(); i != namespaces.end(); ++i)
46      {
47        const sysfs::entry & n = *i;
48  
49        hwNode ns("namespace", hw::disk);
50        ns.claim();
51        ns.setBusInfo(guessBusInfo(n.name()));
52        ns.setPhysId(n.string_attr("nsid"));
53        ns.setDescription("NVMe disk");
54        // try to guess correct logical name when native NVMe multipath is enabled for NVMe devices
55        if(!exists("/dev/"+n.name()) &&
56  		      uppercase(hw::strip(get_string("/sys/module/nvme_core/parameters/multipath")))=="Y" &&
57  		      matches(n.name(), "^nvme[0-9]+c[0-9]+n[0-9]+$")) {
58  	      size_t indexc = n.name().find("c");
59  	      size_t indexn = n.name().find("n", indexc);
60  	      ns.setLogicalName(n.name().erase(indexc, indexn - indexc));
61        } else
62  	      ns.setLogicalName(n.name());
63        ns.setConfig("wwid",::enabled("output:sanitize")?REMOVED:n.string_attr("wwid"));
64        scan_disk(ns);
65        device->addChild(ns);
66      }
67    }
68  
69    return true;
70  }