11__author__ = "desultory"
2- __version__ = "5.5 .0"
2+ __version__ = "5.6 .0"
33
44from pathlib import Path
55from typing import Union
@@ -364,8 +364,8 @@ def _autodetect_dm(self, mountpoint, device=None) -> None:
364364 if device :
365365 self .logger .debug ("[%s] Using provided device for mount autodetection: %s" % (mountpoint , device ))
366366 source_device = device
367- elif mountpoint in self [ "_mounts" ] :
368- source_device = self [ "_mounts" ][ mountpoint ][ "device" ]
367+ elif mountpoint :
368+ source_device = _resolve_overlay_lower_device ( self , mountpoint )
369369 else :
370370 raise FileNotFoundError ("Mountpoint not found in host mounts: %s" % mountpoint )
371371
@@ -537,6 +537,21 @@ def _resolve_dev(self, device_path) -> str:
537537 return self ["_mounts" ][device_path ]["device" ]
538538
539539
540+
541+ def _resolve_overlay_lower_dir (self , mountpoint ) -> str :
542+ for option in self ["_mounts" ][mountpoint ]["options" ]:
543+ if option .startswith ("lowerdir=" ):
544+ return option .removeprefix ("lowerdir=" )
545+ raise ValueError ("[%s] No lower overlayfs mountpoint found: %s" % mountpoint , self ["_mounts" ][mountpoint ]["options" ])
546+
547+ def _resolve_overlay_lower_device (self , mountpoint ) -> dict :
548+ """ Returns device for the lower overlayfs mountpoint."""
549+ if self ["_mounts" ][mountpoint ]["fstype" ] != "overlay" :
550+ return self ["_mounts" ][mountpoint ]["device" ]
551+
552+ lowerdir = _resolve_overlay_lower_dir (self , mountpoint )
553+ return self ["_mounts" ][lowerdir ]["device" ]
554+
540555@contains ("autodetect_root" , "Skipping root autodetection, autodetect_root is disabled." , log_level = 30 )
541556@contains ("hostonly" , "Skipping root autodetection, hostonly mode is disabled." , log_level = 30 )
542557def autodetect_root (self ) -> None :
@@ -547,14 +562,12 @@ def autodetect_root(self) -> None:
547562 )
548563 # Sometimes the root device listed in '/proc/mounts' differs from the blkid info
549564 root_dev = self ["_mounts" ]["/" ]["device" ]
550- if self ["resolve_root_dev" ]:
565+ if self ["resolve_root_dev" ]: # Sometimes the root device listed in '/proc/mounts' differs from the blkid info
551566 root_dev = _resolve_dev (self , "/" )
552567 if ":" in root_dev : # only use the first device
553568 root_dev = root_dev .split (":" )[0 ]
554569 for alt_devices in root_dev .split (":" )[1 :]: # But ensure kmods are loaded for all devices
555570 autodetect_mount_kmods (self , alt_devices )
556- if root_dev not in self ["_blkid_info" ]:
557- get_blkid_info (self , root_dev )
558571 _autodetect_mount (self , "/" )
559572
560573
@@ -563,7 +576,8 @@ def _autodetect_mount(self, mountpoint) -> None:
563576 if mountpoint not in self ["_mounts" ]:
564577 raise FileNotFoundError ("auto_mount mountpoint not found in host mounts: %s" % mountpoint )
565578
566- mount_device = self ["_mounts" ][mountpoint ]["device" ]
579+ mount_device = _resolve_overlay_lower_device (self , mountpoint )
580+
567581 if ":" in mount_device : # Handle bcachefs
568582 mount_device = mount_device .split (":" )[0 ]
569583
@@ -688,8 +702,8 @@ def _validate_host_mount(self, mount, destination_path=None) -> bool:
688702 # If a destination path is passed, like for /, use that instead of the mount's destination
689703 destination_path = str (mount ["destination" ]) if destination_path is None else destination_path
690704
691- # Using the mount path, get relevant hsot mount info
692- host_source_dev = self [ "_mounts" ][ destination_path ][ "device" ]
705+ # Using the mount path, get relevant host mount info
706+ host_source_dev = _resolve_overlay_lower_device ( self , destination_path )
693707 if ":" in host_source_dev : # Handle bcachefs
694708 host_source_dev = host_source_dev .split (":" )[0 ]
695709 if destination_path == "/" and self ["resolve_root_dev" ]:
0 commit comments