]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume util.system create mappings of mounts
authorAlfredo Deza <adeza@redhat.com>
Wed, 18 Oct 2017 15:40:38 +0000 (11:40 -0400)
committerAlfredo Deza <adeza@redhat.com>
Fri, 27 Oct 2017 14:44:16 +0000 (10:44 -0400)
This makes it easier for consumers to detect a path, or a device that
might be mounted or might have more than one mount, including tmpfs and
devtmpfs support, which was just not possible before.

Signed-off-by: Alfredo Deza <adeza@redhat.com>
(cherry picked from commit f61007cc650f6964ef2ff3ea98a1debf02713198)

src/ceph-volume/ceph_volume/util/system.py

index 084a0e0d3710042a8b9d38aeaf530d1038c8ffd0..1a8e7b125817e1ecf4f82535423748908237263b 100644 (file)
@@ -68,37 +68,80 @@ def chown(path, recursive=True):
         os.chown(path, uid, gid)
 
 
-def is_mounted(source, destination=None):
+def path_is_mounted(path, destination=None):
     """
-    Check if the given device is mounted, optionally validating destination.
-    This relies on absolute path devices, it will ignore non-absolute
-    entries like::
+    Check if the given path is mounted
+    """
+    mounts = get_mounts(paths=True)
+    realpath = os.path.realpath(path)
+    mounted_locations = mounts.get(realpath, [])
+
+    if destination:
+        if destination.startswith('/'):
+            destination = os.path.realpath(destination)
+        return destination in mounted_locations
+    return mounted_locations != []
 
-        tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0
 
-    But will parse paths that are absolute like::
+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)
+    realpath = os.path.realpath(dev) if dev.startswith('/') else dev
+    destination = os.path.realpath(destination) if destination else None
+    mounted_locations = mounts.get(realpath, [])
 
-        /dev/sdc2 /boot xfs rw,attr2,inode64,noquota 0 0
+    if destination:
+        return destination in mounted_locations
+    return mounted_locations != []
 
-    When destination is passed in, it will check that the entry where the
-    source appears is mounted to where destination defines. This is useful so
-    that an error message can report that a source is not mounted at an
-    expected destination.
+
+def get_mounts(devices=False, paths=False):
     """
-    dev = os.path.realpath(source)
-    with open(PROCDIR + '/mounts', 'rb') as proc_mounts:
-        for line in proc_mounts:
-            fields = line.split()
-            if len(fields) < 3:
+    Create a mapping of all available system mounts so that other helpers can
+    detect nicely what path or device is mounted
+
+    It ignores (most of) non existing devices, but since some setups might need
+    some extra device information, it will make an exception for:
+
+    - tmpfs
+    - devtmpfs
+
+    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)
+    """
+    devices_mounted = {}
+    paths_mounted = {}
+    do_not_skip = ['tmpfs', 'devtmpfs']
+    default_to_devices = devices is False and paths is False
+
+    with open(PROCDIR + '/mounts', 'rb') as mounts:
+        proc_mounts = mounts.readlines()
+
+    for line in proc_mounts:
+        fields = line.split()
+        if len(fields) < 3:
+            continue
+        device = os.path.realpath(fields[0]) if fields[0].startswith('/') else fields[0]
+        path = os.path.realpath(fields[1])
+        # only care about actual existing devices
+        if not os.path.exists(device) or not device.startswith('/'):
+            if device not in do_not_skip:
                 continue
-            mounted_device = fields[0]
-            mounted_path = fields[1]
-            if os.path.isabs(mounted_device) and os.path.exists(mounted_device):
-                mounted_device = os.path.realpath(mounted_device)
-                if as_string(mounted_device) == dev:
-                    if destination:
-                        destination = os.path.realpath(destination)
-                        return destination == as_string(os.path.realpath(mounted_path))
-                    else:
-                        return True
-    return False
+        if device in devices_mounted.keys():
+            devices_mounted[device].append(path)
+        else:
+            devices_mounted[device] = [path]
+        if path in paths_mounted.keys():
+            paths_mounted[path].append(device)
+        else:
+            paths_mounted[path] = [device]
+
+    # Default to returning information for devices if
+    if devices is True or default_to_devices:
+        return devices_mounted
+    else:
+        return paths_mounted