This commit is contained in:
zj
2026-02-04 21:23:16 +08:00
parent 62219201b8
commit c6fc0d7f40
8 changed files with 219 additions and 60 deletions

View File

@@ -7,12 +7,15 @@ from system_info import SystemInfoManager
import re
import pexpect # <--- 新增导入 pexpect
import sys
# NEW: 导入 DiskOperations
from disk_operations import DiskOperations
logger = logging.getLogger(__name__)
class RaidOperations:
def __init__(self):
self.system_manager = SystemInfoManager()
def __init__(self, system_manager: SystemInfoManager, disk_ops: DiskOperations): # <--- Add system_manager and disk_ops parameters
self.system_manager = system_manager
self.disk_ops = disk_ops # Store disk_ops instance
def _execute_shell_command(self, command_list, error_msg_prefix, suppress_critical_dialog_on_stderr_match=None, input_to_command=None):
"""
@@ -165,7 +168,7 @@ class RaidOperations:
# 等待一小段时间,确保 mdadm 接收并处理了输入,并清空缓冲区
# 避免在下一次 expect 之前,旧的输出再次被匹配
child.expect(pexpect.TIMEOUT, timeout=1)
# child.expect(pexpect.TIMEOUT, timeout=1) # This line might consume output needed for next prompt
except pexpect.exceptions.TIMEOUT:
# 如果在等待任何提示时超时,说明没有更多提示了,或者命令已完成。
@@ -179,7 +182,6 @@ class RaidOperations:
break # 跳出 while 循环,进入等待 EOF 阶段
try:
# 增加一个合理的超时时间,以防 mdadm 在后台进行长时间初始化
child.expect(pexpect.EOF, timeout=120) # 例如,等待 120 秒
@@ -277,6 +279,11 @@ class RaidOperations:
QMessageBox.critical(None, "错误", "RAID10 至少需要两个设备。")
return False
# NEW: 尝试解决所有成员设备的占用问题
for dev in devices:
if not self.disk_ops._resolve_device_occupation(dev, action_description=f"创建 RAID 阵列,成员 {dev}"):
logger.info(f"用户取消或未能解决设备 {dev} 的占用问题,取消创建 RAID 阵列。")
return False
# 确认操作
reply = QMessageBox.question(None, "确认创建 RAID 阵列",
@@ -358,6 +365,7 @@ class RaidOperations:
# 这里需要确保 /etc/mdadm.conf 存在且可写入
# _execute_shell_command 会自动添加 sudo
# 使用 tee -a 而不是 >> 来确保 sudo 权限下的写入
success_append, _, _ = self._execute_shell_command(
["bash", "-c", f"echo '{scan_stdout.strip()}' | tee -a /etc/mdadm.conf > /dev/null"],
"更新 /etc/mdadm/mdadm.conf 失败"
@@ -387,13 +395,11 @@ class RaidOperations:
logger.info(f"尝试停止 RAID 阵列: {array_path}")
# 尝试卸载阵列(如果已挂载),不显示错误对话框
# _execute_shell_command 会自动添加 sudo
self._execute_shell_command(
["umount", array_path],
f"尝试卸载 {array_path} 失败",
suppress_critical_dialog_on_stderr_match=("not mounted", "未挂载") # 修改这里,添加中文错误信息
)
# NEW: 尝试卸载阵列(如果已挂载),利用 DiskOperations 的增强卸载功能
# unmount_partition 内部会尝试解决设备占用问题
if not self.disk_ops.unmount_partition(array_path, show_dialog_on_error=False):
logger.warning(f"未能成功卸载 RAID 阵列 {array_path}。尝试继续停止操作。")
# 即使卸载失败,我们仍然尝试停止 mdadm 阵列,因为有时 mdadm --stop 可以在设备忙时强制停止。
if not self._execute_shell_command(["mdadm", "--stop", array_path], f"停止 RAID 阵列 {array_path} 失败")[0]:
return False
@@ -421,6 +427,7 @@ class RaidOperations:
logger.info(f"尝试删除活动 RAID 阵列: {array_path} (UUID: {uuid})")
# 1. 停止阵列
# stop_raid_array 内部会调用 self.disk_ops.unmount_partition 来尝试卸载并解决占用
if not self.stop_raid_array(array_path):
QMessageBox.critical(None, "错误", f"删除 RAID 阵列 {array_path} 失败,因为无法停止阵列。")
return False