跳转至

SOP — IC617 幂等复跑实测(iscape 对已装目录的真实行为)

工程:ic617_replay_20260927(验证工装)。本轮为 HANDOFF 待办 1「幂等复跑」的落地。 实测时间:2026-09-27 01:58 — 02:15(Asia/Shanghai)。 实现体:deployer.py + utils/(入口 main.py)。

目录

  1. 背景
  2. 目标
  3. 前置条件
  4. 影响范围
  5. 分步操作
  6. 验证
  7. 回滚
  8. 风险说明 附录 A:实测数据 附录 B:结论与对既有文档的修正

1. 背景

ic617_install_20260926 的 SOP 目标 7 要求「幂等:复跑零变更、全跳过」,但该轮没有实现体 (SOP 第 5 章注明「实现体规划(尚未编写)」),因此该目标从未被实测。HANDOFF 待办 1 记录的 假设是「iscape 重跑会检测已装并跳过;尚未实测复跑零变更」。

本轮的实质问题因此不是「跑一次看看」,而是先证伪该假设:安装器对已装目标目录到底做什么。 结论会影响两件事——① 幂等验收判据该由谁保证;② 待办 2(介质与镜像清理)能否安全执行 (若复跑依赖镜像,镜像就不能删)。

2. 目标

变更完成后应达到的可验证状态:

# 目标状态 验证手段
1 取得 iscape 对已装目录的原生行为事实(跳过 / 覆盖 / 报错退出) 安装器输出 + 退出码 + 与首次安装日志对比
2 量化复跑的实际写入范围(哪些文件/目录被改) 跑前/跑后元数据快照 diff,按路径分类统计
3 确认 patch 未被覆盖、工具仍可用 license_checkout 出现 checked out successfully(D.3 同款证据)
4 六台客户端工具版本与变更前一致 六台 virtuoso -version
5 /tools 恢复变更前的只读稳态 六台 findmnt -no OPTIONS /tools 首项为 ro

3. 前置条件

类别 检查项 判据
权限 操作机 → 六台 root 免密 ssh root@<ip> hostname 六台全通
权限 执行端 root 身份 id -u = 0
挂载 /tools 可临时改 rw 由人工 mount -o remount,rw /tools(见第 4 章)
介质 镜像暂存完好 执行端 /var/tmp/ic617/04.IC06.17.700_Base 含 ic_index.sdx 与 Base_IC06.17.700_lnx86.sdp
介质 patch 恢复能力齐备 /var/tmp/patch/07.cadence_patch/{sfk,cadence.pat} 在;/tools/_ic617_media/backup/pre_patch_libs_20260927-004833.tar.gz 在
安装器 iscape 就位 /opt/iscape/iscape.04.23-s010/bin/iscape.sh 可执行
业务 执行端无在跑作业 Slurm squeue -h -w slurm-work-01 为空
空间 安装盘可用 /tools 可用 ≥ 20G(实测 1223G)

全部前置条件已落为实现体的预检查项(utils/precheck.py),其中挂载、介质、回滚资产三项为 BLOCK 级。

4. 影响范围

  • 执行端:slurm-work-01(192.168.31.18),iscape 在此运行并写 NFS 共享盘。
  • 变更对象:/data/nfs/tools/cadence/virtuoso/IC617(安装树本体),六台经只读挂载共享可见。
  • 人工动作:31.18 上 /tools 由 ro 临时改 rw,验证结束立即恢复 ro; 该动作不由实现体代劳(2026-09-26 用户决策:挂载切换人工执行)。
  • 是否停服:否。不动 license 服务、不改 NFS 导出、不重启节点。
  • 窗口期:约 15 分钟(复跑本体约 2 分钟,快照与验证各占数分钟)。
  • 不可逆点:无。本轮未覆盖 patch;即便被覆盖也可用 restore-patch 子命令重跑 sfk 恢复(介质与备份均在),最坏情况按 ic617_install_20260926/docs/SOP.md 第 7 章用 /var/tmp 镜像重装。

5. 分步操作

实现体:deployer.py(编排)、utils/precheck.py(门禁)、utils/replay_module.py(变更)、 utils/snapshot.py(快照与比对)。下列 shell 为等价动作,供复核与手工复现。 幂等、三态探测、备份与失败处置由实现体保证。

步骤 0:预检查与门禁(只读)

汇总配置合法性、六台可达性、执行端 OS/时钟/调度器/权限/磁盘、镜像与回滚资产、/tools 挂载状态。

# 只读预检查(报告落 reports/,有 BLOCK 返回非 0)
cd ic617_replay_20260927 && .venv/bin/python main.py precheck

# 等价底层命令(示例)
ssh root@192.168.31.18 'findmnt -no OPTIONS /tools'
ssh root@192.168.31.18 'test -e /var/tmp/ic617/04.IC06.17.700_Base/ic_index.sdx && echo ok'
ssh root@192.168.31.18 'test -x /var/tmp/patch/07.cadence_patch/sfk && echo sfk-ok'

预期:唯一 BLOCK 为「/tools 当前为 ro」——这正是步骤 1 要人工解除的项。 失败判断:出现其他 BLOCK(镜像缺失、patch 介质缺失、SSH 不通)→ 先处置,不得进入变更。

步骤 1:/tools 临时改 rw(人工,高危)

复跑要写安装目录,NFS 客户端必须先有写权限。此步是唯一需要人工介入的红线动作, 前置检查在只读状态下必然报 BLOCK,属预期而非故障。

ssh root@192.168.31.18 'mount -o remount,rw /tools && findmnt -no OPTIONS /tools'

预期:首项由 ro 变 rw(rw,noatime,vers=4.2,...)。 失败判断:仍为 ro → 检查 NFS 导出与客户端权限,不得绕过继续。

步骤 2:跑前元数据快照(零变更基准)

对安装树取「类型 / 大小 / mtime / 路径」清单并落盘,作为判定零变更的基准。 选元数据而非全量哈希:安装器只要改写文件必然改变 mtime 与大小,而 11.6 万文件的全量哈希 在 NFS 上耗时远超收益。

ssh root@192.168.31.18 'find /tools/cadence/virtuoso/IC617 -xdev \
  -printf "%y %s %T@ %p\n" 2>/dev/null | LC_ALL=C sort \
  > /var/tmp/ic617_replay/snap_IC617_before_<ts>.meta; \
  sha256sum /var/tmp/ic617_replay/snap_IC617_before_<ts>.meta; \
  wc -l < /var/tmp/ic617_replay/snap_IC617_before_<ts>.meta'

预期:115881 行(实测),耗时约 30s。 失败判断:行数明显偏少 → 安装树不完整或 find 被截断,停止变更。

步骤 3:iscape 复跑(核心变更)

对同一个已装目标目录、用同一份介质重跑首次安装时的命令。参数取自首次安装: archiveDirectory 指介质目录(含 .sdp/.sdx),installDirectory 指安装树。

坑:① 安装器需无 DISPLAY 环境;② 必须 < /dev/null 断开 stdin,否则安装器若在 batch 下 等待输入会挂住直到超时;③ 进程要 setsid 脱离会话(长任务),并以 rc 文件出现这一状态量 判定结束(不用固定 sleep);④ 启动命令的 ssh 通道也须 < /dev/null,否则后台进程持有通道 fd, paramiko 侧会等到超时才返回(本轮首次执行即踩此坑,见附录 A.4)。

# 后台启动(inner 用 sh -c 承载;rc 文件出现即结束)
ssh root@192.168.31.18 "mkdir -p /var/tmp/ic617_replay && \
  setsid nohup sh -c 'env -u DISPLAY /opt/iscape/iscape.04.23-s010/bin/iscape.sh -batch \
    majorAction=InstallFromArchive \
    archiveDirectory=/var/tmp/ic617/04.IC06.17.700_Base \
    installDirectory=/tools/cadence/virtuoso/IC617 \
    < /dev/null > /var/tmp/ic617_replay/replay_<ts>.out 2>&1; echo \$? > /var/tmp/ic617_replay/replay_<ts>.rc' \
    >/dev/null 2>&1 < /dev/null & echo LAUNCHED"

# 轮询(就绪判据 = rc 文件出现)
ssh root@192.168.31.18 'cat /var/tmp/ic617_replay/replay_<ts>.rc; tail -n 5 /var/tmp/ic617_replay/replay_<ts>.out'

预期:rc=0;输出先列产品清单,随后直接 Installing: Install from CDROM(s) Successful → Done.,没有逐 kit 的 Installing: <kit> 行; 耗时约 2 分钟(首次安装约 8 分钟)。 失败判断:rc≠0 或输出含 ERROR → 先取日志定位;patch 若被覆盖走步骤 5 的判断分支。

步骤 4:跑后快照与差异分类

ssh root@192.168.31.18 'find /tools/cadence/virtuoso/IC617 -xdev \
  -printf "%y %s %T@ %p\n" 2>/dev/null | LC_ALL=C sort \
  > /var/tmp/ic617_replay/snap_IC617_after_<ts>.meta'
ssh root@192.168.31.18 'diff /var/tmp/ic617_replay/snap_IC617_before_<ts>.meta \
  /var/tmp/ic617_replay/snap_IC617_after_<ts>.meta > /var/tmp/ic617_replay/diff_<ts>.txt; echo DIFF_RC=$?'
# 分类统计(类型分布、是否触及 lib 树)
ssh root@192.168.31.18 'grep -c "^< " /var/tmp/ic617_replay/diff_<ts>.txt; \
  grep "^< " /var/tmp/ic617_replay/diff_<ts>.txt | cut -c3 | sort | uniq -c; \
  grep -E "^[<>] " /var/tmp/ic617_replay/diff_<ts>.txt | grep -c "/tools.lnx86/lib/"'

预期(实测值见附录 A):差异 265 行/侧,其中触及 tools.lnx86/lib 的为 0 行—— 即 patch 覆盖的库二进制未被改写。 失败判断:差异中出现 tools.lnx86/lib 下的文件 → 立即执行步骤 5 的恢复分支。

步骤 5:功能验证(判定 patch 是否仍生效)

sfk patch 的作用是让 license 能真正 checkout(D.3:patch 前 virtuoso 报 Unable to obtain ... license,patch 后成功)。因此license 能否 checkout 就是 patch 是否存活的功能判据。

坑:验证环境必须带齐 Rocky 9 适配要素 OA_UNSUPPORTED_PLAT=linux_rhel50_gcc48x 与 LD_PRELOAD=/lib64/libstdc++.so.6,否则 virtuoso 抛 OA sysname 错误、验证结论无意义; 另外 virtuoso -nograph 不会因 stdin EOF 自行退出,靠 timeout 结束,rc=124 属正常, 成败只看输出证据。

ssh root@192.168.31.18 'export CDS_LIC_FILE=5280@192.168.31.29 CDS_LIC_ONLY=1 CDS_AUTO_64BIT=ALL \
  OA_UNSUPPORTED_PLAT=linux_rhel50_gcc48x LD_PRELOAD=/lib64/libstdc++.so.6; \
  cd /tmp && timeout 120 /tools/cadence/virtuoso/IC617/tools.lnx86/dfII/bin/virtuoso -nograph \
  < /dev/null > verify.out 2>&1; \
  grep -aiE "licen[cs]e.*(checked out|successfully)" verify.out'

预期:Virtuoso Framework License (111) was checked out successfully. Total checkout time was 0.19s. 失败判断:出现 Unable to obtain / license 失败文案 → 判定 patch 被覆盖,执行 restore-patch(重跑 sfk rep -bylist cadence.pat -nowarn -yes -dir <install_dir>)后再复验。

步骤 6:/tools 恢复 ro(人工,高危)

ssh root@192.168.31.18 'mount -o remount,ro /tools && findmnt -no OPTIONS /tools'
ssh root@192.168.31.18 'for ip in 18 19 20 25 26 27; do ssh root@192.168.31.$ip \
  "findmnt -no OPTIONS /tools | cut -d, -f1"; done'

预期:六台首项均为 ro(实测六台全 ro)。 失败判断:任一台仍 rw → 立即对该台 remount ro,避免共享盘长期暴露可写。

步骤 7:六台工具版本核对

for ip in 18 19 20 25 26 27; do ssh root@192.168.31.$ip 'export CDS_LIC_FILE=5280@192.168.31.29 \
  CDS_LIC_ONLY=1 CDS_AUTO_64BIT=ALL OA_UNSUPPORTED_PLAT=linux_rhel50_gcc48x \
  LD_PRELOAD=/lib64/libstdc++.so.6; cd /tmp && \
  timeout 45 /tools/cadence/virtuoso/IC617/tools.lnx86/dfII/bin/virtuoso -version 2>&1 | grep -m1 "6.1.7"'; done

预期:六台均输出 @(#)$CDS: virtuoso version 6.1.7-64b 11/09/2015 12:45 (sjfnl165) $(实测一致)。

6. 验证

验证项 命令 判据 实测
零漂移 .venv/bin/python main.py drift RC=0 RC=0
安装态 同上(内部探测) 主二进制存在、/tools = ro 通过
工具可用性 同上(功能验证) 版本命中 6.1.7 且 license checkout 成功 通过
六台一致性 步骤 7 六台版本串相同 通过
稳定态回归 六台 findmnt 六台均 ro 通过

7. 回滚

本轮未修改任何产品文件(差异 0 行涉及 tools.lnx86/lib),因此不需要文件级回滚。 按影响面排序的恢复路径:

情形 恢复动作 恢复后验证
patch 被覆盖(license checkout 失败) .venv/bin/python main.py restore-patch(等价:cd /var/tmp/patch/07.cadence_patch && ./sfk rep -bylist cadence.pat -nowarn -yes -dir /tools/cadence/virtuoso/IC617) 步骤 5 复验出现 checked out successfully
恢复 patch 仍失败 用 patch 前库备份还原:tar -xzf /tools/_ic617_media/backup/pre_patch_libs_20260927-004833.tar.gz -C /tmp/x && cp -a /tmp/x/. /tools/cadence/ 同上
安装树整体损坏 按 ic617_install_20260926/docs/SOP.md 第 7 章:删安装目录后用 31.18 /var/tmp/ic617 镜像重跑 iscape → 再跑 sfk patch 四工具 -version + license checkout
/tools 忘记恢复 ro mount -o remount,ro /tools 六台 findmnt 首项 ro

备份位置:本轮未产生新备份文件(无文件被改写)。既有备份台账见 ic617_install_20260926/backup/README.md;本轮辅助制品(快照、diff、安装器日志)落在 执行端 /var/tmp/ic617_replay/ 与本工程 reports/,非备份性质,可随介质清理一并删除。

8. 风险说明

# 风险 影响 缓解 本轮实况
1 复跑覆盖已 patch 的二进制 工具失去 license,全部不可用 跑前确认 patch 介质与库备份齐备(BLOCK 门禁);命中即 restore-patch 未发生(lib 差异 0 行)
2 安装器 batch 模式等待交互输入 任务挂住直至超时 全程 < /dev/null;以 rc 文件判结束 未发生
3 长任务在 ssh 通道上挂死 控制端误判失败 setsid + rc 文件 + 轮询;启动命令同时 < /dev/null 首次踩坑(A.4),已修
4 忘记恢复 /tools 为 ro 共享盘长期可写 步骤 6 单独成步 + 六台核验 已恢复
5 安装器在安装树内写日志(iscape_logs)被当作"零变更"误判 幂等结论失实 用元数据 diff 机械判定,不靠肉眼 已如实记录 265 行差异
6 NFS 共享盘 IO 压力 影响同盘其他业务 快照为元数据遍历、复跑仅 2 分钟 未见异常

附录 A:实测数据

A.1 时间线

时刻 事件
01:58:43 预检查(ro 状态)→ 唯一 BLOCK:/tools 为 ro
02:00:0x 人工 remount rw → 预检通过
02:00:22 跑前快照完成:115881 文件,sha256 f0a512345993a13…
02:00:22 iscape 复跑启动
02:02:2x iscape 结束,rc=0
02:03:01 跑后快照完成:115881 文件,sha256 0f714e4959a4491a…
02:03:30 diff:265 行/侧
02:04—02:12 功能验证(含两轮判据修正)
02:12—02:15 drift RC=0、六台版本核对、/tools 恢复 ro

A.2 iscape 复跑输出(关键片段)

InstallScape Installer (Batch Mode) - 04.23.s10
The following products will be installed:
    111:Cadence(R) Design Framework II
    ...(51 项产品清单)...
Installing: Install from CDROM(s) Successful
Done.

对比首次安装 iscape_ic617.log:其后跟数十行 Installing: <kit> <版本>(如 Installing: layout64b_lnx86 06.17-p048lnx86)后才是 Successful / Done.。 本轮无任何逐 kit 行 → 产品组件零安装。

A.3 差异分类(diff_manual_20260927-020329.txt)

指标 数值
差异行(左 / 右) 265 / 265
类型分布 目录 44 / 文件 220 / 符号链接 1
涉及 tools.lnx86/lib 的差异行 0
变化内容性质 安装器收尾动作:install/tmp/* 临时与脚本、inca/files/IEEE_pure/ncrelocate.log、新增 cds.lib.ncreloc、iscape_logs 目录、若干目录 mtime

A.4 本轮踩坑(实现体已修,文档留痕)

现象 根因 处置
启动命令返回 rc=-1、日志报「启动 iscape 失败」,但远端实际已执行完毕 后台进程继承 ssh 通道 stdin,paramiko 侧等不到 EOF,60s 超时后重试(并有重试副作用) 启动命令补 < /dev/null;后续以 rc 文件判结束
virtuoso -version 报 OA sysname unknown 验证环境漏配 OA_UNSUPPORTED_PLAT / LD_PRELOAD 验证环境补齐 Rocky 9 适配要素
license 验证"通过"实为假阳性 判据只匹配 license 关键词,未覆盖 OA 类 ERROR: 判据收窄到 license 语境,并要求出现 checked out successfully

附录 B:结论与对既有文档的修正

结论(实测)

  1. iscape 对已装目标目录复跑不重装任何产品 kit,退出码 0,行为是「识别已装 → 直接报成功」。
  2. 但不是严格零变更:它仍会重跑部分收尾步骤,改写约 220 个文件/目录(安装器临时区、 ncrelocate 产物、自身日志),并刷新 44 个目录 mtime。
  3. 复跑未触碰 tools.lnx86/lib,patch 保持有效,工具功能无退化(license checkout 成功)。
  4. 因此 SOP 目标 7「复跑零变更、全跳过」不能由安装器自身保证,必须由实现体的状态探测 (三态幂等)承担——原假设「iscape 重跑会检测已装并跳过」表述不准确,已在 ic617_install_20260926/docs/SOP.md 附录 D.7 更正。
  5. 副产品结论:复跑依赖 /var/tmp/ic617 镜像,故介质与镜像清理(HANDOFF 待办 2)应在 确认不再需要复跑/重装后退回镜像,不能在无镜像时依赖复跑做验证。

来源:/home/rain/Documents/eda_tools_ins/Cadence/ic617_replay_20260927/docs/SOP.md | 最后更新:2026-09-27 02:15(由 build/sync.py 同步,请勿在站点侧修改)