跳转至

EDA Slurm Epilog 补全方案与执行 SOP

项目:EDA 存储标准化 —— Slurm 作业钩子补全 环境:Slurm 26.05.2 | 计算节点 k8s-node-01/02/03(192.168.0.5/6/7) 日期:2026-09-12


一、背景与目标

1.1 背景

现有 /usr/local/slurm/epilog_eda.sh 仅完成约 1/3 的职责(清 /tmp、/dev/shm、cgroup), 对 EDA 场景最关键的 License 回收、孤儿进程、SysV IPC、scratch 生命周期 均未覆盖, 且使用了 set -e(清理脚本一旦中途失败,后续清理全部跳过)。

1.2 目标

补全为覆盖 数字(VCS/Verdi)、模拟(Virtuoso/Spectre/ADS)、数模混合(AMS/Xcelium) 三类场景的通用 Epilog,并满足: 幂等、尽力执行、快速(≤120s)、可 dry-run、功能可开关、路径不硬编码。


二、Epilog 的完整职责(跨三场景通用性分析)

# 职责 数字 模拟 数模混合 说明
1 孤儿进程清理 ✓ ✓ ✓ 工具崩溃/被 kill 后残留,占 CPU/内存/GPU
2 System V IPC 清理 ✓ ✓ ✓ Cadence/Synopsys 信号量/共享内存,泄漏后耗尽 IPC
3 License 检测/回收 ✓ ✓ ✓ ★EDA 最关键:异常退出时 license 被占住
4 临时文件清理 ✓ ✓ ✓ /tmp、/dev/shm、$TMPDIR 写满致后续作业失败
5 cgroup 残留清理 ✓ ✓ ✓ Slurm 一般自清,此处兜底
6 scratch 生命周期标记 ✓ ✓ ✓ 打 .job_ok/.job_failed,交老化机制按保留期清理
7 审计与告警 ✓ ✓ ✓ 退出码/资源记录、失败现场保留提示

结论:七项职责全部跨三场景通用,无需按工具区分。真正的差异(保留哪些产物) 属作业脚本职责,不应放进 Epilog。


三、现状缺口分析(实测)

职责 原脚本 缺口
临时文件清理 ✓ 命名模式仅 slurm*/vcs*,覆盖不全
cgroup 清理 ✓ —
孤儿进程清理 ✗ 完全缺失
SysV IPC 清理 ✗ 完全缺失
License 处理 ✗ 注释写了"如果配置了 license check",但未实现
scratch 标记 ✗ 完全缺失(新分层无人管)
审计告警 ✗ 仅有简单 start/done 日志
set -e ⚠ 清理脚本用 -e 是隐患,中途失败即中断

另有配套缺口(本轮一并说明,未在本次部署范围): - task_prolog_eda.sh 未注入 TMPDIR/LOCAL_SCRATCH - 无 cron 老化脚本(scratch 保留期无人执行)


四、增强设计

4.1 七项职责与安全边界

职责 动作 安全边界(关键)
1 孤儿进程 pkill -u <JOB_UID> -x <工具名> 仅杀本作业用户 + 精确进程名;GUI 进程默认排除
2 SysV IPC ipcrm -s/-m 仅清 owner = 本作业用户/UID 的项
3 License lmutil lmstat 检测 默认 mode=check 只检测不回收,避免误伤并行会话
4 临时文件 find <dir> -name "*<JOB_ID>*" -delete 仅匹配含作业 ID 的路径(最保守)
5 cgroup rmdir <含ID目录> 仅空目录兜底
6 scratch 标记 touch .job_ok/.job_failed 只标记,不删除(留复查窗口)
7 审计 追加日志 只读作业信息,无系统变更

4.2 核心设计原则

  1. 不用 set -e(改 set -uo pipefail):清理必须"尽力做完",单步失败不中断后续
  2. dry-run 感知:EDA_EPILOG_DRY_RUN=1 时只记录不执行
  3. 功能开关:7 项各自可开关(配置文件)
  4. 不硬编码:License 服务地址、lmutil 路径、scratch 根均走配置
  5. 超时保护:License 查询带 timeout,避免拖慢 Epilog

4.3 scratch 处理策略(回应"能否重建"判据)

Epilog  → 只打标记(.job_ok / .job_failed)
老化机制 → 按保留期清理(成功短、失败长),给工程师留复查窗口
作业脚本 → 决定"留什么"(stage-out 结果;中间产物引导到 scratch)

判据是"能否重建"(波形/日志不可重建须留;csrc/simv 可重建可清), 但该判断只有工具/脚本有知识,Epilog 不猜。


五、风险说明与规避

# 风险 等级 规避措施
1 误杀 GUI 会话(VNC 中的 Virtuoso) 高 Xvnc/vncserver 默认不在清理清单,需显式启用
2 误清他人 SysV IPC 中 仅清 owner = 本作业用户/UID
3 License 误回收活跃会话 高 默认 mode=check 只检测;recover 需运维确认后启用
4 误删非作业文件 中 仅匹配含作业 ID 的路径
5 Epilog 超时被 Slurm 杀 中 各步快速执行;PrologEpilogTimeout=120
6 脚本语法错误致作业异常 高 部署时远端 bash -n 校验,失败自动回滚

六、分步操作(SOP)

前置条件

  • 本机(rian,192.168.0.11)已配置到集群各节点 root 免密
  • 集群无运行中作业(低峰窗口)
  • 源文件:epilog/epilog_eda.sh、epilog/epilog_eda.conf、epilog/nodes.conf

步骤 1:预演(不改任何系统状态)

cd /home/rian/Documents/slurm_ins/eda_storage_standardization/epilog
./deploy_epilog.sh --dry-run

步骤 2:确认节点清单

cat nodes.conf    # 应为 192.168.0.5/6/7

步骤 3:真实部署(自动备份 + 语法校验)

./deploy_epilog.sh

说明:脚本按 SHA256 比对,远端一致则跳过(幂等);不一致则 cp -a <目标> <目标>.bak.<时间戳> 备份后传输并校验。

步骤 4:试运行验证(DRY-RUN 模式,不改系统)

./deploy_epilog.sh --verify

步骤 5:查看日志

ssh root@192.168.0.5 "tail -n 30 /var/log/slurm/epilog.log"

步骤 6(可选):启用 License 检测

需先将 lmutil 分发到计算节点,并核对 epilog_eda.conf 中 EDA_LMUTIL 路径。

当前默认 mode=check 且 lmutil 不存在时自动跳过,不影响作业。


七、验证

验证项 命令 预期
语法 bash -n epilog_eda.sh 无输出
幂等 连续执行两次 ./deploy_epilog.sh 第二次全部"跳过"
部署一致 sha256sum 本地/远端比对 一致
逻辑 ./deploy_epilog.sh --verify 输出 DRY-RUN 动作清单
Slurm 集成 提交测试作业后看 epilog.log 有本次 job 记录

八、回滚

cd /home/rian/Documents/slurm_ins/eda_storage_standardization/epilog
./deploy_epilog.sh --rollback

逻辑:查找各节点 epilog_eda.sh.bak.<时间戳> 中最新备份并恢复 + 语法校验。

手工回滚(单节点):

ssh root@192.168.0.5 "ls -1t /usr/local/slurm/epilog_eda.sh.bak.* | head -1"
ssh root@192.168.0.5 "cp -a /usr/local/slurm/epilog_eda.sh.bak.<TS> /usr/local/slurm/epilog_eda.sh"

应急降级(Epilog 异常时立即停用):

# slurm.conf 中注释 Epilog= 行后重载
ssh root@192.168.0.2 "sed -i 's|^Epilog=/usr/local/slurm/epilog_eda.sh|#&|' /usr/local/slurm/etc/slurm.conf && scontrol reconfigure"

九、第二阶段补全(已完成)

# 事项 状态 说明
1 TaskProlog 注入环境变量 ✅ TMPDIR/LOCAL_SCRATCH/EDA_SCRATCH_LOCAL/EDA_SCRATCH_LUSTRE,并幂等创建作业工作区
2 cron 老化脚本 ✅ scratch_aging.sh + /etc/cron.d/eda-scratch-aging(每日 03:30)
3 lmutil 分发 ✅ 分发到 3 计算节点 /usr/local/bin/lmutil,License 检测已生效
4 scratch 布局校验 ✅ 权限 1777 + Lustre 条带 -c 3 -S 1M(幂等修复)
5 MDS 身份解析修复 ✅ 见第十章(关键阻塞项)

9.1 老化策略(scratch 保留期)

位置 标记 保留期 参考时间
本地 SSD .job_ok 7 天 标记文件 mtime(≈ 作业结束时间)
本地 SSD .job_failed 14 天 失败需更长现场保留
本地 SSD 无标记 3 天 异常终止兜底
Lustre .job_ok / .job_failed / 无标记 14 / 30 / 7 天 容量更大,保留更久

为什么不是"作业一结束就删":必须给仿真工程师留复查窗口(看波形、复现问题、查覆盖空洞)。 判据是"能否重建"(波形/日志不可重建须留;csrc/simv 可重建可清), 但该判断只有工具/作业脚本有知识,Epilog 只打标记、不猜。

9.2 完整闭环

TaskProlog  → 建 scratch + 注入 TMPDIR/SCRATCH 变量
     ↓  作业运行(源在 NFS、中间产物在 scratch)
Epilog      → 清临时 + 回收孤儿进程/SysV IPC + License 检测 + 打标记(.job_ok/.job_failed)
     ↓
cron(03:30) → scratch_aging.sh 按保留期清理

十、关键修复:Lustre MDS 身份解析

10.1 现象

TaskProlog 能在本地 SSD 建目录,但 Lustre 上创建被拒:

mkdir: cannot create directory '/lustre/eda_fs/scratch/users/lws01': Permission denied

而该目录权限已是 drwxrwxrwt(1777),且 root 可以创建。

10.2 根因(证据)

MDS(192.168.0.13)实测:

mdt.eda_fs-MDT0000.identity_upcall=/usr/sbin/l_getidentity
id lws01        → no such user
getent passwd 6001 → 无法解析
sssd 未运行;/etc/sssd/sssd.conf 不存在(但 nsswitch 已配 files sss)

因果链:客户端提交请求 → MDS 通过 l_getidentity upcall 解析 uid 6001 → MDS 本地 NSS 无法解析(sssd 缺失)→ upcall 失败 → MDS 拒绝请求(EACCES)。

同一根因也解释了此前"chown 只能用数字 GID、服务端 ls 显示数字"的现象—— 因为那台机器同时是 NFS Server 与 Lustre MDS。

10.3 修复

# 1) 安装 sssd
ssh root@192.168.0.13 "yum install -y sssd"
# 2) 从正常客户端同步配置(匿名绑定,不含密码)
ssh root@192.168.0.5 "cat /etc/sssd/sssd.conf" | ssh root@192.168.0.13 "cat > /etc/sssd/sssd.conf && chmod 600 /etc/sssd/sssd.conf"
# 3) 启动
ssh root@192.168.0.13 "systemctl enable --now sssd"

验证:id lws01 → uid=6001(lws01) gid=6000(cad) ✓

10.4 回滚

ssh root@192.168.0.13 "systemctl disable --now sssd; rm -f /etc/sssd/sssd.conf"
# nsswitch 的 'files sss' 可保留:sssd 缺失时自动退化到本地 files

行业标准意义:MDS / NFS Server 必须与计算节点处于统一身份体系(LDAP/AD), 否则分布式文件系统的身份 upcall 必然失败。这是通用要求,非本项目特有。


十一、验证记录(2026-09-12)

验证项 结果
部署幂等 第二次执行 18 项全部跳过(sha256/存在性比对)
老化逻辑 造数据实测:.job_ok 10天→清、.job_failed 20天→清、无标记 5天→清、.job_ok 当天→保留 ✓
scratch 布局 node-01 修复后,node-02/03 自动识别"已符合"(Lustre 共享 + 幂等)
lmutil v11.18.3.0 分发成功,Epilog 日志由"不可用"变为"License 处理完成 (mode=check)"
全链路 提交真实作业 435:TaskProlog 注入 ✓ → 本地+Lustre scratch 自动创建 ✓ → Epilog 打 .job_ok ✓
MDS 修复 lws01 用户创建 Lustre 目录成功,属主 lws01:cad ✓
清理 测试文件与测试 scratch 已清除

十二、文件清单

12.1 本地源(eda_storage_standardization/epilog/)

文件 用途 部署目标
epilog_eda.sh 增强版 Epilog 主脚本(7 项职责) /usr/local/slurm/epilog_eda.sh
task_prolog_eda.sh TaskProlog(注入 scratch/TMPDIR) /usr/local/slurm/task_prolog_eda.sh
scratch_aging.sh scratch 老化清理(按标记保留期) /usr/local/slurm/scratch_aging.sh
epilog_eda.conf 功能开关与配置(不硬编码) /usr/local/slurm/epilog_eda.conf
scratch_aging.cron cron 定时任务(每日 03:30) /etc/cron.d/eda-scratch-aging
nodes.conf 部署目标节点清单 —
deploy_epilog.sh 幂等部署脚本(dry-run/备份/回滚) —
SOP.md 本文档 —

12.2 关键日志(计算节点)

日志 用途
/var/log/slurm/epilog.log Epilog 执行日志
/var/log/slurm/epilog_audit.log 作业审计(退出码、资源用量)
/var/log/slurm/scratch_aging.log 老化清理日志
/var/log/slurm/scratch_aging.cron.log cron 任务输出

来源:/home/rain/Documents/slurm/eda_storage_standardization/epilog/SOP.md | 最后更新:2026-09-12 02:58(由 build/sync.py 同步,请勿在站点侧修改)