def resolve_to_by_id_link(path): by_id_paths = TestRun.executor.run_expect_success( "ls /dev/disk/by-id -1").stdout.splitlines() dev_full_paths = [ os.path.join("/dev/disk/by-id", by_id_path) for by_id_path in by_id_paths ] for full_path in dev_full_paths: if readlink(full_path) == readlink(os.path.join("/dev", path)): return full_path raise ValueError(f'By-id device link not found for device {path}')
def __init__(self, path): path = fs_utils.readlink(path) self.size = Size(disk_utils.get_size(path.replace('/dev/', '')), Unit.Byte) self.system_path = path self.filesystem = get_device_filesystem_type(path) self.mount_point = None
def check_partition_after_create(size, part_number, parent_dev_path, part_type, aligned): partition_path = get_partition_path(parent_dev_path, part_number) cmd = f"find {partition_path} -type l" output = TestRun.executor.run_expect_success(cmd).stdout if partition_path not in output: TestRun.LOGGER.info( "Partition created, but could not find it in system, trying 'hdparm -z'") TestRun.executor.run_expect_success(f"hdparm -z {parent_dev_path}") output_after_hdparm = TestRun.executor.run_expect_success( f"parted --script {parent_dev_path} print").stdout TestRun.LOGGER.info(output_after_hdparm) counter = 0 while partition_path not in output and counter < 10: time.sleep(2) output = TestRun.executor.run(cmd).stdout counter += 1 if len(output.split('\n')) > 1 or partition_path not in output: return False if aligned and part_type != PartitionType.extended \ and size.get_value(Unit.Byte) % Unit.Blocks4096.value != 0: TestRun.LOGGER.warning( f"Partition {partition_path} is not 4k aligned: {size.get_value(Unit.KibiByte)}KiB") partition_size = get_size(readlink(partition_path).split('/')[-1]) if part_type == PartitionType.extended or \ partition_size == size.get_value(Unit.Byte): return True TestRun.LOGGER.warning( f"Partition size {partition_size} does not match expected {size.get_value(Unit.Byte)} size." ) return True
def get_system_disks(): system_device = TestRun.executor.run_expect_success('mount | grep " / "').stdout.split()[0] readlink_output = readlink(system_device) device_name = readlink_output.split('/')[-1] sys_block_path = os_utils.get_sys_block_path() used_device_names = __get_slaves(device_name) if not used_device_names: used_device_names = [device_name] disk_names = [] for device_name in used_device_names: if check_if_file_exists(f'{sys_block_path}/{device_name}/partition'): parent_device = readlink(f'{sys_block_path}/{device_name}/..').split('/')[-1] disk_names.append(parent_device) else: disk_names.append(device_name) return disk_names
def is_mounted(self): output = TestRun.executor.run(f"findmnt {self.path}") if output.exit_code != 0: return False else: mount_point_line = output.stdout.split('\n')[1] device_path = fs_utils.readlink(self.path) self.mount_point = mount_point_line[0:mount_point_line.find(device_path)].strip() return True
def __init__( self, path, disk_type: DiskType, serial_number, block_size, ): Device.__init__(self, path) path = fs_utils.readlink(path) self.device_name = path.split('/')[-1] self.serial_number = serial_number self.block_size = Unit(block_size) self.disk_type = disk_type self.partitions = []
def detail_result(cls, raid_device_paths: str): output = cls.detail(raid_device_paths) details = {} for device_details in re.split("^/dev/", output.stdout, flags=re.MULTILINE): if not device_details: continue lines = device_details.splitlines() key = "/dev/" + lines[0].rstrip(':') details[key] = {} details[key]["path"] = readlink(key) details[key]["devices"] = cls.__parse_devices(device_details) details[key]["level"] = cls.__parse_level(device_details) details[key]["uuid"] = cls.__parse_uuid(device_details) metadata = cls.__parse_metadata(device_details) if metadata: details[key]["metadata"] = metadata return details
def create(cls, raid_configuration: RaidConfiguration, devices: [Device]): import copy raid_conf = copy.deepcopy(raid_configuration) if not raid_conf.number_of_devices: raid_conf.number_of_devices = len(devices) elif len(devices) < raid_conf.number_of_devices: raise ValueError("RAID configuration requires at least " f"{raid_conf.number_of_devices} devices") md_dir_path = "/dev/md/" array_devices = devices volume_devices = devices[:raid_conf.number_of_devices] if raid_conf.metadata != MetadataVariant.Legacy: container_conf = RaidConfiguration( name=cls.__get_unique_name(raid_conf.metadata.value), metadata=raid_conf.metadata, number_of_devices=len(array_devices)) Mdadm.create(container_conf, get_devices_paths_string(array_devices)) if not raid_conf.name: raid_conf.name = cls.__get_unique_name() Mdadm.create(raid_conf, get_devices_paths_string(volume_devices)) raid_link = md_dir_path + raid_conf.name raid = [ r for r in Mdadm.examine_result() if r["path"] == readlink(raid_link) ][0] return cls(raid["path"], raid_conf.level, raid["uuid"], raid["container"]["uuid"] if "container" in raid else None, raid["container"]["path"] if "container" in raid else None, raid_conf.metadata, array_devices, volume_devices)
def get_target(self): return readlink(self.full_path)
def test_recovery_flush_reset_raw(cache_mode): """ title: Recovery after reset during cache flushing - test on raw device. description: | Verify that unflushed data can be safely recovered, when reset was pressed during data flushing on raw device. pass_criteria: - CAS recovers successfully after reboot - No data corruption """ with TestRun.step("Prepare cache and core devices."): cache_disk = TestRun.disks['cache'] core_disk = TestRun.disks['core'] cache_disk.create_partitions([Size(2, Unit.GibiByte)]) core_disk.create_partitions([Size(16, Unit.GibiByte)] * 2) cache_device = cache_disk.partitions[0] core_device = core_disk.partitions[0] with TestRun.step("Create test files."): source_file, target_file = create_test_files(test_file_size) source_file_md5 = source_file.md5sum() with TestRun.step("Setup cache and add core."): cache = casadm.start_cache(cache_device, cache_mode) core = cache.add_core(core_device) cache.set_cleaning_policy(CleaningPolicy.nop) cache.set_seq_cutoff_policy(SeqCutOffPolicy.never) with TestRun.step("Copy file to CAS."): copy_file(source=source_file.full_path, target=core.path, size=test_file_size, direct="oflag") with TestRun.step("Sync and flush buffers."): os_utils.sync() output = TestRun.executor.run(f"hdparm -f {core.path}") if output.exit_code != 0: raise CmdException("Error during hdparm", output) with TestRun.step("Trigger flush."): TestRun.executor.run_in_background(cli.flush_cache_cmd(f"{cache.cache_id}")) with TestRun.step("Hard reset DUT during data flushing."): power_cycle_dut(wait_for_flush_begin=True, core_device=core_device) with TestRun.step("Copy file from core and check if current md5sum is different than " "before restart."): copy_file(source=readlink(core_device.path), target=target_file.full_path, size=test_file_size, direct="iflag") target_file_md5 = target_file.md5sum() compare_files(source_file_md5, target_file_md5, should_differ=True) with TestRun.step("Load cache."): cache = casadm.load_cache(cache_device) if cache.get_dirty_blocks() == Size.zero(): TestRun.fail("There are no dirty blocks on cache device.") with TestRun.step("Stop cache with dirty data flush."): core_writes_before = core_device.get_io_stats().sectors_written cache.stop() if core_writes_before >= core_device.get_io_stats().sectors_written: TestRun.fail("No data was flushed after stopping cache started with load option.") with TestRun.step("Copy test file from core device to temporary location. " "Compare it with the first version – they should be the same."): copy_file(source=readlink(core_device.path), target=target_file.full_path, size=test_file_size, direct="iflag") target_file_md5 = target_file.md5sum() compare_files(source_file_md5, target_file_md5) with TestRun.step("Cleanup core device and remove test files."): try: target_file.remove() source_file.remove() except Exception: # On some OSes files at /tmp location are automatically removed after DUT hard reset pass
def get_device_id(self): return fs_utils.readlink(self.path).split('/')[-1]