From 88dfa795a039834f3509cb12aed9f50b9f44d05b Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 4 Oct 2013 17:29:25 -0400 Subject: try to support ephemeral0.1 in cc_mounts --- cloudinit/config/cc_mounts.py | 128 +++++++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 46 deletions(-) (limited to 'cloudinit/config/cc_mounts.py') diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py index 6b47d326..1ec39e3c 100644 --- a/cloudinit/config/cc_mounts.py +++ b/cloudinit/config/cc_mounts.py @@ -45,6 +45,33 @@ def is_mdname(name): return False +def sanitize_devname(devname, transformer, log) + log.debug("Attempting to determine the real name of %s", startname) + + # workaround, allow user to specify 'ephemeral' + # rather than more ec2 correct 'ephemeral0' + devname = startname + if devname == "ephemeral": + devname = "ephemeral0" + log.debug("Adjusted mount option from ephemeral to ephemeral0") + + (blockdev, part) = util.expand_dotted_devname(devname) + + if is_mdname(blockdev): + orig = blockdev + blockdev = transformer(blockdev) + if not blockdev: + return None + if not blockdev.startswith("/"): + blockdev = "/dev/%s" % blockdev + log.debug("Mapped metadata name %s to %s", orig, blockdev) + else: + if SHORTNAME.match(startname): + blockdev = "/dev/%s" % blockdev + + return devnode_for_dev_part(blockdev, part) + + def handle(_name, cfg, cloud, log, _args): # fs_spec, fs_file, fs_vfstype, fs_mntops, fs-freq, fs_passno defvals = [None, None, "auto", "defaults,nobootwait", "0", "2"] @@ -65,34 +92,14 @@ def handle(_name, cfg, cloud, log, _args): (i + 1), type_utils.obj_name(cfgmnt[i])) continue - startname = str(cfgmnt[i][0]) - log.debug("Attempting to determine the real name of %s", startname) - - # workaround, allow user to specify 'ephemeral' - # rather than more ec2 correct 'ephemeral0' - if startname == "ephemeral": - cfgmnt[i][0] = "ephemeral0" - log.debug(("Adjusted mount option %s " - "name from ephemeral to ephemeral0"), (i + 1)) - - if is_mdname(startname): - candidate_name = cloud.device_name_to_device(startname) - newname = disk_or_part(candidate_name) + start = str(cfgmnt[i][0]) + sanitized = sanitize_devname(start, cloud.device_name_to_device, log) + if sanitized is None: + log.debug("Ignorming nonexistant named mount %s", start) - if not newname: - log.debug("Ignoring nonexistant named mount %s", startname) - cfgmnt[i][1] = None - else: - renamed = newname - if not newname.startswith("/"): - renamed = "/dev/%s" % newname - cfgmnt[i][0] = renamed - log.debug("Mapped metadata name %s to %s", startname, renamed) - else: - if SHORTNAME.match(startname): - renamed = "/dev/%s" % startname - log.debug("Mapped shortname name %s to %s", startname, renamed) - cfgmnt[i][0] = renamed + if sanitized != start: + log.debug("changed %s => %s" % (start, sanitized)) + cfgmnt[i][0] = sanitized # in case the user did not quote a field (likely fs-freq, fs_passno) # but do not convert None to 'None' (LP: #898365) @@ -121,12 +128,21 @@ def handle(_name, cfg, cloud, log, _args): # for each of the "default" mounts, add them only if no other # entry has the same device name for defmnt in defmnts: - startname = defmnt[0] - candidate_name = cloud.device_name_to_device(startname) - devname = disk_or_part(candidate_name) + start = defmnt[0] + sanitized = sanitize_devname(start, cloud.device_name_to_device, log) + if sanitized is None: + log.debug("Ignorming nonexistant named mount %s", start) + if sanitized != start: + log.debug("changed %s => %s" % (start, sanitized)) + defmnt[0] = sanitized + + devname = defmnt[0] + if candidate_name is not None: + dev = candidate_name if devname is None: log.debug("Ignoring nonexistant named default mount %s", startname) continue + devname = devnode_for_dev_part(devname, part) if devname.startswith("/"): defmnt[0] = devname else: @@ -204,31 +220,51 @@ def handle(_name, cfg, cloud, log, _args): util.logexc(log, "Activating mounts via 'mount -a' failed") -def disk_or_part(device): +def devnode_for_dev_part(device, partition): """ - Find where the file system is on the disk, either on - the disk itself or on the first partition. We don't go - any deeper than partition 1 though. + Find the name of the partition. While this might seem rather + straight forward, its not since some devices are '' + while others are 'p'. For example, /dev/xvda3 on EC2 + will present as /dev/xvda3p1 for the first partition since /dev/xvda3 is + a block device. """ - - if not device: + if not os.path.exists(device): return None - short_name = device.split('/')[-1] + if not partition: + return device + + short_name = os.path.basename(device) sys_path = "/sys/block/%s" % short_name - # if the sys path does not exist but the device exists, - # then the device is a partition, no sense looking any further - if not os.path.exists(sys_path) and os.path.exists(device): - return device + if not os.path.exists(sys_path): + LOG.debug("did not find entry for %s in /sys/block", short_name) + return None - sys_long_path = sys_path + "/" + short_name + "%s" - valid_mappings = [sys_long_path % "1", - sys_long_path % "p1", - sys_path] + sys_long_path = sys_path + "/" + short_name + + if partition is not None: + partition = str(partition) + + if partition is None: + valid_mappings = [sys_long_path + "1", + sys_long_path + "p1" % partition] + elif partition != "0": + valid_mappings = [sys_long_path + "%s" % partition, + sys_long_path + "p%s" % partition] + else: + valid_mappings = [] for cdisk in valid_mappings: if not os.path.exists(cdisk): continue - return "/dev/%s" % cdisk.split('/')[-1] + + dev_path = "/dev/%s" % os.path.basename(cdisk) + if os.path.exists(dev_path): + return dev_path + + if partition is None or partition == "0": + return device + + LOG.debug("Did not fine partition %s for device %s", partition, device) return None -- cgit v1.2.3