Accept removable block devices by PCI vendor ID
The issue is that, for particular raid controller obtaning vendor of block device from sysfs attributes is not realible. Once every raid controller is connected to PCI bus directly, it's more realible to look at vendor ID of that controller to which removable block device belongs. For example, Adaptec is a perfect canditate to be added to a list of removable PCI vendor IDs, since it's manufacturing RAID controllers mostly. Change-Id: Ib1018abbb46c65d909e594ad1d8921c8c5a139fc Related-Bug: #1486601
This commit is contained in:
parent
e01693992d
commit
d702795287
73
agent
73
agent
|
@ -46,6 +46,10 @@ STORAGE_CODES = [3, 8, 65, 66, 67, 68, 69, 70, 71, 104, 105, 106, 107, 108, 109,
|
|||
REMOVABLE_VENDORS = [
|
||||
"Adaptec", "IBM", "ServeRA",
|
||||
]
|
||||
# PCI vendor IDs for Adaptec
|
||||
REMOVABLE_PCI_VENDORS = [
|
||||
"0x1044", "0x9004", "0x9005",
|
||||
]
|
||||
|
||||
def digest(body)
|
||||
if body.is_a? Hash
|
||||
|
@ -357,7 +361,12 @@ class NodeAgent
|
|||
@logger.debug("Block device seems to be physical data storage: #{bname}")
|
||||
block = physical_data_storage_devices.select{|d| d[:name] == bname}[0]
|
||||
if block[:removable] =~ /^1$/ && ! REMOVABLE_VENDORS.include?(binfo[:vendor])
|
||||
next
|
||||
pci_vendor_id = _get_pci_vendor_id(bname)
|
||||
@logger.debug("Block device #{bname} is removable. PCI vendor ID: #{pci_vendor_id}")
|
||||
unless REMOVABLE_PCI_VENDORS.include?(pci_vendor_id)
|
||||
next
|
||||
end
|
||||
@logger.debug("Block device #{bname} is accepted by PCI vendor ID")
|
||||
end
|
||||
dname = bname.gsub(/!/, '/')
|
||||
|
||||
|
@ -385,6 +394,68 @@ class NodeAgent
|
|||
detailed_meta
|
||||
end
|
||||
|
||||
def _get_pci_vendor_id(devname)
|
||||
Timeout::timeout(30) do
|
||||
udevadm_walk = {}
|
||||
devpath = nil
|
||||
# expected output of `udevadm info --attribute-walk --name=#{devname}`:
|
||||
#
|
||||
# Udevadm info starts with the device specified by the devpath and then
|
||||
# walks up the chain of parent devices. It prints for every device
|
||||
# found, all possible attributes in the udev rules key format.
|
||||
# A rule to match, can be composed by the attributes of the device
|
||||
# and the attributes from one single parent device.
|
||||
#
|
||||
# looking at device '/devices/pci0000:00/0000:00:1e.0/0000:0d:02.0/8:0:0:1/block/sdc':
|
||||
# KERNEL=="sdc"
|
||||
# SUBSYSTEM=="block"
|
||||
# DRIVER==""
|
||||
# ATTR{ro}=="0"
|
||||
# ATTR{size}=="30881792"
|
||||
# ATTR{removable}=="1"
|
||||
#
|
||||
# looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:0d:02.0':
|
||||
# Disk adapter plugged into PCIe slot, we need it's PCI vendor ID
|
||||
# KERNELS=="0000:0d:02.0"
|
||||
# SUBSYSTEMS=="pci"
|
||||
# DRIVERS==""
|
||||
# ATTRS{device}=="0x9030"
|
||||
# ATTRS{vendor}=="0x10b5"
|
||||
#
|
||||
# looking at parent device '/devices/pci0000:00/0000:00:1e.0':
|
||||
# PCIe slot reported as a PCI bridge device, it's PCI vendor ID is NOT what we need
|
||||
# KERNELS=="0000:00:1e.0"
|
||||
# SUBSYSTEMS=="pci"
|
||||
# DRIVERS==""
|
||||
# ATTRS{device}=="0x244e"
|
||||
# ATTRS{vendor}=="0x8086"
|
||||
#
|
||||
# looking at parent device '/devices/pci0000:00':
|
||||
# KERNELS=="pci0000:00"
|
||||
# SUBSYSTEMS==""
|
||||
# DRIVERS==""
|
||||
`udevadm info --attribute-walk --name=#{devname}`.split("\n").each do |line|
|
||||
line.strip!
|
||||
next unless line.start_with?('looking', 'KERNEL', 'SUBSYSTEM', 'DRIVER', 'ATTR')
|
||||
if line.start_with?('looking')
|
||||
devpath = line.split("'")[1]
|
||||
udevadm_walk[devpath] = {}
|
||||
else
|
||||
key, value = line.split("==").each { |a| a.strip! }
|
||||
udevadm_walk[devpath][key] = value.gsub(/(^")|("$)/, '')
|
||||
end
|
||||
end
|
||||
# We need a vendor ID of a disk adapter rather than vendor ID of the PCIe slot where it's plugged into.
|
||||
# Therefore we should pick the device with SUBSYSTEMS==pci having the longest devpath.
|
||||
# For the example given above, vendor ID should be found as '0x10b5'.
|
||||
# Next ID of '0x8086' belongs to PCIe slot to which PCIe RAID disk adapter is inserted.
|
||||
devpath = Hash[udevadm_walk.select { |k, v| v['SUBSYSTEMS'] == 'pci' }].keys.max
|
||||
udevadm_walk[devpath]['ATTRS{vendor}']
|
||||
end
|
||||
rescue => e
|
||||
@logger.error("Error '#{e.message}' in obtaining PCI vendor ID: #{e.backtrace}")
|
||||
end
|
||||
|
||||
def _disk_id_by_name(name)
|
||||
dn = "/dev/disk/by-id"
|
||||
basepath = Dir["#{dn}/**?"].select{|f| /\/#{name}$/.match(File.readlink(f))}
|
||||
|
|
Loading…
Reference in New Issue