-
Notifications
You must be signed in to change notification settings - Fork 80
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
<bug>[sblk]: fix vg being re created #407
base: master
Are you sure you want to change the base?
Conversation
fix vg being re created http://jira.zstack.io/browse/ZSTAC-57025 Resolves/Related: ZSTAC-57025 Change-Id: 180d7b4804474940baf57fb02c047eb3
Walkthrough本次代码更新主要涉及KVM代理的共享块插件和测试套件。新增了参数 Changes
TipsChat with CodeRabbit Bot (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 1
Configuration used: CodeRabbit UI
Files selected for processing (4)
- kvmagent/kvmagent/plugins/shared_block_plugin.py (3 hunks)
- kvmagent/kvmagent/test/shareblock_testsuite/shared_block_plugin_teststub.py (1 hunks)
- kvmagent/kvmagent/test/shareblock_testsuite/test_shareblock_connect.py (2 hunks)
- kvmagent/kvmagent/test/utils/sharedblock_utils.py (1 hunks)
Additional comments: 5
kvmagent/kvmagent/plugins/shared_block_plugin.py (1)
- 643-646: 在
connect
方法中,正确地传递了cmd.isFirst
参数给create_vg_if_not_found
方法,这与PR目标一致。kvmagent/kvmagent/test/shareblock_testsuite/shared_block_plugin_teststub.py (1)
- 19-28: 确保所有调用
connect
方法的代码都已更新,以包含新的isFirst
参数,并且逻辑正确地处理了这个参数。kvmagent/kvmagent/test/shareblock_testsuite/test_shareblock_connect.py (2)
1-1: 代码中新增了
os.path
模块的导入,这可能意味着文件路径操作的增加。51-69: 测试函数
test_sharedblock_connect
中添加了新的逻辑和断言,包括并发执行connect
方法和对卷组状态的额外检查。特别是在第66行,isFirst
参数被用于控制卷组创建的行为,这与PR目标一致,即防止不必要地重新创建卷组。kvmagent/kvmagent/test/utils/sharedblock_utils.py (1)
- 23-33: 确保代码库中所有对
shareblock_connect
函数的调用都已更新,以包含新的isFirst
参数。这是为了防止卷组不必要地被重新创建,从而避免数据丢失。
|
||
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: |
There was a problem hiding this comment.
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_vg
为False
时,抛出异常以防止数据丢失,这与PR目标一致。但是,在add_disk
方法中调用create_vg_if_not_found
时,没有传递is_first_create_vg
参数,这可能会导致在不应该创建vg时创建vg,从而可能导致数据丢失。建议在add_disk
方法中添加对is_first_create_vg
参数的处理。
There was a problem hiding this comment.
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 里加了
There was a problem hiding this comment.
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
方法中添加额外的处理了。🐰
add ping check for sblk vg lock http://jira.zstack.io/browse/SUG-411 Resolves/Related: SUG-411 Change-Id: 3c246404f4944e4db991250bf103b464
@coderabbitai review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 11
Configuration used: CodeRabbit UI
Files selected for processing (9)
- kvmagent/kvmagent/plugins/shared_block_plugin.py (8 hunks)
- kvmagent/kvmagent/test/shareblock_testsuite/test_shareblock_data_volume_with_iothreadpin.py (1 hunks)
- kvmagent/kvmagent/test/shareblock_testsuite/test_shareblock_data_volume_with_multi_queues.py (1 hunks)
- kvmagent/kvmagent/test/shareblock_testsuite/test_sharedblock_check_lock.py (1 hunks)
- kvmagent/kvmagent/test/shareblock_testsuite/test_virtio_scsi_shareblock_data_volume_with_iothreadpin.py (1 hunks)
- kvmagent/kvmagent/test/utils/pytest_utils.py (1 hunks)
- kvmagent/kvmagent/test/utils/sharedblock_utils.py (2 hunks)
- zstacklib/zstacklib/utils/list_ops.py (1 hunks)
- zstacklib/zstacklib/utils/lvm.py (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- kvmagent/kvmagent/plugins/shared_block_plugin.py
Additional comments: 3
kvmagent/kvmagent/test/shareblock_testsuite/test_shareblock_data_volume_with_iothreadpin.py (1)
- 11-16:
kvmagent/kvmagent/test/shareblock_testsuite/test_virtio_scsi_shareblock_data_volume_with_iothreadpin.py (1)
- 11-16: 根据PR目标和生成的摘要,
init_kvmagent()
函数调用已从test_virtio_scsi_shareblock_data_volume_with_iothreadpin.py
文件中移除。这表明初始化KVM代理或相关功能的过程可能已经改变。请确保这一更改不会影响测试的执行和预期结果。kvmagent/kvmagent/test/utils/pytest_utils.py (1)
- 3-4: 新增了对
zstacklib.utils
模块中debug
的依赖,并调用了install_runtime_tracedumper()
函数。这可能会改变代码的运行时调试和跟踪收集行为。
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 |
There was a problem hiding this comment.
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.
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 |
@@ -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): |
There was a problem hiding this comment.
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
,这可能会影响函数的现有行为,需要验证这一点是否符合预期。
hostUuid = "8b12f74e6a834c5fa90304b8ea54b1dd" | ||
hostId = 24 | ||
vgUuid = "36b02490bb944233b0b01990a450ba83" | ||
vg2Uuid = "ee09b7986bbc4a1f85f439b168c3aee7" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在测试用例中使用硬编码的UUID和主机ID可能不是最佳实践,因为在不同的环境或资源下运行测试时可能会导致问题。建议使用动态生成或配置文件中的值来替换这些硬编码值。
) | ||
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__) |
There was a problem hiding this comment.
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.
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, rsp.failedVgs.__dict__) | |
self.assertIn(vgUuid, rsp.failedVgs, str(rsp.failedVgs)) |
vgUuids=[vgUuid, vg2Uuid], | ||
) | ||
self.assertEqual(True, rsp.success, rsp.error) | ||
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, str(rsp.failedVgs)) |
There was a problem hiding this comment.
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.
self.assertEqual(rsp.failedVgs.hasattr(vgUuid), True, str(rsp.failedVgs)) | |
self.assertIn(vgUuid, rsp.failedVgs, str(rsp.failedVgs)) |
@@ -1,10 +1,11 @@ | |||
import os | |||
import coverage | |||
from zstacklib.test.utils import env | |||
from zstacklib.utils import debug | |||
|
|||
Out_flag = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
全局变量Out_flag
用于控制测试环境的退出状态,但这种做法可能不是最佳实践,因为它可能会绕过一些清理和日志记录步骤。
import os | ||
import coverage | ||
from zstacklib.test.utils import env | ||
from zstacklib.utils import debug | ||
|
||
Out_flag = True | ||
|
||
|
||
debug.install_runtime_tracedumper() | ||
class PytestExtension(object): | ||
|
||
cov = None |
There was a problem hiding this comment.
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
。
|
||
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: |
There was a problem hiding this comment.
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.
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: |
def vgck(vgUuid, timeout): | ||
return bash.bash_roe('timeout -s SIGKILL %s vgck %s 2>&1' % (timeout, vgUuid)) |
There was a problem hiding this comment.
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.
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: |
There was a problem hiding this comment.
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.
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: |
fix vg being re created
http://jira.zstack.io/browse/ZSTAC-57025
Resolves/Related: ZSTAC-57025
Change-Id: 180d7b4804474940baf57fb02c047eb3
Summary by CodeRabbit
新功能
错误修复
测试
重构
样式
文档
杂务