跳转至

SOP — 普通用户 Lustre 写入被拒(服务端身份解析缺失)

  • 主题目录:fix-lustre-write-perm/
  • 执行日期:2026-10-06
  • 类型:C 类变更(服务端账户条目补齐)
  • 关联:docs/HANDOFF.md §3.1 #13(本变更结案项);巡检报告 reports/inspect-20261006-012305.md

1. 背景

EDA 仿真需把中间文件落到 Lustre(/mnt/lustre/scratch/tmp),但普通用户 rain01 真实写入报 Permission denied,root 正常,阻塞仿真落盘。该问题由巡检发现并经手工复现确认, 列为 HANDOFF §3.1 #13。

排查中排除了多个常见怀疑点:目录权限(scratch/tmp 已是 drwxrwxrwt 1777)、SELinux (Disabled/Permissive)、挂载状态(.18/.20/.28 均 state=FULL)。真正原因在服务端。

根因(有日志证据):客户端用户来自集中身份源(SSSD + LDAP),而服务端 .21/.22 未接入该身份源, 本地解析不到客户端 UID,导致 MDS 的身份解析程序 l_getidentity 失败、拒绝一切非 root 请求:

(MDS .21,journalctl,时间戳与本轮写入测试完全对应)
l_getidentity[108071]: no such user 2001
l_getidentity[108071]: get identity for uid 2001 ... rc = -1

root 不受影响,是因为 mdt.*.root_squash = 0:0——root 身份不走该解析路径。

2. 目标

项 可验证状态
验收 .18 / .20 / .28 三台以 rain01 真实写入 /mnt/lustre/scratch/tmp 成功
回归 复跑仍成功(幂等);root 写入不受影响
旁证 MDS .21 近 10 分钟 l_getidentity 日志条数为 0
边界 不改变任何 Lustre 配置、目录权限与调优参数

3. 前置条件

  • root 免密 SSH 可达 .21(MGS+MDT)、.22(OSS)
  • UID/GID 事实(客户端经 LDAP 解析,ldap_id_mapping = false,故必须严格一致): rain01 = uid 2001、主组 design = gid 2000
  • 服务端 uid 2001 / gid 2000 均空闲(已实测确认)
  • 远程备份落点:/var/backups/lustre-ins/

4. 影响范围

主机 组件 变更内容 停服 窗口
192.168.31.21 MGS + MDT /etc/{passwd,group,shadow,gshadow} 各新增 1 组 + 1 用户 否 任意
192.168.31.22 OSS 同上 否 任意
  • 不重启 lnet / 不重挂载 / 不重启 Lustre 服务;不影响在跑作业
  • 不改目录属主与权限(scratch/tmp 维持 1777)

5. 分步操作

步骤 0:判据——必须真实写入,不要用 test -w

test -w(及部分工具的预检)在 Lustre/llite 上会对不可写目录误报「可写」,本问题即被它掩盖过一次。 判据一律为「以目标用户真实创建文件」。

# 在客户端执行;预期输出 Permission denied 才是复现
su -s /bin/bash rain01 -c 'touch /mnt/lustre/scratch/tmp/.probe && rm -f /mnt/lustre/scratch/tmp/.probe'

失败判断:若此处成功,说明现象已变,先回到步骤 1 重新取证,不要套用本 SOP。

步骤 1:定位根因(客户端现场 + 服务端日志)

先在客户端确认「不是权限位、不是 SELinux」:

findmnt -n -o SOURCE,TARGET,FSTYPE --target /mnt/lustre
# 预期 192.168.31.21@tcp:/edafs /mnt/lustre lustre
stat -c '%A %U:%G %n' /mnt/lustre /mnt/lustre/scratch /mnt/lustre/scratch/tmp
# 预期 /mnt/lustre/scratch/tmp 为 drwxrwxrwt root:root(1777,任何用户可写)
getenforce
# 预期 Disabled 或 Permissive

再在 MDS 上取身份解析日志(关键判据):

journalctl --since '-10min' | grep -iE 'l_getidentity|no such user'
# 命中 "no such user <uid>" 即根因确认
lctl get_param -n mdt.*.identity_upcall
# 预期 /usr/sbin/l_getidentity
lctl get_param -n mdt.*.root_squash
# 预期 0:0(说明 root 为何不受影响)
getent passwd 2001
# 修复前为空 —— 这是被拒的直接原因

坑:不要被「ACL 显示 other::rwx 却仍被拒」误导去改目录权限。Lustre 的权限判定发生在 MDS 侧, 身份解析失败时任何权限位都不生效,改目录权限是无效动作。

实现体:无(本变更为一次性手工变更,未产出脚本)。

步骤 2:备份并补齐服务端账户条目(在 .21、.22 各执行一次)

先备份四个账户文件(必须,回滚依赖它),再以幂等方式新增组与用户。

TS=$(date +%Y%m%d-%H%M%S)
mkdir -p /var/backups/lustre-ins
for f in passwd group shadow gshadow; do
  cp -a "/etc/$f" "/var/backups/lustre-ins/$f.bak.$TS"
done

getent group  design  >/dev/null 2>&1 || groupadd -g 2000 design
getent passwd rain01  >/dev/null 2>&1 || \
  useradd -u 2001 -g 2000 -M -s /sbin/nologin -c "EDA user (mirror of client LDAP)" rain01

getent passwd 2001
getent group 2000

预期:rain01:x:2001:2000:...:/home/rain01:/sbin/nologin 与 design:x:2000:。

坑与注意:

  • -M 不在服务端建家目录,-s /sbin/nologin 防止服务端出现可登录账户;两者都不影响 Lustre 权限判定 (MDS 只做 NSS 数字 UID/GID 解析,不看 shell 与家目录)
  • UID/GID 必须与客户端逐位一致(2001/2000)。客户端 ldap_id_mapping = false, 若服务端用 SSSD 自动映射会得到另一套 UID,仍然失败
  • 命令以 getent ... || 前置判空,重复执行零变更(幂等)

步骤 3(可选,长期方案):服务端接入同一 LDAP

本地条目与 LDAP 属双轨:后续新增 EDA 用户仍需在服务端同步一次。长期正解是让服务端接入同一身份源:

# 示意:需先解决装包(跨境仓库约 2 KB/s,可从既有客户端拷 /var/cache/dnf 与 repo 文件)
dnf install -y sssd sssd-ldap
# 复制客户端同款配置(含域 rainchen / ldap_uri / ldap_schema=rfc2307 / ldap_id_mapping=false)
install -m 600 /path/to/sssd.conf /etc/sssd/sssd.conf
systemctl enable --now sssd
getent passwd rain01    # 预期返回 uid 2001 即接入成功

本轮未采用该方案(需在服务端装包并引入对 LDAP 的运行时依赖),记为待办。

6. 验证

# 在 .18 / .20 / .28 三台分别执行;两次都应输出 OK(第二次即幂等回归)
su -s /bin/bash rain01 -c 'f=/mnt/lustre/scratch/tmp/.verify_$$; touch $f && { echo OK; rm -f $f; } || echo FAIL'

预期:三台均 OK。

# MDS 侧旁证
journalctl --since '-10min' | grep -c l_getidentity     # 预期 0
getent passwd 2001                                      # 预期返回 rain01 行
验证项 结果(2026-10-06)
.18 / .20 / .28 真实写入 scratch/tmp 三台 OK
复跑(幂等回归) 三台 OK
MDS l_getidentity 报错(近 10 min) 0 条
getent passwd 2001(服务端) 返回 rain01
root 写入 不受影响(全程正常)

说明:/mnt/lustre/scratch(755 root:root)对 rain01 仍拒绝写入,这是正常的 POSIX 语义, 不是缺陷;如有业务需求让 design 组在 scratch/ 下写,应单独调整目录属组或加 ACL。

7. 回滚

备份位置:192.168.31.21:/var/backups/lustre-ins/、192.168.31.22:/var/backups/lustre-ins/ (文件名 passwd.bak.20261006-052523 等)。台账见本目录 backup/README.md。

# 回滚触发条件(任一即回滚):
#   ① 三台任一写入验证不通过;② MDS 出现新的身份解析报错;③ 影响在跑作业
TS=20261006-052523
for f in passwd group shadow gshadow; do
  cp -a "/var/backups/lustre-ins/$f.bak.$TS" "/etc/$f"
done
getent passwd 2001 || echo "回滚完成:uid 2001 已不可解析"

回滚后验证:getent passwd 2001 返回空、客户端写入回到 Permission denied 状态即回滚成功。 回滚不影响正在运行的 Lustre(无需重挂载)。

8. 风险说明

风险 等级 缓解
本地条目与 LDAP 双轨漂移(新增用户需手工同步) 中 记待办:服务端接入 SSSD;或纳入服务端初始化流程
useradd 误占 uid/gid(若与未来 LDAP 用户冲突) 低 已实测 2001/2000 空闲;创建前均做 getent 判空
服务端新增账户带来登录面 低 -M -s /sbin/nologin,无家目录、不可登录
备份文件散落 低 统一落 /var/backups/lustre-ins/,已登记台账

未做且不应做的动作:未修改目录权限、未改 mdt.*.identity_upcall、未改 nodemap、未重挂载。

附录:交付物与证据

  • 本目录:SOP.md、backup/README.md
  • 排障场景沉淀:docs/troubleshoot.md → 「普通用户写入 Permission denied」
  • 巡检报告:reports/inspect-20261006-012305.md

来源:/home/rain/Documents/lustre_ins/fix-lustre-write-perm/SOP.md | 最后更新:2026-10-06 05:26(由 build/sync.py 同步,请勿在站点侧修改)