11__author__ = "desultory"
2- __version__ = "7.1.4 "
2+ __version__ = "7.2.0 "
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,40 @@ 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+
550564 autodetect_mount_kmods (self , slave_source )
551565
566+ # Check that the source device name matches the devie mapper name
567+ if source_device .name != self ["_vblk_info" ][dev_name ]["name" ] and source_device .name != dev_name :
568+ raise ValidationError (
569+ "Device mapper device name mismatch: %s != %s" % (source_device .name , self ["_vblk_info" ][dev_name ]["name" ])
570+ )
571+
572+ # Get block info using the slave source device
552573 try :
553574 blkid_info = self ["_blkid_info" ][f"/dev/{ slave_source } " ]
554575 except KeyError :
555576 if slave_source in self ["_vblk_info" ]:
577+ # If the slave source isn't used in blkid, use the /dev/mapper path with the slave name
556578 blkid_info = self ["_blkid_info" ][f"/dev/mapper/{ self ['_vblk_info' ][slave_source ]['name' ]} " ]
557579 else :
558580 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- )
563581
564582 self .logger .debug (
565583 "[%s] Device mapper info: %s\n Device config: %s"
566584 % (source_device .name , self ["_vblk_info" ][dev_name ], blkid_info )
567585 )
586+
587+ # With the blkid info, run the appropriate autodetect function based on the type
568588 if blkid_info .get ("type" ) == "crypto_LUKS" or source_device .name in self .get ("cryptsetup" , {}):
569589 autodetect_luks (self , source_device , dev_name , blkid_info )
570590 elif blkid_info .get ("type" ) == "LVM2_member" :
@@ -579,6 +599,7 @@ def _autodetect_dm(self, mountpoint, device=None) -> None:
579599 raise AutodetectError ("[%s] No type found for device mapper device: %s" % (dev_name , source_device ))
580600 raise ValidationError ("Unknown device mapper device type: %s" % blkid_info .get ("type" ))
581601
602+ # Run autodetect on all slaves, in case of nested device mapper devices
582603 for slave in self ["_vblk_info" ][dev_name ]["slaves" ]:
583604 try :
584605 _autodetect_dm (self , mountpoint , slave ) # Just pass the slave device name, as it will be re-detected
0 commit comments