11__author__ = "desultory"
2- __version__ = "7.1.4 "
2+ __version__ = "7.2.1 "
33
44from pathlib import Path
55from re import search
@@ -504,20 +504,26 @@ def _autodetect_dm(self, mountpoint, device=None) -> None:
504504 Ensures it's a device mapper mount, then autodetects the mount type.
505505 Adds kmods to the autodetect list based on the mount source.
506506 """
507+ # If a device is explicity passed, set it as the source device
507508 if device :
508509 self .logger .debug ("[%s] Using provided device for mount autodetection: %s" % (mountpoint , device ))
509510 source_device = device
511+ # If it's a mountpoint, try to resolve underlying devices
510512 elif mountpoint :
511513 source_device = _resolve_overlay_lower_device (self , mountpoint )
512514 else :
513515 raise AutodetectError ("Mountpoint not found in host mounts: %s" % mountpoint )
514516
517+ # Get the name of the device from the path
515518 device_name = source_device .split ("/" )[- 1 ]
519+ # Check that it's a device mapper mount (by prefix or path)
520+ # If it's not, skip this autodetection by returning early
516521 if not any (device_name .startswith (prefix ) for prefix in ["dm-" , "md" ]):
517522 if not source_device .startswith ("/dev/mapper/" ):
518523 self .logger .debug ("Mount is not a device mapper mount: %s" % source_device )
519524 return
520525
526+ # Get the source device using blkid info/virtual block device info
521527 if source_device not in self ["_blkid_info" ]:
522528 if device_name in self ["_vblk_info" ]:
523529 source_name = self ["_vblk_info" ][device_name ]["name" ]
@@ -535,6 +541,7 @@ def _autodetect_dm(self, mountpoint, device=None) -> None:
535541 major , minor = _get_device_id (source_device )
536542 self .logger .debug ("[%s] Major: %s, Minor: %s" % (source_device , major , minor ))
537543
544+ # Get the virtual block device name using the major/minor
538545 for name , info in self ["_vblk_info" ].items ():
539546 if info ["major" ] == str (major ) and info ["minor" ] == str (minor ):
540547 dev_name = name
@@ -544,27 +551,43 @@ def _autodetect_dm(self, mountpoint, device=None) -> None:
544551 "[%s] Unable to find device mapper device with maj: %s min: %s" % (source_device , major , minor )
545552 )
546553
554+ # Check that the virtual block device has slaves defined
547555 if len (self ["_vblk_info" ][dev_name ]["slaves" ]) == 0 :
548556 raise AutodetectError ("No slaves found for device mapper device, unknown type: %s" % source_device .name )
557+ # Treat the first slave as the source for autodetection
549558 slave_source = self ["_vblk_info" ][dev_name ]["slaves" ][0 ]
559+ # If the slave source is a CRYPT-SUBDEV device, use its slave instead
560+ if self ["_vblk_info" ].get (slave_source , {}).get ("uuid" , "" ).startswith ("CRYPT-SUBDEV" ):
561+ slave_source = self ["_vblk_info" ][slave_source ]["slaves" ][0 ]
562+ self .logger .info (f"[{ c_ (dev_name , 'blue' )} ] Slave is a CRYPT-SUBDEV, using its slave instead: { c_ (slave_source , 'cyan' )} " )
563+ # Add the kmod for it
564+ self .logger .info (f"[{ c_ (dev_name , 'blue' )} ] Adding kmod for CRYPT-SUBDEV: { c_ ('dm-crypt' , 'magenta' )} " )
565+ self ["_kmod_auto" ] = ["dm_integrity" , "authenc" ]
566+
550567 autodetect_mount_kmods (self , slave_source )
551568
569+ # Check that the source device name matches the devie mapper name
570+ if source_device .name != self ["_vblk_info" ][dev_name ]["name" ] and source_device .name != dev_name :
571+ raise ValidationError (
572+ "Device mapper device name mismatch: %s != %s" % (source_device .name , self ["_vblk_info" ][dev_name ]["name" ])
573+ )
574+
575+ # Get block info using the slave source device
552576 try :
553577 blkid_info = self ["_blkid_info" ][f"/dev/{ slave_source } " ]
554578 except KeyError :
555579 if slave_source in self ["_vblk_info" ]:
580+ # If the slave source isn't used in blkid, use the /dev/mapper path with the slave name
556581 blkid_info = self ["_blkid_info" ][f"/dev/mapper/{ self ['_vblk_info' ][slave_source ]['name' ]} " ]
557582 else :
558583 return self .logger .warning (f"No blkid info found for device mapper slave: { c_ (slave_source , 'yellow' )} " )
559- if source_device .name != self ["_vblk_info" ][dev_name ]["name" ] and source_device .name != dev_name :
560- raise ValidationError (
561- "Device mapper device name mismatch: %s != %s" % (source_device .name , self ["_vblk_info" ][dev_name ]["name" ])
562- )
563584
564585 self .logger .debug (
565586 "[%s] Device mapper info: %s\n Device config: %s"
566587 % (source_device .name , self ["_vblk_info" ][dev_name ], blkid_info )
567588 )
589+
590+ # With the blkid info, run the appropriate autodetect function based on the type
568591 if blkid_info .get ("type" ) == "crypto_LUKS" or source_device .name in self .get ("cryptsetup" , {}):
569592 autodetect_luks (self , source_device , dev_name , blkid_info )
570593 elif blkid_info .get ("type" ) == "LVM2_member" :
@@ -579,8 +602,19 @@ def _autodetect_dm(self, mountpoint, device=None) -> None:
579602 raise AutodetectError ("[%s] No type found for device mapper device: %s" % (dev_name , source_device ))
580603 raise ValidationError ("Unknown device mapper device type: %s" % blkid_info .get ("type" ))
581604
605+ # Run autodetect on all slaves, in case of nested device mapper devices
582606 for slave in self ["_vblk_info" ][dev_name ]["slaves" ]:
583607 try :
608+ # If the slave is a CRYPT-SUBDEV, iterate over its slaves instead
609+ if self ["_vblk_info" ][slave ]["uuid" ].startswith ("CRYPT-SUBDEV" ):
610+ for crypt_slave in self ["_vblk_info" ][slave ]["slaves" ]:
611+ _autodetect_dm (self , mountpoint , crypt_slave )
612+ self .logger .info (
613+ "[%s] Autodetected device mapper container: %s"
614+ % (c_ (source_device .name , "blue" , bright = True ), c_ (crypt_slave , "cyan" ))
615+ )
616+ continue
617+ # Otherwise, just autodetect the slave device
584618 _autodetect_dm (self , mountpoint , slave ) # Just pass the slave device name, as it will be re-detected
585619 self .logger .info (
586620 "[%s] Autodetected device mapper container: %s"
0 commit comments