From: Alfredo Deza Date: Wed, 18 Oct 2017 15:40:38 +0000 (-0400) Subject: ceph-volume util.system create mappings of mounts X-Git-Tag: v13.0.1~463^2~31 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f61007cc650f6964ef2ff3ea98a1debf02713198;p=ceph.git ceph-volume util.system create mappings of mounts 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 --- diff --git a/src/ceph-volume/ceph_volume/util/system.py b/src/ceph-volume/ceph_volume/util/system.py index 084a0e0d3710..1a8e7b125817 100644 --- a/src/ceph-volume/ceph_volume/util/system.py +++ b/src/ceph-volume/ceph_volume/util/system.py @@ -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