Skip to content

<bug>[sblk]: fix vg being re created #407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
59 changes: 53 additions & 6 deletions kvmagent/kvmagent/plugins/shared_block_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from zstacklib.utils import linux
from zstacklib.utils import lock
from zstacklib.utils import lvm
from zstacklib.utils import list_ops
from zstacklib.utils import bash
from zstacklib.utils import qemu_img, qcow2
from zstacklib.utils import traceable_shell
Expand Down Expand Up @@ -353,6 +354,7 @@ class SharedBlockPlugin(kvmagent.KvmAgent):
CONVERT_VOLUME_FORMAT_PATH = "/sharedblock/volume/convertformat"
SHRINK_SNAPSHOT_PATH = "/sharedblock/snapshot/shrink"
GET_QCOW2_HASH_VALUE_PATH = "/sharedblock/getqcow2hash"
CHECK_LOCK_PATH = "/sharedblock/lock/check"

vgs_in_progress = set()
vg_size = {}
Expand Down Expand Up @@ -401,6 +403,7 @@ def start(self):
http_server.register_async_uri(self.GET_DOWNLOAD_BITS_FROM_KVM_HOST_PROGRESS_PATH, self.get_download_bits_from_kvmhost_progress)
http_server.register_async_uri(self.SHRINK_SNAPSHOT_PATH, self.shrink_snapshot)
http_server.register_async_uri(self.GET_QCOW2_HASH_VALUE_PATH, self.get_qcow2_hashvalue)
http_server.register_async_uri(self.CHECK_LOCK_PATH, self.check_lock)

self.imagestore_client = ImageStoreClient()

Expand Down Expand Up @@ -444,10 +447,10 @@ def get_disk_paths(disks):

return diskPaths

def create_vg_if_not_found(self, vgUuid, disks, hostUuid, allDisks, forceWipe=False):
def create_vg_if_not_found(self, vgUuid, disks, hostUuid, allDisks, forceWipe=False, is_first_create_vg=False):
# type: (str, set([CheckDisk]), str, set([CheckDisk]), bool) -> bool
@linux.retry(times=5, sleep_time=random.uniform(0.1, 3))
def find_vg(vgUuid, raise_exception = True):
def find_vg(vgUuid, raise_exception=True):
cmd = shell.ShellCmd("timeout 5 vgscan --ignorelockingfailure; vgs --nolocking -t %s -otags | grep %s" % (vgUuid, INIT_TAG))
cmd(is_exception=False)
if cmd.return_code != 0 and raise_exception:
Comment on lines 447 to 456
Copy link

@coderabbitai coderabbitai bot Dec 3, 2023

Choose a reason for hiding this comment

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

Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [447-463]

create_vg_if_not_found方法中,当is_first_create_vgFalse时,抛出异常以防止数据丢失,这与PR目标一致。但是,在add_disk方法中调用create_vg_if_not_found时,没有传递is_first_create_vg参数,这可能会导致在不应该创建vg时创建vg,从而可能导致数据丢失。建议在add_disk方法中添加对is_first_create_vg参数的处理。

Copy link
Member Author

Choose a reason for hiding this comment

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

我在 create_vg_if_not_found 的 is_first_create_vg 参数设置为默认 false,是不是这样就比较安全,就不需要在 add_disk 里加了

Copy link

Choose a reason for hiding this comment

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

@MatheMatrix 您的建议将is_first_create_vg参数的默认值设置为False是一个安全的做法,这样可以确保在默认情况下不会无意中重新创建卷组,从而避免数据丢失。如果您的代码逻辑中确实需要在某些情况下创建新的卷组,您可以显式地将该参数设置为True。这样,就不需要在add_disk方法中添加额外的处理了。🐰

Expand All @@ -457,14 +460,17 @@ def find_vg(vgUuid, raise_exception = True):
return True

@linux.retry(times=3, sleep_time=random.uniform(0.1, 3))
def create_vg(hostUuid, vgUuid, diskPaths, raise_excption = True):
def create_vg(hostUuid, vgUuid, diskPaths, raise_exception=True):
if not is_first_create_vg:
raise Exception("vg %s has already been created before, and there may be a risk of data loss during "
"secondary creation. Please check your storage" % vgUuid)
cmd = shell.ShellCmd("vgcreate -qq --shared --addtag '%s::%s::%s::%s' --metadatasize %s %s %s" %
(INIT_TAG, hostUuid, time.time(), linux.get_hostname(),
DEFAULT_VG_METADATA_SIZE, vgUuid, " ".join(diskPaths)))
cmd(is_exception=False)
logger.debug("created vg %s, ret: %s, stdout: %s, stderr: %s" %
(vgUuid, cmd.return_code, cmd.stdout, cmd.stderr))
if cmd.return_code != 0 and raise_excption:
if cmd.return_code != 0 and raise_exception:
raise RetryException("ret: %s, stdout: %s, stderr: %s" %
(cmd.return_code, cmd.stdout, cmd.stderr))
elif cmd.return_code != 0:
Expand Down Expand Up @@ -499,7 +505,7 @@ def ping(self, req):
cmd = jsonobject.loads(req[http.REQUEST_BODY])
rsp = AgentRsp()
size_cache = self.vg_size.get(cmd.vgUuid)
if size_cache != None and linux.get_current_timestamp() - size_cache['currentTimestamp'] < 60:
if size_cache is not None and linux.get_current_timestamp() - size_cache['currentTimestamp'] < 60:
rsp.totalCapacity = size_cache['totalCapacity']
rsp.availableCapacity = size_cache['availableCapacity']
elif cmd.vgUuid not in self.vgs_in_progress:
Expand Down Expand Up @@ -640,7 +646,7 @@ def config_lvm(host_id, enableLvmetad=False):

lvm.start_lvmlockd(cmd.ioTimeout)
logger.debug("find/create vg %s lock..." % cmd.vgUuid)
rsp.isFirst = self.create_vg_if_not_found(cmd.vgUuid, disks, cmd.hostUuid, allDisks, cmd.forceWipe)
rsp.isFirst = self.create_vg_if_not_found(cmd.vgUuid, disks, cmd.hostUuid, allDisks, cmd.forceWipe, cmd.isFirst)

# sanlock table:
#
Expand Down Expand Up @@ -1641,4 +1647,45 @@ def get_qcow2_hashvalue(self, req):

with lvm.RecursiveOperateLv(abs_path, shared=True):
rsp.hashValue = secret.get_image_hash(abs_path)
return jsonobject.dumps(rsp)

@kvmagent.replyerror
def check_lock(self, req):
cmd = jsonobject.loads(req[http.REQUEST_BODY])
rsp = AgentRsp()
if cmd.vgUuids is None or len(cmd.vgUuids) == 0:
return jsonobject.dumps(rsp)

rsp.failedVgs = {}

def vgck(vg_group):
if len(vg_group) == 0:
return

vgUuid = vg_group.pop(0)
r, o, e = lvm.vgck(vgUuid, 10)

if o is not None and o != "":
for es in o.strip().splitlines():
if "lock start in progress" in es:
break
elif "held by other host" in es:
break
elif "Reading VG %s without a lock" % vgUuid in es:
rsp.failedVgs.update({vgUuid : o})
break
vgck(vg_group)

# up to three worker threads executing vgck
threads_maxnum = 3
vg_groups = list_ops.list_split(cmd.vgUuids, threads_maxnum)

threads = []
for vg_group in vg_groups:
if len(vg_group) != 0:
threads.append(thread.ThreadFacade.run_in_thread(vgck, (vg_group,)))

for t in threads:
t.join()

return jsonobject.dumps(rsp)
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ def __init__(self):
def disconnect(self, vgUuid, hostUuid):
return sharedblock_utils.shareblock_disconnect(vgUuid=vgUuid,hostUuid=hostUuid)

def connect(self, sharedBlockUuids, allSharedBlockUuids, vgUuid, hostUuid, hostId, forceWipe=False):
def connect(self, sharedBlockUuids, allSharedBlockUuids, vgUuid, hostUuid, hostId, forceWipe=False, isFirst=True):
return sharedblock_utils.shareblock_connect(
sharedBlockUuids=sharedBlockUuids,
allSharedBlockUuids=allSharedBlockUuids,
vgUuid=vgUuid,
hostId=hostId,
hostUuid=hostUuid,
forceWipe=forceWipe
forceWipe=forceWipe,
isFirst=isFirst
)

def logout(self, vgUuid, hostUuid):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import os.path
import random

from kvmagent.test.shareblock_testsuite.shared_block_plugin_teststub import SharedBlockPluginTestStub
from kvmagent.test.utils import sharedblock_utils,pytest_utils,storage_device_utils
from zstacklib.utils import bash
from zstacklib.utils import bash,lvm
from unittest import TestCase
from zstacklib.test.utils import misc,env
import concurrent.futures
Expand Down Expand Up @@ -50,4 +51,19 @@ def test_sharedblock_connect(self):
to_do.append(future)

for future in concurrent.futures.as_completed(to_do):
self.assertEqual(future.result().success, True, future.result().error)
if not future.result().success:
self.assertEqual("other thread is connecting now" in future.result().error, True, future.result().error)

r, o ,e = bash.bash_roe("vgchange --lockstop %s" % vgUuid)
self.assertEqual(0, r, e)

r, o = bash.bash_ro(" pvs -oname --noheading -Svg_name=%s" % vgUuid)
disk = o.strip().splitlines()[0].strip()
bash.bash_roe("wipefs -af %s" % disk)
r = bash.bash_r("vgs | grep %s" % vgUuid)
self.assertNotEqual(0, r)

rsp = self.connect([blockUuid], [blockUuid], vgUuid, hostUuid, hostId, forceWipe=True, isFirst=False)
self.assertEqual(False, rsp.success, rsp.error)
r = bash.bash_r("vgs | grep %s" % vgUuid)
self.assertNotEqual(0, r)
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@


storage_device_utils.init_storagedevice_plugin()
init_kvmagent()
vm_utils.init_vm_plugin()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@


storage_device_utils.init_storagedevice_plugin()
init_kvmagent()
vm_utils.init_vm_plugin()


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# coding=utf-8
from kvmagent.test.shareblock_testsuite.shared_block_plugin_teststub import SharedBlockPluginTestStub
from kvmagent.test.utils import sharedblock_utils,pytest_utils,storage_device_utils
from zstacklib.utils import bash, lvm, jsonobject
from unittest import TestCase
from zstacklib.test.utils import misc,env


storage_device_utils.init_storagedevice_plugin()

PKG_NAME = __name__

# must create iSCSI stroage before run test
__ENV_SETUP__ = {
'self': {
'xml':'http://smb.zstack.io/mirror/ztest/xml/threeDiskVm.xml',
'init':['bash ./createTwoLunsIscsiStorage.sh']
}
}

hostUuid = "8b12f74e6a834c5fa90304b8ea54b1dd"
hostId = 24
vgUuid = "36b02490bb944233b0b01990a450ba83"
vg2Uuid = "ee09b7986bbc4a1f85f439b168c3aee7"

Comment on lines +21 to +25
Copy link

Choose a reason for hiding this comment

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

在测试用例中使用硬编码的UUID和主机ID可能不是最佳实践,因为在不同的环境或资源下运行测试时可能会导致问题。建议使用动态生成或配置文件中的值来替换这些硬编码值。

## describe: case will manage by ztest
class TestSharedBlockPlugin(TestCase, SharedBlockPluginTestStub):
@classmethod
def setUpClass(cls):
pass
@pytest_utils.ztest_decorater
def test_sharedblock_check_lock(self):
self_vm = env.get_vm_metadata('self')
rsp = storage_device_utils.iscsi_login(
self_vm.ip,"3260"
)
self.assertEqual(rsp.success, True, rsp.error)

# test connect shareblock
r, o = bash.bash_ro("ls /dev/disk/by-id | grep scsi|awk -F '-' '{print $2}'")
blockUuids = o.strip().splitlines()

rsp = self.connect(blockUuids[0 : 1], blockUuids, vgUuid, hostUuid, hostId, forceWipe=True)
self.assertEqual(True, rsp.success, rsp.error)
o = bash.bash_o("vgs")
self.assertEqual(True, rsp.success, o)

rsp = self.connect(blockUuids[1 : 2], blockUuids, vg2Uuid, hostUuid, hostId, forceWipe=True)
self.assertEqual(True, rsp.success, rsp.error)

# normal
rsp = sharedblock_utils.sharedblock_check_lock(
vgUuids=[vgUuid, vg2Uuid],
)
self.assertEqual(True, rsp.success, rsp.error)
self.assertEqual(0, len(rsp.failedVgs), rsp.failedVgs.__dict__)

# vg without a lock
lvm.drop_vg_lock(vgUuid)

rsp = sharedblock_utils.sharedblock_check_lock(
vgUuids=[vgUuid, vg2Uuid],
)
self.assertEqual(True, rsp.success, rsp.error)
self.assertEqual(1, len(rsp.failedVgs), rsp.failedVgs.__dict__)
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, rsp.failedVgs.__dict__)
Copy link

Choose a reason for hiding this comment

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

hasattr函数的使用似乎是不正确的。在这里,它被用来检查rsp.failedVgs是否包含特定的UUID,但hasattr是用来检查对象是否有特定名称的属性。如果failedVgs是一个包含UUID的列表,应该使用vgUuid in rsp.failedVgs来进行检查。

- self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, rsp.failedVgs.__dict__)
+ self.assertIn(vgUuid, rsp.failedVgs, str(rsp.failedVgs))

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, rsp.failedVgs.__dict__)
self.assertIn(vgUuid, rsp.failedVgs, str(rsp.failedVgs))


rsp = self.connect(blockUuids[0 : 1], blockUuids, vgUuid, hostUuid, hostId, forceWipe=False)
self.assertEqual(True, rsp.success, rsp.error)

# If there is no lv, restarting lvmlockd may not restore vg lock(lvm 2.03.11)
bash.bash_errorout("lvcreate --size 10M %s" % vgUuid)
bash.bash_errorout("lvcreate --size 10M %s" % vg2Uuid)

# kill lvmlockd
lvm.stop_lvmlockd()
rsp = sharedblock_utils.sharedblock_check_lock(
vgUuids=[vgUuid, vg2Uuid],
)
self.assertEqual(True, rsp.success, rsp.error)
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, str(rsp.failedVgs))
Copy link

Choose a reason for hiding this comment

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

同上,这里的hasattr使用也是不正确的。如果failedVgs是一个字典或者有属性的对象,应该使用getattr(rsp.failedVgs, vgUuid, None)来代替hasattr,或者如果failedVgs是一个列表,应该使用vgUuid in rsp.failedVgs

- self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, str(rsp.failedVgs))
+ self.assertIn(vgUuid, rsp.failedVgs, str(rsp.failedVgs))

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, str(rsp.failedVgs))
self.assertIn(vgUuid, rsp.failedVgs, str(rsp.failedVgs))

self.assertEqual(rsp.failedVgs.hasattr(vg2Uuid), True, str(rsp.failedVgs))

rsp = self.connect(blockUuids[0 : 1], blockUuids, vgUuid, hostUuid, hostId, forceWipe=False)
self.assertEqual(True, rsp.success, rsp.error)
rsp = self.connect(blockUuids[1 : 2], blockUuids, vg2Uuid, hostUuid, hostId, forceWipe=False)
self.assertEqual(True, rsp.success, rsp.error)
bash.bash_errorout("lvcreate --size 10M %s" % vgUuid)
bash.bash_errorout("lvcreate --size 10M %s" % vg2Uuid)


Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@


storage_device_utils.init_storagedevice_plugin()
init_kvmagent()
vm_utils.init_vm_plugin()


Expand Down
3 changes: 2 additions & 1 deletion kvmagent/kvmagent/test/utils/pytest_utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import os
import coverage
from zstacklib.test.utils import env
from zstacklib.utils import debug

Out_flag = True
Copy link

Choose a reason for hiding this comment

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

全局变量Out_flag用于控制测试环境的退出状态,但这种做法可能不是最佳实践,因为它可能会绕过一些清理和日志记录步骤。



debug.install_runtime_tracedumper()
class PytestExtension(object):

cov = None
Comment on lines 1 to 11
Copy link

Choose a reason for hiding this comment

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

Note: This review was outside the patches, and no patch overlapping with it was found. Original lines [26-30]

teardown_class中直接使用os._exit(0)os._exit(1)退出进程可能不是最佳实践,因为这会立即退出进程,而不会调用清理处理程序、执行日志记录等。建议使用更标准的测试框架方法来处理测试的退出。


Note: This review was outside the patches, and no patch overlapping with it was found. Original lines [32-32]

函数名ztest_decorater可能是一个拼写错误,正确的应该是ztest_decorator

Expand Down
11 changes: 9 additions & 2 deletions kvmagent/kvmagent/test/utils/sharedblock_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ def sharedblock_ping(vgUuid):
}))

@misc.return_jsonobject()
def shareblock_connect(sharedBlockUuids=None, allSharedBlockUuids=None, vgUuid=None,hostId=None,hostUuid=None, forceWipe=True):
def shareblock_connect(sharedBlockUuids=None, allSharedBlockUuids=None, vgUuid=None,hostId=None,hostUuid=None, forceWipe=True, isFirst=True):
Copy link

Choose a reason for hiding this comment

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

shareblock_connect 函数中添加了一个新参数 isFirst。请确认所有调用此函数的代码都已更新,以包含这个新参数。由于 isFirst 的默认值设置为 True,这可能会影响函数的现有行为,需要验证这一点是否符合预期。

return get_sharedblock_plugin().connect(misc.make_a_request({
"sharedBlockUuids":sharedBlockUuids, # [], ls /dev/disk/by-id -l|grep scsi
"allSharedBlockUuids":allSharedBlockUuids,
"vgUuid": vgUuid ,# random uuid
"hostId":hostId,
"hostUuid": hostUuid,
"forceWipe": forceWipe,
"primaryStorageUuid":vgUuid
"primaryStorageUuid":vgUuid,
"isFirst":isFirst
}))

@misc.return_jsonobject()
Expand Down Expand Up @@ -313,3 +314,9 @@ def shareblock_get_qcow2_hashvalue(installPath=None):
return get_sharedblock_plugin().get_qcow2_hashvalue(misc.make_a_request({
"installPath": installPath
}))

@misc.return_jsonobject()
def sharedblock_check_lock(vgUuids=[]):
return get_sharedblock_plugin().check_lock(misc.make_a_request({
"vgUuids": vgUuids
}))
12 changes: 12 additions & 0 deletions zstacklib/zstacklib/utils/list_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,15 @@ def list_and(list1, list2):
new_list.append(item)

return new_list

def list_split(list, n):
if len(list) == 0:
return list

if n <= 0:
raise Exception("num must be positive")

result = [[] for _ in range(min(n, len(list)))]
for i, v in enumerate(list):
result[i % n].append(v)
return result
Comment on lines +33 to +43
Copy link

Choose a reason for hiding this comment

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

Avoid using list as a variable name since it shadows the built-in list type in Python. Consider using a different name like input_list or items. Also, when the input list is empty, the function should return an empty list of lists to maintain consistency with its intended purpose. Lastly, the exception message should refer to the parameter n instead of "num" for clarity.

- def list_split(list, n):
+ def list_split(input_list, n):
-     if len(list) == 0:
+     if len(input_list) == 0:
-         return list
+         return [[]]
-         raise Exception("num must be positive")
+         raise Exception("n must be positive")
-     result = [[] for _ in range(min(n, len(list)))]
+     result = [[] for _ in range(min(n, len(input_list)))]
-     for i, v in enumerate(list):
+     for i, v in enumerate(input_list):

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def list_split(list, n):
if len(list) == 0:
return list
if n <= 0:
raise Exception("num must be positive")
result = [[] for _ in range(min(n, len(list)))]
for i, v in enumerate(list):
result[i % n].append(v)
return result
def list_split(input_list, n):
if len(input_list) == 0:
return [[]]
if n <= 0:
raise Exception("n must be positive")
result = [[] for _ in range(min(n, len(input_list)))]
for i, v in enumerate(input_list):
result[i % n].append(v)
return result

5 changes: 4 additions & 1 deletion zstacklib/zstacklib/utils/lvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1814,9 +1814,12 @@ def check_pv_status(vgUuid, timeout):

return True, ""

@bash.in_bash
def vgck(vgUuid, timeout):
return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))
Comment on lines +1818 to +1819
Copy link

Choose a reason for hiding this comment

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

The vgck function is not handling the case where the timeout command may not be available on the system. Ensure that the system has the timeout utility installed or handle the absence gracefully.

- return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))
+ # Ensure that the timeout command is available or handle its absence
+ if not shell.command_exists('timeout'):
+     raise Exception('The "timeout" command is not available on this system.')
+ return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def vgck(vgUuid, timeout):
return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))
def vgck(vgUuid, timeout):
# 确保系统已安装 timeout 命令或优雅地处理其缺失
if not shell.command_exists('timeout'):
raise Exception('The "timeout" command is not available on this system.')
return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))


def lvm_vgck(vgUuid, timeout):
health, o, e = bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (360 if timeout < 360 else timeout, vgUuid))
health, o, e = vgck(vgUuid, 360 if timeout < 360 else timeout)
check_stuck_vglk()

if health != 0:
Comment on lines 1814 to 1825
Copy link

Choose a reason for hiding this comment

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

The lvm_vgck function is using a hardcoded timeout value of 360 seconds for the vgck command. Consider making the timeout value configurable or ensuring that it is suitable for all expected use cases.

- health, o, e = vgck(vgUuid, 360 if timeout < 360 else timeout)
+ # Consider replacing the hardcoded value with a configurable parameter or constant
+ health, o, e = vgck(vgUuid, timeout)

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
return True, ""
@bash.in_bash
def vgck(vgUuid, timeout):
return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))
def lvm_vgck(vgUuid, timeout):
health, o, e = bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (360 if timeout < 360 else timeout, vgUuid))
health, o, e = vgck(vgUuid, 360 if timeout < 360 else timeout)
check_stuck_vglk()
if health != 0:
return True, ""
@bash.in_bash
def vgck(vgUuid, timeout):
return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid))
def lvm_vgck(vgUuid, timeout):
# Consider replacing the hardcoded value with a configurable parameter or constant
health, o, e = vgck(vgUuid, timeout)
check_stuck_vglk()
if health != 0:

Comment on lines 1821 to 1825
Copy link

Choose a reason for hiding this comment

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

The lvm_vgck function is calling check_stuck_vglk without capturing its return value or any exceptions it might raise. Ensure that the result of check_stuck_vglk is handled appropriately.

- check_stuck_vglk()
+ # Handle the result of check_stuck_vglk
+ try:
+     check_stuck_vglk()
+ except Exception as e:
+     logger.error('An error occurred while checking for stuck vglk: %s' % str(e))
+     return False, 'An error occurred while checking for stuck vglk'

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def lvm_vgck(vgUuid, timeout):
health, o, e = bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (360 if timeout < 360 else timeout, vgUuid))
health, o, e = vgck(vgUuid, 360 if timeout < 360 else timeout)
check_stuck_vglk()
if health != 0:
def lvm_vgck(vgUuid, timeout):
health, o, e = vgck(vgUuid, 360 if timeout < 360 else timeout)
# Handle the result of check_stuck_vglk
try:
check_stuck_vglk()
except Exception as e:
logger.error('An error occurred while checking for stuck vglk: %s' % str(e))
return False, 'An error occurred while checking for stuck vglk'
if health != 0:

Expand Down