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 _skip_unless_have_unprivileged_subvolume_iterator(self, path): with drop_privs(): try: for _ in btrfsutil.SubvolumeIterator(path): break except OSError as e: if e.errno == errno.ENOTTY: self.skipTest('BTRFS_IOC_GET_SUBVOL_ROOTREF is not available') else: raise
def mocker_check(uuid1): it = btrfsutil.SubvolumeIterator(btrfs_path, info=True, post_order=True) try: for path, info in it: if str(path) == uuid1: return 0 return 1 except Exception as e: print(e) finally: it.close()
def test_subvolume_iterator_unprivileged(self): os.chown(self.mountpoint, NOBODY_UID, -1) pwd = os.getcwd() try: os.chdir(self.mountpoint) with drop_privs(): try: list(btrfsutil.SubvolumeIterator('.')) except OSError as e: if e.errno == errno.ENOTTY: self.skipTest('BTRFS_IOC_GET_SUBVOL_ROOTREF is not available') else: raise self._test_subvolume_iterator() finally: os.chdir(pwd)
def mocker_check(uuid1): it = btrfsutil.SubvolumeIterator(btrfs_path, info=True, post_order=True) try: # print(len(it)) for path, info in it: print(info.id, info.parent_id, path) if str(path) == uuid1: print('ccccccccccccccccccc') return 0 print('bbbbbbbbbbbbbbbbb') return 1 except Exception as e: print(e) finally: it.close() print('aaaaaaaaaaaaaaaaaaaaa')
def _test_subvolume_iterator_race(self): procs = [] fd = os.open('.', os.O_RDONLY | os.O_DIRECTORY) try: for i in range(10): procs.append( multiprocessing.Process( target=self._create_and_delete_subvolume, args=(i,), daemon=True, ) ) for proc in procs: proc.start() for i in range(1000): with btrfsutil.SubvolumeIterator(fd) as it: for _ in it: pass finally: for proc in procs: proc.terminate() proc.join() os.close(fd)
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()