Skip to content

Commit e525377

Browse files
committed
install: Handle mount points in rootfs operations
Allow mount points (separate filesystems) to exist during to-filesystem installations by detecting and skipping them in the empty rootdir check. When cleaning directories during commit, recursively clean the contents of mount point directories while preserving the mount point itself. This is necessary for cases where subdirectories like /var/log or /var/home are separate logical volumes. Assisted-by: Claude Code Signed-off-by: ckyrouac <[email protected]>
1 parent 52f49b5 commit e525377

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

crates/lib/src/install.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,19 @@ fn require_empty_rootdir(rootfs_fd: &Dir) -> Result<()> {
17711771
if name == LOST_AND_FOUND {
17721772
continue;
17731773
}
1774+
1775+
// Check if this entry is a directory
1776+
let etype = e.file_type()?;
1777+
if etype == FileType::dir() {
1778+
// Check if this directory is a mount point (separate filesystem)
1779+
// If open_dir_noxdev returns None, it means this directory is on a different device
1780+
// (i.e., it's a mount point), which is acceptable for to-filesystem installations
1781+
if rootfs_fd.open_dir_noxdev(&name)?.is_none() {
1782+
tracing::debug!("Skipping mount point: {name}");
1783+
continue;
1784+
}
1785+
}
1786+
17741787
// There must be a boot directory (that is empty)
17751788
if name == BOOT {
17761789
let mut entries = rootfs_fd.read_dir(BOOT)?;

crates/ostree-ext/src/commit.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,23 @@ fn clean_subdir(root: &Dir, rootdev: u64) -> Result<()> {
5757
tracing::trace!("Skipping entry in foreign dev {path:?}");
5858
continue;
5959
}
60-
// Also ignore bind mounts, if we have a new enough kernel with statx()
61-
// that will tell us.
60+
// For mount points (e.g., separate LVM volumes under /var), we need to clean
61+
// their contents but preserve the directory itself. This is critical for cases
62+
// where subdirectories like /var/log or /var/home are separate logical volumes.
6263
if root.is_mountpoint(&path)?.unwrap_or_default() {
63-
tracing::trace!("Skipping mount point {path:?}");
64+
if metadata.is_dir() {
65+
tracing::debug!("Cleaning contents of mount point directory {path:?}");
66+
// Get the device ID of the mountpoint itself
67+
let mountpoint_dev = metadata.dev();
68+
// Open the mountpoint directory and clean its contents
69+
if let Some(mountpoint_dir) = root.open_dir_optional(&path)? {
70+
clean_subdir(&mountpoint_dir, mountpoint_dev)
71+
.with_context(|| format!("Cleaning mountpoint {path:?}"))?;
72+
}
73+
// Do not remove the directory itself - it's a mount point
74+
} else {
75+
tracing::trace!("Skipping non-directory mount point {path:?}");
76+
}
6477
continue;
6578
}
6679
if metadata.is_dir() {

0 commit comments

Comments
 (0)