def test_luks2_integrity(self): """Verify that we can get create a LUKS 2 device with integrity""" if not BlockDev.utils_have_kernel_module("dm-integrity"): self.skipTest('dm-integrity kernel module not available, skipping.') extra = BlockDev.CryptoLUKSExtra() extra.integrity = "hmac(sha256)" succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 512, PASSWD, None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) info = BlockDev.crypto_integrity_info("libblockdevTestLUKS") self.assertIsNotNone(info) self.assertEqual(info.algorithm, "hmac(sha256)") # get integrity device dm name _ret, int_name, _err = run_command('ls /sys/block/%s/holders/' % self.loop_dev.split("/")[-1]) self.assertTrue(int_name) # true == not empty tag_size = read_file("/sys/block/%s/integrity/tag_size" % int_name) self.assertEqual(info.tag_size, int(tag_size)) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_create_too_small(self): """Verify that an attempt to create BTRFS on a too small device fails""" # even one small devices is enough for the fail with self.assertRaises(GLib.GError): BlockDev.btrfs_create_volume([self.loop_dev, self.loop_dev2], None, None, None)
def test_get_device_symlinks(self): """Verify that getting device symlinks works as expected""" with self.assertRaises(GLib.GError): BlockDev.utils_get_device_symlinks("no_such_device") symlinks = BlockDev.utils_get_device_symlinks(self.loop_dev) # there should be at least 2 symlinks for something like "/dev/sda" (in /dev/disk/by-id/) self.assertGreaterEqual(len(symlinks), 2) symlinks = BlockDev.utils_get_device_symlinks(self.loop_dev[5:]) self.assertGreaterEqual(len(symlinks), 2) # create an LV to get a device with more symlinks ret, _out, _err = run_command ("pvcreate %s" % self.loop_dev) self.assertEqual(ret, 0) self.addCleanup(run_command, "pvremove %s" % self.loop_dev) ret, _out, _err = run_command ("vgcreate utilsTestVG %s" % self.loop_dev) self.assertEqual(ret, 0) self.addCleanup(run_command, "vgremove -y utilsTestVG") ret, _out, _err = run_command ("lvcreate -n utilsTestLV -L 12M utilsTestVG") self.assertEqual(ret, 0) self.addCleanup(run_command, "lvremove -y utilsTestVG/utilsTestLV") symlinks = BlockDev.utils_get_device_symlinks("utilsTestVG/utilsTestLV") # there should be at least 4 symlinks for an LV self.assertGreaterEqual(len(symlinks), 4)
def test_activate_deactivate(self): """Verify that it is possible to activate and deactivate an MD RAID""" with wait_for_resync(): succ = BlockDev.md_create( "bd_test_md", "raid1", [self.loop_dev, self.loop_dev2, self.loop_dev3], 1, None, True ) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.md_deactivate("non_existing_md") with wait_for_resync(): succ = BlockDev.md_deactivate("bd_test_md") self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.md_activate("bd_test_md", ["/non/existing/device", self.loop_dev2, self.loop_dev3], None) with wait_for_resync(): succ = BlockDev.md_activate("bd_test_md", [self.loop_dev, self.loop_dev2, self.loop_dev3], None) self.assertTrue(succ) # try to deactivate using the node instead of name with wait_for_resync(): succ = BlockDev.md_deactivate(BlockDev.md_node_from_name("bd_test_md")) self.assertTrue(succ) with wait_for_resync(): succ = BlockDev.md_activate("bd_test_md", [self.loop_dev, self.loop_dev2, self.loop_dev3], None) self.assertTrue(succ)
def tearDown(self): try: BlockDev.lvm_lvremove("testVG", "testLV", True) except: pass LvmPVVGTestCase.tearDown(self)
def test_name_node_bijection(self): """Verify that MD RAID node and name match each other""" with wait_for_resync(): succ = BlockDev.md_create( "bd_test_md", "raid1", [self.loop_dev, self.loop_dev2, self.loop_dev3], 1, None, True ) self.assertTrue(succ) node = BlockDev.md_node_from_name("bd_test_md") self.assertEqual(BlockDev.md_name_from_node(node), "bd_test_md") with self.assertRaises(GLib.GError): node = BlockDev.md_node_from_name("made_up_md") with six.assertRaisesRegex(self, GLib.GError, r"No name"): BlockDev.md_name_from_node("no_such_node") succ = BlockDev.md_deactivate("bd_test_md") self.assertTrue(succ) succ = BlockDev.md_destroy(self.loop_dev) self.assertTrue(succ) succ = BlockDev.md_destroy(self.loop_dev2) self.assertTrue(succ) succ = BlockDev.md_destroy(self.loop_dev3) self.assertTrue(succ)
def test_add_remove(self): """Verify that it is possible to add a device to and remove from an MD RAID""" # the MD array doesn't exist yet with self.assertRaises(GLib.GError): BlockDev.md_add("bd_test_md", self.loop_dev3, 0) with wait_for_resync(): succ = BlockDev.md_create("bd_test_md", "raid1", [self.loop_dev, self.loop_dev2], 0, None, False) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.md_add("bd_test_md", "/non/existing/device", 0) succ = BlockDev.md_add("bd_test_md", self.loop_dev3, 0) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.md_add("bd_test_md", self.loop_dev3, 0) with wait_for_resync(): succ = BlockDev.md_remove("bd_test_md", self.loop_dev3, True) self.assertTrue(succ) # XXX: cannnot remove device added as a spare device nor a different # device? succ = BlockDev.md_add("bd_test_md", self.loop_dev3, 2) self.assertTrue(succ)
def test_get_info(self): """Verify that it is possible to get information about an existing VDO volume""" ret = BlockDev.vdo_create(self.vdo_name, self.loop_dev) self.addCleanup(self._remove_vdo, self.vdo_name) self.assertTrue(ret) bd_info = BlockDev.vdo_info(self.vdo_name) self.assertIsNotNone(bd_info) sys_info = self._get_vdo_info(self.vdo_name) self.assertIsNotNone(sys_info) self.assertEqual(bd_info.deduplication, sys_info["Deduplication"] == "enabled") self.assertEqual(bd_info.deduplication, sys_info["Compression"] == "enabled") self.assertEqual(BlockDev.vdo_get_write_policy_str(bd_info.write_policy), sys_info["Configured write policy"]) # index memory is printed in gigabytes without the unit self.assertEqual(bd_info.index_memory, sys_info["Index memory setting"] * 1000**3) # logical and physical size are printed with units self.assertEqual(bd_info.physical_size, bytesize.Size(sys_info["Physical size"])) self.assertEqual(bd_info.logical_size, bytesize.Size(sys_info["Logical size"]))
def _zram_get_stats_old(self): with _track_module_load(self, "zram", "_loaded_zram_module"): self.assertTrue(BlockDev.kbd_zram_create_devices(1, [10 * 1024**2], [2])) time.sleep(1) stats = BlockDev.kbd_zram_get_stats("zram0") self.assertTrue(stats) # /dev/zram0 should work too stats = BlockDev.kbd_zram_get_stats("/dev/zram0") self.assertTrue(stats) self.assertEqual(stats.disksize, 10 * 1024**2) self.assertEqual(stats.max_comp_streams, 2) self.assertTrue(stats.comp_algorithm) num_reads = int(read_file("/sys/block/zram0/num_reads").strip()) self.assertEqual(stats.num_reads, num_reads) num_writes = int(read_file("/sys/block/zram0/num_writes").strip()) self.assertEqual(stats.num_writes, num_writes) orig_data_size = int(read_file("/sys/block/zram0/orig_data_size").strip()) self.assertEqual(stats.orig_data_size, orig_data_size) compr_data_size = int(read_file("/sys/block/zram0/compr_data_size").strip()) self.assertEqual(stats.compr_data_size, compr_data_size) mem_used_total = int(read_file("/sys/block/zram0/mem_used_total").strip()) self.assertEqual(stats.mem_used_total, mem_used_total) zero_pages = int(read_file("/sys/block/zram0/zero_pages").strip()) self.assertEqual(stats.zero_pages, zero_pages) invalid_io = int(read_file("/sys/block/zram0/invalid_io").strip()) self.assertEqual(stats.invalid_io, invalid_io) with _track_module_load(self, "zram", "_loaded_zram_module"): self.assertTrue(BlockDev.kbd_zram_destroy_devices())
def _clean_up(self): try: BlockDev.lvm_lvremove("testVG", "testThLV_bak", True, None) except: pass LvmPVVGLVthLVTestCase._clean_up(self)
def _clean_up(self): # change the sources back and recompile os.system("sed -ri 's?1024;//test-change?BD_LVM_MAX_LV_SIZE;?' src/plugins/lvm.c > /dev/null") os.system("make -C src/plugins/ libbd_lvm.la &> /dev/null") # try to get everything back to normal by (re)loading all plugins BlockDev.reinit(None, True, None)
def _clean_up(self): try: BlockDev.lvm_vgremove("testVG", None) except: pass LvmPVonlyTestCase._clean_up(self)
def test_cache_get_default_md_size(self): """Verify that default cache metadata size is calculated properly""" # 1000x smaller than the data LV size, but at least 8 MiB self.assertEqual(BlockDev.lvm_cache_get_default_md_size(100 * 1024**3), (100 * 1024**3) // 1000) self.assertEqual(BlockDev.lvm_cache_get_default_md_size(80 * 1024**3), (80 * 1024**3) // 1000) self.assertEqual(BlockDev.lvm_cache_get_default_md_size(6 * 1024**3), 8 * 1024**2)
def test_vgcreate_vgremove(self): """Verify that it is possible to create and destroy a VG""" succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.lvm_vgcreate("testVG", ["/non/existing/device"], 0, None) succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) self.assertTrue(succ) # VG already exists with self.assertRaises(GLib.GError): BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) succ = BlockDev.lvm_vgremove("testVG", None) self.assertTrue(succ) # no longer exists with self.assertRaises(GLib.GError): BlockDev.lvm_vgremove("testVG", None)
def _clean_up(self): try: BlockDev.lvm_lvremove("testVG", "testPool", True, None) except: pass LvmPVVGTestCase._clean_up(self)
def test_logging_setup(self): """Verify that setting up logging works as expected""" self.assertTrue(BlockDev.reinit(self.requested_plugins, False, self.my_log_func)) succ = BlockDev.utils_exec_and_report_error(["true"]) self.assertTrue(succ) # reinit with no logging function should change nothing about logging self.assertTrue(BlockDev.reinit(self.requested_plugins, False, None)) succ, out = BlockDev.utils_exec_and_capture_output(["echo", "hi"]) self.assertTrue(succ) self.assertEqual(out, "hi\n") match = re.search(r'Running \[(\d+)\] true', self.log) self.assertIsNot(match, None) task_id1 = match.group(1) match = re.search(r'Running \[(\d+)\] echo hi', self.log) self.assertIsNot(match, None) task_id2 = match.group(1) self.assertIn("...done [%s] (exit code: 0)" % task_id1, self.log) self.assertIn("stdout[%s]:" % task_id1, self.log) self.assertIn("stderr[%s]:" % task_id1, self.log) self.assertIn("stdout[%s]: hi" % task_id2, self.log) self.assertIn("stderr[%s]:" % task_id2, self.log) self.assertIn("...done [%s] (exit code: 0)" % task_id2, self.log)
def tearDown(self): try: BlockDev.lvm_vgremove("testVG") except: pass LvmPVonlyTestCase.tearDown(self)
def test_create_part_simple(self): """Verify that it is possible to create a parition""" # we first need a partition table succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True) self.assertTrue(succ) # for now, let's just create a typical primary partition starting at the # sector 2048, 10 MiB big with optimal alignment ps = BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.NORMAL, 2048*512, 10 * 1024**2, BlockDev.PartAlign.OPTIMAL) # we should get proper data back self.assertTrue(ps) self.assertEqual(ps.path, self.loop_dev + "p1") self.assertEqual(ps.type, BlockDev.PartType.NORMAL) self.assertEqual(ps.start, 2048 * 512) self.assertEqual(ps.size, 10 * 1024**2) self.assertEqual(ps.flags, 0) # no flags (combination of bit flags) ps2 = BlockDev.part_get_part_spec (self.loop_dev, ps.path) self.assertEqual(ps.path, ps2.path) self.assertEqual(ps.type, ps2.type); self.assertEqual(ps.start, ps2.start) self.assertEqual(ps.size, ps2.size) self.assertEqual(ps.flags, ps2.flags) pss = BlockDev.part_get_disk_parts (self.loop_dev) self.assertEqual(len(pss), 1) ps3 = pss[0] self.assertEqual(ps.path, ps3.path) self.assertEqual(ps.type, ps3.type) self.assertEqual(ps.start, ps3.start) self.assertEqual(ps.size, ps3.size) self.assertEqual(ps.flags, ps3.flags)
def test_bcache_status(self): succ, dev = BlockDev.kbd_bcache_create(self.loop_dev, self.loop_dev2, None) self.assertTrue(succ) self.assertTrue(dev) self.bcache_dev = dev _wait_for_bcache_setup(dev) # should work with both "bcacheX" and "/dev/bcacheX" status = BlockDev.kbd_bcache_status(self.bcache_dev) self.assertTrue(status) status = BlockDev.kbd_bcache_status("/dev/" + self.bcache_dev) self.assertTrue(status) # check some basic values (default block size is 512) self.assertTrue(status.state) self.assertEqual(status.state, "clean") self.assertEqual(status.block_size, 512) self.assertGreater(status.cache_size, 0) succ = BlockDev.kbd_bcache_destroy(self.bcache_dev) self.assertTrue(succ) self.bcache_dev = None time.sleep(1) wipe_all(self.loop_dev, self.loop_dev2)
def test_create_table(self): """Verify that it is possible to create a new partition table""" # doesn't matter if we want to ignore any preexisting partition tables # or not on a nonexisting device with self.assertRaises(GLib.GError): BlockDev.part_create_table ("/non/existing", BlockDev.PartTableType.MSDOS, False) with self.assertRaises(GLib.GError): BlockDev.part_create_table ("/non/existing", BlockDev.PartTableType.MSDOS, True) # doesn't matter if we want to ignore any preexisting partition tables # or not on a clean device succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, False) self.assertTrue(succ) succ = BlockDev.part_create_table (self.loop_dev2, BlockDev.PartTableType.MSDOS, True) self.assertTrue(succ) # should fail because of a preexisting partition table (and not ignoring it) with self.assertRaises(GLib.GError): BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, False) # should succeed if we want to ignore any preexisting partition tables succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.MSDOS, True) self.assertTrue(succ) succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True) self.assertTrue(succ)
def test_ext4_get_info(self): """Verify that it is possible to get info about an ext4 file system""" succ = BlockDev.fs_ext4_mkfs(self.loop_dev, None) self.assertTrue(succ) fi = BlockDev.fs_ext4_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.block_size, 1024) self.assertEqual(fi.block_count, 100 * 1024**2 / 1024) # at least 90 % should be available, so it should be reported self.assertGreater(fi.free_blocks, 0.90 * 100 * 1024**2 / 1024) self.assertEqual(fi.label, "") # should be an non-empty string self.assertTrue(fi.uuid) self.assertTrue(fi.state, "clean") with mounted(self.loop_dev, self.mount_dir): fi = BlockDev.fs_ext4_get_info(self.loop_dev) self.assertEqual(fi.block_size, 1024) self.assertEqual(fi.block_count, 100 * 1024**2 / 1024) # at least 90 % should be available, so it should be reported self.assertGreater(fi.free_blocks, 0.90 * 100 * 1024**2 / 1024) self.assertEqual(fi.label, "") # should be an non-empty string self.assertTrue(fi.uuid) self.assertTrue(fi.state, "clean")
def test_backup_passphrase(self): """Verify that a backup passphrase can be created for a device""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) escrow_dir = tempfile.mkdtemp(prefix='libblockdev_test_escrow') self.addCleanup(shutil.rmtree, escrow_dir) backup_passphrase = BlockDev.crypto_generate_backup_passphrase() with open(self.public_cert, 'rb') as cert_file: succ = BlockDev.crypto_escrow_device(self.loop_dev, PASSWD, cert_file.read(), escrow_dir, backup_passphrase) self.assertTrue(succ) # Find the backup passphrase escrow_backup_passphrase = "%s/%s-escrow-backup-passphrase" % (escrow_dir, BlockDev.crypto_luks_uuid(self.loop_dev)) self.assertTrue(os.path.isfile(escrow_backup_passphrase)) # Check that the encrypted file contains what we put in env = os.environ env.update({"LC_ALL": "C"}) passphrase = subprocess.check_output( ['volume_key', '--secrets', '-d', self.nss_dir, escrow_backup_passphrase], env=env) passphrase = passphrase.strip().split()[1].decode('ascii') self.assertEqual(passphrase, backup_passphrase) # Check that the backup passphrase works succ = BlockDev.crypto_luks_open(self.loop_dev, 'libblockdevTestLUKS', backup_passphrase, None) self.assertTrue(succ)
def test_bcache_status(self): succ, dev = BlockDev.kbd_bcache_create(self.loop_dev, self.loop_dev2, None) self.assertTrue(succ) self.assertTrue(dev) self.bcache_dev = dev _wait_for_bcache_setup(dev) # should work with both "bcacheX" and "/dev/bcacheX" status = BlockDev.kbd_bcache_status(self.bcache_dev) self.assertTrue(status) status = BlockDev.kbd_bcache_status("/dev/" + self.bcache_dev) self.assertTrue(status) # check some basic values self.assertTrue(status.state) sys_state = read_file("/sys/block/%s/bcache/state" % self.bcache_dev).strip() self.assertEqual(status.state, sys_state) sys_block = read_file("/sys/block/%s/bcache/cache/block_size" % self.bcache_dev).strip() self.assertEqual(status.block_size, int(bytesize.Size(sys_block))) sys_size = self._get_size(self.bcache_dev) self.assertGreater(status.cache_size, sys_size) succ = BlockDev.kbd_bcache_destroy(self.bcache_dev) self.assertTrue(succ) self.bcache_dev = None time.sleep(1) wipe_all(self.loop_dev, self.loop_dev2)
def test_luks2_format(self): """Verify that we can get information about a LUKS 2 device""" extra = BlockDev.CryptoLUKSExtra() extra.sector_size = 4096 succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 256, PASSWD, None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) info = BlockDev.crypto_luks_info("libblockdevTestLUKS") self.assertIsNotNone(info) self.assertEqual(info.version, BlockDev.CryptoLUKSVersion.LUKS2) self.assertEqual(info.cipher, "aes") self.assertEqual(info.mode, "cbc-essiv:sha256") self.assertEqual(info.backing_device, self.loop_dev) self.assertEqual(info.sector_size, 4096) _ret, uuid, _err = run_command("blkid -p -ovalue -sUUID %s" % self.loop_dev) self.assertEqual(info.uuid, uuid) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_mkfs_label(self): """Verify that it is possible to create a btrfs filesystem with a label""" succ = BlockDev.btrfs_mkfs([self.loop_dev], "myShinyBtrfs", None, None) self.assertTrue(succ) devs = BlockDev.btrfs_list_devices(self.loop_dev) self.assertEqual(len(devs), 1)
def test_change_key(self): """Verify that changing key in LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_change_key(self.loop_dev, PASSWD, PASSWD2) self.assertTrue(succ)
def testLoop_get_backing_file(self): """Verify that loop_get_backing_file works as expected""" self.assertIs(BlockDev.loop_get_backing_file("/non/existing"), None) succ, self.loop = BlockDev.loop_setup(self.dev_file) f_name = BlockDev.loop_get_backing_file(self.loop) self.assertEqual(f_name, self.dev_file)
def test_create_remove_linear(self): """Verify that it is possible to create new linear mapping and remove it""" succ = BlockDev.dm_create_linear("testMap", self.loop_dev, 100, None) self.assertTrue(succ) succ = BlockDev.dm_remove("testMap") self.assertTrue(succ)
def test_repair(self): """Verify that it's possible to repair the btrfs filesystem""" succ = BlockDev.btrfs_create_volume([self.loop_dev], None, None, None) self.assertTrue(succ) succ = BlockDev.btrfs_repair(self.loop_dev) self.assertTrue(succ)
def test_get_md_uuid(self): """Verify that getting UUID in MD RAID format works as expected""" self.assertEqual(BlockDev.md_get_md_uuid("3386ff85-f501-2621-4a43-5f061eb47236"), "3386ff85:f5012621:4a435f06:1eb47236") with six.assertRaisesRegex(self, GLib.GError, r'malformed or invalid'): BlockDev.md_get_md_uuid("malformed-uuid-example")
def test_generic_wipe(self): """Verify that generic signature wipe works as expected""" with self.assertRaises(GLib.GError): BlockDev.fs_wipe("/non/existing/device", True) ret = run("pvcreate %s &>/dev/null" % self.loop_dev) self.assertEqual(ret, 0) succ = BlockDev.fs_wipe(self.loop_dev, True) self.assertTrue(succ) # now test the same multiple times in a row for i in range(10): ret = run("pvcreate %s &>/dev/null" % self.loop_dev) self.assertEqual(ret, 0) succ = BlockDev.fs_wipe(self.loop_dev, True) self.assertTrue(succ) # vfat has multiple signatures on the device so it allows us to test the # 'all' argument of fs_wipe() ret = run("mkfs.vfat -I %s &>/dev/null" % self.loop_dev) self.assertEqual(ret, 0) time.sleep(0.5) succ = BlockDev.fs_wipe(self.loop_dev, False) self.assertTrue(succ) # the second signature should still be there # XXX: lsblk uses the udev db so it we need to make sure it is up to date run("udevadm settle") fs_type = check_output( ["blkid", "-ovalue", "-sTYPE", "-p", self.loop_dev]).strip() self.assertEqual(fs_type, b"vfat") # get rid of all the remaining signatures (there could be vfat + PMBR for some reason) succ = BlockDev.fs_wipe(self.loop_dev, True) self.assertTrue(succ) run("udevadm settle") fs_type = check_output( ["blkid", "-ovalue", "-sTYPE", "-p", self.loop_dev]).strip() self.assertEqual(fs_type, b"") # now do the wipe all in a one step ret = run("mkfs.vfat -I %s &>/dev/null" % self.loop_dev) self.assertEqual(ret, 0) succ = BlockDev.fs_wipe(self.loop_dev, True) self.assertTrue(succ) run("udevadm settle") fs_type = check_output( ["blkid", "-ovalue", "-sTYPE", "-p", self.loop_dev]).strip() self.assertEqual(fs_type, b"") # try to wipe empty device with six.assertRaisesRegex(self, GLib.GError, "No signature detected on the device"): BlockDev.fs_wipe(self.loop_dev, True)
def test_lvrename(self): """Verify that it's possible to rename an LV""" with self.assertRaises(GLib.GError): BlockDev.lvm_lvrename("nonexistingVG", "testLV", "newTestLV", None) with self.assertRaises(GLib.GError): BlockDev.lvm_lvrename("testVG", "nonexistingLV", "newTestLV", None) succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) self.assertTrue(succ) succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, None, [self.loop_dev], None) self.assertTrue(succ) # rename succ = BlockDev.lvm_lvrename("testVG", "testLV", "newTestLV", None) self.assertTrue(succ) # and back succ = BlockDev.lvm_lvrename("testVG", "newTestLV", "testLV", None) self.assertTrue(succ) # needs a change with self.assertRaises(GLib.GError): BlockDev.lvm_lvrename("testVG", "testLV", "testLV", None)
def _clean_up(self): try: BlockDev.md_deactivate("bd_test_md") except: pass try: BlockDev.md_deactivate(BlockDev.md_node_from_name("bd_test_md")) except: pass try: BlockDev.md_destroy(self.loop_dev) except: pass try: BlockDev.md_destroy(self.loop_dev2) except: pass try: BlockDev.md_destroy(self.loop_dev3) except: pass try: BlockDev.md_deactivate("bd_test_md") except: pass try: BlockDev.md_deactivate(BlockDev.md_node_from_name("bd_test_md")) except: pass succ = BlockDev.loop_teardown(self.loop_dev) if not succ: os.unlink(self.dev_file) raise RuntimeError("Failed to tear down loop device used for testing") os.unlink(self.dev_file) succ = BlockDev.loop_teardown(self.loop_dev2) if not succ: os.unlink(self.dev_file2) raise RuntimeError("Failed to tear down loop device used for testing") os.unlink(self.dev_file2) succ = BlockDev.loop_teardown(self.loop_dev3) if not succ: os.unlink(self.dev_file3) raise RuntimeError("Failed to tear down loop device used for testing") os.unlink(self.dev_file3)
def test_nilfs2_available(self): """Verify that it is possible to check nilfs2 tech availability""" available = BlockDev.fs_is_tech_avail( BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.MKFS | BlockDev.FSTechMode.SET_LABEL | BlockDev.FSTechMode.QUERY | BlockDev.FSTechMode.RESIZE | BlockDev.FSTechMode.SET_UUID) self.assertTrue(available) with self.assertRaisesRegex(GLib.GError, "doesn't support filesystem check"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.CHECK) with self.assertRaisesRegex(GLib.GError, "doesn't support filesystem repair"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.REPAIR) BlockDev.switch_init_checks(False) BlockDev.reinit(self.requested_plugins, True, None) # now try without mkfs.nilfs2 with utils.fake_path(all_but="mkfs.nilfs2"): with self.assertRaisesRegex( GLib.GError, "The 'mkfs.nilfs2' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.MKFS) # now try without nilfs-tune with utils.fake_path(all_but="nilfs-tune"): with self.assertRaisesRegex( GLib.GError, "The 'nilfs-tune' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.QUERY) with self.assertRaisesRegex( GLib.GError, "The 'nilfs-tune' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.SET_LABEL) # now try without nilfs-resize with utils.fake_path(all_but="nilfs-resize"): with self.assertRaisesRegex( GLib.GError, "The 'nilfs-resize' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NILFS2, BlockDev.FSTechMode.RESIZE)
def test_vfat_wipe(self): """Verify that it is possible to wipe an vfat file system""" succ = BlockDev.fs_vfat_mkfs(self.loop_dev, None) self.assertTrue(succ) succ = BlockDev.fs_vfat_wipe(self.loop_dev) self.assertTrue(succ) # already wiped, should fail this time with self.assertRaises(GLib.GError): BlockDev.fs_vfat_wipe(self.loop_dev) run("pvcreate %s >/dev/null" % self.loop_dev) # LVM PV signature, not an vfat file system with self.assertRaises(GLib.GError): BlockDev.fs_vfat_wipe(self.loop_dev) BlockDev.fs_wipe(self.loop_dev, True) run("mkfs.ext2 -F %s &>/dev/null" % self.loop_dev) # ext2, not an vfat file system with self.assertRaises(GLib.GError): BlockDev.fs_vfat_wipe(self.loop_dev) BlockDev.fs_wipe(self.loop_dev, True)
def _luks_open_close(self, create_fn): """Verify that opening/closing LUKS device works""" succ = create_fn(self.loop_dev, PASSWD, self.keyfile) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open("/non/existing/device", "libblockdevTestLUKS", PASSWD, None, False) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", None, None, False) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", "wrong-passhprase", None, False) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", None, "wrong-keyfile", False) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) # use the full /dev/mapper/ path succ = BlockDev.crypto_luks_close("/dev/mapper/libblockdevTestLUKS") self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", None, self.keyfile, False) self.assertTrue(succ) # use just the LUKS device name succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
class UdisksEncryptedTestLUKS2(UdisksEncryptedTest): '''This is a LUKS2 encrypted device test suite''' luks_version = '2' requested_plugins = BlockDev.plugin_specs_from_names(("crypto",)) @classmethod def setUpClass(cls): if not BlockDev.is_initialized(): BlockDev.init(cls.requested_plugins, None) else: BlockDev.reinit(cls.requested_plugins, True, None) super(UdisksEncryptedTestLUKS2, cls).setUpClass() def _create_luks(self, device, passphrase, binary=False): options = dbus.Dictionary(signature='sv') if binary: options['encrypt.passphrase'] = self.bytes_to_ay(passphrase) options['encrypt.type'] = 'luks2' else: options['encrypt.passphrase'] = passphrase options['encrypt.type'] = 'luks2' device.Format('xfs', options, dbus_interface=self.iface_prefix + '.Block') def _create_luks_integrity(self, device, passphrase): if not BlockDev.utils_have_kernel_module('dm-integrity'): self.skipTest('dm-integrity kernel module not available, skipping.') # UDisks doesn't support creating LUKS2 with integrity, we need to use libblockdev extra = BlockDev.CryptoLUKSExtra() extra.integrity = 'hmac(sha256)' BlockDev.crypto_luks_format(device, 'aes-cbc-essiv:sha256', 512, passphrase, None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) def _get_metadata_size_from_dump(self, disk): ret, out = self.run_command("cryptsetup luksDump %s" % disk) if ret != 0: self.fail("Failed to get LUKS 2 information from '%s':\n%s" % (disk, out)) m = re.search(r"offset:\s*([0-9]+)\s*\[bytes\]", out) if m is None: self.fail("Failed to get LUKS 2 offset information using 'cryptsetup luksDump %s'" % disk) return int(m.group(1)) def _get_key_location(self, device): ret, out = self.run_command('cryptsetup status %s' % device) if ret != 0: self.fail('Failed to get key location from:\n%s' % out) m = re.search(r'\s*key location:\s*(\S+)\s*', out) if not m or len(m.groups()) != 1: self.fail('Failed to get key location from:\n%s' % out) return m.group(1) def setUp(self): cryptsetup_version = self._get_cryptsetup_version() if cryptsetup_version < LooseVersion('2.0.0'): self.skipTest('LUKS2 not supported') super(UdisksEncryptedTestLUKS2, self).setUp() def test_resize(self): passwd = 'test' device = self.get_device(self.vdevs[0]) self._create_luks(device, passwd) self.addCleanup(self._remove_luks, device) self.udev_settle() _ret, clear_dev = self.run_command('ls /sys/block/%s/holders/' % os.path.basename(self.vdevs[0])) self.assertEqual(_ret, 0) clear_size = self.get_block_size(clear_dev) # kernel keyring support and no passphrase for LUKS 2 given = fail if self._get_key_location('/dev/' + clear_dev) == 'keyring': msg = 'org.freedesktop.UDisks2.Error.Failed: Error resizing encrypted device /dev/dm-[0-9]+: Insufficient persmissions to resize device. *' with six.assertRaisesRegex(self, dbus.exceptions.DBusException, msg): device.Resize(dbus.UInt64(100*1024*1024), self.no_options, dbus_interface=self.iface_prefix + '.Encrypted') # wrong passphrase d = dbus.Dictionary(signature='sv') d['passphrase'] = 'wrongpassphrase' msg = 'org.freedesktop.UDisks2.Error.Failed: Error resizing encrypted device /dev/dm-[0-9]+: '\ 'Failed to activate device: (Operation not permitted|Incorrect passphrase)' with six.assertRaisesRegex(self, dbus.exceptions.DBusException, msg): device.Resize(dbus.UInt64(100*1024*1024), d, dbus_interface=self.iface_prefix + '.Encrypted') # right passphrase d = dbus.Dictionary(signature='sv') d['passphrase'] = passwd device.Resize(dbus.UInt64(100*1024*1024), d, dbus_interface=self.iface_prefix + '.Encrypted') clear_size2 = self.get_block_size(clear_dev) self.assertEqual(clear_size2, 100*1024*1024) # resize back to the original size (using binary passphrase) d = dbus.Dictionary(signature='sv') d['keyfile_contents'] = self.str_to_ay(passwd, False) device.Resize(dbus.UInt64(clear_size), d, dbus_interface=self.iface_prefix + '.Encrypted') clear_size3 = self.get_block_size(clear_dev) self.assertEqual(clear_size3, clear_size) def _get_default_luks_version(self): manager = self.get_object('/Manager') default_encryption_type = self.get_property(manager, '.Manager', 'DefaultEncryptionType') return default_encryption_type.value[-1] def test_create_default(self): disk_name = os.path.basename(self.vdevs[0]) disk = self.get_object('/block_devices/' + disk_name) # create LUKS without specifying version options = dbus.Dictionary(signature='sv') options['encrypt.passphrase'] = 'test' disk.Format('xfs', options, dbus_interface=self.iface_prefix + '.Block') self.addCleanup(self._remove_luks, disk) self.udev_settle() default_version = self._get_default_luks_version() dbus_version = self.get_property(disk, '.Block', 'IdVersion') dbus_version.assertEqual(default_version) def test_suppported_encryption_types(self): manager = self.get_object('/Manager') supported_encryption_types = self.get_property(manager, '.Manager', 'SupportedEncryptionTypes') supported_encryption_types.assertLen(2) supported_encryption_types.assertContains("luks1") supported_encryption_types.assertContains("luks2") def test_default_encryption_type(self): if not os.path.exists(UDISKS_CONFIG_FILE): self.fail('UDisks config file not found.') config = configparser.ConfigParser() config.read(UDISKS_CONFIG_FILE) if 'defaults' not in config: self.fail('Failed to read defaults from UDisks config file.') manager = self.get_object('/Manager') default_encryption_type = self.get_property(manager, '.Manager', 'DefaultEncryptionType') default_encryption_type.assertEqual(config['defaults']['encryption']) @udiskstestcase.unstable_test def test_integrity(self): passwd = 'test' cryptsetup_version = self._get_cryptsetup_version() if cryptsetup_version < LooseVersion('2.2.0'): self.skipTest('Integrity devices are not marked as internal in cryptsetup < 2.2.0') device = self.get_device(self.vdevs[0]) self._create_luks_integrity(self.vdevs[0], passwd) self.addCleanup(self._remove_luks, device) self.udev_settle() self.assertHasIface(device, self.iface_prefix + '.Encrypted') # the device is not opened, we need to read the UUID from LUKS metadata luks_uuid = BlockDev.crypto_luks_uuid(self.vdevs[0]) luks_path = device.Unlock('test', self.no_options, dbus_interface=self.iface_prefix + '.Encrypted') self.assertIsNotNone(luks_path) self.assertTrue(os.path.exists('/dev/disk/by-uuid/%s' % luks_uuid)) luks = self.bus.get_object(self.iface_prefix, luks_path) self.assertIsNotNone(luks) crypto_dev = self.get_property(luks, '.Block', 'CryptoBackingDevice') crypto_dev.assertEqual(device.object_path) dbus_cleartext = self.get_property(device, '.Encrypted', 'CleartextDevice') dbus_cleartext.assertEqual(luks_path) device.Lock(self.no_options, dbus_interface=self.iface_prefix + '.Encrypted') dbus_cleartext = self.get_property(device, '.Encrypted', 'CleartextDevice') dbus_cleartext.assertEqual('/')
def tearDown(self): # make sure the library is initialized with all plugins loaded for other # tests self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
def test_lvactivate_lvdeactivate(self): """Verify it's possible to (de)actiavate an LV""" succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) self.assertTrue(succ) succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, None, [self.loop_dev], None) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.lvm_lvactivate("nonexistingVG", "testLV", True, None) with self.assertRaises(GLib.GError): BlockDev.lvm_lvactivate("testVG", "nonexistingLV", True, None) with self.assertRaises(GLib.GError): BlockDev.lvm_lvactivate("nonexistingVG", "nonexistingLV", True, None) succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, None) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.lvm_lvdeactivate("nonexistingVG", "testLV", None) with self.assertRaises(GLib.GError): BlockDev.lvm_lvdeactivate("testVG", "nonexistingLV", None) with self.assertRaises(GLib.GError): BlockDev.lvm_lvdeactivate("nonexistingVG", "nonexistingLV", None) succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) self.assertTrue(succ) succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, None) self.assertTrue(succ) succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) self.assertTrue(succ)
def test_create_destroy_devices(self): # the easiest case with _track_module_load(self, "zram", "_loaded_zram_module"): self.assertTrue(BlockDev.kbd_zram_create_devices(2, [10 * 1024**2, 10 * 1024**2], [1, 2])) time.sleep(1) self.assertTrue(BlockDev.kbd_zram_destroy_devices()) time.sleep(1) # no nstreams specified with _track_module_load(self, "zram", "_loaded_zram_module"): self.assertTrue(BlockDev.kbd_zram_create_devices(2, [10 * 1024**2, 10 * 1024**2], None)) time.sleep(1) self.assertTrue(BlockDev.kbd_zram_destroy_devices()) time.sleep(1) # with module pre-loaded, but unsed self.assertEqual(os.system("modprobe zram num_devices=2"), 0) time.sleep(1) with _track_module_load(self, "zram", "_loaded_zram_module"): self.assertTrue(BlockDev.kbd_zram_create_devices(2, [10 * 1024**2, 10 * 1024**2], [1, 1])) time.sleep(1) self.assertTrue(BlockDev.kbd_zram_destroy_devices()) time.sleep(1) # with module pre-loaded, and devices used (as active swaps) self.assertEqual(os.system("modprobe zram num_devices=2"), 0) self.assertEqual(os.system("echo 10M > /sys/class/block/zram0/disksize"), 0) self.assertEqual(os.system("echo 10M > /sys/class/block/zram1/disksize"), 0) time.sleep(1) for zram_dev in ("/dev/zram0", "/dev/zram1"): self.assertTrue(BlockDev.swap_mkswap(zram_dev, None)) self.assertTrue(BlockDev.swap_swapon(zram_dev, -1)) with _track_module_load(self, "zram", "_loaded_zram_module"): with self.assertRaises(GLib.GError): self.assertTrue(BlockDev.kbd_zram_create_devices(2, [10 * 1024**2, 10 * 1024**2], [1, 1])) for zram_dev in ("/dev/zram0", "/dev/zram1"): self.assertTrue(BlockDev.swap_swapoff(zram_dev)) self.assertEqual(os.system("rmmod zram"), 0) # should work just fine now self.assertTrue(BlockDev.kbd_zram_create_devices(2, [10 * 1024**2, 10 * 1024**2], [1, 1])) time.sleep(1) self.assertTrue(BlockDev.kbd_zram_destroy_devices()) time.sleep(1)
def _clean_up(self): try: BlockDev.md_deactivate("bd_test_md") except: pass try: BlockDev.md_deactivate(BlockDev.md_node_from_name("bd_test_md")) except: pass try: BlockDev.md_destroy(self.loop_dev) except: pass try: BlockDev.md_destroy(self.loop_dev2) except: pass try: BlockDev.md_destroy(self.loop_dev3) except: pass try: BlockDev.md_deactivate("bd_test_md") except: pass try: BlockDev.md_deactivate(BlockDev.md_node_from_name("bd_test_md")) except: pass try: delete_lio_device(self.loop_dev) except RuntimeError: # just move on, we can do no better here pass os.unlink(self.dev_file) try: delete_lio_device(self.loop_dev2) except RuntimeError: # just move on, we can do no better here pass os.unlink(self.dev_file2) try: delete_lio_device(self.loop_dev3) except RuntimeError: # just move on, we can do no better here pass os.unlink(self.dev_file3)
def test_exfat_set_label(self): """Verify that it is possible to set label of an exfat file system""" succ = BlockDev.fs_exfat_mkfs(self.loop_dev, None) self.assertTrue(succ) fi = BlockDev.fs_exfat_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "") succ = BlockDev.fs_exfat_set_label(self.loop_dev, "test_label") self.assertTrue(succ) fi = BlockDev.fs_exfat_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "test_label") succ = BlockDev.fs_exfat_set_label(self.loop_dev, "test_label2") self.assertTrue(succ) fi = BlockDev.fs_exfat_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "test_label2") succ = BlockDev.fs_exfat_set_label(self.loop_dev, "") self.assertTrue(succ) fi = BlockDev.fs_exfat_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "") succ = BlockDev.fs_exfat_check_label("TEST_LABEL") self.assertTrue(succ) with six.assertRaisesRegex(self, GLib.GError, "at most 11 characters long."): BlockDev.fs_exfat_check_label(12 * "a")
def test_exfat_available(self): """Verify that it is possible to check exfat tech availability""" available = BlockDev.fs_is_tech_avail( BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.MKFS | BlockDev.FSTechMode.REPAIR | BlockDev.FSTechMode.CHECK | BlockDev.FSTechMode.SET_LABEL) self.assertTrue(available) with six.assertRaisesRegex(self, GLib.GError, "doesn't support setting UUID"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.SET_UUID) with six.assertRaisesRegex(self, GLib.GError, "doesn't support resizing"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.RESIZE) BlockDev.switch_init_checks(False) BlockDev.reinit(self.requested_plugins, True, None) # now try without mkfs.exfat with utils.fake_path(all_but="mkfs.exfat"): with six.assertRaisesRegex( self, GLib.GError, "The 'mkfs.exfat' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.MKFS) # now try without fsck.exfat with utils.fake_path(all_but="fsck.exfat"): with six.assertRaisesRegex( self, GLib.GError, "The 'fsck.exfat' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.CHECK) with six.assertRaisesRegex( self, GLib.GError, "The 'fsck.exfat' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.REPAIR) # now try without tune.exfat with utils.fake_path(all_but="tune.exfat"): with six.assertRaisesRegex( self, GLib.GError, "The 'tune.exfat' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.QUERY) with six.assertRaisesRegex( self, GLib.GError, "The 'tune.exfat' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.EXFAT, BlockDev.FSTechMode.SET_LABEL)
def test_ntfs_set_label(self): succ = BlockDev.fs_ntfs_mkfs(self.loop_dev, None) self.assertTrue(succ) fi = BlockDev.fs_ntfs_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "") succ = BlockDev.fs_ntfs_set_label(self.loop_dev, "TEST_LABEL") self.assertTrue(succ) fi = BlockDev.fs_ntfs_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "TEST_LABEL") succ = BlockDev.fs_ntfs_set_label(self.loop_dev, "TEST_LABEL2") self.assertTrue(succ) fi = BlockDev.fs_ntfs_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "TEST_LABEL2") succ = BlockDev.fs_ntfs_set_label(self.loop_dev, "") self.assertTrue(succ) fi = BlockDev.fs_ntfs_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "") succ = BlockDev.fs_ntfs_check_label("TEST_LABEL") self.assertTrue(succ) with self.assertRaisesRegex(GLib.GError, "at most 128 characters long."): BlockDev.fs_ntfs_check_label(129 * "a")
def test_xfs_resize(self): """Verify that it is possible to resize an xfs file system""" run("pvcreate -ff -y %s &>/dev/null" % self.loop_dev) run("vgcreate -s10M libbd_fs_tests %s &>/dev/null" % self.loop_dev) run("lvcreate -n xfs_test -L50M libbd_fs_tests &>/dev/null") self.addCleanup(self._destroy_lvm) lv = "/dev/libbd_fs_tests/xfs_test" succ = BlockDev.fs_xfs_mkfs(lv, None) self.assertTrue(succ) with mounted(lv, self.mount_dir): fi = BlockDev.fs_xfs_get_info(lv) self.assertTrue(fi) self.assertEqual(fi.block_size * fi.block_count, 50 * 1024**2) # no change, nothing should happen with mounted(lv, self.mount_dir): succ = BlockDev.fs_xfs_resize(self.mount_dir, 0, None) self.assertTrue(succ) with mounted(lv, self.mount_dir): fi = BlockDev.fs_xfs_get_info(lv) self.assertTrue(fi) self.assertEqual(fi.block_size * fi.block_count, 50 * 1024**2) # (still) impossible to shrink an XFS file system with mounted(lv, self.mount_dir): with self.assertRaises(GLib.GError): succ = BlockDev.fs_xfs_resize(self.mount_dir, 40 * 1024**2 / fi.block_size, None) run("lvresize -L70M libbd_fs_tests/xfs_test &>/dev/null") # should grow with mounted(lv, self.mount_dir): succ = BlockDev.fs_xfs_resize(self.mount_dir, 0, None) self.assertTrue(succ) with mounted(lv, self.mount_dir): fi = BlockDev.fs_xfs_get_info(lv) self.assertTrue(fi) self.assertEqual(fi.block_size * fi.block_count, 70 * 1024**2) run("lvresize -L90M libbd_fs_tests/xfs_test &>/dev/null") # should grow just to 80 MiB with mounted(lv, self.mount_dir): succ = BlockDev.fs_xfs_resize(self.mount_dir, 80 * 1024**2 / fi.block_size, None) self.assertTrue(succ) with mounted(lv, self.mount_dir): fi = BlockDev.fs_xfs_get_info(lv) self.assertTrue(fi) self.assertEqual(fi.block_size * fi.block_count, 80 * 1024**2) # should grow to 90 MiB with mounted(lv, self.mount_dir): succ = BlockDev.fs_xfs_resize(self.mount_dir, 0, None) self.assertTrue(succ) with mounted(lv, self.mount_dir): fi = BlockDev.fs_xfs_get_info(lv) self.assertTrue(fi) self.assertEqual(fi.block_size * fi.block_count, 90 * 1024**2)
def test_bcache_get_set_mode(self): """Verify that it is possible to get and set Bcache mode""" succ, dev = BlockDev.kbd_bcache_create(self.loop_dev, self.loop_dev2, None) self.assertTrue(succ) self.assertTrue(dev) self.bcache_dev = dev _wait_for_bcache_setup(dev) mode = BlockDev.kbd_bcache_get_mode(self.bcache_dev) self.assertNotEqual(mode, BlockDev.KBDBcacheMode.UNKNOWN) for mode_str in ("writethrough", "writeback", "writearound", "none"): mode = BlockDev.kbd_bcache_get_mode_from_str(mode_str) succ = BlockDev.kbd_bcache_set_mode(self.bcache_dev, mode) self.assertTrue(succ) new_mode = BlockDev.kbd_bcache_get_mode(self.bcache_dev) self.assertEqual(mode, new_mode) self.assertEqual(mode_str, BlockDev.kbd_bcache_get_mode_str(new_mode)) mode_str = "unknown" mode = BlockDev.kbd_bcache_get_mode_from_str(mode_str) with self.assertRaises(GLib.GError): # cannot set mode to "uknown" BlockDev.kbd_bcache_set_mode(self.bcache_dev, mode) mode_str = "bla" with self.assertRaises(GLib.GError): mode = BlockDev.kbd_bcache_get_mode_from_str(mode_str) # set back to some caching mode mode_str = "writethrough" mode = BlockDev.kbd_bcache_get_mode_from_str(mode_str) succ = BlockDev.kbd_bcache_set_mode(self.bcache_dev, mode) self.assertTrue(succ) _wait_for_bcache_setup(dev) succ = BlockDev.kbd_bcache_destroy(self.bcache_dev) self.assertTrue(succ) self.bcache_dev = None time.sleep(1) wipe_all(self.loop_dev, self.loop_dev2)
def test_ntfs_available(self): """Verify that it is possible to check ntfs tech availability""" available = BlockDev.fs_is_tech_avail( BlockDev.FSTech.NTFS, BlockDev.FSTechMode.MKFS | BlockDev.FSTechMode.QUERY | BlockDev.FSTechMode.REPAIR | BlockDev.FSTechMode.CHECK | BlockDev.FSTechMode.SET_LABEL | BlockDev.FSTechMode.RESIZE | BlockDev.FSTechMode.SET_UUID) self.assertTrue(available) BlockDev.switch_init_checks(False) BlockDev.reinit(self.requested_plugins, True, None) # now try without mkntfs with utils.fake_path(all_but="mkntfs"): with self.assertRaisesRegex( GLib.GError, "The 'mkntfs' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.MKFS) # now try without ntfsfix with utils.fake_path(all_but="ntfsfix"): with self.assertRaisesRegex( GLib.GError, "The 'ntfsfix' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.CHECK) with self.assertRaisesRegex( GLib.GError, "The 'ntfsfix' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.REPAIR) # now try without ntfscluster with utils.fake_path(all_but="ntfscluster"): with self.assertRaisesRegex( GLib.GError, "The 'ntfscluster' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.QUERY) # now try without ntfsresize with utils.fake_path(all_but="ntfsresize"): with self.assertRaisesRegex( GLib.GError, "The 'ntfsresize' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.RESIZE) # now try without ntfslabel with utils.fake_path(all_but="ntfslabel"): with self.assertRaisesRegex( GLib.GError, "The 'ntfslabel' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.SET_LABEL) with self.assertRaisesRegex( GLib.GError, "The 'ntfslabel' utility is not available"): BlockDev.fs_is_tech_avail(BlockDev.FSTech.NTFS, BlockDev.FSTechMode.SET_UUID)
import unittest import os import time import subprocess import tempfile from contextlib import contextmanager import utils from utils import run import six import overrides_hack from gi.repository import BlockDev, GLib if not BlockDev.is_initialized(): BlockDev.init(None, None) def mount(device, where): if not os.path.isdir(where): os.makedirs(where) run("mount %s %s" % (device, where)) def umount(what): try: run("umount %s &>/dev/null" % what) except OSError: # no such file or directory pass def check_output(args, ignore_retcode=True):
def test_all(self): """Verify that swap_* functions work as expected""" with self.assertRaises(GLib.GError): BlockDev.swap_mkswap("/non/existing/device", None, None) with self.assertRaises(GLib.GError): BlockDev.swap_swapon("/non/existing/device", -1) with self.assertRaises(GLib.GError): BlockDev.swap_swapoff("/non/existing/device") self.assertFalse(BlockDev.swap_swapstatus("/non/existing/device")) # not a swap device (yet) with self.assertRaises(GLib.GError): BlockDev.swap_swapon(self.loop_dev, -1) with self.assertRaises(GLib.GError): BlockDev.swap_swapoff(self.loop_dev) on = BlockDev.swap_swapstatus(self.loop_dev) self.assertFalse(on) # the common/expected sequence of calls succ = BlockDev.swap_mkswap(self.loop_dev, None, None) self.assertTrue(succ) succ = BlockDev.swap_set_label(self.loop_dev, "BlockDevSwap") self.assertTrue(succ) _ret, out, _err = run_command("blkid -ovalue -sLABEL -p %s" % self.loop_dev) self.assertEqual(out, "BlockDevSwap") succ = BlockDev.swap_swapon(self.loop_dev, -1) self.assertTrue(succ) on = BlockDev.swap_swapstatus(self.loop_dev) self.assertTrue(on) succ = BlockDev.swap_swapoff(self.loop_dev) self.assertTrue(succ) # already off with self.assertRaises(GLib.GError): BlockDev.swap_swapoff(self.loop_dev) on = BlockDev.swap_swapstatus(self.loop_dev) self.assertFalse(on)
def test_set_bitmap_location(self): """Verify we can change bitmap location for an existing MD array""" with wait_for_action("resync"): succ = BlockDev.md_create( "bd_test_md", "raid1", [self.loop_dev, self.loop_dev2, self.loop_dev3], 1, None, True) self.assertTrue(succ) succ = BlockDev.md_set_bitmap_location("bd_test_md", "none") self.assertTrue(succ) loc = BlockDev.md_get_bitmap_location("bd_test_md") self.assertEqual(loc, "none") succ = BlockDev.md_set_bitmap_location("bd_test_md", "internal") self.assertTrue(succ) loc = BlockDev.md_get_bitmap_location("bd_test_md") self.assertEqual(loc, "+8") # test some different name specifications # (need to switch between internal and none because setting the same # location multiple times results in an error) succ = BlockDev.md_set_bitmap_location("/dev/md/bd_test_md", "none") self.assertTrue(succ) node = BlockDev.md_node_from_name("bd_test_md") self.assertIsNotNone(node) succ = BlockDev.md_set_bitmap_location(node, "internal") self.assertTrue(succ) succ = BlockDev.md_set_bitmap_location("/dev/%s" % node, "none") self.assertTrue(succ) # get_bitmap_location should accept name, node or path loc = BlockDev.md_get_bitmap_location(node) self.assertEqual(loc, "none") loc = BlockDev.md_get_bitmap_location("/dev/%s" % node) self.assertEqual(loc, "none") loc = BlockDev.md_get_bitmap_location("/dev/md/bd_test_md") self.assertEqual(loc, "none")
def test_nilfs2_set_label(self): """Verify that it is possible to set label of an nilfs2 file system""" succ = BlockDev.fs_nilfs2_mkfs(self.loop_dev, None) self.assertTrue(succ) fi = BlockDev.fs_nilfs2_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "") succ = BlockDev.fs_nilfs2_set_label(self.loop_dev, "test_label") self.assertTrue(succ) fi = BlockDev.fs_nilfs2_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "test_label") succ = BlockDev.fs_nilfs2_set_label(self.loop_dev, "test_label2") self.assertTrue(succ) fi = BlockDev.fs_nilfs2_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "test_label2") succ = BlockDev.fs_nilfs2_set_label(self.loop_dev, "") self.assertTrue(succ) fi = BlockDev.fs_nilfs2_get_info(self.loop_dev) self.assertTrue(fi) self.assertEqual(fi.label, "") succ = BlockDev.fs_nilfs2_check_label("test_label") self.assertTrue(succ) with self.assertRaisesRegex(GLib.GError, "at most 80 characters long."): BlockDev.fs_nilfs2_check_label(81 * "a")
def test_name_node_bijection(self): """Verify that MD RAID node and name match each other""" with wait_for_action("resync"): succ = BlockDev.md_create( "bd_test_md", "raid1", [self.loop_dev, self.loop_dev2, self.loop_dev3], 1, None, True) self.assertTrue(succ) node = BlockDev.md_node_from_name("bd_test_md") self.assertEqual(BlockDev.md_name_from_node(node), "bd_test_md") self.assertEqual(BlockDev.md_name_from_node("/dev/" + node), "bd_test_md") with self.assertRaises(GLib.GError): node = BlockDev.md_node_from_name("made_up_md") with six.assertRaisesRegex(self, GLib.GError, r'No name'): BlockDev.md_name_from_node("no_such_node") succ = BlockDev.md_deactivate("bd_test_md") self.assertTrue(succ) succ = BlockDev.md_destroy(self.loop_dev) self.assertTrue(succ) succ = BlockDev.md_destroy(self.loop_dev2) self.assertTrue(succ) succ = BlockDev.md_destroy(self.loop_dev3) self.assertTrue(succ)
def _clean_up(self): BlockDev.lvm_lvremove("testVG", "testPool", True, None) LvmPVVGTestCase._clean_up(self)
def test_add_remove(self): """Verify that it is possible to add a device to and remove from an MD RAID""" # the MD array doesn't exist yet with self.assertRaises(GLib.GError): BlockDev.md_add("bd_test_md", self.loop_dev3, 0, None) with wait_for_action("resync"): succ = BlockDev.md_create("bd_test_md", "raid1", [self.loop_dev, self.loop_dev2], 0, None, False) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.md_add("bd_test_md", "/non/existing/device", 0, None) # add the device as a spare succ = BlockDev.md_add("bd_test_md", self.loop_dev3, 0, None) self.assertTrue(succ) md_info = BlockDev.md_detail("bd_test_md") self.assertEqual(md_info.raid_devices, 2) self.assertEqual(md_info.spare_devices, 1) with self.assertRaises(GLib.GError): BlockDev.md_add("bd_test_md", self.loop_dev3, 0, None) # now remove the spare device (should be possible without --fail) with wait_for_action("resync"): succ = BlockDev.md_remove("bd_test_md", self.loop_dev3, False, None) self.assertTrue(succ) md_info = BlockDev.md_detail("bd_test_md") self.assertEqual(md_info.raid_devices, 2) self.assertEqual(md_info.spare_devices, 0) # remove one of the original devices (with --fail enabled) with wait_for_action("resync"): succ = BlockDev.md_remove("bd_test_md", self.loop_dev2, True, None) self.assertTrue(succ) md_info = BlockDev.md_detail("bd_test_md") self.assertEqual(md_info.raid_devices, 2) self.assertEqual(md_info.active_devices, 1) self.assertEqual(md_info.spare_devices, 0) # now try to add it back -- it should be re-added automatically as # a RAID device, not a spare device with wait_for_action("recovery"): succ = BlockDev.md_add("bd_test_md", self.loop_dev2, 0, None) self.assertTrue(succ) md_info = BlockDev.md_detail("bd_test_md") self.assertEqual(md_info.raid_devices, 2) self.assertEqual(md_info.active_devices, 2) self.assertEqual(md_info.spare_devices, 0)
def test_lvresize(self): """Verify that it's possible to resize an LV""" succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) self.assertTrue(succ) succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, None, [self.loop_dev], None) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.lvm_lvresize("nonexistingVG", "testLV", 768 * 1024**2, None) with self.assertRaises(GLib.GError): BlockDev.lvm_lvresize("testVG", "nonexistingLV", 768 * 1024**2, None) # grow succ = BlockDev.lvm_lvresize("testVG", "testLV", 768 * 1024**2, None) self.assertTrue(succ) # same size with self.assertRaises(GLib.GError): BlockDev.lvm_lvresize("testVG", "testLV", 768 * 1024**2, None) # shrink succ = BlockDev.lvm_lvresize("testVG", "testLV", 512 * 1024**2, None) self.assertTrue(succ) # shrink, not a multiple of 512 succ = BlockDev.lvm_lvresize("testVG", "testLV", 500 * 1024**2, None) self.assertTrue(succ) succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) self.assertTrue(succ)
def test_get_superblock_size(self): """Verify that superblock size si calculated properly""" # 2 MiB for versions <= 1.0 self.assertEqual(BlockDev.md_get_superblock_size(2 * 1024**3, "0.9"), 2 * 1024**2) self.assertEqual(BlockDev.md_get_superblock_size(2 * 1024**3, "1.0"), 2 * 1024**2) # no version, "default" or > 1.0 self.assertEqual(BlockDev.md_get_superblock_size(256 * 1024**3, None), 128 * 1024**2) self.assertEqual(BlockDev.md_get_superblock_size(128 * 1024**3, None), 128 * 1024**2) self.assertEqual( BlockDev.md_get_superblock_size(64 * 1024**3, "default"), 64 * 1024**2) self.assertEqual( BlockDev.md_get_superblock_size(63 * 1024**3, "default"), 32 * 1024**2) self.assertEqual(BlockDev.md_get_superblock_size(10 * 1024**3, "1.1"), 8 * 1024**2) self.assertEqual(BlockDev.md_get_superblock_size(1 * 1024**3, "1.1"), 1 * 1024**2) self.assertEqual( BlockDev.md_get_superblock_size(1023 * 1024**2, "1.2"), 1 * 1024**2) self.assertEqual(BlockDev.md_get_superblock_size(512 * 1024**2, "1.2"), 1 * 1024**2) # unsupported version -> default superblock size self.assertEqual( BlockDev.md_get_superblock_size(257 * 1024**2, version="unknown version"), 2 * 1024**2)
def setUpClass(cls): if not BlockDev.is_initialized(): BlockDev.init(cls.requested_plugins, None) else: BlockDev.reinit(cls.requested_plugins, True, None)
def test_zram_add_remove_device(self): """Verify that it is possible to add and remove a zram device""" # the easiest case with _track_module_load(self, "zram", "_loaded_zram_module"): succ, device = BlockDev.kbd_zram_add_device (10 * 1024**2, 4) self.assertTrue(succ) self.assertTrue(device.startswith("/dev/zram")) time.sleep(5) self.assertTrue(BlockDev.kbd_zram_remove_device(device)) # no nstreams specified with _track_module_load(self, "zram", "_loaded_zram_module"): succ, device = BlockDev.kbd_zram_add_device (10 * 1024**2, 0) self.assertTrue(succ) self.assertTrue(device.startswith("/dev/zram")) time.sleep(5) self.assertTrue(BlockDev.kbd_zram_remove_device(device)) # create two devices with _track_module_load(self, "zram", "_loaded_zram_module"): succ, device = BlockDev.kbd_zram_add_device (10 * 1024**2, 4) self.assertTrue(succ) self.assertTrue(device.startswith("/dev/zram")) succ, device2 = BlockDev.kbd_zram_add_device (10 * 1024**2, 4) self.assertTrue(succ) self.assertTrue(device2.startswith("/dev/zram")) time.sleep(5) self.assertTrue(BlockDev.kbd_zram_remove_device(device)) self.assertTrue(BlockDev.kbd_zram_remove_device(device2)) # mixture of multiple devices and a single device with _track_module_load(self, "zram", "_loaded_zram_module"): self.assertTrue(BlockDev.kbd_zram_create_devices(2, [10 * 1024**2, 10 * 1024**2], [1, 2])) time.sleep(5) succ, device = BlockDev.kbd_zram_add_device (10 * 1024**2, 4) self.assertTrue(succ) self.assertTrue(device.startswith("/dev/zram")) time.sleep(5) self.assertTrue(BlockDev.kbd_zram_destroy_devices()) time.sleep(5)
import gi gi.require_version("GLib", "2.0") gi.require_version("BlockDev", "1.0") # initialize the libblockdev library from gi.repository import GLib from gi.repository import BlockDev as blockdev if arch.is_s390(): _REQUESTED_PLUGIN_NAMES = set(("lvm", "btrfs", "swap", "crypto", "loop", "mdraid", "mpath", "dm", "s390")) else: _REQUESTED_PLUGIN_NAMES = set( ("lvm", "btrfs", "swap", "crypto", "loop", "mdraid", "mpath", "dm")) _requested_plugins = blockdev.plugin_specs_from_names(_REQUESTED_PLUGIN_NAMES) try: succ_, avail_plugs = blockdev.try_reinit( require_plugins=_requested_plugins, reload=False, log_func=log_bd_message) except GLib.GError as err: raise RuntimeError("Failed to intialize the libblockdev library: %s" % err) else: avail_plugs = set(avail_plugs) missing_plugs = _REQUESTED_PLUGIN_NAMES - avail_plugs for p in missing_plugs: log.info("Failed to load plugin %s", p)
def test_lvcreate_type(self): """Verify it's possible to create LVs with various types""" succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) self.assertTrue(succ) succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) self.assertTrue(succ) # try to create a striped LV succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, "striped", [self.loop_dev, self.loop_dev2], None) self.assertTrue(succ) # verify that the LV has the requested segtype info = BlockDev.lvm_lvinfo("testVG", "testLV") self.assertEqual(info.segtype, "striped") succ = BlockDev.lvm_lvremove("testVG", "testLV", True, None) self.assertTrue(succ) # try to create a mirrored LV succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, "mirror", [self.loop_dev, self.loop_dev2], None) self.assertTrue(succ) # verify that the LV has the requested segtype info = BlockDev.lvm_lvinfo("testVG", "testLV") self.assertEqual(info.segtype, "mirror") succ = BlockDev.lvm_lvremove("testVG", "testLV", True, None) self.assertTrue(succ) # try to create a raid1 LV succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, "raid1", [self.loop_dev, self.loop_dev2], None) self.assertTrue(succ) # verify that the LV has the requested segtype info = BlockDev.lvm_lvinfo("testVG", "testLV") self.assertEqual(info.segtype, "raid1") succ = BlockDev.lvm_lvremove("testVG", "testLV", True, None) self.assertTrue(succ)