|
15 | 15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | 16 | # |
17 | 17 |
|
18 | | -from sm_typing import override |
| 18 | +from sm_typing import Any, Dict, override |
19 | 19 |
|
20 | 20 | import errno |
21 | 21 | import json |
@@ -273,7 +273,8 @@ class LinstorVolumeManagerError(Exception): |
273 | 273 | ERR_VOLUME_EXISTS = 1, |
274 | 274 | ERR_VOLUME_NOT_EXISTS = 2, |
275 | 275 | ERR_VOLUME_DESTROY = 3, |
276 | | - ERR_GROUP_NOT_EXISTS = 4 |
| 276 | + ERR_GROUP_NOT_EXISTS = 4, |
| 277 | + ERR_VOLUME_IN_USE = 5 |
277 | 278 |
|
278 | 279 | def __init__(self, message, code=ERR_GENERIC): |
279 | 280 | super(LinstorVolumeManagerError, self).__init__(message) |
@@ -302,7 +303,8 @@ class LinstorVolumeManager(object): |
302 | 303 | '_base_group_name', '_group_name', '_ha_group_name', |
303 | 304 | '_volumes', '_storage_pools', '_storage_pools_time', |
304 | 305 | '_kv_cache', '_resource_cache', '_volume_info_cache', |
305 | | - '_kv_cache_dirty', '_resource_cache_dirty', '_volume_info_cache_dirty' |
| 306 | + '_kv_cache_dirty', '_resource_cache_dirty', '_volume_info_cache_dirty', |
| 307 | + '_resources_info_cache', |
306 | 308 | ) |
307 | 309 |
|
308 | 310 | DEV_ROOT_PATH = DRBD_BY_RES_PATH |
@@ -439,6 +441,7 @@ def __init__( |
439 | 441 | self._resource_cache_dirty = True |
440 | 442 | self._volume_info_cache = None |
441 | 443 | self._volume_info_cache_dirty = True |
| 444 | + self._resources_info_cache = None |
442 | 445 | self._build_volumes(repair=repair) |
443 | 446 |
|
444 | 447 | @property |
@@ -698,6 +701,13 @@ def destroy_volume(self, volume_uuid): |
698 | 701 | self._ensure_volume_exists(volume_uuid) |
699 | 702 | self.ensure_volume_is_not_locked(volume_uuid) |
700 | 703 |
|
| 704 | + is_volume_in_use = any(node["in-use"] for node in self.get_resource_info(volume_uuid)["nodes"].values()) |
| 705 | + if is_volume_in_use: |
| 706 | + raise LinstorVolumeManagerError( |
| 707 | + f"Could not destroy volume `{volume_uuid}` as it is currently in use", |
| 708 | + LinstorVolumeManagerError.ERR_VOLUME_IN_USE |
| 709 | + ) |
| 710 | + |
701 | 711 | # Mark volume as destroyed. |
702 | 712 | volume_properties = self._get_volume_properties(volume_uuid) |
703 | 713 | volume_properties[self.PROP_NOT_EXISTS] = self.STATE_NOT_EXISTS |
@@ -1701,6 +1711,9 @@ def get_resources_info(self): |
1701 | 1711 | Give all resources of current group name. |
1702 | 1712 | :rtype: dict(str, list) |
1703 | 1713 | """ |
| 1714 | + if self._resources_info_cache and not self._resource_cache_dirty: |
| 1715 | + return self._resources_info_cache |
| 1716 | + |
1704 | 1717 | resources = {} |
1705 | 1718 | resource_list = self._get_resource_cache() |
1706 | 1719 | volume_names = self.get_volumes_with_name() |
@@ -1757,7 +1770,23 @@ def get_resources_info(self): |
1757 | 1770 | if resource: |
1758 | 1771 | resource['uuid'] = volume_uuid |
1759 | 1772 |
|
1760 | | - return resources |
| 1773 | + self._resources_info_cache = resources |
| 1774 | + return self._resources_info_cache |
| 1775 | + |
| 1776 | + def get_resource_info(self, volume_uuid: str) -> Dict[str, Any]: |
| 1777 | + """ |
| 1778 | + Give a resource info based on its UUID. |
| 1779 | + :param volume_uuid str: volume uuid to search for |
| 1780 | + :rtype: dict(str, any) |
| 1781 | + """ |
| 1782 | + for volume in self.get_resources_info().values(): |
| 1783 | + if volume["uuid"] == volume_uuid: |
| 1784 | + return volume |
| 1785 | + |
| 1786 | + raise LinstorVolumeManagerError( |
| 1787 | + f"Could not find info about volume `{volume_uuid}`", |
| 1788 | + LinstorVolumeManagerError.ERR_VOLUME_NOT_EXISTS |
| 1789 | + ) |
1761 | 1790 |
|
1762 | 1791 | def get_database_path(self): |
1763 | 1792 | """ |
|
0 commit comments