Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
coverage
coverage<7.11
astroid
pylint
bitarray
Expand Down
8 changes: 6 additions & 2 deletions drivers/LinstorSR.py
Original file line number Diff line number Diff line change
Expand Up @@ -1934,8 +1934,9 @@ def resize(self, sr_uuid, vdi_uuid, size) -> str:
raise xs_errors.XenError('VDISize', opterr='shrinking not allowed')

if size == self.size:
return VDI.VDI.get_params(self)
return VDI.VDI.get_params(self) # No change needed

# Compute VDI sizes
if self.vdi_type == vhdutil.VDI_TYPE_RAW:
old_volume_size = self.size
new_volume_size = LinstorVolumeManager.round_up_volume_size(size)
Expand All @@ -1952,8 +1953,10 @@ def resize(self, sr_uuid, vdi_uuid, size) -> str:
self.sr._ensure_space_available(space_needed)

old_size = self.size

# Resize VDI
if self.vdi_type == vhdutil.VDI_TYPE_RAW:
self._linstor.resize(self.uuid, new_volume_size)
self._linstor.resize_volume(self.uuid, new_volume_size)
else:
if new_volume_size != old_volume_size:
self.sr._vhdutil.inflate(
Expand All @@ -1965,6 +1968,7 @@ def resize(self, sr_uuid, vdi_uuid, size) -> str:
# Reload size attributes.
self._load_this()

# Update metadata
vdi_ref = self.sr.srcmd.params['vdi_ref']
self.session.xenapi.VDI.set_virtual_size(vdi_ref, str(self.size))
self.session.xenapi.VDI.set_physical_utilisation(
Expand Down
42 changes: 22 additions & 20 deletions drivers/linstorvolumemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,31 +841,33 @@ def resize_volume(self, volume_uuid, new_size):
self.ensure_volume_is_not_locked(volume_uuid)
new_size = self.round_up_volume_size(new_size) // 1024

retry_count = 30
while True:
result = self._linstor.volume_dfn_modify(
rsc_name=volume_name,
volume_nr=0,
size=new_size
# We can't resize anything until DRBD is up to date.
# We wait here for 5min max and raise an easy to understand error for the user.
# 5min is an arbitrary time, it's impossible to get a fit all situation value
# and it's currently impossible to know how much time we have to wait
# This is mostly an issue for thick provisioning, thin isn't affected.
start_time = time.monotonic()
try:
self._linstor.resource_dfn_wait_synced(volume_name, wait_interval=1.0, timeout=60*5)
except linstor.LinstorTimeoutError:
raise LinstorVolumeManagerError(
f"Volume `{volume_uuid}` from SR `{self._group_name}` is busy and can't be resized right now. " +
"Please retry later."
)
util.SMlog(f"DRBD is up to date, syncing took {time.monotonic() - start_time}s")

self._mark_resource_cache_as_dirty()

error_str = self._get_error_str(result)
if not error_str:
break
result = self._linstor.volume_dfn_modify(
rsc_name=volume_name,
volume_nr=0,
size=new_size
)
Comment on lines +859 to +863
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to keep the initial call before waiting for the sync to complete. The idea would then be to display a message saying that we need to wait, which would create a sort of block/symmetry with your message suggestion "DRBD is up to date, syncing took...".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experience proves that we do need to wait, especially for early steps. That's why we had the previous retry mechanism.

Either we keep the previous process which is a bit bruteforce or we just wait before but we can't keep both.
I don't see the benefit of calling the function if we know that it's gonna crash anyway.

I think we should discuss this :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to discuss this, I'm not sure this would be benificial


# After volume creation, DRBD volume can be unusable during many seconds.
# So we must retry the definition change if the device is not up to date.
# Often the case for thick provisioning.
if retry_count and error_str.find('non-UpToDate DRBD device') >= 0:
time.sleep(2)
retry_count -= 1
continue
self._mark_resource_cache_as_dirty()

error_str = self._get_error_str(result)
if error_str:
raise LinstorVolumeManagerError(
'Could not resize volume `{}` from SR `{}`: {}'
.format(volume_uuid, self._group_name, error_str)
f"Could not resize volume `{volume_uuid}` from SR `{self._group_name}`: {error_str}"
)

def get_volume_name(self, volume_uuid):
Expand Down