wic: Clean up PartitionedMount

wic doesn't use a lot of ParitionedMount, so remove it.

(From OE-Core rev: 0f793ff0767b0cce032c20b677974806c65610d6)

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Tom Zanussi 2014-08-05 10:59:11 -05:00 committed by Richard Purdie
parent 1601821636
commit f12336aa4a
1 changed files with 2 additions and 353 deletions

View File

@ -33,18 +33,13 @@ MBR_OVERHEAD = 1
SECTOR_SIZE = 512
class PartitionedMount(Mount):
def __init__(self, mountdir, skipformat = False):
def __init__(self, mountdir):
Mount.__init__(self, mountdir)
self.disks = {}
self.partitions = []
self.subvolumes = []
self.mapped = False
self.mountOrder = []
self.unmountOrder = []
self.parted = find_binary_path("parted")
self.btrfscmd=None
self.skipformat = skipformat
self.snapshot_created = self.skipformat
# Size of a sector used in calculations
self.sector_size = SECTOR_SIZE
self._partitions_layed_out = False
@ -62,7 +57,6 @@ class PartitionedMount(Mount):
self.disks[disk_name] = \
{ 'disk': None, # Disk object
'mapped': False, # True if kpartx mapping exists
'numpart': 0, # Number of allocate partitions
'partitions': [], # Indexes to self.partitions
'offset': 0, # Offset of next partition (in sectors)
@ -98,40 +92,8 @@ class PartitionedMount(Mount):
# Converting MB to sectors for parted
size = size * 1024 * 1024 / self.sector_size
# We need to handle subvolumes for btrfs
if fstype == "btrfs" and fsopts and fsopts.find("subvol=") != -1:
self.btrfscmd=find_binary_path("btrfs")
subvol = None
opts = fsopts.split(",")
for opt in opts:
if opt.find("subvol=") != -1:
subvol = opt.replace("subvol=", "").strip()
break
if not subvol:
raise MountError("No subvolume: %s" % fsopts)
self.subvolumes.append({'size': size, # In sectors
'mountpoint': mountpoint, # Mount relative to chroot
'fstype': fstype, # Filesystem type
'fsopts': fsopts, # Filesystem mount options
'disk_name': disk_name, # physical disk name holding partition
'device': None, # kpartx device node for partition
'mount': None, # Mount object
'subvol': subvol, # Subvolume name
'boot': boot, # Bootable flag
'mounted': False # Mount flag
})
# We still need partition for "/" or non-subvolume
if mountpoint == "/" or not fsopts or fsopts.find("subvol=") == -1:
# Don't need subvolume for "/" because it will be set as default subvolume
if fsopts and fsopts.find("subvol=") != -1:
opts = fsopts.split(",")
for opt in opts:
if opt.strip().startswith("subvol="):
opts.remove(opt)
break
fsopts = ",".join(opts)
if mountpoint == "/" or not fsopts:
part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file
'size': size, # In sectors
'mountpoint': mountpoint, # Mount relative to chroot
@ -283,10 +245,6 @@ class PartitionedMount(Mount):
def __format_disks(self):
self.layout_partitions()
if self.skipformat:
msger.debug("Skipping disk format, because skipformat flag is set.")
return
for dev in self.disks.keys():
d = self.disks[dev]
msger.debug("Initializing partition table for %s" % \
@ -346,103 +304,6 @@ class PartitionedMount(Mount):
self.__run_parted(["-s", d['disk'].device, "set",
"%d" % p['num'], "lba", "off"])
def __map_partitions(self):
"""Load it if dm_snapshot isn't loaded. """
load_module("dm_snapshot")
for dev in self.disks.keys():
d = self.disks[dev]
if d['mapped']:
continue
msger.debug("Running kpartx on %s" % d['disk'].device )
rc, kpartxOutput = runner.runtool([self.kpartx, "-l", "-v", d['disk'].device])
kpartxOutput = kpartxOutput.splitlines()
if rc != 0:
raise MountError("Failed to query partition mapping for '%s'" %
d['disk'].device)
# Strip trailing blank and mask verbose output
i = 0
while i < len(kpartxOutput) and kpartxOutput[i][0:4] != "loop":
i = i + 1
kpartxOutput = kpartxOutput[i:]
# Make sure kpartx reported the right count of partitions
if len(kpartxOutput) != d['numpart']:
# If this disk has more than 3 partitions, then in case of MBR
# paritions there is an extended parition. Different versions
# of kpartx behave differently WRT the extended partition -
# some map it, some ignore it. This is why we do the below hack
# - if kpartx reported one more partition and the partition
# table type is "msdos" and the amount of partitions is more
# than 3, we just assume kpartx mapped the extended parition
# and we remove it.
if len(kpartxOutput) == d['numpart'] + 1 \
and d['ptable_format'] == 'msdos' and len(kpartxOutput) > 3:
kpartxOutput.pop(3)
else:
raise MountError("Unexpected number of partitions from " \
"kpartx: %d != %d" % \
(len(kpartxOutput), d['numpart']))
for i in range(len(kpartxOutput)):
line = kpartxOutput[i]
newdev = line.split()[0]
mapperdev = "/dev/mapper/" + newdev
loopdev = d['disk'].device + newdev[-1]
msger.debug("Dev %s: %s -> %s" % (newdev, loopdev, mapperdev))
pnum = d['partitions'][i]
self.partitions[pnum]['device'] = loopdev
# grub's install wants partitions to be named
# to match their parent device + partition num
# kpartx doesn't work like this, so we add compat
# symlinks to point to /dev/mapper
if os.path.lexists(loopdev):
os.unlink(loopdev)
os.symlink(mapperdev, loopdev)
msger.debug("Adding partx mapping for %s" % d['disk'].device)
rc = runner.show([self.kpartx, "-v", "-a", d['disk'].device])
if rc != 0:
# Make sure that the device maps are also removed on error case.
# The d['mapped'] isn't set to True if the kpartx fails so
# failed mapping will not be cleaned on cleanup either.
runner.quiet([self.kpartx, "-d", d['disk'].device])
raise MountError("Failed to map partitions for '%s'" %
d['disk'].device)
# FIXME: there is a bit delay for multipath device setup,
# wait 10ms for the setup
import time
time.sleep(10)
d['mapped'] = True
def __unmap_partitions(self):
for dev in self.disks.keys():
d = self.disks[dev]
if not d['mapped']:
continue
msger.debug("Removing compat symlinks")
for pnum in d['partitions']:
if self.partitions[pnum]['device'] != None:
os.unlink(self.partitions[pnum]['device'])
self.partitions[pnum]['device'] = None
msger.debug("Unmapping %s" % d['disk'].device)
rc = runner.quiet([self.kpartx, "-d", d['disk'].device])
if rc != 0:
raise MountError("Failed to unmap partitions for '%s'" %
d['disk'].device)
d['mapped'] = False
def __calculate_mountorder(self):
msger.debug("Calculating mount order")
for p in self.partitions:
@ -457,7 +318,6 @@ class PartitionedMount(Mount):
def cleanup(self):
Mount.cleanup(self)
if self.disks:
self.__unmap_partitions()
for dev in self.disks.keys():
d = self.disks[dev]
try:
@ -466,7 +326,6 @@ class PartitionedMount(Mount):
pass
def unmount(self):
self.__unmount_subvolumes()
for mp in self.unmountOrder:
if mp == 'swap':
continue
@ -478,217 +337,11 @@ class PartitionedMount(Mount):
if p['mount'] != None:
try:
# Create subvolume snapshot here
if p['fstype'] == "btrfs" and p['mountpoint'] == "/" and not self.snapshot_created:
self.__create_subvolume_snapshots(p, p["mount"])
p['mount'].cleanup()
except:
pass
p['mount'] = None
# Only for btrfs
def __get_subvolume_id(self, rootpath, subvol):
if not self.btrfscmd:
self.btrfscmd=find_binary_path("btrfs")
argv = [ self.btrfscmd, "subvolume", "list", rootpath ]
rc, out = runner.runtool(argv)
msger.debug(out)
if rc != 0:
raise MountError("Failed to get subvolume id from %s', return code: %d." % (rootpath, rc))
subvolid = -1
for line in out.splitlines():
if line.endswith(" path %s" % subvol):
subvolid = line.split()[1]
if not subvolid.isdigit():
raise MountError("Invalid subvolume id: %s" % subvolid)
subvolid = int(subvolid)
break
return subvolid
def __create_subvolume_metadata(self, p, pdisk):
if len(self.subvolumes) == 0:
return
argv = [ self.btrfscmd, "subvolume", "list", pdisk.mountdir ]
rc, out = runner.runtool(argv)
msger.debug(out)
if rc != 0:
raise MountError("Failed to get subvolume id from %s', return code: %d." % (pdisk.mountdir, rc))
subvolid_items = out.splitlines()
subvolume_metadata = ""
for subvol in self.subvolumes:
for line in subvolid_items:
if line.endswith(" path %s" % subvol["subvol"]):
subvolid = line.split()[1]
if not subvolid.isdigit():
raise MountError("Invalid subvolume id: %s" % subvolid)
subvolid = int(subvolid)
opts = subvol["fsopts"].split(",")
for opt in opts:
if opt.strip().startswith("subvol="):
opts.remove(opt)
break
fsopts = ",".join(opts)
subvolume_metadata += "%d\t%s\t%s\t%s\n" % (subvolid, subvol["subvol"], subvol['mountpoint'], fsopts)
if subvolume_metadata:
fd = open("%s/.subvolume_metadata" % pdisk.mountdir, "w")
fd.write(subvolume_metadata)
fd.close()
def __get_subvolume_metadata(self, p, pdisk):
subvolume_metadata_file = "%s/.subvolume_metadata" % pdisk.mountdir
if not os.path.exists(subvolume_metadata_file):
return
fd = open(subvolume_metadata_file, "r")
content = fd.read()
fd.close()
for line in content.splitlines():
items = line.split("\t")
if items and len(items) == 4:
self.subvolumes.append({'size': 0, # In sectors
'mountpoint': items[2], # Mount relative to chroot
'fstype': "btrfs", # Filesystem type
'fsopts': items[3] + ",subvol=%s" % items[1], # Filesystem mount options
'disk_name': p['disk_name'], # physical disk name holding partition
'device': None, # kpartx device node for partition
'mount': None, # Mount object
'subvol': items[1], # Subvolume name
'boot': False, # Bootable flag
'mounted': False # Mount flag
})
def __create_subvolumes(self, p, pdisk):
""" Create all the subvolumes. """
for subvol in self.subvolumes:
argv = [ self.btrfscmd, "subvolume", "create", pdisk.mountdir + "/" + subvol["subvol"]]
rc = runner.show(argv)
if rc != 0:
raise MountError("Failed to create subvolume '%s', return code: %d." % (subvol["subvol"], rc))
# Set default subvolume, subvolume for "/" is default
subvol = None
for subvolume in self.subvolumes:
if subvolume["mountpoint"] == "/" and p['disk_name'] == subvolume['disk_name']:
subvol = subvolume
break
if subvol:
# Get default subvolume id
subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
# Set default subvolume
if subvolid != -1:
rc = runner.show([ self.btrfscmd, "subvolume", "set-default", "%d" % subvolid, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to set default subvolume id: %d', return code: %d." % (subvolid, rc))
self.__create_subvolume_metadata(p, pdisk)
def __mount_subvolumes(self, p, pdisk):
if self.skipformat:
# Get subvolume info
self.__get_subvolume_metadata(p, pdisk)
# Set default mount options
if len(self.subvolumes) != 0:
for subvol in self.subvolumes:
if subvol["mountpoint"] == p["mountpoint"] == "/":
opts = subvol["fsopts"].split(",")
for opt in opts:
if opt.strip().startswith("subvol="):
opts.remove(opt)
break
pdisk.fsopts = ",".join(opts)
break
if len(self.subvolumes) == 0:
# Return directly if no subvolumes
return
# Remount to make default subvolume mounted
rc = runner.show([self.umountcmd, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
rc = runner.show([self.mountcmd, "-o", pdisk.fsopts, pdisk.disk.device, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
for subvol in self.subvolumes:
if subvol["mountpoint"] == "/":
continue
subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
if subvolid == -1:
msger.debug("WARNING: invalid subvolume %s" % subvol["subvol"])
continue
# Replace subvolume name with subvolume ID
opts = subvol["fsopts"].split(",")
for opt in opts:
if opt.strip().startswith("subvol="):
opts.remove(opt)
break
opts.extend(["subvolrootid=0", "subvol=%s" % subvol["subvol"]])
fsopts = ",".join(opts)
subvol['fsopts'] = fsopts
mountpoint = self.mountdir + subvol['mountpoint']
makedirs(mountpoint)
rc = runner.show([self.mountcmd, "-o", fsopts, pdisk.disk.device, mountpoint])
if rc != 0:
raise MountError("Failed to mount subvolume %s to %s" % (subvol["subvol"], mountpoint))
subvol["mounted"] = True
def __unmount_subvolumes(self):
""" It may be called multiple times, so we need to chekc if it is still mounted. """
for subvol in self.subvolumes:
if subvol["mountpoint"] == "/":
continue
if not subvol["mounted"]:
continue
mountpoint = self.mountdir + subvol['mountpoint']
rc = runner.show([self.umountcmd, mountpoint])
if rc != 0:
raise MountError("Failed to unmount subvolume %s from %s" % (subvol["subvol"], mountpoint))
subvol["mounted"] = False
def __create_subvolume_snapshots(self, p, pdisk):
import time
if self.snapshot_created:
return
# Remount with subvolid=0
rc = runner.show([self.umountcmd, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
if pdisk.fsopts:
mountopts = pdisk.fsopts + ",subvolid=0"
else:
mountopts = "subvolid=0"
rc = runner.show([self.mountcmd, "-o", mountopts, pdisk.disk.device, pdisk.mountdir])
if rc != 0:
raise MountError("Failed to umount %s" % pdisk.mountdir)
# Create all the subvolume snapshots
snapshotts = time.strftime("%Y%m%d-%H%M")
for subvol in self.subvolumes:
subvolpath = pdisk.mountdir + "/" + subvol["subvol"]
snapshotpath = subvolpath + "_%s-1" % snapshotts
rc = runner.show([ self.btrfscmd, "subvolume", "snapshot", subvolpath, snapshotpath ])
if rc != 0:
raise MountError("Failed to create subvolume snapshot '%s' for '%s', return code: %d." % (snapshotpath, subvolpath, rc))
self.snapshot_created = True
def __install_partition(self, num, source_file, start, size):
"""
Install source_file contents into a partition.
@ -734,7 +387,3 @@ class PartitionedMount(Mount):
self.__calculate_mountorder()
return
def resparse(self, size = None):
# Can't re-sparse a disk image - too hard
pass