This commit is contained in:
zj
2026-02-03 15:18:43 +08:00
parent f17080b506
commit 38ce31d93e
5 changed files with 480 additions and 143 deletions

View File

@@ -343,29 +343,29 @@ class RaidOperations:
examine_scan_cmd = ["mdadm", "--examine", "--scan"]
success_scan, scan_stdout, _ = self._execute_shell_command(examine_scan_cmd, "扫描 mdadm 配置失败")
if success_scan:
# --- 新增:确保 /etc/mdadm 目录存在 ---
mkdir_cmd = ["mkdir", "-p", "/etc/mdadm"]
# --- 新增:确保 /etc 目录存在 ---
mkdir_cmd = ["mkdir", "-p", "/etc"]
success_mkdir, _, stderr_mkdir = self._execute_shell_command(
mkdir_cmd,
"创建 /etc/mdadm 目录失败"
"创建 /etc 目录失败"
)
if not success_mkdir:
logger.error(f"无法创建 /etc/mdadm 目录,更新 mdadm.conf 失败。错误: {stderr_mkdir}")
QMessageBox.critical(None, "错误", f"无法创建 /etc/mdadm 目录,更新 mdadm.conf 失败。\n详细信息: {stderr_mkdir}")
logger.error(f"无法创建 /etc 目录,更新 mdadm.conf 失败。错误: {stderr_mkdir}")
QMessageBox.critical(None, "错误", f"无法创建 /etc 目录,更新 mdadm.conf 失败。\n详细信息: {stderr_mkdir}")
return False # 如果连目录都无法创建,则认为创建阵列失败,因为无法保证重启后自动识别
logger.info("已确保 /etc/mdadm 目录存在。")
logger.info("已确保 /etc 目录存在。")
# --- 新增结束 ---
# 这里需要确保 /etc/mdadm/mdadm.conf 存在且可写入
# 这里需要确保 /etc/mdadm.conf 存在且可写入
# _execute_shell_command 会自动添加 sudo
success_append, _, _ = self._execute_shell_command(
["bash", "-c", f"echo '{scan_stdout.strip()}' | tee -a /etc/mdadm/mdadm.conf > /dev/null"],
["bash", "-c", f"echo '{scan_stdout.strip()}' | tee -a /etc/mdadm.conf > /dev/null"],
"更新 /etc/mdadm/mdadm.conf 失败"
)
if not success_append:
logger.warning("更新 /etc/mdadm/mdadm.conf 失败。")
logger.warning("更新 /etc/mdadm.conf 失败。")
else:
logger.info("已成功更新 /etc/mdadm/mdadm.conf。")
logger.info("已成功更新 /etc/mdadm.conf。")
else:
logger.warning("未能扫描到 mdadm 配置,跳过更新 mdadm.conf。")
@@ -402,22 +402,23 @@ class RaidOperations:
QMessageBox.information(None, "成功", f"成功停止 RAID 阵列 {array_path}")
return True
def delete_raid_array(self, array_path, member_devices):
def delete_active_raid_array(self, array_path, member_devices, uuid): # <--- 修改方法名并添加 uuid 参数
"""
删除一个 RAID 阵列。
此操作将停止阵列清除成员设备上的超级块。
删除一个活动的 RAID 阵列。
此操作将停止阵列清除成员设备上的超级块,并删除 mdadm.conf 中的配置
:param array_path: RAID 阵列的设备路径,例如 /dev/md0
:param member_devices: 成员设备列表,例如 ['/dev/sdb1', '/dev/sdc1']
:param uuid: RAID 阵列的 UUID
"""
reply = QMessageBox.question(None, "确认删除 RAID 阵列",
f"你确定要删除 RAID 阵列 {array_path} 吗?\n"
"此操作将停止阵列清除成员设备上的 RAID 超级块,数据将无法访问!",
"此操作将停止阵列清除成员设备上的 RAID 超级块,并删除其配置,数据将无法访问!",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.No:
logger.info(f"用户取消了删除 RAID 阵列 {array_path} 的操作。")
return False
logger.info(f"尝试删除 RAID 阵列: {array_path}")
logger.info(f"尝试删除活动 RAID 阵列: {array_path} (UUID: {uuid})")
# 1. 停止阵列
if not self.stop_raid_array(array_path):
@@ -444,6 +445,15 @@ class RaidOperations:
success_all_cleared = False
logger.warning(f"未能清除设备 {dev} 上的 RAID 超级块,请手动检查。")
# 3. 从 mdadm.conf 中删除配置条目
try:
self.system_manager.delete_raid_array_config(uuid)
logger.info(f"已成功从 mdadm.conf 中删除 UUID 为 {uuid} 的 RAID 阵列配置。")
except Exception as e:
QMessageBox.critical(None, "错误", f"删除 RAID 阵列 {array_path} 的配置失败: {e}")
logger.error(f"删除 RAID 阵列 {array_path} 的配置失败: {e}")
return False # 如果配置文件删除失败,也视为整体操作失败
if success_all_cleared:
logger.info(f"成功删除 RAID 阵列 {array_path} 并清除了成员设备超级块。")
QMessageBox.information(None, "成功", f"成功删除 RAID 阵列 {array_path}")
@@ -451,3 +461,58 @@ class RaidOperations:
else:
QMessageBox.critical(None, "错误", f"删除 RAID 阵列 {array_path} 完成,但部分成员设备超级块未能完全清除。")
return False
def delete_configured_raid_array(self, uuid): # <--- 新增方法
"""
只删除 mdadm.conf 中停止状态 RAID 阵列的配置条目。
:param uuid: 要删除的 RAID 阵列的 UUID。
:return: True 如果成功False 如果失败。
"""
reply = QMessageBox.question(None, "确认删除 RAID 阵列配置",
f"您确定要删除 UUID 为 {uuid} 的 RAID 阵列配置吗?\n"
"此操作将从配置文件中移除该条目,但不会影响实际的磁盘数据或活动阵列。",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.No:
logger.info(f"用户取消了删除 UUID 为 {uuid} 的 RAID 阵列配置的操作。")
return False
logger.info(f"尝试删除 UUID 为 {uuid} 的 RAID 阵列配置文件条目。")
try:
self.system_manager.delete_raid_array_config(uuid)
QMessageBox.information(None, "成功", f"成功删除 UUID 为 {uuid} 的 RAID 阵列配置。")
return True
except Exception as e:
QMessageBox.critical(None, "错误", f"删除 RAID 阵列配置失败: {e}")
logger.error(f"删除 RAID 阵列配置失败: {e}")
return False
def activate_raid_array(self, array_path, array_uuid): # 添加 array_uuid 参数
"""
激活一个已停止的 RAID 阵列。
使用 mdadm --assemble <device> --uuid=<uuid>
"""
if not array_uuid or array_uuid == 'N/A':
QMessageBox.critical(None, "错误", f"无法激活 RAID 阵列 {array_path}:缺少 UUID 信息。")
logger.error(f"激活 RAID 阵列 {array_path} 失败:缺少 UUID。")
return False
logger.info(f"尝试激活 RAID 阵列: {array_path} (UUID: {array_uuid})")
# 使用 mdadm --assemble <device> --uuid=<uuid>
# 这样可以确保只激活用户选择的特定阵列
success, stdout, stderr = self._execute_shell_command(
["mdadm", "--assemble", array_path, "--uuid", array_uuid],
f"激活 RAID 阵列 {array_path} 失败",
# 抑制一些常见的非致命错误,例如阵列已经激活
suppress_critical_dialog_on_stderr_match=("mdadm: device /dev/md", "already active", "No such file or directory")
)
if success:
logger.info(f"成功激活 RAID 阵列 {array_path} (UUID: {array_uuid})。")
QMessageBox.information(None, "成功", f"成功激活 RAID 阵列 {array_path}")
return True
else:
logger.error(f"激活 RAID 阵列 {array_path} 失败。")
return False