Formality 权限被拒:fm_shell permission denied 速查
更新时间:2026-10-23。FAQ 速查页,属于 EDA 工具排错系列。Formality 做等价性比对时报 Permission denied,几乎从不是工具本身坏了,而是操作系统层「当前用户对这个文件或目录摸不得」的直白转述——读 .db 库被拒、写比对日志被拒、启动时建 .synopsys 缓存目录被拒,都是同一套 Unix 权限模型在 fm_shell 不同环节上的表现。同族问题见 SpyGlass 权限被拒;「摸不得」的相邻问题「找不到」见 Formality 模块找不到。
本文要回答的问题
- fm_shell 一启动就 Permission denied,连 banner 都没出,是哪一环?
- .db 库文件明明在,为什么 read_db 读不进来?
- 共享项目目录里,为什么同事的验证结果我写不了、我的日志同事看不了?
- 容器里跑 Formality,为什么 uid 看起来没问题还是写不进挂载卷?
一、报错原文与现象
/bin/fm_shell: Permission denied
Error: Cannot open file '/proj/work/fm/formality.log' for writing: Permission denied (EACCES)
Error: Cannot read file '/proj/libs/stdcell.db': Permission denied (EACCES)
Error: Cannot create directory '/home/user/.synopsys': Permission denied先定三要素:什么动作(执行 fm_shell / 读 .db 或库文件 / 写工作目录与日志 / 建 .synopsys 缓存目录)、什么对象(报错文本通常带完整路径)、以什么身份(id 一条命令确认当前用户与组)。EACCES 是内核返回码 13,专指「路径存在但权限不放行」,与「路径不存在」的 ENOENT 分工明确——路径在报错里真实存在,只是不让你摸。
二、可能原因总览
| 报错现象 | 可能原因 | 处置 |
|---|---|---|
| fm_shell 启动瞬间被拒 | 二进制或启动脚本执行位被误清 | ls -l 核对后 chmod 恢复执行位 |
| .synopsys 缓存目录创建失败 | HOME 不可写或属主是别人 | 换可写 HOME 或用 -cache 类选项重定向 |
| 工程目录写不进日志与报告 | 属主是同事,组无写权限 | 放开组写或把工作目录换到自己空间 |
| read_db 读 .db 失败 | 库文件 600 属 root 或属别人 | 库文件放开到 644 属只读共享属主 |
| 共享盘某节点全拒、别台正常 | 该节点挂载为只读 ro | mount 核对挂载选项,重挂 rw 或换节点 |
| sudo 之后在 NFS 上仍被拒 | root squash 把 root 映射成 nobody | 不用 sudo,修对属主、组与 umask |
| 新建结果文件同事打不开 | umask 太严(027/077)锁死组权限 | 项目 env 脚本固定 umask 002 |
| 容器内写挂载卷被拒 | 容器内 uid 与宿主机目录属主不映射 | 以属主 uid 起容器或调挂载卷属主 |
三、逐条排查展开
先分清「启动即拒」与「工作中拒」。 fm_shell 连 banner 都没出就 Permission denied,是二进制或封装脚本缺执行位——安装树被人误 chmod -R 之后常见。判别一条命令:
ls -l $(which fm_shell)
ls -ld <工程目录> <库文件路径>
idls -l 对普通文件看执行位 x,对目录看属主与组权限。id 确认你是谁、在哪些组——属主不是你、你又不在属主组里时,组权限对你无效,这条线索直接决定走 chmod 还是走「找属主」。
.synopsys 缓存目录是 Formality 特有的第一坑。 fm_shell 启动早期就要往 HOME 下的 .synopsys 目录写缓存与历史,HOME 不可写(只读挂载、磁盘配额打满、HOME 属主被运维改成 root)都会让它启动即拒,报错路径直指 .synopsys。判别:ls -ld ~ ~/.synopsys。处置要么修 HOME 属主与权限,要么把缓存目录重定向到本地可写盘,重跑验证。
.db 库文件读不进,先看文件本身的读权限而不是路径。 库文件被发布流程设成 600 属 root 或属某个发布账号,普通验证用户跑 read_db 时内核直接回 EACCES,报错只说 Cannot read file 不说是谁的锅。判别:ls -l <库路径>。库文件内容不含写机密,行业惯例是 644 属只读共享属主——所有人可读、只有属主可写,发布脚本里固化这个权限。
工程目录属主是同事,是共享 NFS 工作区的主战场。 多人共用一个项目区,上次同事跑比对留下的 formality 工作目录、日志与报告属主是同事,组权限没开写,你续跑立刻写不进。正解不是 chmod 别人的东西(你没有权限),而是临时让属主放开组写,或把本次比对的工作目录换到自己空间;长期按组协作建目录(统一项目组 + setgid 位 + umask 002),从建目录第一天配好。
「这台机器行、那台不行」先查挂载选项。 共享盘在不同计算节点的挂载选项可能不同——某台挂了 ro 只读,该节点上所有写操作集体 EACCES,读却完全正常,极具迷惑性。mount | grep <挂载点> 看到 ro 就找运维重挂或换节点。
NFS root squash 让 sudo 变成反效果。 直觉上「权限不够就 sudo」,在 NFS 挂载点上恰好相反:服务端默认把客户端 root 映射成 nobody,sudo 之后权限反而更小,而且产物属主变 root,后续正常用户集体撞墙。判别:
mount | grep <挂载点>
sudo touch <挂载点>/fmtest && ls -l <挂载点>/fmtest看到属主是 nobody 就坐实 root squash。正解永远是修对属主、组、umask,不是抬高身份。
umask 太严是「建出来就锁死同事」的根源。 登录环境 umask 027 或 077 时,你跑 Formality 生成的报告目录组无权限——自己续跑没事,同事接手立刻 Permission denied。判别:umask 看当前值。协作项目的 env 脚本里固定 umask 002,保组可写又不对外放开。
容器内 uid 映射是近两年新增的坑。 在容器里跑 fm_shell,容器内用户 uid 与宿主机挂载卷属主不对应时,容器内看着「我是谁」正常、写卷照样 EACCES。判别:容器内 id 对比宿主机 ls -ln <挂载卷> 的数字属主。处置:以与卷属主一致的 uid 起容器,或把卷属主调成容器内 uid。
颜色按语义分角色:红是报错入口,蓝是排查动作,橙是修复,紫是收尾防复发。主线是「先定三要素,再按动作分三条通道:启动即拒查 fm_shell 执行位与 .synopsys 缓存目录可写性,工作中拒查工程目录与 .db 库文件属主和组,换机或容器才拒查挂载选项与 uid 映射」。sudo 在任何一条通道里都不是出口——NFS root squash 下它反而让你更没权限。
四、预防与纪律
- 项目目录统一组协作配置:统一项目组 + setgid + env 脚本固定
umask 002,建目录第一天配好,别等撞墙再补。 - 库文件发布权限写进发布脚本:.db 与工艺库固定 644 属只读共享属主,发布即核对一次。
- HOME 与 .synopsys 缓存纳入环境自检:跑 Formality 前脚本先
touch ~/.synopsys/.probe验证可写,失败早报警。 - 禁 sudo 跑工具写进团队公约:sudo 产物属主污染比原问题更难收拾,发现统一 chown 清理并复盘来源。
- 容器作业固化 uid 约定:起容器命令里写明以属主 uid 运行,挂载卷属主纳入部署清单。
- 排查留三件套:
id、ls -l <路径>、mount | grep <挂载点>的输出连同报错原文一起记录,跨人交接不靠口述。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇中「权限」节点的 Formality FAQ 页,与 SpyGlass 权限被拒 同族;Formality 工具族的其他高频报错见 Formality 模块找不到、Formality license checkout 失败,Formality 工具本身的能力定位见 等价性验证与 Formality 实战。
一句话总结
Formality 权限被拒先定三要素(动作、对象、身份),再按动作分流:启动即拒查 fm_shell 执行位与 .synopsys 缓存目录可写性,工作中写不进查工程目录属主与组(协作场景靠项目组 + setgid + umask 002 根治),读库失败查 .db 文件 644,换机或容器才拒查 mount 只读挂载、NFS root squash 与容器 uid 映射;sudo 跑工具在 NFS 上反而更没权限,明确禁止;最后靠「组协作配置 + 库文件发布权限 + 排查三件套留痕」三条纪律防复发。