Skip to content

Commit aa72d44

Browse files
committed
fix(linstorvolumemanager): don't allow InUse volumes to be deleted
Check for usage status before deleting a linstor volume and raise an appropriate error if this happens Signed-off-by: Antoine Bartuccio <antoine.bartuccio@vates.tech>
1 parent d2c0f99 commit aa72d44

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

drivers/linstorvolumemanager.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1616
#
1717

18-
from sm_typing import override
18+
from sm_typing import Any, Dict, override
1919

2020
import errno
2121
import json
@@ -273,7 +273,8 @@ class LinstorVolumeManagerError(Exception):
273273
ERR_VOLUME_EXISTS = 1,
274274
ERR_VOLUME_NOT_EXISTS = 2,
275275
ERR_VOLUME_DESTROY = 3,
276-
ERR_GROUP_NOT_EXISTS = 4
276+
ERR_GROUP_NOT_EXISTS = 4,
277+
ERR_VOLUME_IN_USE = 5
277278

278279
def __init__(self, message, code=ERR_GENERIC):
279280
super(LinstorVolumeManagerError, self).__init__(message)
@@ -302,7 +303,8 @@ class LinstorVolumeManager(object):
302303
'_base_group_name', '_group_name', '_ha_group_name',
303304
'_volumes', '_storage_pools', '_storage_pools_time',
304305
'_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',
306308
)
307309

308310
DEV_ROOT_PATH = DRBD_BY_RES_PATH
@@ -439,6 +441,7 @@ def __init__(
439441
self._resource_cache_dirty = True
440442
self._volume_info_cache = None
441443
self._volume_info_cache_dirty = True
444+
self._resources_info_cache = None
442445
self._build_volumes(repair=repair)
443446

444447
@property
@@ -698,6 +701,13 @@ def destroy_volume(self, volume_uuid):
698701
self._ensure_volume_exists(volume_uuid)
699702
self.ensure_volume_is_not_locked(volume_uuid)
700703

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+
701711
# Mark volume as destroyed.
702712
volume_properties = self._get_volume_properties(volume_uuid)
703713
volume_properties[self.PROP_NOT_EXISTS] = self.STATE_NOT_EXISTS
@@ -1701,6 +1711,9 @@ def get_resources_info(self):
17011711
Give all resources of current group name.
17021712
:rtype: dict(str, list)
17031713
"""
1714+
if self._resources_info_cache and not self._resource_cache_dirty:
1715+
return self._resources_info_cache
1716+
17041717
resources = {}
17051718
resource_list = self._get_resource_cache()
17061719
volume_names = self.get_volumes_with_name()
@@ -1757,7 +1770,23 @@ def get_resources_info(self):
17571770
if resource:
17581771
resource['uuid'] = volume_uuid
17591772

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+
)
17611790

17621791
def get_database_path(self):
17631792
"""

0 commit comments

Comments
 (0)