def test_deleted_subvolumes(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol + '1') btrfsutil.delete_subvolume(subvol + '1') for arg in self.path_or_fd(self.mountpoint): with self.subTest(type=type(arg)): self.assertEqual(btrfsutil.deleted_subvolumes(arg), [256])
def test_subvolume_inherit(self): subvol = os.path.join(self.mountpoint, 'subvol') inherit = btrfsutil.QgroupInherit() inherit.add_group(5) btrfsutil.create_subvolume(subvol, qgroup_inherit=inherit)
def test_subvolume_path(self): btrfsutil.create_subvolume(os.path.join(self.mountpoint, 'subvol1')) os.mkdir(os.path.join(self.mountpoint, 'dir1')) os.mkdir(os.path.join(self.mountpoint, 'dir1/dir2')) btrfsutil.create_subvolume(os.path.join(self.mountpoint, 'dir1/dir2/subvol2')) btrfsutil.create_subvolume(os.path.join(self.mountpoint, 'dir1/dir2/subvol2/subvol3')) os.mkdir(os.path.join(self.mountpoint, 'subvol1/dir3')) btrfsutil.create_subvolume(os.path.join(self.mountpoint, 'subvol1/dir3/subvol4')) for arg in self.path_or_fd(self.mountpoint): with self.subTest(type=type(arg)): self.assertEqual(btrfsutil.subvolume_path(arg), '') self.assertEqual(btrfsutil.subvolume_path(arg, 5), '') self.assertEqual(btrfsutil.subvolume_path(arg, 256), 'subvol1') self.assertEqual(btrfsutil.subvolume_path(arg, 257), 'dir1/dir2/subvol2') self.assertEqual(btrfsutil.subvolume_path(arg, 258), 'dir1/dir2/subvol2/subvol3') self.assertEqual(btrfsutil.subvolume_path(arg, 259), 'subvol1/dir3/subvol4') pwd = os.getcwd() try: os.chdir(self.mountpoint) path = '' for i in range(26): name = chr(ord('a') + i) * 255 path = os.path.join(path, name) btrfsutil.create_subvolume(name) os.chdir(name) self.assertEqual(btrfsutil.subvolume_path('.'), path) finally: os.chdir(pwd)
def create(type_): volume = get_free_volume(type_) btfrs.create_subvolume(str(volume.path())) for path in volume.type.properties.values(): (volume.path() / path).touch() print('Created: ' + volume.name()) return volume
def _create_and_delete_subvolume(i): dir_name = f'dir{i}' subvol_name = dir_name + '/subvol' while True: os.mkdir(dir_name) btrfsutil.create_subvolume(subvol_name) btrfsutil.delete_subvolume(subvol_name) os.rmdir(dir_name)
def test_subvolume_info(self): for arg in self.path_or_fd(self.mountpoint): with self.subTest(type=type(arg)): info = btrfsutil.subvolume_info(arg) self.assertEqual(info.id, 5) self.assertEqual(info.parent_id, 0) self.assertEqual(info.dir_id, 0) self.assertEqual(info.flags, 0) self.assertIsInstance(info.uuid, bytes) self.assertEqual(len(info.uuid), 16) self.assertEqual(info.parent_uuid, bytes(16)) self.assertEqual(info.received_uuid, bytes(16)) self.assertNotEqual(info.generation, 0) self.assertEqual(info.ctransid, 0) self.assertEqual(info.otransid, 0) self.assertEqual(info.stransid, 0) self.assertEqual(info.rtransid, 0) self.assertIsInstance(info.ctime, float) self.assertIsInstance(info.otime, float) self.assertEqual(info.stime, 0) self.assertEqual(info.rtime, 0) subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) info = btrfsutil.subvolume_info(subvol) self.assertEqual(info.id, 256) self.assertEqual(info.parent_id, 5) self.assertEqual(info.dir_id, 256) self.assertEqual(info.flags, 0) self.assertIsInstance(info.uuid, bytes) self.assertEqual(len(info.uuid), 16) self.assertEqual(info.parent_uuid, bytes(16)) self.assertEqual(info.received_uuid, bytes(16)) self.assertNotEqual(info.generation, 0) self.assertNotEqual(info.ctransid, 0) self.assertNotEqual(info.otransid, 0) self.assertEqual(info.stransid, 0) self.assertEqual(info.rtransid, 0) self.assertNotEqual(info.ctime, 0) self.assertNotEqual(info.otime, 0) self.assertEqual(info.stime, 0) self.assertEqual(info.rtime, 0) subvol_uuid = info.uuid snapshot = os.path.join(self.mountpoint, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot) info = btrfsutil.subvolume_info(snapshot) self.assertEqual(info.parent_uuid, subvol_uuid) # TODO: test received_uuid, stransid, rtransid, stime, and rtime for arg in self.path_or_fd(self.mountpoint): with self.subTest(type=type(arg)): with self.assertRaises(btrfsutil.BtrfsUtilError) as e: # BTRFS_EXTENT_TREE_OBJECTID btrfsutil.subvolume_info(arg, 2)
def make_subvolumes(path: Path, subvolumes) -> list: """create a subvolumes inside of path for each element in iterable subvolumes""" paths = list() for s in subvolumes: p = path.joinpath(str(s)) btrfsutil.create_subvolume(p) paths.append(p) if len(paths) > 0: return paths return None
def test_default_subvolume(self): for arg in self.path_or_fd(self.mountpoint): with self.subTest(type=type(arg)): self.assertEqual(btrfsutil.get_default_subvolume(arg), 5) subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) for arg in self.path_or_fd(subvol): with self.subTest(type=type(arg)): btrfsutil.set_default_subvolume(arg) self.assertEqual(btrfsutil.get_default_subvolume(arg), 256) btrfsutil.set_default_subvolume(arg, 5) self.assertEqual(btrfsutil.get_default_subvolume(arg), 5)
def test_subvolume_info_unprivileged(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) snapshot = os.path.join(self.mountpoint, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot) with drop_privs(): try: self._test_subvolume_info(subvol, snapshot) except OSError as e: if e.errno == errno.ENOTTY: self.skipTest('BTRFS_IOC_GET_SUBVOL_INFO is not available') else: raise
def test_subvolume_info(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) snapshot = os.path.join(self.mountpoint, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot) self._test_subvolume_info(subvol, snapshot) for arg in self.path_or_fd(self.mountpoint): with self.subTest(type=type(arg)): with self.assertRaises(btrfsutil.BtrfsUtilError) as e: # BTRFS_EXTENT_TREE_OBJECTID btrfsutil.subvolume_info(arg, 2) self.assertEqual(e.exception.btrfsutilerror, btrfsutil.ERROR_SUBVOLUME_NOT_FOUND)
def test_subvolume_info_unprivileged(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) snapshot = os.path.join(self.mountpoint, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot) with drop_privs(): try: btrfsutil.subvolume_info(self.mountpoint) except OSError as e: if e.errno == errno.ENOTTY: self.skipTest('BTRFS_IOC_GET_SUBVOL_INFO is not available') else: raise self._test_subvolume_info(subvol, snapshot)
def mocker_init(directory): ''' init <directory> - создать образ контейнера используя указанную директорию как корневую. Возвращает в stdout id созданного образа. ''' uuid1 = 'img_' + str(random.randint(42002, 42254)) if os.path.exists(directory): if mocker_check(uuid1) == 0: print('UUID conflict, retrying...') mocker_init(directory) return btrfsutil.create_subvolume(btrfs_path + '/' + str(uuid1)) os.system('cp -rf --reflink=auto ' + directory + '/* ' + btrfs_path + '/' + str(uuid1)) if not os.path.exists(btrfs_path + '/' + str(uuid1) + '/img.source'): file = open(btrfs_path + '/' + str(uuid1) + '/img.source', 'w') file.write(directory) file.close() print("created " + str(uuid1)) else: print("Noo directory named " + directory + " exists")
def test_scandir(self): dirs = None mnt_point = None vol = None try: # setup dirs = dev.setup_dirs(Path('/tmp/lazytest/test_scandir')) mnt_point = dirs[dev.DirKey.MOUNTS].joinpath('test') os.mkdir(mnt_point, mode=0o755) vol = dev.make_volume(dirs, 'test', 50) vol.mount(mnt_point) # tests self.assertIsNone( snapshotkit2.scan_dir(mnt_point)) # no subvolumes os.mkdir(mnt_point.joinpath('notasnapshot')) self.assertIsNone( snapshotkit2.scan_dir(mnt_point)) # still no subvolumes btrfsutil.create_subvolume(mnt_point.joinpath('0')) self.assertTrue(len( snapshotkit2.scan_dir(mnt_point)) == 1) # one subvolume make_subvolumes(mnt_point, range(1, 5)) self.assertTrue(len( snapshotkit2.scan_dir(mnt_point)) == 5) # five subvolumes btrfsutil.create_subvolume(mnt_point.joinpath('test')) self.assertTrue(len( snapshotkit2.scan_dir(mnt_point)) == 6) # six subvolumes # five subvolumes with names that can be converted to integers self.assertTrue( len(snapshotkit2.scan_dir(mnt_point, filter_func=filter_int)) == 5) finally: # teardown if vol is not None: vol.scrap() if mnt_point is not None: os.rmdir(mnt_point) if dirs is not None: dev.scrap_dirs(dirs)
def test_subvolume_iterator(self): pwd = os.getcwd() try: os.chdir(self.mountpoint) btrfsutil.create_subvolume('foo') path, subvol = next(btrfsutil.SubvolumeIterator('.', info=True)) self.assertEqual(path, 'foo') self.assertIsInstance(subvol, btrfsutil.SubvolumeInfo) self.assertEqual(subvol.id, 256) self.assertEqual(subvol.parent_id, 5) btrfsutil.create_subvolume('foo/bar') btrfsutil.create_subvolume('foo/bar/baz') subvols = [ ('foo', 256), ('foo/bar', 257), ('foo/bar/baz', 258), ] for arg in self.path_or_fd('.'): with self.subTest(type=type(arg)): self.assertEqual(list(btrfsutil.SubvolumeIterator(arg)), subvols) self.assertEqual(list(btrfsutil.SubvolumeIterator('.', top=0)), subvols) self.assertEqual( list(btrfsutil.SubvolumeIterator('.', post_order=True)), [('foo/bar/baz', 258), ('foo/bar', 257), ('foo', 256)]) subvols = [ ('bar', 257), ('bar/baz', 258), ] self.assertEqual(list(btrfsutil.SubvolumeIterator('.', top=256)), subvols) self.assertEqual(list(btrfsutil.SubvolumeIterator('foo', top=0)), subvols) os.rename('foo/bar/baz', 'baz') self.assertEqual(sorted(btrfsutil.SubvolumeIterator('.')), [('baz', 258), ('foo', 256), ('foo/bar', 257)]) with btrfsutil.SubvolumeIterator('.') as it: self.assertGreaterEqual(it.fileno(), 0) it.close() with self.assertRaises(ValueError): next(iter(it)) with self.assertRaises(ValueError): it.fileno() it.close() finally: os.chdir(pwd)
def test_subvolume_iterator(self): pwd = os.getcwd() try: os.chdir(self.mountpoint) btrfsutil.create_subvolume('foo') path, subvol = next(btrfsutil.SubvolumeIterator('.', info=True)) self.assertEqual(path, 'foo') self.assertIsInstance(subvol, btrfsutil.SubvolumeInfo) self.assertEqual(subvol.id, 256) self.assertEqual(subvol.parent_id, 5) btrfsutil.create_subvolume('foo/bar') btrfsutil.create_subvolume('foo/bar/baz') subvols = [ ('foo', 256), ('foo/bar', 257), ('foo/bar/baz', 258), ] for arg in self.path_or_fd('.'): with self.subTest(type=type(arg)): self.assertEqual(list(btrfsutil.SubvolumeIterator(arg)), subvols) self.assertEqual(list(btrfsutil.SubvolumeIterator('.', top=0)), subvols) self.assertEqual(list(btrfsutil.SubvolumeIterator('.', post_order=True)), [('foo/bar/baz', 258), ('foo/bar', 257), ('foo', 256)]) subvols = [ ('bar', 257), ('bar/baz', 258), ] self.assertEqual(list(btrfsutil.SubvolumeIterator('.', top=256)), subvols) self.assertEqual(list(btrfsutil.SubvolumeIterator('foo', top=0)), subvols) os.rename('foo/bar/baz', 'baz') self.assertEqual(sorted(btrfsutil.SubvolumeIterator('.')), [('baz', 258), ('foo', 256), ('foo/bar', 257)]) with btrfsutil.SubvolumeIterator('.') as it: self.assertGreaterEqual(it.fileno(), 0) it.close() with self.assertRaises(ValueError): next(iter(it)) with self.assertRaises(ValueError): it.fileno() it.close() finally: os.chdir(pwd)
def test_create_snapshot(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) os.mkdir(os.path.join(subvol, 'dir')) for i, arg in enumerate(self.path_or_fd(subvol)): with self.subTest(type=type(arg)): snapshots_dir = os.path.join(self.mountpoint, 'snapshots{}'.format(i)) os.mkdir(snapshots_dir) snapshot = os.path.join(snapshots_dir, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot + '1') self.assertTrue(btrfsutil.is_subvolume(snapshot + '1')) self.assertTrue(os.path.exists(os.path.join(snapshot + '1', 'dir'))) btrfsutil.create_snapshot(subvol, (snapshot + '2').encode()) self.assertTrue(btrfsutil.is_subvolume(snapshot + '2')) self.assertTrue(os.path.exists(os.path.join(snapshot + '2', 'dir'))) if HAVE_PATH_LIKE: btrfsutil.create_snapshot(subvol, PurePath(snapshot + '3')) self.assertTrue(btrfsutil.is_subvolume(snapshot + '3')) self.assertTrue(os.path.exists(os.path.join(snapshot + '3', 'dir'))) nested_subvol = os.path.join(subvol, 'nested') more_nested_subvol = os.path.join(nested_subvol, 'more_nested') btrfsutil.create_subvolume(nested_subvol) btrfsutil.create_subvolume(more_nested_subvol) os.mkdir(os.path.join(more_nested_subvol, 'nested_dir')) snapshot = os.path.join(self.mountpoint, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot + '1') # Dummy subvolume. self.assertEqual(os.stat(os.path.join(snapshot + '1', 'nested')).st_ino, 2) self.assertFalse(os.path.exists(os.path.join(snapshot + '1', 'nested', 'more_nested'))) btrfsutil.create_snapshot(subvol, snapshot + '2', recursive=True) self.assertTrue(os.path.exists(os.path.join(snapshot + '2', 'nested/more_nested/nested_dir'))) transid = btrfsutil.create_snapshot(subvol, snapshot + '3', recursive=True, async_=True) self.assertTrue(os.path.exists(os.path.join(snapshot + '3', 'nested/more_nested/nested_dir'))) self.assertGreater(transid, 0) btrfsutil.create_snapshot(subvol, snapshot + '4', read_only=True) self.assertTrue(btrfsutil.get_subvolume_read_only(snapshot + '4'))
def test_create_snapshot(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol) os.mkdir(os.path.join(subvol, 'dir')) for i, arg in enumerate(self.path_or_fd(subvol)): with self.subTest(type=type(arg)): snapshots_dir = os.path.join(self.mountpoint, 'snapshots{}'.format(i)) os.mkdir(snapshots_dir) snapshot = os.path.join(snapshots_dir, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot + '1') self.assertTrue(btrfsutil.is_subvolume(snapshot + '1')) self.assertTrue(os.path.exists(os.path.join(snapshot + '1', 'dir'))) btrfsutil.create_snapshot(subvol, (snapshot + '2').encode()) self.assertTrue(btrfsutil.is_subvolume(snapshot + '2')) self.assertTrue(os.path.exists(os.path.join(snapshot + '2', 'dir'))) if HAVE_PATH_LIKE: btrfsutil.create_snapshot(subvol, PurePath(snapshot + '3')) self.assertTrue(btrfsutil.is_subvolume(snapshot + '3')) self.assertTrue(os.path.exists(os.path.join(snapshot + '3', 'dir'))) nested_subvol = os.path.join(subvol, 'nested') more_nested_subvol = os.path.join(nested_subvol, 'more_nested') btrfsutil.create_subvolume(nested_subvol) btrfsutil.create_subvolume(more_nested_subvol) os.mkdir(os.path.join(more_nested_subvol, 'nested_dir')) snapshot = os.path.join(self.mountpoint, 'snapshot') btrfsutil.create_snapshot(subvol, snapshot + '1') # Dummy subvolume. self.assertEqual(os.stat(os.path.join(snapshot + '1', 'nested')).st_ino, 2) self.assertFalse(os.path.exists(os.path.join(snapshot + '1', 'nested', 'more_nested'))) btrfsutil.create_snapshot(subvol, snapshot + '2', recursive=True) self.assertTrue(os.path.exists(os.path.join(snapshot + '2', 'nested/more_nested/nested_dir'))) transid = btrfsutil.create_snapshot(subvol, snapshot + '3', recursive=True, no_wait=True) self.assertTrue(os.path.exists(os.path.join(snapshot + '3', 'nested/more_nested/nested_dir'))) self.assertGreater(transid, 0) btrfsutil.create_snapshot(subvol, snapshot + '4', read_only=True) self.assertTrue(btrfsutil.get_subvolume_read_only(snapshot + '4'))
def test_delete_subvolume(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol + '1') self.assertTrue(os.path.exists(subvol + '1')) btrfsutil.create_subvolume(subvol + '2') self.assertTrue(os.path.exists(subvol + '2')) btrfsutil.create_subvolume(subvol + '3') self.assertTrue(os.path.exists(subvol + '3')) btrfsutil.delete_subvolume(subvol + '1') self.assertFalse(os.path.exists(subvol + '1')) btrfsutil.delete_subvolume((subvol + '2').encode()) self.assertFalse(os.path.exists(subvol + '2')) if HAVE_PATH_LIKE: btrfsutil.delete_subvolume(PurePath(subvol + '3')) self.assertFalse(os.path.exists(subvol + '3')) # Test deleting subvolumes under '/' in a chroot. pid = os.fork() if pid == 0: try: os.chroot(self.mountpoint) os.chdir('/') btrfsutil.create_subvolume('/subvol4') self.assertTrue(os.path.exists('/subvol4')) btrfsutil.delete_subvolume('/subvol4') self.assertFalse(os.path.exists('/subvol4')) with self.assertRaises(btrfsutil.BtrfsUtilError): btrfsutil.delete_subvolume('/') os._exit(0) except Exception: traceback.print_exc() os._exit(1) wstatus = os.waitpid(pid, 0)[1] self.assertTrue(os.WIFEXITED(wstatus)) self.assertEqual(os.WEXITSTATUS(wstatus), 0) btrfsutil.create_subvolume(subvol + '5') btrfsutil.create_subvolume(subvol + '5/foo') btrfsutil.create_subvolume(subvol + '5/bar') btrfsutil.create_subvolume(subvol + '5/bar/baz') btrfsutil.create_subvolume(subvol + '5/bar/qux') btrfsutil.create_subvolume(subvol + '5/quux') with self.assertRaises(btrfsutil.BtrfsUtilError): btrfsutil.delete_subvolume(subvol + '5') btrfsutil.delete_subvolume(subvol + '5', recursive=True) self.assertFalse(os.path.exists(subvol + '5'))
def _test_subvolume_iterator(self): btrfsutil.create_subvolume('foo') with btrfsutil.SubvolumeIterator('.', info=True) as it: path, subvol = next(it) self.assertEqual(path, 'foo') self.assertIsInstance(subvol, btrfsutil.SubvolumeInfo) self.assertEqual(subvol.id, 256) self.assertEqual(subvol.parent_id, 5) self.assertRaises(StopIteration, next, it) btrfsutil.create_subvolume('foo/bar') btrfsutil.create_subvolume('foo/bar/baz') subvols = [ ('foo', 256), ('foo/bar', 257), ('foo/bar/baz', 258), ] for arg in self.path_or_fd('.'): with self.subTest(type=type(arg)), btrfsutil.SubvolumeIterator(arg) as it: self.assertEqual(list(it), subvols) with btrfsutil.SubvolumeIterator('.', top=0) as it: self.assertEqual(list(it), subvols) if os.geteuid() == 0: with btrfsutil.SubvolumeIterator('foo', top=5) as it: self.assertEqual(list(it), subvols) with btrfsutil.SubvolumeIterator('.', post_order=True) as it: self.assertEqual(list(it), [('foo/bar/baz', 258), ('foo/bar', 257), ('foo', 256)]) subvols = [ ('bar', 257), ('bar/baz', 258), ] if os.geteuid() == 0: with btrfsutil.SubvolumeIterator('.', top=256) as it: self.assertEqual(list(it), subvols) with btrfsutil.SubvolumeIterator('foo') as it: self.assertEqual(list(it), subvols) with btrfsutil.SubvolumeIterator('foo', top=0) as it: self.assertEqual(list(it), subvols) os.rename('foo/bar/baz', 'baz') os.mkdir('dir') btrfsutil.create_subvolume('dir/qux') os.mkdir('dir/qux/dir2') btrfsutil.create_subvolume('dir/qux/dir2/quux') subvols = [ ('baz', 258), ('dir/qux', 259), ('dir/qux/dir2/quux', 260), ('foo', 256), ('foo/bar', 257), ] # Test various corner cases of the unprivileged implementation # where we can't access the subvolume. if os.geteuid() != 0: with regain_privs(): # We don't have permission to traverse the path. os.mkdir('directory_perms', 0o700) btrfsutil.create_subvolume('directory_perms/subvol') # We don't have permission to resolve the subvolume path. os.mkdir('subvol_perms', 0o755) btrfsutil.create_subvolume('subvol_perms/subvol') os.chmod('subvol_perms/subvol', 0o700) # The path doesn't exist. os.mkdir('enoent', 0o755) btrfsutil.create_subvolume('enoent/subvol') subprocess.check_call(['mount', '-t', 'tmpfs', 'tmpfs', 'enoent']) # The path exists but it's not a subvolume. os.mkdir('notsubvol', 0o755) btrfsutil.create_subvolume('notsubvol/subvol') subprocess.check_call(['mount', '-t', 'tmpfs', 'tmpfs', 'notsubvol']) os.mkdir('notsubvol/subvol') # The path exists and is a subvolume, but on a different # filesystem. os.mkdir('wrongfs', 0o755) btrfsutil.create_subvolume('wrongfs/subvol') other_mountpoint, _ = self.mount_btrfs() subprocess.check_call(['mount', '--bind', '--', other_mountpoint, 'wrongfs/subvol']) # The path exists and is a subvolume on the same # filesystem, but not the right one. os.mkdir('wrongsubvol', 0o755) btrfsutil.create_subvolume('wrongsubvol/subvol') subprocess.check_call(['mount', '--bind', 'baz', 'wrongsubvol/subvol']) with btrfsutil.SubvolumeIterator('.') as it: self.assertEqual(sorted(it), subvols) with btrfsutil.SubvolumeIterator('.', post_order=True) as it: self.assertEqual(sorted(it), subvols) with btrfsutil.SubvolumeIterator('.') as it: self.assertGreaterEqual(it.fileno(), 0) it.close() with self.assertRaises(ValueError): next(iter(it)) with self.assertRaises(ValueError): it.fileno() it.close()
def test_create_subvolume(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol + '1') self.assertTrue(btrfsutil.is_subvolume(subvol + '1')) btrfsutil.create_subvolume((subvol + '2').encode()) self.assertTrue(btrfsutil.is_subvolume(subvol + '2')) if HAVE_PATH_LIKE: btrfsutil.create_subvolume(PurePath(subvol + '3')) self.assertTrue(btrfsutil.is_subvolume(subvol + '3')) pwd = os.getcwd() try: os.chdir(self.mountpoint) btrfsutil.create_subvolume('subvol4') self.assertTrue(btrfsutil.is_subvolume('subvol4')) finally: os.chdir(pwd) btrfsutil.create_subvolume(subvol + '5/') self.assertTrue(btrfsutil.is_subvolume(subvol + '5')) btrfsutil.create_subvolume(subvol + '6//') self.assertTrue(btrfsutil.is_subvolume(subvol + '6')) transid = btrfsutil.create_subvolume(subvol + '7', no_wait=True) self.assertTrue(btrfsutil.is_subvolume(subvol + '7')) self.assertGreater(transid, 0) # Test creating subvolumes under '/' in a chroot. pid = os.fork() if pid == 0: try: os.chroot(self.mountpoint) os.chdir('/') btrfsutil.create_subvolume('/subvol8') self.assertTrue(btrfsutil.is_subvolume('/subvol8')) with self.assertRaises(btrfsutil.BtrfsUtilError): btrfsutil.create_subvolume('/') os._exit(0) except Exception: traceback.print_exc() os._exit(1) wstatus = os.waitpid(pid, 0)[1] self.assertTrue(os.WIFEXITED(wstatus)) self.assertEqual(os.WEXITSTATUS(wstatus), 0)
def test_create_subvolume(self): subvol = os.path.join(self.mountpoint, 'subvol') btrfsutil.create_subvolume(subvol + '1') self.assertTrue(btrfsutil.is_subvolume(subvol + '1')) btrfsutil.create_subvolume((subvol + '2').encode()) self.assertTrue(btrfsutil.is_subvolume(subvol + '2')) if HAVE_PATH_LIKE: btrfsutil.create_subvolume(PurePath(subvol + '3')) self.assertTrue(btrfsutil.is_subvolume(subvol + '3')) pwd = os.getcwd() try: os.chdir(self.mountpoint) btrfsutil.create_subvolume('subvol4') self.assertTrue(btrfsutil.is_subvolume('subvol4')) finally: os.chdir(pwd) btrfsutil.create_subvolume(subvol + '5/') self.assertTrue(btrfsutil.is_subvolume(subvol + '5')) btrfsutil.create_subvolume(subvol + '6//') self.assertTrue(btrfsutil.is_subvolume(subvol + '6')) transid = btrfsutil.create_subvolume(subvol + '7', async=True) self.assertTrue(btrfsutil.is_subvolume(subvol + '7')) self.assertGreater(transid, 0) # Test creating subvolumes under '/' in a chroot. pid = os.fork() if pid == 0: try: os.chroot(self.mountpoint) os.chdir('/') btrfsutil.create_subvolume('/subvol8') self.assertTrue(btrfsutil.is_subvolume('/subvol8')) with self.assertRaises(btrfsutil.BtrfsUtilError): btrfsutil.create_subvolume('/') os._exit(0) except Exception: traceback.print_exc() os._exit(1) wstatus = os.waitpid(pid, 0)[1] self.assertTrue(os.WIFEXITED(wstatus)) self.assertEqual(os.WEXITSTATUS(wstatus), 0)