Fix incorect stale ostree_repo mount check

This commit fixes a regression introduced in
https://review.opendev.org/c/starlingx/distcloud/+/920194

The incorrect path was being used for comparing the inodes
of the target and source mount paths, which results in incorrectly
detected stale mounts, followed by a failure to properly clean up the
mount.

Test Plan:
PASS:
- Unmount (but do not delete) the /var/www/pages/iso/<rel>/ostree_repo
  directory. When a subcloud add or deploy operation is done, the bind
  mount is recreated.
- Stale mount:
    # Replace the original
    sudo cp -a /var/www/pages/feed/rel-24.09/ostree_repo \
      /var/www/pages/feed/rel-24.09/ostree_repo.orig
    sudo rm -rf /var/www/pages/feed/rel-24.09/ostree_repo
    sudo cp -a /var/www/pages/feed/rel-24.09/ostree_repo.orig \
      /var/www/pages/feed/rel-24.09/ostree_repo
  When a subcloud add or deploy operation is done, the stale bind
  mount is detected. The /var/www/pages/iso/24.09/ostree_repo is
  unmounted, and the directory is removed.
  When a subcloud add or deploy operation is done, the bind
  mount is recreated.

Closes-Bug: 2066411

Change-Id: I14332ef008f781f742c69fcb3987037e871ba19d
Signed-off-by: Kyle MacLeod <kyle.macleod@windriver.com>
This commit is contained in:
Kyle MacLeod
2024-06-04 13:49:02 -04:00
parent ec3811f321
commit 42b72fd08a

View File

@@ -17,7 +17,7 @@ from dcmanager.common import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
def check_stale_bindmount(mount_path, source_path, log_error=True): def check_stale_bind_mount(mount_path, source_path):
"""Check if the mount has become stale. """Check if the mount has become stale.
We do this by comparing the directory inodes. If the bind mount is We do this by comparing the directory inodes. If the bind mount is
@@ -29,16 +29,22 @@ def check_stale_bindmount(mount_path, source_path, log_error=True):
mount_path_inode = sh.stat("--format", "%i", mount_path) mount_path_inode = sh.stat("--format", "%i", mount_path)
source_path_inode = sh.stat("--format", "%i", source_path) source_path_inode = sh.stat("--format", "%i", source_path)
if mount_path_inode != source_path_inode: if mount_path_inode != source_path_inode:
logmsg = f"Found stale bind mount: {mount_path}, unmounting" failure_prefix = f"Failed to repair bind mount at {mount_path}"
if log_error: LOG.error(f"Found stale bind mount: {mount_path}: attempting repair")
LOG.error(logmsg)
else:
LOG.warn(logmsg)
try: try:
sh.umount(mount_path) sh.umount(mount_path)
except sh.ErrorReturnCode_32:
# Exit code 32 is "mount failure"
# Log the exception, but proceed with the rmdir, allowing a
# remount attempt
LOG.exception(f"{failure_prefix}: unmount failed (continuing)")
except Exception:
LOG.error(f"{failure_prefix}: unexpected umount failure")
raise
try:
os.rmdir(mount_path) os.rmdir(mount_path)
except Exception: except Exception:
LOG.error(f"Failed to fix bind mount at {mount_path}") LOG.error(f"{failure_prefix}: rmdir failed")
raise raise
return True return True
@@ -55,17 +61,15 @@ def validate_ostree_iso_mount(www_iso_root, source_path):
Note that ostree_repo is mounted in a location not specific to a subcloud. Note that ostree_repo is mounted in a location not specific to a subcloud.
""" """
ostree_repo_mount_path = os.path.join(www_iso_root, "ostree_repo") ostree_repo_mount_path = os.path.join(www_iso_root, "ostree_repo")
LOG.debug("Checking ostree_repo mount: %s", ostree_repo_mount_path) ostree_repo_source_path = os.path.join(source_path, "ostree_repo")
if os.path.exists(ostree_repo_mount_path) and check_stale_bindmount( LOG.debug(
ostree_repo_mount_path, source_path "Checking ostree_repo mount: %s against %s",
): ostree_repo_mount_path,
LOG.warn(f"Found stale bind mount: {ostree_repo_mount_path}, unmounting") ostree_repo_source_path,
try: )
sh.umount(ostree_repo_mount_path) if os.path.exists(ostree_repo_mount_path):
os.rmdir(ostree_repo_mount_path) check_stale_bind_mount(ostree_repo_mount_path, ostree_repo_source_path)
except Exception:
LOG.error(f"Failed to fix bind mount at {ostree_repo_mount_path}")
raise
# Check for the config file inside the ostree_repo # Check for the config file inside the ostree_repo
check_path = os.path.join(ostree_repo_mount_path, "config") check_path = os.path.join(ostree_repo_mount_path, "config")
if not os.path.exists(check_path): if not os.path.exists(check_path):