@@ -67,14 +67,54 @@ def setUp(self):
6767 package )
6868 # get the disk name
6969 self .disk_name = ''
70+ self .is_multipath = False
7071 output = process .system_output ("df -h" , shell = True ).decode ().splitlines ()
71- filtered_lines = [line for line in output if re .search (r'\b(sd[a-z]\d+|vd[a-z]\d+|nvme\d+n\d+p\d+)\b' , line )]
72+ # Match standard disks (sda1, vda1, nvme0n1p1) and multipath devices (mpatha-part2, mpath0p1)
73+ filtered_lines = [line for line in output if re .search (r'\b(sd[a-z]\d+|vd[a-z]\d+|nvme\d+n\d+p\d+|mpath[a-z0-9]+-part\d+|mpath[a-z0-9]+p\d+)\b' , line )]
7274 if filtered_lines :
7375 disk_entry = filtered_lines [- 1 ].split ()[0 ]
74- # Strip partition number: for sdX or vdX it’s trailing digits, for nvme it’s after 'p'
75- self .disk_name = re .sub (r'(\d+$|p\d+$)' , '' , disk_entry )
76+ # Strip partition number: for sdX/vdX it's trailing digits, for nvme it's after 'p', for multipath it's after '-part' or 'p'
77+ if '/dev/mapper/' in disk_entry :
78+ # For multipath devices like /dev/mapper/mpatha-part2, extract mpatha
79+ self .disk_name = re .sub (r'(-part\d+|p\d+)$' , '' , disk_entry )
80+ self .is_multipath = True
81+ else :
82+ self .disk_name = re .sub (r'(\d+$|p\d+$)' , '' , disk_entry )
7683 if not self .disk_name :
7784 self .cancel ("Couldn't get Disk name." )
85+
86+ # For multipath devices, find the underlying physical disk
87+ if self .is_multipath :
88+ try :
89+ # Try to get underlying disk using multipath command
90+ mpath_name = self .disk_name .split ('/' )[- 1 ] # Extract mpatha from /dev/mapper/mpatha
91+ mp_output = process .system_output (f"multipath -ll { mpath_name } " ,
92+ shell = True , ignore_status = True ).decode ()
93+ # Parse multipath output to find physical disk (e.g., sda, sdb)
94+ # Format: `- 1:0:0:2 sda 8:0 active ready running
95+ for line in mp_output .splitlines ():
96+ match = re .search (r'\s+(sd[a-z]+|vd[a-z]+|nvme\d+n\d+)\s+' , line )
97+ if match :
98+ physical_disk = match .group (1 ).strip ()
99+ self .disk_name = f"/dev/{ physical_disk } "
100+ self .is_multipath = False
101+ break
102+ except Exception :
103+ # If multipath command fails, try dmsetup
104+ try :
105+ dm_output = process .system_output (f"dmsetup deps { mpath_name } " ,
106+ shell = True , ignore_status = True ).decode ()
107+ # dmsetup deps output: 1 dependencies : (8, 0)
108+ # We need to find which device has this major:minor
109+ if 'dependencies' in dm_output :
110+ # Just try to find any sd* device as fallback
111+ all_disks = process .system_output ("ls /dev/sd* /dev/vd* 2>/dev/null | head -1" ,
112+ shell = True , ignore_status = True ).decode ().strip ()
113+ if all_disks :
114+ self .disk_name = all_disks .splitlines ()[0 ]
115+ self .is_multipath = False
116+ except Exception :
117+ pass
78118
79119 @staticmethod
80120 def run_cmd_out (cmd ):
@@ -368,11 +408,15 @@ def test_ls_vdev(self):
368408 self .run_cmd ("ls-vdev" )
369409 self .run_cmd ("ls-vdev -h" )
370410 self .run_cmd ("ls-vdev -V" )
371- dev_name = self .run_cmd_out ("ls-vdev" ).split ()[1 ]
372- lsblk_disks = disk .get_disks ()
373- lsblk_dev_name = [i .replace ('/dev/' , '' ) for i in lsblk_disks ]
374- if dev_name .strip () not in lsblk_dev_name :
375- self .is_fail += 1
411+ output = self .run_cmd_out ("ls-vdev" ).split ()
412+ if len (output ) > 1 :
413+ dev_name = output [1 ]
414+ lsblk_disks = disk .get_disks ()
415+ lsblk_dev_name = [i .replace ('/dev/' , '' ) for i in lsblk_disks ]
416+ if dev_name .strip () not in lsblk_dev_name :
417+ self .is_fail += 1
418+ else :
419+ self .log .warning ("ls-vdev returned no device information" )
376420 if self .is_fail >= 1 :
377421 self .fail ("%s command(s) failed in ls-vdev tool "
378422 "verification" % self .is_fail )
@@ -434,16 +478,21 @@ def test_bootlist(self):
434478 cmd = "bootlist %s" % list_item
435479 self .run_cmd (cmd )
436480 output = self .run_cmd_out ("lsvio -e" ).splitlines ()
481+ interface = None
437482 for line in output :
438483 if len (line .split ()) > 1 :
439484 interface = line .split ()[1 ]
485+ break # Use the first valid interface found
440486 file_path = os .path .join (self .workdir , 'file' )
441487 process .run ("echo %s > %s" %
442488 (self .disk_name , file_path ), ignore_status = True ,
443489 sudo = True , shell = True )
444- process .run ("echo %s >> %s" %
445- (interface , file_path ), ignore_status = True ,
446- sudo = True , shell = True )
490+ if interface :
491+ process .run ("echo %s >> %s" %
492+ (interface , file_path ), ignore_status = True ,
493+ sudo = True , shell = True )
494+ else :
495+ self .log .warning ("No interface found from lsvio -e, skipping interface in bootlist" )
447496 self .run_cmd ("bootlist -r -m both -f %s" % file_path )
448497 self .error_check ()
449498
0 commit comments