]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume util.system optionally use realpath on devices
authorAlfredo Deza <adeza@redhat.com>
Tue, 13 Feb 2018 17:59:48 +0000 (12:59 -0500)
committerAlfredo Deza <adeza@redhat.com>
Tue, 13 Feb 2018 20:55:11 +0000 (15:55 -0500)
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 <adeza@redhat.com>
src/ceph-volume/ceph_volume/util/system.py

index 952fa56fe58628274ff7b4ed537495654be6882e..f04f00e130917c722ff7a5d50456be665ab98f6d 100644 (file)
@@ -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('/'):