partition.py revision 861b2d54aec24228cdb3895dbc40062cb40cb2ad
19bfef382c7abd3737e9abe10c958de6b04e290b9mbligh""" 2543dceb5ea025a99639b74e65dfdc867284001c4jadmanskiAPIs to write tests and control files that handle partition creation, deletion 3543dceb5ea025a99639b74e65dfdc867284001c4jadmanskiand formatting. 4543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 5543dceb5ea025a99639b74e65dfdc867284001c4jadmanski@copyright: Google 2006-2008 6543dceb5ea025a99639b74e65dfdc867284001c4jadmanski@author: Martin Bligh (mbligh@google.com) 79bfef382c7abd3737e9abe10c958de6b04e290b9mbligh""" 8d7fb4a6d385df6d97032f8ef9d62c2a3b4c5ab98mbligh 9543dceb5ea025a99639b74e65dfdc867284001c4jadmanskiimport os, re, string, sys, fcntl, logging 10543dceb5ea025a99639b74e65dfdc867284001c4jadmanskifrom autotest_lib.client.bin import os_dep, utils 11543dceb5ea025a99639b74e65dfdc867284001c4jadmanskifrom autotest_lib.client.common_lib import error 12543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 13543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 14543dceb5ea025a99639b74e65dfdc867284001c4jadmanskiclass FsOptions(object): 15543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 16543dceb5ea025a99639b74e65dfdc867284001c4jadmanski A class encapsulating a filesystem test's parameters. 17543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 18543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # NOTE(gps): This class could grow or be merged with something else in the 19543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # future that actually uses the encapsulated data (say to run mkfs) rather 20543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # than just being a container. 21543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # Ex: fsdev_disks.mkfs_all_disks really should become a method. 22543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 23543dceb5ea025a99639b74e65dfdc867284001c4jadmanski __slots__ = ('fstype', 'mkfs_flags', 'mount_options', 'fs_tag') 24543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 25543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def __init__(self, fstype, fs_tag, mkfs_flags=None, mount_options=None): 26543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 27543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Fill in our properties. 28543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 29543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param fstype: The filesystem type ('ext2', 'ext4', 'xfs', etc.) 30543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param fs_tag: A short name for this filesystem test to use 31543dceb5ea025a99639b74e65dfdc867284001c4jadmanski in the results. 32543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param mkfs_flags: Optional. Additional command line options to mkfs. 33543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param mount_options: Optional. The options to pass to mount -o. 34543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 35543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 36543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not fstype or not fs_tag: 37543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise ValueError('A filesystem and fs_tag are required.') 38543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fstype = fstype 39543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fs_tag = fs_tag 40543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mkfs_flags = mkfs_flags or "" 41543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mount_options = mount_options or "" 42543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 43543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 44543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def __str__(self): 45543dceb5ea025a99639b74e65dfdc867284001c4jadmanski val = ('FsOptions(fstype=%r, mkfs_flags=%r, ' 46543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 'mount_options=%r, fs_tag=%r)' % 47543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (self.fstype, self.mkfs_flags, 48543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mount_options, self.fs_tag)) 49543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return val 50543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 51543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 52543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef partname_to_device(part): 53543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ Converts a partition name to its associated device """ 54543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return os.path.join(os.sep, 'dev', part) 55543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 56543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 57543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef list_mount_devices(): 58543dceb5ea025a99639b74e65dfdc867284001c4jadmanski devices = [] 59543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # list mounted filesystems 60543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for line in utils.system_output('mount').splitlines(): 61543dceb5ea025a99639b74e65dfdc867284001c4jadmanski devices.append(line.split()[0]) 62543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # list mounted swap devices 63543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for line in utils.system_output('swapon -s').splitlines(): 64543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if line.startswith('/'): # skip header line 65543dceb5ea025a99639b74e65dfdc867284001c4jadmanski devices.append(line.split()[0]) 66543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return devices 67543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 68543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 69543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef list_mount_points(): 70543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoints = [] 71543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for line in utils.system_output('mount').splitlines(): 72543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoints.append(line.split()[2]) 73543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return mountpoints 74543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 75543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 76543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef get_iosched_path(device_name, component): 77543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return '/sys/block/%s/queue/%s' % (device_name, component) 78543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 79543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 80543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef wipe_filesystem(job, mountpoint): 81543dceb5ea025a99639b74e65dfdc867284001c4jadmanski wipe_cmd = 'rm -rf %s/*' % mountpoint 82543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 83543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(wipe_cmd) 84543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except: 85543dceb5ea025a99639b74e65dfdc867284001c4jadmanski job.record('FAIL', None, wipe_cmd, error.format_error()) 86543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise 87543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 88543dceb5ea025a99639b74e65dfdc867284001c4jadmanski job.record('GOOD', None, wipe_cmd) 89543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 90543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 91543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef is_linux_fs_type(device): 92543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 93543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Checks if specified partition is type 83 94543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 95543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param device: the device, e.g. /dev/sda3 96543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 97543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @return: False if the supplied partition name is not type 83 linux, True 98543dceb5ea025a99639b74e65dfdc867284001c4jadmanski otherwise 99543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 100543dceb5ea025a99639b74e65dfdc867284001c4jadmanski disk_device = device.rstrip('0123456789') 101543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 102543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # Parse fdisk output to get partition info. Ugly but it works. 103543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fdisk_fd = os.popen("/sbin/fdisk -l -u '%s'" % disk_device) 104543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fdisk_lines = fdisk_fd.readlines() 105543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fdisk_fd.close() 106543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for line in fdisk_lines: 107543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not line.startswith(device): 108543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 109543dceb5ea025a99639b74e65dfdc867284001c4jadmanski info_tuple = line.split() 110543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # The Id will be in one of two fields depending on if the boot flag 111543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # was set. Caveat: this assumes no boot partition will be 83 blocks. 112543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for fsinfo in info_tuple[4:6]: 113543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if fsinfo == '83': # hex 83 is the linux fs partition type 114543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return True 115543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return False 116543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 117543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 118543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef get_partition_list(job, min_blocks=0, filter_func=None, exclude_swap=True, 119543dceb5ea025a99639b74e65dfdc867284001c4jadmanski open_func=open): 120543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 121543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Get a list of partition objects for all disk partitions on the system. 122543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 123543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Loopback devices and unnumbered (whole disk) devices are always excluded. 124543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 125543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param job: The job instance to pass to the partition object 126543dceb5ea025a99639b74e65dfdc867284001c4jadmanski constructor. 127543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param min_blocks: The minimum number of blocks for a partition to 128543dceb5ea025a99639b74e65dfdc867284001c4jadmanski be considered. 129543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param filter_func: A callable that returns True if a partition is 130543dceb5ea025a99639b74e65dfdc867284001c4jadmanski desired. It will be passed one parameter: 131543dceb5ea025a99639b74e65dfdc867284001c4jadmanski The partition name (hdc3, etc.). 132543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Some useful filter functions are already defined in this module. 133543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param exclude_swap: If True any partition actively in use as a swap 134543dceb5ea025a99639b74e65dfdc867284001c4jadmanski device will be excluded. 135543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param __open: Reserved for unit testing. 136543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 137543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @return: A list of L{partition} objects. 138543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 139543dceb5ea025a99639b74e65dfdc867284001c4jadmanski active_swap_devices = set() 140543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if exclude_swap: 141543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for swapline in open_func('/proc/swaps'): 142543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if swapline.startswith('/'): 143543dceb5ea025a99639b74e65dfdc867284001c4jadmanski active_swap_devices.add(swapline.split()[0]) 144543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 145543dceb5ea025a99639b74e65dfdc867284001c4jadmanski partitions = [] 146543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for partline in open_func('/proc/partitions').readlines(): 147543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fields = partline.strip().split() 148543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if len(fields) != 4 or partline.startswith('major'): 149543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 150543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (major, minor, blocks, partname) = fields 151543dceb5ea025a99639b74e65dfdc867284001c4jadmanski blocks = int(blocks) 152543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 153543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # The partition name better end with a digit, else it's not a partition 154543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not partname[-1].isdigit(): 155543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 156543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 157543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # We don't want the loopback device in the partition list 158543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if 'loop' in partname: 159543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 160543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 161543dceb5ea025a99639b74e65dfdc867284001c4jadmanski device = partname_to_device(partname) 162543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if exclude_swap and device in active_swap_devices: 163543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Skipping %s - Active swap.' % partname) 164543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 165543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 166543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if min_blocks and blocks < min_blocks: 167543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Skipping %s - Too small.' % partname) 168543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 169543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 170543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if filter_func and not filter_func(partname): 171543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Skipping %s - Filter func.' % partname) 172543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 173543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 174543dceb5ea025a99639b74e65dfdc867284001c4jadmanski partitions.append(partition(job, device)) 175543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 176543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return partitions 177543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 178543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 179e0493a4af57c1a73376a7bafaed542c01f588196Eric Lidef get_mount_info(partition_list): 180e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 181e0493a4af57c1a73376a7bafaed542c01f588196Eric Li Picks up mount point information about the machine mounts. By default, we 182e0493a4af57c1a73376a7bafaed542c01f588196Eric Li try to associate mount points with UUIDs, because in newer distros the 183e0493a4af57c1a73376a7bafaed542c01f588196Eric Li partitions are uniquely identified using them. 184e0493a4af57c1a73376a7bafaed542c01f588196Eric Li """ 185e0493a4af57c1a73376a7bafaed542c01f588196Eric Li mount_info = set() 186e0493a4af57c1a73376a7bafaed542c01f588196Eric Li for p in partition_list: 187e0493a4af57c1a73376a7bafaed542c01f588196Eric Li try: 188861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li uuid = utils.system_output('blkid -p -s UUID -o value %s' % p.device) 189e0493a4af57c1a73376a7bafaed542c01f588196Eric Li except error.CmdError: 190e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # fall back to using the partition 191e0493a4af57c1a73376a7bafaed542c01f588196Eric Li uuid = p.device 192e0493a4af57c1a73376a7bafaed542c01f588196Eric Li mount_info.add((uuid, p.get_mountpoint())) 193e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 194e0493a4af57c1a73376a7bafaed542c01f588196Eric Li return mount_info 195e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 196e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 197543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef filter_partition_list(partitions, devnames): 198543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 199543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Pick and choose which partition to keep. 200543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 201543dceb5ea025a99639b74e65dfdc867284001c4jadmanski filter_partition_list accepts a list of partition objects and a list 202543dceb5ea025a99639b74e65dfdc867284001c4jadmanski of strings. If a partition has the device name of the strings it 203543dceb5ea025a99639b74e65dfdc867284001c4jadmanski is returned in a list. 204543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 205543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param partitions: A list of L{partition} objects 206543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param devnames: A list of devnames of the form '/dev/hdc3' that 207543dceb5ea025a99639b74e65dfdc867284001c4jadmanski specifies which partitions to include in the returned list. 208543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 209543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @return: A list of L{partition} objects specified by devnames, in the 210543dceb5ea025a99639b74e65dfdc867284001c4jadmanski order devnames specified 211543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 212543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 213543dceb5ea025a99639b74e65dfdc867284001c4jadmanski filtered_list = [] 214543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for p in partitions: 215543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for d in devnames: 216543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if p.device == d and p not in filtered_list: 217543dceb5ea025a99639b74e65dfdc867284001c4jadmanski filtered_list.append(p) 218543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 219543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return filtered_list 220543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 221543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 222543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef get_unmounted_partition_list(root_part, job=None, min_blocks=0, 223543dceb5ea025a99639b74e65dfdc867284001c4jadmanski filter_func=None, exclude_swap=True, 224543dceb5ea025a99639b74e65dfdc867284001c4jadmanski open_func=open): 225543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 226543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Return a list of partition objects that are not mounted. 227543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 228543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param root_part: The root device name (without the '/dev/' prefix, example 229543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 'hda2') that will be filtered from the partition list. 230543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 231543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Reasoning: in Linux /proc/mounts will never directly mention the 232543dceb5ea025a99639b74e65dfdc867284001c4jadmanski root partition as being mounted on / instead it will say that 233543dceb5ea025a99639b74e65dfdc867284001c4jadmanski /dev/root is mounted on /. Thus require this argument to filter out 234543dceb5ea025a99639b74e65dfdc867284001c4jadmanski the root_part from the ones checked to be mounted. 235543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param job, min_blocks, filter_func, exclude_swap, open_func: Forwarded 236543dceb5ea025a99639b74e65dfdc867284001c4jadmanski to get_partition_list(). 237543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @return List of L{partition} objects that are not mounted. 238543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 239543dceb5ea025a99639b74e65dfdc867284001c4jadmanski partitions = get_partition_list(job=job, min_blocks=min_blocks, 240543dceb5ea025a99639b74e65dfdc867284001c4jadmanski filter_func=filter_func, exclude_swap=exclude_swap, open_func=open_func) 241543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 242543dceb5ea025a99639b74e65dfdc867284001c4jadmanski unmounted = [] 243543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for part in partitions: 244543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if (part.device != partname_to_device(root_part) and 245543dceb5ea025a99639b74e65dfdc867284001c4jadmanski not part.get_mountpoint(open_func=open_func)): 246543dceb5ea025a99639b74e65dfdc867284001c4jadmanski unmounted.append(part) 247543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 248543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return unmounted 249543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 250543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 251543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef parallel(partitions, method_name, *args, **dargs): 252543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 253543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Run a partition method (with appropriate arguments) in parallel, 254543dceb5ea025a99639b74e65dfdc867284001c4jadmanski across a list of partition objects 255543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 256543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not partitions: 257543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 258543dceb5ea025a99639b74e65dfdc867284001c4jadmanski job = partitions[0].job 259543dceb5ea025a99639b74e65dfdc867284001c4jadmanski flist = [] 260543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if (not hasattr(partition, method_name) or 261543dceb5ea025a99639b74e65dfdc867284001c4jadmanski not callable(getattr(partition, method_name))): 262543dceb5ea025a99639b74e65dfdc867284001c4jadmanski err = "partition.parallel got invalid method %s" % method_name 263543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise RuntimeError(err) 264543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 265543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for p in partitions: 266543dceb5ea025a99639b74e65dfdc867284001c4jadmanski print_args = list(args) 267543dceb5ea025a99639b74e65dfdc867284001c4jadmanski print_args += ['%s=%s' % (key, dargs[key]) for key in dargs.keys()] 268543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('%s.%s(%s)' % (str(p), method_name, 269543dceb5ea025a99639b74e65dfdc867284001c4jadmanski ', '.join(print_args))) 270543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sys.stdout.flush() 271543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _run_named_method(function, part=p): 272543dceb5ea025a99639b74e65dfdc867284001c4jadmanski getattr(part, method_name)(*args, **dargs) 273543dceb5ea025a99639b74e65dfdc867284001c4jadmanski flist.append((_run_named_method, ())) 274543dceb5ea025a99639b74e65dfdc867284001c4jadmanski job.parallel(*flist) 275543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 276543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 277543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef filesystems(): 278543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 279543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Return a list of all available filesystems 280543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 281543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return [re.sub('(nodev)?\s*', '', fs) for fs in open('/proc/filesystems')] 282543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 283543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 284543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef unmount_partition(device): 285543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 286543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Unmount a mounted partition 287543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 288543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param device: e.g. /dev/sda1, /dev/hda1 289543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 290543dceb5ea025a99639b74e65dfdc867284001c4jadmanski p = partition(job=None, device=device) 291543dceb5ea025a99639b74e65dfdc867284001c4jadmanski p.unmount(record=False) 292543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 293543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 294543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef is_valid_partition(device): 295543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 296543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Checks if a partition is valid 297543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 298543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param device: e.g. /dev/sda1, /dev/hda1 299543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 300543dceb5ea025a99639b74e65dfdc867284001c4jadmanski parts = get_partition_list(job=None) 301543dceb5ea025a99639b74e65dfdc867284001c4jadmanski p_list = [ p.device for p in parts ] 302543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if device in p_list: 303543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return True 304543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 305543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return False 306543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 307543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 308543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef is_valid_disk(device): 309543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 310543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Checks if a disk is valid 311543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 312543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param device: e.g. /dev/sda, /dev/hda 313543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 314543dceb5ea025a99639b74e65dfdc867284001c4jadmanski partitions = [] 315543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for partline in open('/proc/partitions').readlines(): 316543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fields = partline.strip().split() 317543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if len(fields) != 4 or partline.startswith('major'): 318543dceb5ea025a99639b74e65dfdc867284001c4jadmanski continue 319543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (major, minor, blocks, partname) = fields 320543dceb5ea025a99639b74e65dfdc867284001c4jadmanski blocks = int(blocks) 321543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 322543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not partname[-1].isdigit(): 323543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # Disk name does not end in number, AFAIK 324543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # so use it as a reference to a disk 325543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if device.strip("/dev/") == partname: 326543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return True 327543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 328543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return False 329543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 330543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 331543dceb5ea025a99639b74e65dfdc867284001c4jadmanskidef run_test_on_partitions(job, test, partitions, mountpoint_func, 332e0493a4af57c1a73376a7bafaed542c01f588196Eric Li tag, fs_opt, do_fsck=True, **dargs): 333543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 334543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Run a test that requires multiple partitions. Filesystems will be 335543dceb5ea025a99639b74e65dfdc867284001c4jadmanski made on the partitions and mounted, then the test will run, then the 336e0493a4af57c1a73376a7bafaed542c01f588196Eric Li filesystems will be unmounted and optionally fsck'd. 337543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 338543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param job: A job instance to run the test 339543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param test: A string containing the name of the test 340543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param partitions: A list of partition objects, these are passed to the 341543dceb5ea025a99639b74e65dfdc867284001c4jadmanski test as partitions= 342543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param mountpoint_func: A callable that returns a mountpoint given a 343543dceb5ea025a99639b74e65dfdc867284001c4jadmanski partition instance 344543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param tag: A string tag to make this test unique (Required for control 345543dceb5ea025a99639b74e65dfdc867284001c4jadmanski files that make multiple calls to this routine with the same value 346543dceb5ea025a99639b74e65dfdc867284001c4jadmanski of 'test'.) 347543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param fs_opt: An FsOptions instance that describes what filesystem to make 348e0493a4af57c1a73376a7bafaed542c01f588196Eric Li @param do_fsck: include fsck in post-test partition cleanup. 349543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param dargs: Dictionary of arguments to be passed to job.run_test() and 350543dceb5ea025a99639b74e65dfdc867284001c4jadmanski eventually the test 351543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 352543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # setup the filesystem parameters for all the partitions 353543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for p in partitions: 354543dceb5ea025a99639b74e65dfdc867284001c4jadmanski p.set_fs_options(fs_opt) 355543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 356543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # make and mount all the partitions in parallel 357543dceb5ea025a99639b74e65dfdc867284001c4jadmanski parallel(partitions, 'setup_before_test', mountpoint_func=mountpoint_func) 358543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 359543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoint = mountpoint_func(partitions[0]) 360543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 361543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # run the test against all the partitions 362543dceb5ea025a99639b74e65dfdc867284001c4jadmanski job.run_test(test, tag=tag, partitions=partitions, dir=mountpoint, **dargs) 363543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 364e0493a4af57c1a73376a7bafaed542c01f588196Eric Li parallel(partitions, 'unmount') # unmount all partitions in parallel 365e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if do_fsck: 366e0493a4af57c1a73376a7bafaed542c01f588196Eric Li parallel(partitions, 'fsck') # fsck all partitions in parallel 367e0493a4af57c1a73376a7bafaed542c01f588196Eric Li # else fsck is done by caller 368543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 369543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 370543dceb5ea025a99639b74e65dfdc867284001c4jadmanskiclass partition(object): 371543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 372543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Class for handling partitions and filesystems 373543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 374543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 375543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def __init__(self, job, device, loop_size=0, mountpoint=None): 376543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 377543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param job: A L{client.bin.job} instance. 378543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param device: The device in question (e.g."/dev/hda2"). If device is a 379543dceb5ea025a99639b74e65dfdc867284001c4jadmanski file it will be mounted as loopback. If you have job config 380543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 'partition.partitions', e.g., 381543dceb5ea025a99639b74e65dfdc867284001c4jadmanski job.config_set('partition.partitions', ["/dev/sda2", "/dev/sda3"]) 382543dceb5ea025a99639b74e65dfdc867284001c4jadmanski you may specify a partition in the form of "partN" e.g. "part0", 383543dceb5ea025a99639b74e65dfdc867284001c4jadmanski "part1" to refer to elements of the partition list. This is 384543dceb5ea025a99639b74e65dfdc867284001c4jadmanski specially useful if you run a test in various machines and you 385543dceb5ea025a99639b74e65dfdc867284001c4jadmanski don't want to hardcode device names as those may vary. 386543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param loop_size: Size of loopback device (in MB). Defaults to 0. 387543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 388543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # NOTE: This code is used by IBM / ABAT. Do not remove. 389543dceb5ea025a99639b74e65dfdc867284001c4jadmanski part = re.compile(r'^part(\d+)$') 390543dceb5ea025a99639b74e65dfdc867284001c4jadmanski m = part.match(device) 391543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if m: 392543dceb5ea025a99639b74e65dfdc867284001c4jadmanski number = int(m.groups()[0]) 393543dceb5ea025a99639b74e65dfdc867284001c4jadmanski partitions = job.config_get('partition.partitions') 394543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 395543dceb5ea025a99639b74e65dfdc867284001c4jadmanski device = partitions[number] 396543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except: 397543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError("Partition '" + device + "' not available") 398543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 399543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.device = device 400543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.name = os.path.basename(device) 401543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job = job 402543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.loop = loop_size 403543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fstype = None 404543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mountpoint = mountpoint 405543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mkfs_flags = None 406543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mount_options = None 407543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fs_tag = None 408543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.loop: 409543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'dd if=/dev/zero of=%s bs=1M count=%d' % (device, loop_size) 410543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(cmd) 411543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 412543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 413543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def __repr__(self): 414543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return '<Partition: %s>' % self.device 415543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 416543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 417543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def set_fs_options(self, fs_options): 418543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 419543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Set filesystem options 420543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 421543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param fs_options: A L{FsOptions} object 422543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 423543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 424543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fstype = fs_options.fstype 425543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mkfs_flags = fs_options.mkfs_flags 426543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mount_options = fs_options.mount_options 427543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fs_tag = fs_options.fs_tag 428543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 429543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 430543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def run_test(self, test, **dargs): 431543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.run_test(test, dir=self.get_mountpoint(), **dargs) 432543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 433543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 434543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def setup_before_test(self, mountpoint_func): 435543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 436543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Prepare a partition for running a test. Unmounts any 437543dceb5ea025a99639b74e65dfdc867284001c4jadmanski filesystem that's currently mounted on the partition, makes a 438543dceb5ea025a99639b74e65dfdc867284001c4jadmanski new filesystem (according to this partition's filesystem 439543dceb5ea025a99639b74e65dfdc867284001c4jadmanski options) and mounts it where directed by mountpoint_func. 440543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 441543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param mountpoint_func: A callable that returns a path as a string, 442543dceb5ea025a99639b74e65dfdc867284001c4jadmanski given a partition instance. 443543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 444543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoint = mountpoint_func(self) 445543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not mountpoint: 446543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise ValueError('Don\'t know where to put this partition') 447543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.unmount(ignore_status=True, record=False) 448543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mkfs() 449543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not os.path.isdir(mountpoint): 450543dceb5ea025a99639b74e65dfdc867284001c4jadmanski os.makedirs(mountpoint) 451543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.mount(mountpoint) 452543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 453543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 454543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def run_test_on_partition(self, test, mountpoint_func, **dargs): 455543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 456543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Executes a test fs-style (umount,mkfs,mount,test) 457543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 458543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Here we unmarshal the args to set up tags before running the test. 459543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Tests are also run by first umounting, mkfsing and then mounting 460543dceb5ea025a99639b74e65dfdc867284001c4jadmanski before executing the test. 461543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 462543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param test: name of test to run 463543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param mountpoint_func: function to return mount point string 464543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 465543dceb5ea025a99639b74e65dfdc867284001c4jadmanski tag = dargs.get('tag') 466543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if tag: 467543dceb5ea025a99639b74e65dfdc867284001c4jadmanski tag = '%s.%s' % (self.name, tag) 468543dceb5ea025a99639b74e65dfdc867284001c4jadmanski elif self.fs_tag: 469543dceb5ea025a99639b74e65dfdc867284001c4jadmanski tag = '%s.%s' % (self.name, self.fs_tag) 470543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 471543dceb5ea025a99639b74e65dfdc867284001c4jadmanski tag = self.name 472543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 473543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # If there's a 'suffix' argument, append it to the tag and remove it 474543dceb5ea025a99639b74e65dfdc867284001c4jadmanski suffix = dargs.pop('suffix', None) 475543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if suffix: 476543dceb5ea025a99639b74e65dfdc867284001c4jadmanski tag = '%s.%s' % (tag, suffix) 477543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 478543dceb5ea025a99639b74e65dfdc867284001c4jadmanski dargs['tag'] = test + '.' + tag 479543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 480543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _make_partition_and_run_test(test_tag, dir=None, **dargs): 481543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.setup_before_test(mountpoint_func) 482543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 483543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.run_test(test, tag=test_tag, dir=mountpoint, **dargs) 484543dceb5ea025a99639b74e65dfdc867284001c4jadmanski finally: 485e0493a4af57c1a73376a7bafaed542c01f588196Eric Li self.unmount() 486e0493a4af57c1a73376a7bafaed542c01f588196Eric Li self.fsck() 487e0493a4af57c1a73376a7bafaed542c01f588196Eric Li 488543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 489543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoint = mountpoint_func(self) 490543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 491543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # The tag is the tag for the group (get stripped off by run_group) 492543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # The test_tag is the tag for the test itself 493543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.run_group(_make_partition_and_run_test, 494543dceb5ea025a99639b74e65dfdc867284001c4jadmanski test_tag=tag, dir=mountpoint, **dargs) 495543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 496543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 497543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def get_mountpoint(self, open_func=open, filename=None): 498543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 499543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Find the mount point of this partition object. 500543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 501543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param open_func: the function to use for opening the file containing 502543dceb5ea025a99639b74e65dfdc867284001c4jadmanski the mounted partitions information 503543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param filename: where to look for the mounted partitions information 504543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (default None which means it will search /proc/mounts and/or 505543dceb5ea025a99639b74e65dfdc867284001c4jadmanski /etc/mtab) 506543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 507543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @returns a string with the mount point of the partition or None if not 508543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mounted 509543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 510543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if filename: 511543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for line in open_func(filename).readlines(): 512543dceb5ea025a99639b74e65dfdc867284001c4jadmanski parts = line.split() 513e0493a4af57c1a73376a7bafaed542c01f588196Eric Li if parts[0] == self.device or parts[1] == self.mountpoint: 514543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return parts[1] # The mountpoint where it's mounted 515543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return None 516543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 517543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # no specific file given, look in /proc/mounts 518543dceb5ea025a99639b74e65dfdc867284001c4jadmanski res = self.get_mountpoint(open_func=open_func, filename='/proc/mounts') 519543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not res: 520543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # sometimes the root partition is reported as /dev/root in 521543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # /proc/mounts in this case, try /etc/mtab 522543dceb5ea025a99639b74e65dfdc867284001c4jadmanski res = self.get_mountpoint(open_func=open_func, filename='/etc/mtab') 523543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 524543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # trust /etc/mtab only about / 525543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if res != '/': 526543dceb5ea025a99639b74e65dfdc867284001c4jadmanski res = None 527543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 528543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return res 529543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 530543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 531543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def mkfs_exec(self, fstype): 532543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 533543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Return the proper mkfs executable based on fs 534543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 535543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if fstype == 'ext4': 536543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if os.path.exists('/sbin/mkfs.ext4'): 537543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 'mkfs' 538543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # If ext4 supported e2fsprogs is not installed we use the 539543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # autotest supplied one in tools dir which is statically linked""" 540543dceb5ea025a99639b74e65dfdc867284001c4jadmanski auto_mkfs = os.path.join(self.job.toolsdir, 'mkfs.ext4dev') 541543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if os.path.exists(auto_mkfs): 542543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return auto_mkfs 543543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 544543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 'mkfs' 545543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 546543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError('Error creating partition for filesystem type %s' % 547543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fstype) 548543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 549543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 550543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def mkfs(self, fstype=None, args='', record=True): 551543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 552543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Format a partition to filesystem type 553543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 554543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param fstype: the filesystem type, e.g.. "ext3", "ext2" 555543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param args: arguments to be passed to mkfs command. 556543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param record: if set, output result of mkfs operation to autotest 557543dceb5ea025a99639b74e65dfdc867284001c4jadmanski output 558543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 559543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 560543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if list_mount_devices().count(self.device): 561543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError('Attempted to format mounted device %s' % 562543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.device) 563543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 564543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not fstype: 565543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.fstype: 566543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fstype = self.fstype 567543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 568543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fstype = 'ext2' 569543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 570543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.mkfs_flags: 571543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' ' + self.mkfs_flags 572543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if fstype == 'xfs': 573543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' -f' 574543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 575543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.loop: 576543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # BAH. Inconsistent mkfs syntax SUCKS. 577543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if fstype.startswith('ext'): 578543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' -F' 579543dceb5ea025a99639b74e65dfdc867284001c4jadmanski elif fstype == 'reiserfs': 580543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' -f' 581543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 582543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # If there isn't already a '-t <type>' argument, add one. 583543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not "-t" in args: 584543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args = "-t %s %s" % (fstype, args) 585543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 586543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args = args.strip() 587543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 588543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mkfs_cmd = "%s %s %s" % (self.mkfs_exec(fstype), args, self.device) 589543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 590543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sys.stdout.flush() 591543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 592543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # We throw away the output here - we only need it on error, in 593543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # which case it's in the exception 594543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system_output("yes | %s" % mkfs_cmd) 595543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 596543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.error(e.result_obj) 597543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 598543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, mkfs_cmd, error.format_error()) 599543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise 600543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except: 601543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 602543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, mkfs_cmd, error.format_error()) 603543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise 604543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 605543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 606543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('GOOD', None, mkfs_cmd) 607543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fstype = fstype 608543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 609543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 610543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def get_fsck_exec(self): 611543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 612543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Return the proper mkfs executable based on self.fstype 613543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 614543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.fstype == 'ext4': 615543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if os.path.exists('/sbin/fsck.ext4'): 616543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 'fsck' 617543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # If ext4 supported e2fsprogs is not installed we use the 618543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # autotest supplied one in tools dir which is statically linked""" 619543dceb5ea025a99639b74e65dfdc867284001c4jadmanski auto_fsck = os.path.join(self.job.toolsdir, 'fsck.ext4dev') 620543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if os.path.exists(auto_fsck): 621543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return auto_fsck 622543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 623543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 'fsck' 624543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 625543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError('Error creating partition for filesystem type %s' % 626543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fstype) 627543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 628543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 629543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def fsck(self, args='-fy', record=True): 630543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 631543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Run filesystem check 632543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 633543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param args: arguments to filesystem check tool. Default is "-n" 634543dceb5ea025a99639b74e65dfdc867284001c4jadmanski which works on most tools. 635543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 636543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 637543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # I hate reiserfstools. 638543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # Requires an explit Yes for some inane reason 639543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fsck_cmd = '%s %s %s' % (self.get_fsck_exec(), self.device, args) 640543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.fstype == 'reiserfs': 641543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fsck_cmd = 'yes "Yes" | ' + fsck_cmd 642543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sys.stdout.flush() 643543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 644543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system_output(fsck_cmd) 645543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except: 646543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 647543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, fsck_cmd, error.format_error()) 648543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.TestError('Fsck found errors with the underlying ' 649543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 'file system') 650543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 651543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 652543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('GOOD', None, fsck_cmd) 653543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 654543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 6556f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li def mount(self, mountpoint=None, fstype=None, args='', record=True): 656543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 657543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Mount this partition to a mount point 658543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 659543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param mountpoint: If you have not provided a mountpoint to partition 660543dceb5ea025a99639b74e65dfdc867284001c4jadmanski object or want to use a different one, you may specify it here. 661543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param fstype: Filesystem type. If not provided partition object value 662543dceb5ea025a99639b74e65dfdc867284001c4jadmanski will be used. 663543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param args: Arguments to be passed to "mount" command. 664543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param record: If True, output result of mount operation to autotest 665543dceb5ea025a99639b74e65dfdc867284001c4jadmanski output. 666543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 667543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 668543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if fstype is None: 669543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fstype = self.fstype 670543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 671543dceb5ea025a99639b74e65dfdc867284001c4jadmanski assert(self.fstype is None or self.fstype == fstype); 672543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 673543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.mount_options: 674543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' -o ' + self.mount_options 675543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if fstype: 676543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' -t ' + fstype 677543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.loop: 678543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args += ' -o loop' 679543dceb5ea025a99639b74e65dfdc867284001c4jadmanski args = args.lstrip() 680543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 681543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not mountpoint and not self.mountpoint: 682543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise ValueError("No mountpoint specified and no default " 683543dceb5ea025a99639b74e65dfdc867284001c4jadmanski "provided to this partition object") 684543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not mountpoint: 685543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoint = self.mountpoint 686543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 687543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mount_cmd = "mount %s %s %s" % (args, self.device, mountpoint) 688543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 689543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if list_mount_devices().count(self.device): 690543dceb5ea025a99639b74e65dfdc867284001c4jadmanski err = 'Attempted to mount mounted device' 691543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, mount_cmd, err) 692543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError(err) 693543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if list_mount_points().count(mountpoint): 694543dceb5ea025a99639b74e65dfdc867284001c4jadmanski err = 'Attempted to mount busy mountpoint' 695543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, mount_cmd, err) 696543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError(err) 697543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 698543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mtab = open('/etc/mtab') 699543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # We have to get an exclusive lock here - mount/umount are racy 700543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fcntl.flock(mtab.fileno(), fcntl.LOCK_EX) 701543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sys.stdout.flush() 702543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 703543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(mount_cmd) 704543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mtab.close() 705543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except: 706543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mtab.close() 707543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 708543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, mount_cmd, error.format_error()) 709543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise 710543dceb5ea025a99639b74e65dfdc867284001c4jadmanski else: 711543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 712543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('GOOD', None, mount_cmd) 713543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.fstype = fstype 714543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 715543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 716543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def unmount_force(self): 717543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 718543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Kill all other jobs accessing this partition. Use fuser and ps to find 719543dceb5ea025a99639b74e65dfdc867284001c4jadmanski all mounts on this mountpoint and unmount them. 720543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 721543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @return: true for success or false for any errors 722543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 723543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 724543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug("Standard umount failed, will try forcing. Users:") 725543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 726543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'fuser ' + self.get_mountpoint() 727543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug(cmd) 728543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fuser = utils.system_output(cmd) 729543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug(fuser) 730543dceb5ea025a99639b74e65dfdc867284001c4jadmanski users = re.sub('.*:', '', fuser).split() 731543dceb5ea025a99639b74e65dfdc867284001c4jadmanski for user in users: 732543dceb5ea025a99639b74e65dfdc867284001c4jadmanski m = re.match('(\d+)(.*)', user) 733543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (pid, usage) = (m.group(1), m.group(2)) 734543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 735543dceb5ea025a99639b74e65dfdc867284001c4jadmanski ps = utils.system_output('ps -p %s | sed 1d' % pid) 736543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('%s %s %s' % (usage, pid, ps)) 737543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except Exception: 738543dceb5ea025a99639b74e65dfdc867284001c4jadmanski pass 739543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system('ls -l ' + self.device) 740543dceb5ea025a99639b74e65dfdc867284001c4jadmanski umount_cmd = "umount -f " + self.device 741543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(umount_cmd) 742543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return True 743543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError: 744543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Umount_force failed for %s' % self.device) 745543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return False 746543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 747543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 748543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 749543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def unmount(self, ignore_status=False, record=True): 750543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 751543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Umount this partition. 752543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 753543dceb5ea025a99639b74e65dfdc867284001c4jadmanski It's easier said than done to umount a partition. 754543dceb5ea025a99639b74e65dfdc867284001c4jadmanski We need to lock the mtab file to make sure we don't have any 755543dceb5ea025a99639b74e65dfdc867284001c4jadmanski locking problems if we are umounting in paralllel. 756543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 757543dceb5ea025a99639b74e65dfdc867284001c4jadmanski If there turns out to be a problem with the simple umount we 758543dceb5ea025a99639b74e65dfdc867284001c4jadmanski end up calling umount_force to get more agressive. 759543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 760543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param ignore_status: should we notice the umount status 761543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param record: if True, output result of umount operation to 762543dceb5ea025a99639b74e65dfdc867284001c4jadmanski autotest output 763543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 764543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 765543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mountpoint = self.get_mountpoint() 766543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if not mountpoint: 767543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # It's not even mounted to start with 768543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record and not ignore_status: 769543dceb5ea025a99639b74e65dfdc867284001c4jadmanski msg = 'umount for dev %s has no mountpoint' % self.device 770543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, msg, 'Not mounted') 771543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 772543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 773543dceb5ea025a99639b74e65dfdc867284001c4jadmanski umount_cmd = "umount " + mountpoint 774543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mtab = open('/etc/mtab') 775543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 776543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # We have to get an exclusive lock here - mount/umount are racy 777543dceb5ea025a99639b74e65dfdc867284001c4jadmanski fcntl.flock(mtab.fileno(), fcntl.LOCK_EX) 778543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sys.stdout.flush() 779543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 780543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(umount_cmd) 781543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mtab.close() 782543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record: 783543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('GOOD', None, umount_cmd) 784543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except (error.CmdError, IOError): 785543dceb5ea025a99639b74e65dfdc867284001c4jadmanski mtab.close() 786543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 787543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # Try the forceful umount 788543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if self.unmount_force(): 789543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return 790543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 791543dceb5ea025a99639b74e65dfdc867284001c4jadmanski # If we are here we cannot umount this partition 792543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if record and not ignore_status: 793543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.job.record('FAIL', None, umount_cmd, error.format_error()) 794543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise 795543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 796543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 797543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def wipe(self): 798543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 799543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Delete all files of a given partition filesystem. 800543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 801543dceb5ea025a99639b74e65dfdc867284001c4jadmanski wipe_filesystem(self.job, self.get_mountpoint()) 802543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 803543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 804543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def get_io_scheduler_list(self, device_name): 805543dceb5ea025a99639b74e65dfdc867284001c4jadmanski names = open(self.__sched_path(device_name)).read() 806543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return names.translate(string.maketrans('[]', ' ')).split() 807543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 808543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 809543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def get_io_scheduler(self, device_name): 810543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return re.split('[\[\]]', 811543dceb5ea025a99639b74e65dfdc867284001c4jadmanski open(self.__sched_path(device_name)).read())[1] 812543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 813543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 814543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def set_io_scheduler(self, device_name, name): 815543dceb5ea025a99639b74e65dfdc867284001c4jadmanski if name not in self.get_io_scheduler_list(device_name): 816543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise NameError('No such IO scheduler: %s' % name) 817543dceb5ea025a99639b74e65dfdc867284001c4jadmanski f = open(self.__sched_path(device_name), 'w') 818543dceb5ea025a99639b74e65dfdc867284001c4jadmanski f.write(name) 819543dceb5ea025a99639b74e65dfdc867284001c4jadmanski f.close() 820543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 821543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 822543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def __sched_path(self, device_name): 823543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return '/sys/block/%s/queue/scheduler' % device_name 824543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 825543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 826543dceb5ea025a99639b74e65dfdc867284001c4jadmanskiclass virtual_partition: 827543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 828543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Handles block device emulation using file images of disks. 829543dceb5ea025a99639b74e65dfdc867284001c4jadmanski It's important to note that this API can be used only if 830543dceb5ea025a99639b74e65dfdc867284001c4jadmanski we have the following programs present on the client machine: 831543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 832543dceb5ea025a99639b74e65dfdc867284001c4jadmanski * sfdisk 833543dceb5ea025a99639b74e65dfdc867284001c4jadmanski * losetup 834543dceb5ea025a99639b74e65dfdc867284001c4jadmanski * kpartx 835543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 836543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def __init__(self, file_img, file_size): 837543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 838543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Creates a virtual partition, keeping record of the device created 839543dceb5ea025a99639b74e65dfdc867284001c4jadmanski under /dev/mapper (device attribute) so test writers can use it 840543dceb5ea025a99639b74e65dfdc867284001c4jadmanski on their filesystem tests. 841543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 842543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param file_img: Path to the desired disk image file. 843543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param file_size: Size of the desired image in Bytes. 844543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 845543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Sanity check before attempting to create virtual ' 846543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 'partition') 847543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 848543dceb5ea025a99639b74e65dfdc867284001c4jadmanski os_dep.commands('sfdisk', 'losetup', 'kpartx') 849543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except ValueError, e: 850543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Unable to create virtual partition: %s' % e 851543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 852543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 853543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Creating virtual partition') 854543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.img = self._create_disk_img(file_img, file_size) 855543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.loop = self._attach_img_loop(self.img) 856543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self._create_single_partition(self.loop) 857543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.device = self._create_entries_partition(self.loop) 858543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Virtual partition successfuly created') 859543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Image disk: %s', self.img) 860543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Loopback device: %s', self.loop) 861543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Device path: %s', self.device) 862543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 863543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 864543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def destroy(self): 865543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 866543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Removes the virtual partition from /dev/mapper, detaches the image file 867543dceb5ea025a99639b74e65dfdc867284001c4jadmanski from the loopback device and removes the image file. 868543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 869543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Removing virtual partition - device %s', self.device) 870543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self._remove_entries_partition() 871543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self._detach_img_loop() 872543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self._remove_disk_img() 873543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 874543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 875543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _create_disk_img(self, img_path, size): 876543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 877543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Creates a disk image using dd. 878543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 879543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param img_path: Path to the desired image file. 880543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param size: Size of the desired image in Bytes. 881543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @returns: Path of the image created. 882543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 883543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Creating disk image %s, size = %d Bytes', img_path, size) 884543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 885543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'dd if=/dev/zero of=%s bs=1024 count=%d' % (img_path, size) 886543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(cmd) 887543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 888543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Error creating disk image %s: %s' % (img_path, e) 889543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 890543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return img_path 891543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 892543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 893543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _attach_img_loop(self, img_path): 894543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 895543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Attaches a file image to a loopback device using losetup. 896543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 897543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param img_path: Path of the image file that will be attached to a 898543dceb5ea025a99639b74e65dfdc867284001c4jadmanski loopback device 899543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @returns: Path of the loopback device associated. 900543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 901543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Attaching image %s to a loop device', img_path) 902543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 903543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'losetup -f' 904543dceb5ea025a99639b74e65dfdc867284001c4jadmanski loop_path = utils.system_output(cmd) 905543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'losetup -f %s' % img_path 906543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(cmd) 907543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 908543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Error attaching image %s to a loop device: %s' % \ 909543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (img_path, e) 910543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 911543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return loop_path 912543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 913543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 914543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _create_single_partition(self, loop_path): 915543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 916543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Creates a single partition encompassing the whole 'disk' using cfdisk. 917543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 918543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param loop_path: Path to the loopback device. 919543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 920543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Creating single partition on %s', loop_path) 921543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 922543dceb5ea025a99639b74e65dfdc867284001c4jadmanski single_part_cmd = '0,,c\n' 923543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sfdisk_file_path = '/tmp/create_partition.sfdisk' 924543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sfdisk_cmd_file = open(sfdisk_file_path, 'w') 925543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sfdisk_cmd_file.write(single_part_cmd) 926543dceb5ea025a99639b74e65dfdc867284001c4jadmanski sfdisk_cmd_file.close() 927543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system('sfdisk %s < %s' % (loop_path, sfdisk_file_path)) 928543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 929543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Error partitioning device %s: %s' % (loop_path, e) 930543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 931543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 932543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 933543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _create_entries_partition(self, loop_path): 934543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 935543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Takes the newly created partition table on the loopback device and 936543dceb5ea025a99639b74e65dfdc867284001c4jadmanski makes all its devices available under /dev/mapper. As we previously 937543dceb5ea025a99639b74e65dfdc867284001c4jadmanski have partitioned it using a single partition, only one partition 938543dceb5ea025a99639b74e65dfdc867284001c4jadmanski will be returned. 939543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 940543dceb5ea025a99639b74e65dfdc867284001c4jadmanski @param loop_path: Path to the loopback device. 941543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 942543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Creating entries under /dev/mapper for %s loop dev', 943543dceb5ea025a99639b74e65dfdc867284001c4jadmanski loop_path) 944543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 945543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'kpartx -a %s' % loop_path 946543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(cmd) 947543dceb5ea025a99639b74e65dfdc867284001c4jadmanski l_cmd = 'kpartx -l %s | cut -f1 -d " "' % loop_path 948543dceb5ea025a99639b74e65dfdc867284001c4jadmanski device = utils.system_output(l_cmd) 949543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 950543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Error creating entries for %s: %s' % (loop_path, e) 951543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 952543dceb5ea025a99639b74e65dfdc867284001c4jadmanski return os.path.join('/dev/mapper', device) 953543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 954543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 955543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _remove_entries_partition(self): 956543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 957543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Removes the entries under /dev/mapper for the partition associated 958543dceb5ea025a99639b74e65dfdc867284001c4jadmanski to the loopback device. 959543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 960543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Removing the entry on /dev/mapper for %s loop dev', 961543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.loop) 962543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 963543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'kpartx -d %s' % self.loop 964543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(cmd) 965543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 966543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Error removing entries for loop %s: %s' % (self.loop, e) 967543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 968543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 969543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 970543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _detach_img_loop(self): 971543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 972543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Detaches the image file from the loopback device. 973543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 974543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Detaching image %s from loop device %s', self.img, 975543dceb5ea025a99639b74e65dfdc867284001c4jadmanski self.loop) 976543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 977543dceb5ea025a99639b74e65dfdc867284001c4jadmanski cmd = 'losetup -d %s' % self.loop 978543dceb5ea025a99639b74e65dfdc867284001c4jadmanski utils.system(cmd) 979543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except error.CmdError, e: 980543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = ('Error detaching image %s from loop device %s: %s' % 981543dceb5ea025a99639b74e65dfdc867284001c4jadmanski (self.img, self.loop, e)) 982543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 983543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 984543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 985543dceb5ea025a99639b74e65dfdc867284001c4jadmanski def _remove_disk_img(self): 986543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 987543dceb5ea025a99639b74e65dfdc867284001c4jadmanski Removes the disk image. 988543dceb5ea025a99639b74e65dfdc867284001c4jadmanski """ 989543dceb5ea025a99639b74e65dfdc867284001c4jadmanski logging.debug('Removing disk image %s', self.img) 990543dceb5ea025a99639b74e65dfdc867284001c4jadmanski try: 991543dceb5ea025a99639b74e65dfdc867284001c4jadmanski os.remove(self.img) 992543dceb5ea025a99639b74e65dfdc867284001c4jadmanski except: 993543dceb5ea025a99639b74e65dfdc867284001c4jadmanski e_msg = 'Error removing image file %s' % self.img 994543dceb5ea025a99639b74e65dfdc867284001c4jadmanski raise error.AutotestError(e_msg) 995543dceb5ea025a99639b74e65dfdc867284001c4jadmanski 996543dceb5ea025a99639b74e65dfdc867284001c4jadmanski# import a site partition module to allow it to override functions 99769bdaacdf2b8161ae95dded60ed6eedbeb5f8f47jadmanskitry: 99869bdaacdf2b8161ae95dded60ed6eedbeb5f8f47jadmanski from autotest_lib.client.bin.site_partition import * 99969bdaacdf2b8161ae95dded60ed6eedbeb5f8f47jadmanskiexcept ImportError: 100069bdaacdf2b8161ae95dded60ed6eedbeb5f8f47jadmanski pass 1001