Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
0
    def test_read_only(self):
        for arg in self.path_or_fd(self.mountpoint):
            with self.subTest(type=type(arg)):
                btrfsutil.set_subvolume_read_only(arg)
                self.assertTrue(btrfsutil.get_subvolume_read_only(arg))
                self.assertTrue(btrfsutil.subvolume_info(arg).flags & 1)

                btrfsutil.set_subvolume_read_only(arg, False)
                self.assertFalse(btrfsutil.get_subvolume_read_only(arg))
                self.assertFalse(btrfsutil.subvolume_info(arg).flags & 1)

                btrfsutil.set_subvolume_read_only(arg, True)
                self.assertTrue(btrfsutil.get_subvolume_read_only(arg))
                self.assertTrue(btrfsutil.subvolume_info(arg).flags & 1)

                btrfsutil.set_subvolume_read_only(arg, False)
Пример #8
0
    def test_read_only(self):
        for arg in self.path_or_fd(self.mountpoint):
            with self.subTest(type=type(arg)):
                btrfsutil.set_subvolume_read_only(arg)
                self.assertTrue(btrfsutil.get_subvolume_read_only(arg))
                self.assertTrue(btrfsutil.subvolume_info(arg).flags & 1)

                btrfsutil.set_subvolume_read_only(arg, False)
                self.assertFalse(btrfsutil.get_subvolume_read_only(arg))
                self.assertFalse(btrfsutil.subvolume_info(arg).flags & 1)

                btrfsutil.set_subvolume_read_only(arg, True)
                self.assertTrue(btrfsutil.get_subvolume_read_only(arg))
                self.assertTrue(btrfsutil.subvolume_info(arg).flags & 1)

                btrfsutil.set_subvolume_read_only(arg, False)
Пример #9
0
    def _test_subvolume_info(self, subvol, snapshot):
        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.assertGreaterEqual(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)

        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

        info = btrfsutil.subvolume_info(snapshot)
        self.assertEqual(info.parent_uuid, subvol_uuid)
Пример #10
0
    def _test_subvolume_info(self, subvol, snapshot):
        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.assertGreaterEqual(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)

        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

        info = btrfsutil.subvolume_info(snapshot)
        self.assertEqual(info.parent_uuid, subvol_uuid)
Пример #11
0
    def get_subvolume_from(self, filesystem_path: Path) -> Optional[Subvolume]:
        logger = self._logger

        if not filesystem_path.exists():
            raise SubvolumeError(
                f"The '{filesystem_path}' path does not exist!")

        if not filesystem_path.is_dir():
            raise SubvolumeError(
                f"The '{filesystem_path}' path does not represent a directory!"
            )

        try:
            filesystem_path_str = str(filesystem_path)

            if btrfsutil.is_subvolume(filesystem_path_str):
                subvolume_id = btrfsutil.subvolume_id(filesystem_path_str)
                subvolume_path = btrfsutil.subvolume_path(
                    filesystem_path_str, subvolume_id)
                subvolume_read_only = btrfsutil.get_subvolume_read_only(
                    filesystem_path_str)
                subvolume_info = btrfsutil.subvolume_info(
                    filesystem_path_str, subvolume_id)
                self_uuid = default_if_none(
                    try_convert_bytes_to_uuid(subvolume_info.uuid),
                    constants.EMPTY_UUID,
                )
                parent_uuid = default_if_none(
                    try_convert_bytes_to_uuid(subvolume_info.parent_uuid),
                    constants.EMPTY_UUID,
                )

                return Subvolume(
                    filesystem_path,
                    subvolume_path,
                    datetime.fromtimestamp(subvolume_info.otime),
                    UuidRelation(self_uuid, parent_uuid),
                    NumIdRelation(subvolume_info.id, subvolume_info.parent_id),
                    subvolume_read_only,
                )
        except btrfsutil.BtrfsUtilError as e:
            logger.exception("btrfsutil call failed!")
            raise SubvolumeError(
                f"Could not initialize the subvolume for '{filesystem_path}'!"
            ) from e

        return None