From 2ed4eeaada04ffd53f547119d917ce41f907314b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Szukie=C5=82oj=C4=87?= Date: Fri, 19 Feb 2016 23:21:25 +0100 Subject: [PATCH] Adding multipath info to output disk information This is all in one solution for parsing and interpretation of multipath devices Blueprint: multipath-disks-support Change-Id: I48095d0fa6ba52545a5bd5c72026100912c7c436 --- agent | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/agent b/agent index d624d0a..ab3c3f1 100755 --- a/agent +++ b/agent @@ -156,6 +156,7 @@ class NodeAgent @logger.info("API URL is #{@api_url}") @os = ohai_system_info @numa_topology = get_numa_topology + @mpath_devices, @skip_devices = multipath_devices end def get_scheme_and_port @@ -422,9 +423,21 @@ class NodeAgent begin Timeout::timeout(30) do @logger.debug("Trying to find block devices") + + # ohai reports the disk size according to /sys/block/#{bname} + # which is always measured in 512 bytes blocks, no matter what + # the physical (minimal unit which can be atomically written) + # or logical (minimal # unit which can be addressed) block sizes are, see + # http://lxr.free-electrons.com/source/include/linux/types.h?v=4.4#L124 + # http://lxr.free-electrons.com/source/drivers/scsi/sd.c?v=4.4#L2340 + block_size = 512 + (@os[:block_device] or {} rescue {}).each do |bname, binfo| @logger.debug("Found block device: #{bname}") @logger.debug("Block device info: #{binfo.inspect}") + dname = bname.gsub(/!/, '/') + next if @skip_devices.include?(dname) + if physical_data_storage_devices.map{|d| d[:name]}.include?(bname) && binfo @logger.debug("Block device seems to be physical data storage: #{bname}") block = physical_data_storage_devices.select{|d| d[:name] == bname}[0] @@ -436,22 +449,27 @@ class NodeAgent end @logger.debug("Block device #{bname} is accepted by PCI vendor ID") end - dname = bname.gsub(/!/, '/') - # ohai reports the disk size according to /sys/block/#{bname} - # which is always measured in 512 bytes blocks, no matter what - # the physical (minimal unit which can be atomically written) - # or logical (minimal # unit which can be addressed) block sizes are, see - # http://lxr.free-electrons.com/source/include/linux/types.h?v=4.4#L124 - # http://lxr.free-electrons.com/source/drivers/scsi/sd.c?v=4.4#L2340 - block_size = 512 detailed_meta[:disks] << { :name => dname, :model => binfo[:model], :size => (binfo[:size].to_i * block_size), :disk => block[:disk], :extra => block[:extra], - :removable => block[:removable] + :removable => block[:removable], + :paths => nil + } + + elsif @mpath_devices.has_key?(dname) + device = @mpath_devices[dname] + detailed_meta[:disks] << { + :name => 'mapper/' + device["DM_NAME"], + :model => binfo[:model], + :size => (binfo[:size].to_i * block_size), + :disk => dname, + :extra => _disk_id_by_name(dname), + :removable => 0, + :paths => device["DM_BLKDEVS_USED"].map{|name| _disk_path_by_name(name)}.join(', ') } end end @@ -464,6 +482,35 @@ class NodeAgent detailed_meta end + def multipath_devices + dmsetup = `/sbin/dmsetup info -c --nameprefixes --noheadings -o blkdevname,subsystem,blkdevs_used,name,uuid` + # Example output: + # DM_BLKDEVNAME='dm-0':DM_SUBSYSTEM='mpath':DM_BLKDEVS_USED='sdb,sda':DM_NAME='31234567890abcdef':DM_UUID='mpath-31234567890abcdef' + # DM_BLKDEVNAME='dm-1':DM_SUBSYSTEM='mpath':DM_BLKDEVS_USED='sdc,sdd':DM_NAME='92344567890abcdef':DM_UUID='mpath-92344567890abcdef' + + mpath_devices = {} + mapping = [] + unless dmsetup.include?("No devices found") + dmsetup.lines.each do |line| + device = {} + line.split(/:/).each do |key_value| + k, v = key_value.split('=') + device[k] = v.strip().gsub(/'/, '') + end + next unless device["DM_SUBSYSTEM"] == 'mpath' + device["DM_BLKDEVS_USED"] = device["DM_BLKDEVS_USED"].split(',') + device["DM_BLKDEVS_USED"].each do | name | + mapping << name + end + mpath_devices[device["DM_BLKDEVNAME"]] = device + end + end + [mpath_devices, mapping] + rescue => e + @logger.error("Error '#{e.message}' while scanning for multipath devices.") + [{}, []] + end + def _get_pci_vendor_id(devname) Timeout::timeout(30) do udevadm_walk = {}