跳转至

SOP — FlexLM 双实例 systemd 化(31.29)

变更日期:2026-09-28 | 类型:C 类(生产变更) 交付目录:flexlm_systemd_20260928/ 涉及主机:192.168.31.29(license 主机) 备份台账:backup/README.md

目录

  1. 背景
  2. 目标
  3. 前置条件
  4. 影响范围
  5. 分步操作
  6. 验证
  7. 回滚
  8. 风险说明
  9. 附录

1. 背景

31.29 上同时运行两套 FlexLM 许可服务:

服务 目录 端口 上线时间
Cadence(cdslmd) /opt/FlexLM/Cadence/ 5280 / 5281 2026-09-26
Synopsys(snpslmd) /opt/FlexLM/Synopsys/ 2700 / 2701 2026-09-28

两套原先都用 setsid nohup ./lmgrd … & 拉起的裸进程,带来三个问题:

  1. 无开机自启——主机重启后许可服务全丢,且无人察觉;
  2. 无自愈——lmgrd 异常退出后不会拉起;
  3. 停服靠按 PID 手工 kill,而机器上有两个 lmgrd,按名 kill 会误杀另一套(RED 线风险)。

本次把两套服务纳入 systemd 托管。

2. 目标

目标 可验证状态
两套服务由 systemd 托管 systemctl is-active 均为 active,MainPID 指向各自的 lmgrd
开机自启 systemctl is-enabled 均为 enabled,multi-user.target.wants 下有符号链接
cgroup 隔离 停一套不影响另一套(实测)
停止后状态干净 systemctl stop 后为 inactive (dead),而非 failed
自动重启 非正常退出时 Restart=on-failure 在 10s 后拉起

不在本次范围:探活告警脚本与告警通道(用户决定暂不做,见第 9 章待办)。

3. 前置条件

  • 31.29 root 免密 SSH 可达;systemd 252;Python 3.9.25(本次未用)
  • 两套服务当前以裸进程运行,且需确认可接受中断窗口
  • 执行前检查:
ssh root@192.168.31.29 'systemctl --version | head -1; pgrep -ax lmgrd; ss -lntp | grep -E ":5280|:5281|:2700|:2701"'

预期:systemd 版本可用;两条 lmgrd;四个端口 LISTEN。

4. 影响范围

项 内容
主机 192.168.31.29
是否停服 是——切换需停掉两套裸进程再交由 systemd 拉起
实际中断时长 Cadence 约 64 秒、Synopsys 约 40 秒(⚠️ 远高于事前预估的 5–10 秒,原因见第 8 章风险 1)
在跑业务 切换时无 Cadence/Synopsys 作业;Synopsys 工具此时因运行期兼容问题尚不可用
窗口 无特殊要求,但应避开 Cadence 作业时段
回滚代价 低:systemctl disable --now + 恢复裸进程启动命令

5. 分步操作

步骤 1:编写 unit 并投放

两个 unit 内容见 units/。Cadence 版如下(Synopsys 版仅路径不同):

[Unit]
Description=FlexNet License Server - Cadence (cdslmd)
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/FlexLM/Cadence
ExecStart=/opt/FlexLM/Cadence/lmgrd -z -c /opt/FlexLM/Cadence/cds.license.dat -l /opt/FlexLM/Cadence/lmgrd.log
Restart=on-failure
RestartSec=10
SuccessExitStatus=15
TimeoutStopSec=30
KillMode=control-group
LimitNOFILE=8192

[Install]
WantedBy=multi-user.target
scp units/flexlm-cadence.service units/flexlm-synopsys.service root@192.168.31.29:/etc/systemd/system/
ssh root@192.168.31.29 'chmod 644 /etc/systemd/system/flexlm-*.service && systemctl daemon-reload'

关键设计点与坑:

  • -z + Type=simple:实测现有 lmgrd 进程 pid≠sid(setsid 后仍不一致),说明 lmgrd 会自行 fork,直接用 Type=simple 会让 systemd 立刻判定"主进程已退出"。加 -z(前台运行)后 lmgrd 不再 fork,systemd 才能正确跟踪。-z 由 lmgrd -help 实测确认受支持。
  • SuccessExitStatus=15:实测 lmgrd 收到 SIGTERM 后 exit(15)(journal 记 status=15/n/a)。不声明则 systemctl stop 后单元状态显示 failed,运维会误判为故障。
  • KillMode=control-group(默认):停止时杀整个 cgroup,连带清掉 vendor daemon;这正是取代"按 PID 手工 kill"的关键。
  • StartLimitIntervalSec / StartLimitBurst:防止 license 损坏导致 lmgrd 秒退时无限重启。

步骤 2:停止裸进程

⚠️ 必须按 PID 精确识别,机器上有两个 lmgrd:

ssh root@192.168.31.29 '
for p in $(pgrep -x lmgrd); do
  cmd=$(tr "\0" " " < /proc/$p/cmdline 2>/dev/null || true)
  case "$cmd" in
    *Cadence/cds.license.dat*) echo "[STOP] cadence bare pid=$p"; kill "$p" ;;
    *Synopsys/Synopsys.dat*)  echo "[STOP] synopsys bare pid=$p"; kill "$p" ;;
  esac
done'

坑:用 pgrep -x lmgrd(按进程名精确匹配),不要用 pgrep -f 或 pkill -f——SSH 脚本自身命令行含这些路径字符串,-f 会把脚本自己匹配进来并杀掉会话。

步骤 3:交由 systemd 启动

ssh root@192.168.31.29 'systemctl daemon-reload && systemctl enable --now flexlm-cadence.service flexlm-synopsys.service'

预期:两个 Created symlink … multi-user.target.wants/…,随后 is-active 为 active。

坑(端口占用):切换瞬间 lmgrd 会在日志里报

The TCP port number in the license, 5280, is already in use.
… Retrying for about 5 more minutes

这是正常现象:被 kill 的旧 lmgrd 持有过客户端连接,socket 进入 TIME-WAIT(实测 ss -ant 可见),而 lmgrd 未使用 SO_REUSEADDR,无法立即 bind。lmgrd 会自行重试,实测约 60–70 秒后自动绑上,无需干预。此行为与 systemd 无关,裸进程重启同样存在。

步骤 4:等待就绪(不要用固定 sleep 判定)

就绪判据是端口真正 LISTEN,而非进程存在:

ssh root@192.168.31.29 '
for i in $(seq 1 30); do
  ss -lnt 2>/dev/null | grep -q ":5280" && ss -lnt 2>/dev/null | grep -q ":2701" && break
  sleep 5
done
ss -lntp | grep -E ":5280|:5281|:2700|:2701"'

预期:四个端口 LISTEN,且 lmgrd 与各自的 vendor daemon 并列在同一行(说明 vendor daemon 已被拉起)。

6. 验证

验证项 命令 本次实测结果
单元状态 systemctl is-active flexlm-cadence flexlm-synopsys active / active ✅
开机自启 systemctl is-enabled flexlm-cadence flexlm-synopsys enabled / enabled ✅
cgroup 归属 systemctl status <unit> -n 0 \| grep -A3 CGroup lmgrd 与 vendor daemon 同属一个 slice ✅
服务端 Cadence lmutil lmstat -c 5280@192.168.31.29 server UP (MASTER) v11.16.4 ✅
服务端 Synopsys lmutil lmstat -c 2700@192.168.31.29 server UP (MASTER) v11.14.1 ✅
cgroup 隔离 停 Synopsys 后查 Cadence Cadence 端口/进程/许可全程未受影响 ✅
stop 状态 systemctl stop 后查状态 inactive (dead)、Result=success ✅
幂等复跑 重跑 systemctl enable --now 无变更,enabled 保持 ✅
客户端(Cadence) .18 上 lmdiag -c 5280@… -n Assura_DRC 正常 ✅
客户端(Synopsys) .18 上 lmdiag -c 2700@… -n Verdi This license can be checked out ✅
重启恢复耗时 stop 后 start 并轮询端口 约 70 秒(TIME-WAIT 等待)

7. 回滚

触发判据(任一达标即回滚):单元持续 failed 且自动重启无效;lmstat 报 server 不可达; Cadence 许可在切换后长时间不恢复。

回滚步骤

# 1) 停用并禁用单元(不会误伤另一套,cgroup 隔离)
ssh root@192.168.31.29 'systemctl disable --now flexlm-cadence.service flexlm-synopsys.service'

# 2) 确认端口与进程已清空
ssh root@192.168.31.29 'pgrep -ax lmgrd; ss -lnt | grep -E ":5280|:5281|:2700|:2701"'

# 3) 恢复裸进程(原启动方式,两套各一条)
ssh root@192.168.31.29 'cd /opt/FlexLM/Cadence && setsid nohup ./lmgrd -c /opt/FlexLM/Cadence/cds.license.dat -l /opt/FlexLM/Cadence/lmgrd.log </dev/null >/dev/null 2>&1 &'
ssh root@192.168.31.29 'cd /opt/FlexLM/Synopsys && setsid nohup ./lmgrd -c /opt/FlexLM/Synopsys/Synopsys.dat -l /opt/FlexLM/Synopsys/lmgrd.log </dev/null >/dev/null 2>&1 &'

# 4) 移除 unit 文件(确认无需保留后)
ssh root@192.168.31.29 'rm -f /etc/systemd/system/flexlm-cadence.service /etc/systemd/system/flexlm-synopsys.service && systemctl daemon-reload'

回滚后验证

ssh root@192.168.31.29 'pgrep -ax lmgrd; pgrep -ax cdslmd; pgrep -ax snpslmd; ss -lntp | grep -E ":5280|:5281|:2700|:2701"'

预期:两条 lmgrd + 两个 vendor daemon;四个端口 LISTEN。 注意回滚后 lmgrd 恢复为前台 fork 模式(去掉 -z),与 systemd 版本行为不同,属预期。

8. 风险说明

# 风险 缓解 / 实测结论
1 中断时长被低估:事前预估 5–10 秒,实测 Cadence 约 64 秒、Synopsys 约 40 秒 根因是 TIME-WAIT 阻塞 bind(见步骤 3 的坑),lmgrd 重试后才绑上。下次同类变更应按 60–90 秒预留窗口
2 停一套误杀另一套 实测已消除:两个 unit 各自独立 cgroup,systemctl stop flexlm-synopsys 全程未触及 Cadence 的进程与端口
3 裸进程残留导致端口冲突 步骤 2 按 PID 精确停止,并显式清理孤儿 vendor daemon
4 unit 行为不符预期导致服务起不来 首次上线时确实出现"端口被占用"告警,确认为 TIME-WAIT(非配置错误);已备完整回滚路径
5 Restart=on-failure 遇 license 损坏时无限重启 StartLimitIntervalSec=300 + StartLimitBurst=5 限制
6 lmgrd 以 root 运行(安全提示) 沿用原部署方式(FlexLM 传统以 root 运行),未改变既有安全姿势
7 无告警:服务挂了无人知 本次未做(用户决定);systemd 的自动重启是当前唯一自愈手段,见第 9 章待办

9. 附录

交付物清单

文件 说明
docs/SOP.md 本文件
docs/RUNBOOK.md FlexLM systemd 单元运维手册
units/flexlm-cadence.service Cadence 许可服务单元(投放至 /etc/systemd/system/)
units/flexlm-synopsys.service Synopsys 许可服务单元(同上)
backup/README.md 回滚方式台账

变更清单(31.29)

项 变更前 变更后
/etc/systemd/system/ 无 flexlm 单元 新增 flexlm-cadence.service、flexlm-synopsys.service
服务启动方式 setsid nohup … & 裸进程 systemd 托管(-z 前台 + Type=simple)
开机自启 无 multi-user.target.wants 下已 enable
自动重启 无 Restart=on-failure,RestartSec=10
Cadence license/二进制 — 未改动
Synopsys license/二进制 — 未改动
firewalld — 未改动

待办

  1. 探活告警(用户本次决定暂不做):systemd 只能自愈"进程退出",无法发现"进程活着但不发许可"。 后续可加 systemd timer + lmstat 探活脚本,异常时写 journal / 发 Webhook。31.29 已实测可出网。
  2. systemctl restart 的 TIME-WAIT 等待:可考虑在内核侧调 net.ipv4.tcp_tw_reuse(对 listen socket 无效, 实用性待评估),或接受 60–70 秒恢复。
  3. lmgrd 日志无限增长:-l <file> 每次启动截断重写,进程长跑期间日志会持续增长,后续可纳入 logrotate。

来源:/home/rain/Documents/eda_tools_ins/Synopsys/flexlm_systemd_20260928/docs/SOP.md | 最后更新:2026-09-28 13:25(由 build/sync.py 同步,请勿在站点侧修改)