From 8fbc4d640535387b402aa38cb6227df11c010ff0 Mon Sep 17 00:00:00 2001 From: Vladimir Kozhukalov Date: Wed, 4 Jan 2017 19:37:10 +0300 Subject: [PATCH] Fix multipath device search When nailgun-agent starts before device mapper assembles multipath devices it reports physical disks that are used for multipath devices as usual disks. This patch does the following * filter out devices that are DM_MULTIPATH_DEVICE_PATH = 1 * run 'udevadm settle' before scanning multipath devices * delays scanning multipath devices until building block device info Change-Id: I088aede0cf3bd1d16a57e7cdec4e50cab2c19175 Closes-Bug: #1652788 --- agent | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/agent b/agent index 2471814..d9206d0 100755 --- a/agent +++ b/agent @@ -167,7 +167,6 @@ class NodeAgent @facter = facter_system_info @network = _network @numa_topology = get_numa_topology - @mpath_devices, @skip_devices = multipath_devices end def get_scheme_and_port @@ -721,11 +720,13 @@ class NodeAgent # http://lxr.free-electrons.com/source/drivers/scsi/sd.c?v=4.4#L2340 block_size = 512 + mpath_devices, skip_devices = _multipath_devices + (_get_blkdev_info 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) + 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}") @@ -749,8 +750,8 @@ class NodeAgent :paths => nil } - elsif @mpath_devices.has_key?(dname) - device = @mpath_devices[dname] + elsif mpath_devices.has_key?(dname) + device = mpath_devices[dname] detailed_meta[:disks] << { :name => 'mapper/' + device["DM_NAME"], :model => binfo[:model], @@ -781,8 +782,13 @@ class NodeAgent [nil, nil] end - def multipath_devices - dmsetup = `/sbin/dmsetup info -c --nameprefixes --noheadings -o blkdevname,subsystem,blkdevs_used,name,uuid` + def _multipath_devices + @logger.debug("Waiting for udev to complete evaluating rules") + `udevadm settle` + + dmsetup_command = "/sbin/dmsetup info -c --nameprefixes --noheadings -o blkdevname,subsystem,blkdevs_used,name,uuid" + @logger.debug("Running command: #{dmsetup_command}") + dmsetup = `#{dmsetup_command}` # 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' @@ -803,7 +809,10 @@ class NodeAgent end mpath_devices[device["DM_BLKDEVNAME"]] = device end + mapping.uniq! end + @logger.debug("Multipath devices: #{mpath_devices}") + @logger.debug("Physical devices that are used in multipath devices: #{mapping}") [mpath_devices, mapping] rescue => e @logger.error("Error '#{e.message}' while scanning for multipath devices.") @@ -987,6 +996,9 @@ class NodeAgent end @logger.debug("Device #{devname} udev properties: #{properties.inspect}") + @logger.debug("Filtering out devices that are used in multipath devices: 'DM_MULTIPATH_DEVICE_PATH' = '1'") + next if properties['DM_MULTIPATH_DEVICE_PATH'] == '1' + @logger.debug("Trying to find out if device #{devname} is removable or not") if File.exists?("/sys/block/#{basename_dir}/removable") removable = File.open("/sys/block/#{basename_dir}/removable"){ |f| f.read_nonblock(1024).strip } @@ -994,18 +1006,20 @@ class NodeAgent @logger.debug("Device #{devname} removable parameter: #{removable.inspect}") if STORAGE_CODES.include?(properties['MAJOR'].to_i) - @logger.debug("Device #{devname} seems to be appropriate") # Exclude LVM volumes (in CentOS - 253, in Ubuntu - 252) using additional check # Exclude any storage device connected through USB by the default + @logger.debug("Trying to exclude LVM volumes and USB devices") next if properties['DEVPATH'].include?('virtual/block/dm') || (properties['ID_BUS'] == 'usb' && !@settings.has_key?("report_usb_block_devices")) - @blocks << { - :name => basename_dir, - :disk => _disk_path_by_name(devname) || devname, - :extra => _disk_id_by_name(devname) || [], - :removable => removable, - } + + @logger.debug("Device #{devname} seems to be appropriate") + @blocks << { + :name => basename_dir, + :disk => _disk_path_by_name(devname) || devname, + :extra => _disk_id_by_name(devname) || [], + :removable => removable, + } end end @logger.debug("Final list of physical devices is: #{@blocks.inspect}")