Browse Source

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
Krzysztof Szukiełojć 3 years ago
parent
commit
2ed4eeaada
1 changed files with 57 additions and 10 deletions
  1. 57
    10
      agent

+ 57
- 10
agent View File

@@ -156,6 +156,7 @@ class NodeAgent
156 156
     @logger.info("API URL is #{@api_url}")
157 157
     @os = ohai_system_info
158 158
     @numa_topology = get_numa_topology
159
+    @mpath_devices, @skip_devices = multipath_devices
159 160
   end
160 161
 
161 162
   def get_scheme_and_port
@@ -422,9 +423,21 @@ class NodeAgent
422 423
     begin
423 424
       Timeout::timeout(30) do
424 425
         @logger.debug("Trying to find block devices")
426
+
427
+        # ohai reports the disk size according to /sys/block/#{bname}
428
+        # which is always measured in 512 bytes blocks, no matter what
429
+        # the physical (minimal unit which can be atomically written)
430
+        # or logical (minimal # unit which can be addressed) block sizes are, see
431
+        # http://lxr.free-electrons.com/source/include/linux/types.h?v=4.4#L124
432
+        # http://lxr.free-electrons.com/source/drivers/scsi/sd.c?v=4.4#L2340
433
+        block_size = 512
434
+
425 435
         (@os[:block_device] or {} rescue {}).each do |bname, binfo|
426 436
           @logger.debug("Found block device: #{bname}")
427 437
           @logger.debug("Block device info: #{binfo.inspect}")
438
+          dname = bname.gsub(/!/, '/')
439
+          next if @skip_devices.include?(dname)
440
+
428 441
           if physical_data_storage_devices.map{|d| d[:name]}.include?(bname) && binfo
429 442
             @logger.debug("Block device seems to be physical data storage: #{bname}")
430 443
             block = physical_data_storage_devices.select{|d| d[:name] == bname}[0]
@@ -436,22 +449,27 @@ class NodeAgent
436 449
               end
437 450
               @logger.debug("Block device #{bname} is accepted by PCI vendor ID")
438 451
             end
439
-            dname = bname.gsub(/!/, '/')
440
-
441
-            # ohai reports the disk size according to /sys/block/#{bname}
442
-            # which is always measured in 512 bytes blocks, no matter what
443
-            # the physical (minimal unit which can be atomically written)
444
-            # or logical (minimal # unit which can be addressed) block sizes are, see
445
-            # http://lxr.free-electrons.com/source/include/linux/types.h?v=4.4#L124
446
-            # http://lxr.free-electrons.com/source/drivers/scsi/sd.c?v=4.4#L2340
447
-            block_size = 512
452
+
448 453
             detailed_meta[:disks] << {
449 454
               :name => dname,
450 455
               :model => binfo[:model],
451 456
               :size => (binfo[:size].to_i * block_size),
452 457
               :disk => block[:disk],
453 458
               :extra => block[:extra],
454
-              :removable => block[:removable]
459
+              :removable => block[:removable],
460
+              :paths => nil
461
+            }
462
+
463
+          elsif @mpath_devices.has_key?(dname)
464
+            device = @mpath_devices[dname]
465
+            detailed_meta[:disks] << {
466
+              :name => 'mapper/' + device["DM_NAME"],
467
+              :model => binfo[:model],
468
+              :size => (binfo[:size].to_i * block_size),
469
+              :disk => dname,
470
+              :extra => _disk_id_by_name(dname),
471
+              :removable => 0,
472
+              :paths => device["DM_BLKDEVS_USED"].map{|name| _disk_path_by_name(name)}.join(', ')
455 473
             }
456 474
           end
457 475
         end
@@ -464,6 +482,35 @@ class NodeAgent
464 482
     detailed_meta
465 483
   end
466 484
 
485
+  def multipath_devices
486
+    dmsetup = `/sbin/dmsetup info -c --nameprefixes --noheadings -o blkdevname,subsystem,blkdevs_used,name,uuid`
487
+    # Example output:
488
+    # DM_BLKDEVNAME='dm-0':DM_SUBSYSTEM='mpath':DM_BLKDEVS_USED='sdb,sda':DM_NAME='31234567890abcdef':DM_UUID='mpath-31234567890abcdef'
489
+    # DM_BLKDEVNAME='dm-1':DM_SUBSYSTEM='mpath':DM_BLKDEVS_USED='sdc,sdd':DM_NAME='92344567890abcdef':DM_UUID='mpath-92344567890abcdef'
490
+
491
+    mpath_devices = {}
492
+    mapping = []
493
+    unless dmsetup.include?("No devices found")
494
+      dmsetup.lines.each do |line|
495
+        device = {}
496
+        line.split(/:/).each do |key_value|
497
+          k, v = key_value.split('=')
498
+          device[k] = v.strip().gsub(/'/, '')
499
+        end
500
+        next unless device["DM_SUBSYSTEM"] == 'mpath'
501
+        device["DM_BLKDEVS_USED"] = device["DM_BLKDEVS_USED"].split(',')
502
+        device["DM_BLKDEVS_USED"].each do | name |
503
+          mapping << name
504
+        end
505
+        mpath_devices[device["DM_BLKDEVNAME"]] = device
506
+      end
507
+    end
508
+    [mpath_devices, mapping]
509
+  rescue => e
510
+    @logger.error("Error '#{e.message}' while scanning for multipath devices.")
511
+    [{}, []]
512
+  end
513
+
467 514
   def _get_pci_vendor_id(devname)
468 515
     Timeout::timeout(30) do
469 516
       udevadm_walk = {}

Loading…
Cancel
Save