diff options
author | Blair Zajac <blair@orcaware.com> | 2013-03-12 09:00:48 -0400 |
---|---|---|
committer | Scott Moser <smoser@ubuntu.com> | 2013-03-12 09:00:48 -0400 |
commit | fd938d20c62320c9068a9f517ccc465f561e7499 (patch) | |
tree | 3b3e1480b561f2e328c723fc586140ff6b712b48 /cloudinit/util.py | |
parent | cad31255aff2b3b7d0d640bf58649aeca43b7263 (diff) | |
parent | 64c8f384ffb81f34357f2b917b08b7851c470552 (diff) | |
download | vyos-cloud-init-fd938d20c62320c9068a9f517ccc465f561e7499.tar.gz vyos-cloud-init-fd938d20c62320c9068a9f517ccc465f561e7499.zip |
refactor get_mount_info and add tests
1) Refactor util.get_mount_info() to facilitate unit testing.
2) Add unit tests for /proc/$$/mountinfo parsing.
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r-- | cloudinit/util.py | 88 |
1 files changed, 54 insertions, 34 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py index 709d5cca..a1f6e004 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -1576,44 +1576,29 @@ def expand_package_list(version_fmt, pkgs): return pkglist -def get_mount_info(path, log=LOG): - # Use /proc/$$/mountinfo to find the device where path is mounted. - # This is done because with a btrfs filesystem using os.stat(path) - # does not return the ID of the device. - # - # Here, / has a device of 18 (decimal). - # - # $ stat / - # File: '/' - # Size: 234 Blocks: 0 IO Block: 4096 directory - # Device: 12h/18d Inode: 256 Links: 1 - # Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) - # Access: 2013-01-13 07:31:04.358011255 +0000 - # Modify: 2013-01-13 18:48:25.930011255 +0000 - # Change: 2013-01-13 18:48:25.930011255 +0000 - # Birth: - - # - # Find where / is mounted: - # - # $ mount | grep ' / ' - # /dev/vda1 on / type btrfs (rw,subvol=@,compress=lzo) - # - # And the device ID for /dev/vda1 is not 18: - # - # $ ls -l /dev/vda1 - # brw-rw---- 1 root disk 253, 1 Jan 13 08:29 /dev/vda1 - # - # So use /proc/$$/mountinfo to find the device underlying the - # input path. +def parse_mount_info(path, mountinfo_lines, log=LOG): + """Return the mount information for PATH given the lines from + /proc/$$/mountinfo.""" + path_elements = [e for e in path.split('/') if e] devpth = None fs_type = None match_mount_point = None match_mount_point_elements = None - mountinfo_path = '/proc/%s/mountinfo' % os.getpid() - for line in load_file(mountinfo_path).splitlines(): + for i, line in enumerate(mountinfo_lines): parts = line.split() + # Completely fail if there is anything in any line that is + # unexpected, as continuing to parse past a bad line could + # cause an incorrect result to be returned, so it's better + # return nothing than an incorrect result. + + # The minimum number of elements in a valid line is 10. + if len(parts) < 10: + log.debug("Line %d has two few columns (%d): %s", + i + 1, len(parts), line) + return None + mount_point = parts[4] mount_point_elements = [e for e in mount_point.split('/') if e] @@ -1638,8 +1623,8 @@ def get_mount_info(path, log=LOG): try: i = parts.index('-') except ValueError: - log.debug("Did not find column named '-' in %s", - mountinfo_path) + log.debug("Did not find column named '-' in line %d: %s", + i + 1, line) return None # Get the path to the device. @@ -1647,7 +1632,8 @@ def get_mount_info(path, log=LOG): fs_type = parts[i + 1] devpth = parts[i + 2] except IndexError: - log.debug("Too few columns in %s after '-' column", mountinfo_path) + log.debug("Too few columns after '-' column in line %d: %s", + i + 1, line) return None match_mount_point = mount_point @@ -1657,3 +1643,37 @@ def get_mount_info(path, log=LOG): return (devpth, fs_type, match_mount_point) else: return None + + +def get_mount_info(path, log=LOG): + # Use /proc/$$/mountinfo to find the device where path is mounted. + # This is done because with a btrfs filesystem using os.stat(path) + # does not return the ID of the device. + # + # Here, / has a device of 18 (decimal). + # + # $ stat / + # File: '/' + # Size: 234 Blocks: 0 IO Block: 4096 directory + # Device: 12h/18d Inode: 256 Links: 1 + # Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) + # Access: 2013-01-13 07:31:04.358011255 +0000 + # Modify: 2013-01-13 18:48:25.930011255 +0000 + # Change: 2013-01-13 18:48:25.930011255 +0000 + # Birth: - + # + # Find where / is mounted: + # + # $ mount | grep ' / ' + # /dev/vda1 on / type btrfs (rw,subvol=@,compress=lzo) + # + # And the device ID for /dev/vda1 is not 18: + # + # $ ls -l /dev/vda1 + # brw-rw---- 1 root disk 253, 1 Jan 13 08:29 /dev/vda1 + # + # So use /proc/$$/mountinfo to find the device underlying the + # input path. + mountinfo_path = '/proc/%s/mountinfo' % os.getpid() + lines = load_file(mountinfo_path).splitlines() + return parse_mount_info(path, lines, log) |