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