From: Alfredo Deza Date: Tue, 13 Feb 2018 17:59:48 +0000 (-0500) Subject: ceph-volume util.system optionally use realpath on devices X-Git-Tag: v13.0.2~278^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=53e691e1d5122ff533e69ae08c73e18c1ed74765;p=ceph.git ceph-volume util.system optionally use realpath on devices To check a mounted device it is needed to verify on a combination of realpath and plain devices against realpath and plain paths. In LVM, two different paths might refer to the same devices Signed-off-by: Alfredo Deza --- diff --git a/src/ceph-volume/ceph_volume/util/system.py b/src/ceph-volume/ceph_volume/util/system.py index 952fa56fe5862..f04f00e130917 100644 --- a/src/ceph-volume/ceph_volume/util/system.py +++ b/src/ceph-volume/ceph_volume/util/system.py @@ -1,4 +1,5 @@ import errno +import logging import os import pwd import platform @@ -7,6 +8,7 @@ import uuid from ceph_volume import process from . import as_string +logger = logging.getLogger(__name__) # TODO: get these out of here and into a common area for others to consume if platform.system() == 'FreeBSD': @@ -137,16 +139,40 @@ def device_is_mounted(dev, destination=None): Check if the given device is mounted, optionally validating that a destination exists """ - mounts = get_mounts(devices=True) + plain_mounts = get_mounts(devices=True) + realpath_mounts = get_mounts(devices=True, realpath=True) + realpath_dev = os.path.realpath(dev) if dev.startswith('/') else dev destination = os.path.realpath(destination) if destination else None - mounted_locations = mounts.get(dev, []) - - if destination: - return destination in mounted_locations - return mounted_locations != [] + # plain mounts + plain_dev_mounts = plain_mounts.get(dev, []) + realpath_dev_mounts = plain_mounts.get(realpath_dev, []) + # realpath mounts + plain_dev_real_mounts = realpath_mounts.get(dev, []) + realpath_dev_real_mounts = realpath_mounts.get(realpath_dev, []) + + mount_locations = [ + plain_dev_mounts, + realpath_dev_mounts, + plain_dev_real_mounts, + realpath_dev_real_mounts + ] + + for mounts in mount_locations: + if mounts: # we have a matching mount + if destination: + if destination in mounts: + logger.info( + '%s detected as mounted, exists at destination: %s', dev, destination + ) + return True + else: + logger.info('%s was found as mounted') + return True + logger.info('%s was not found as mounted') + return False -def get_mounts(devices=False, paths=False): +def get_mounts(devices=False, paths=False, realpath=False): """ Create a mapping of all available system mounts so that other helpers can detect nicely what path or device is mounted @@ -160,6 +186,9 @@ def get_mounts(devices=False, paths=False): If ``devices`` is set to ``True`` the mapping will be a device-to-path(s), if ``paths`` is set to ``True`` then the mapping will be a path-to-device(s) + + :param realpath: Resolve devices to use their realpaths. This is useful for + paths like LVM where more than one path can point to the same device """ devices_mounted = {} paths_mounted = {} @@ -173,7 +202,10 @@ def get_mounts(devices=False, paths=False): fields = [as_string(f) for f in line.split()] if len(fields) < 3: continue - device = fields[0] + if realpath: + device = os.path.realpath(fields[0]) if fields[0].startswith('/') else fields[0] + else: + device = fields[0] path = os.path.realpath(fields[1]) # only care about actual existing devices if not os.path.exists(device) or not device.startswith('/'):