Skip to content

Commit 948860b

Browse files
authored
Merge pull request #219 from desultory/dev
improve mount detection for late mounts
2 parents 933a8c1 + 354cd8f commit 948860b

File tree

2 files changed

+41
-44
lines changed

2 files changed

+41
-44
lines changed

src/ugrd/fs/mounts.py

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -410,37 +410,6 @@ def get_zpool_info(self, poolname=None) -> Union[dict, None]:
410410
return self["_zpool_info"][poolname]
411411

412412

413-
@contains("hostonly", "Skipping init mount autodetection, hostonly mode is disabled.", log_level=30)
414-
@contains("autodetect_init_mount", "Init mount autodetection disabled, skipping.", log_level=30)
415-
@contains("init_target", "init_target must be set", raise_exception=True)
416-
def autodetect_init_mount(self) -> None:
417-
"""Checks the parent directories of init_target, if the path is a mountpoint, add it to late_mounts."""
418-
init_mount = _find_mountpoint(self, self["init_target"])
419-
if init_mount == "/":
420-
return
421-
422-
if init_mount in self["late_mounts"]:
423-
return self.logger.debug("Init mount already detected: %s" % init_mount)
424-
425-
if init_mount not in self["_mounts"]:
426-
raise AutodetectError("Init mount not found in host mounts: %s" % init_mount)
427-
428-
self.logger.info("Detected init mount: %s" % colorize(init_mount, "cyan"))
429-
mount_name = init_mount.removeprefix("/")
430-
mount_dest = init_mount
431-
mount_device = self["_mounts"][init_mount]["device"]
432-
mount_type = self["_mounts"][init_mount]["fstype"]
433-
mount_options = self["_mounts"][init_mount]["options"]
434-
blkid_info = self["_blkid_info"][mount_device]
435-
mount_source_type, mount_source = _get_mount_source_type(self, blkid_info, with_val=True)
436-
self["late_mounts"][mount_name] = {
437-
"destination": mount_dest,
438-
mount_source_type: mount_source,
439-
"type": mount_type,
440-
"options": mount_options,
441-
}
442-
443-
444413
@contains("hostonly", "Skipping virtual block device enumeration, hostonly mode is disabled.", log_level=30)
445414
def get_virtual_block_info(self) -> dict:
446415
"""Populates the virtual block device info. (previously device mapper only)
@@ -673,6 +642,28 @@ def autodetect_luks(self, source_dev, dm_num, blkid_info) -> None:
673642
)
674643

675644

645+
@contains("hostonly", "Skipping init mount autodetection, hostonly mode is disabled.", log_level=30)
646+
@contains("autodetect_init_mount", "Init mount autodetection disabled, skipping.", log_level=30)
647+
@contains("init_target", "init_target must be set", raise_exception=True)
648+
def autodetect_init_mount(self) -> None:
649+
"""Checks the parent directories of init_target, if the path is a mountpoint, add it to late_mounts."""
650+
for mountpoint in ["/usr", "/var", "/etc"]:
651+
_autodetect_mount(self, mountpoint, "late_mounts", missing_ok=True)
652+
653+
init_mount = _find_mountpoint(self, self["init_target"])
654+
if init_mount == "/":
655+
return
656+
657+
if init_mount in self["late_mounts"]:
658+
return self.logger.debug("Init mount already detected: %s" % init_mount)
659+
660+
if init_mount not in self["_mounts"]:
661+
raise AutodetectError("Init mount not found in host mounts: %s" % init_mount)
662+
663+
self.logger.info("Detected init mount: %s" % colorize(init_mount, "cyan"))
664+
_autodetect_mount(self, init_mount, "late_mounts")
665+
666+
676667
@contains("autodetect_root", "Skipping root autodetection, autodetect_root is disabled.", log_level=30)
677668
@contains("hostonly", "Skipping root autodetection, hostonly mode is disabled.", log_level=30)
678669
def autodetect_root(self) -> None:
@@ -697,11 +688,14 @@ def autodetect_root(self) -> None:
697688
_autodetect_dm(self, "/")
698689

699690

700-
def _autodetect_mount(self, mountpoint) -> str:
701-
"""Sets mount config for the specified mountpoint.
691+
def _autodetect_mount(self, mountpoint, mount_class="mounts", missing_ok=False) -> str:
692+
"""Sets mount config for the specified mountpoint, in the specified mount class.
693+
702694
Returns the "real" device path for the mountpoint.
703695
"""
704696
if mountpoint not in self["_mounts"]:
697+
if missing_ok:
698+
return self.logger.debug("Mountpoint not found in host mounts: %s" % mountpoint)
705699
self.logger.error("Host mounts:\n%s" % pretty_print(self["_mounts"]))
706700
raise AutodetectError("auto_mount mountpoint not found in host mounts: %s" % mountpoint)
707701

@@ -728,24 +722,25 @@ def _autodetect_mount(self, mountpoint) -> str:
728722
mount_name = "root" if mountpoint == "/" else mountpoint.removeprefix("/")
729723

730724
# Don't overwrite existing mounts if a source type is already set
731-
if mount_name in self["mounts"] and any(s_type in self["mounts"][mount_name] for s_type in SOURCE_TYPES):
725+
if mount_name in self[mount_class] and any(s_type in self[mount_class][mount_name] for s_type in SOURCE_TYPES):
732726
return self.logger.warning(
733727
"[%s] Skipping autodetection, mount config already set:\n%s"
734-
% (colorize(mountpoint, "yellow"), pretty_print(self["mounts"][mount_name]))
728+
% (colorize(mountpoint, "yellow"), pretty_print(self[mount_class][mount_name]))
735729
)
736730

737-
mount_config = {mount_name: {"type": "auto", "options": ["ro"]}} # Default to auto and ro
731+
# For standard mounts, default to auto and ro
732+
if mount_class == "mounts":
733+
mount_config = {mount_name: {"options": ["ro"]}}
734+
else: # For other mounts, use the existing mount config
735+
mount_config = {mount_name: {"options": self["_mounts"][mountpoint].get("options", ["default"])}}
736+
738737
fs_type = mount_info.get("type", fs_type) or "auto"
739738
if fs_type == "auto":
740739
self.logger.warning("Failed to autodetect mount type for mountpoint:" % (colorize(mountpoint, "yellow")))
741740
else:
742741
self.logger.info("[%s] Autodetected mount type from device: %s" % (mount_device, colorize(fs_type, "cyan")))
743742
mount_config[mount_name]["type"] = fs_type.lower()
744743

745-
# for zfs mounts, set the path to the pool name
746-
if fs_type == "zfs":
747-
mount_config[mount_name]["path"] = mount_device
748-
749744
for source_type in SOURCE_TYPES:
750745
if source := mount_info.get(source_type):
751746
self.logger.info(
@@ -758,7 +753,11 @@ def _autodetect_mount(self, mountpoint) -> str:
758753
if fs_type != "zfs": # For ZFS, the source is the pool name
759754
raise AutodetectError("[%s] Failed to autodetect mount source." % mountpoint)
760755

761-
self["mounts"] = mount_config
756+
# for zfs mounts, set the path to the pool name
757+
if fs_type == "zfs":
758+
mount_config[mount_name]["path"] = mount_device
759+
760+
self[mount_class] = mount_config
762761
return mount_device
763762

764763

src/ugrd/fs/mounts.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ autodetect_root_luks = true
2121
autodetect_root_lvm = true
2222
autodetect_root_raid = true
2323
autodetect_init_mount = true
24-
late_fstab = "/etc/fstab.late"
2524

2625
[imports.config_processing]
2726
"ugrd.fs.mounts" = [ "_process_run_dirs_multi",
@@ -48,7 +47,7 @@ late_fstab = "/etc/fstab.late"
4847
"ugrd.fs.mounts" = [ "mount_fstab" ]
4948

5049
[imports.init_mount]
51-
"ugrd.fs.mounts" = [ "mount_root" ]
50+
"ugrd.fs.mounts" = [ "mount_root", "mount_late" ]
5251

5352
[imports.functions]
5453
"ugrd.fs.mounts" = [ "mount_default_root" ]
@@ -65,7 +64,6 @@ mounts = "dict" # Add the mounts property, used to define the mounts to be made
6564
mount_devpts = "bool" # Whether or not to mount devpts
6665
run_dirs = "NoDupFlatList" # A list of directories to be created under /run
6766
late_mounts = "dict" # Like mounts, but run after the root is mounted
68-
late_fstab = "str" # The path to the late_fstab file
6967
auto_mounts = "NoDupFlatList" # A list of mounts to be automatically added to the mounts list
7068
mount_timeout = "float" # The time to wait between mount attempts
7169
mount_retries = "int" # The number of times to re-attempt mounting the fstab, infinite if not set

0 commit comments

Comments
 (0)