Skip to content

Commit da7074a

Browse files
committed
fix(linstorvolumemanager): robustify "usable size" getters
Impacted functions: `_get_volumes_info` and `_get_volume_node_names_and_size`. Before this change "usable_size" validity was checked too early and which could lead to an exception for no good reason while the size could be known on at least one host despite an issue on other machines. Signed-off-by: Ronan Abhamon <ronan.abhamon@vates.tech>
1 parent fb3fe3a commit da7074a

1 file changed

Lines changed: 47 additions & 44 deletions

File tree

drivers/linstorvolumemanager.py

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -520,13 +520,10 @@ def allocated_volume_size(self):
520520
if volume.storage_pool_name != self._group_name:
521521
continue
522522

523-
current_size = volume.allocated_size
524-
if current_size < 0:
525-
raise LinstorVolumeManagerError(
526-
'Failed to get allocated size of `{}` on `{}`'
527-
.format(resource.name, volume.storage_pool_name)
528-
)
529-
current[volume.number] = max(current_size, current.get(volume.number) or 0)
523+
allocated_size = max(volume.allocated_size, 0)
524+
current_allocated_size = current.get(volume.number) or -1
525+
if allocated_size > current_allocated_size:
526+
current[volume.number] = allocated_size
530527

531528
total_size = 0
532529
for volumes in sizes.values():
@@ -2111,7 +2108,7 @@ def _get_volumes_info(self, volume_name=None):
21112108
if not self._volume_info_cache_dirty:
21122109
return self._volume_info_cache
21132110

2114-
for resource in self._get_resource_cache().resources:
2111+
def process_resource(resource):
21152112
if resource.name not in all_volume_info:
21162113
current = all_volume_info[resource.name] = self.VolumeInfo(
21172114
resource.name
@@ -2124,34 +2121,38 @@ def _get_volumes_info(self, volume_name=None):
21242121

21252122
for volume in resource.volumes:
21262123
# We ignore diskless pools of the form "DfltDisklessStorPool".
2127-
if volume.storage_pool_name == self._group_name:
2128-
if volume.allocated_size < 0:
2129-
raise LinstorVolumeManagerError(
2130-
'Failed to get allocated size of `{}` on `{}`'
2131-
.format(resource.name, volume.storage_pool_name)
2132-
)
2133-
allocated_size = volume.allocated_size
2124+
if volume.storage_pool_name != self._group_name:
2125+
continue
2126+
# Only fetch first volume.
2127+
if volume.number != 0:
2128+
continue
21342129

2135-
current.allocated_size = current.allocated_size and \
2136-
max(current.allocated_size, allocated_size) or \
2137-
allocated_size
2130+
allocated_size = volume.allocated_size
2131+
if allocated_size > current.allocated_size:
2132+
current.allocated_size = allocated_size
21382133

2139-
usable_size = volume.usable_size
2140-
if usable_size > 0 and (
2141-
usable_size < current.virtual_size or
2142-
not current.virtual_size
2143-
):
2144-
current.virtual_size = usable_size
2134+
usable_size = volume.usable_size
2135+
if usable_size > 0 and (
2136+
usable_size < current.virtual_size or
2137+
not current.virtual_size
2138+
):
2139+
current.virtual_size = usable_size
21452140

2146-
if current.virtual_size <= 0:
2147-
raise LinstorVolumeManagerError(
2148-
'Failed to get usable size of `{}` on `{}`'
2149-
.format(resource.name, volume.storage_pool_name)
2150-
)
2141+
try:
2142+
for resource in self._get_resource_cache().resources:
2143+
process_resource(resource)
2144+
for volume in all_volume_info.values():
2145+
if volume.allocated_size <= 0:
2146+
raise LinstorVolumeManagerError('Failed to get allocated size of `{}`'.format(resource.name))
21512147

2152-
for current in all_volume_info.values():
2153-
current.allocated_size *= 1024
2154-
current.virtual_size *= 1024
2148+
if volume.virtual_size <= 0:
2149+
raise LinstorVolumeManagerError('Failed to get usable size of `{}`'.format(volume.name))
2150+
2151+
volume.allocated_size *= 1024
2152+
volume.virtual_size *= 1024
2153+
except LinstorVolumeManagerError:
2154+
self._mark_resource_cache_as_dirty()
2155+
raise
21552156

21562157
self._volume_info_cache_dirty = False
21572158
self._volume_info_cache = all_volume_info
@@ -2166,20 +2167,22 @@ def _get_volume_node_names_and_size(self, volume_name):
21662167
).resources:
21672168
for volume in resource.volumes:
21682169
# We ignore diskless pools of the form "DfltDisklessStorPool".
2169-
if volume.storage_pool_name == self._group_name:
2170-
node_names.add(resource.node_name)
2170+
if volume.storage_pool_name != self._group_name:
2171+
continue
21712172

2172-
current_size = volume.usable_size
2173-
if current_size < 0:
2174-
raise LinstorVolumeManagerError(
2175-
'Failed to get usable size of `{}` on `{}`'
2176-
.format(resource.name, volume.storage_pool_name)
2177-
)
2173+
node_names.add(resource.node_name)
21782174

2179-
if size < 0:
2180-
size = current_size
2181-
else:
2182-
size = min(size, current_size)
2175+
usable_size = volume.usable_size
2176+
if usable_size <= 0:
2177+
continue
2178+
2179+
if size < 0:
2180+
size = usable_size
2181+
else:
2182+
size = min(size, usable_size)
2183+
2184+
if size <= 0:
2185+
raise LinstorVolumeManagerError('Failed to get usable size of `{}`'.format(resource.name))
21832186

21842187
return (node_names, size * 1024)
21852188

0 commit comments

Comments
 (0)