问题:
晚上刚到家,值班的同事反馈,有个主机df -h卡死,由于之前处理过类似情况,就以为还是nfs挂载的问题。
处理过程:
登上主机发现,查看/etc/fstab文件,没有异常。继续查看/etc/mtab,mtab记录的事当前已挂载的信息。
首先分析卡死原因,使用starce df命令。结果如下
lockdreamer可以看到,执行到/proc/sys/fs/binfint_misc这个目录时,停止不动。使用mount -l发现
lockdreamer可以看到,这个目录有系统方式的挂载。
查看系统日志:
Lockdreamer解决办法:
systemctl restart proc-sys-fs-binfmt_misc.automount
知识点!!以下是大牛分析:
在 systemd 服务中, 挂载/proc/sys/fs/binfmt_misc的只有两个 unit, 分别为proc-sys-fs-binfmt_misc.automount和proc-sys-fs-binfmt_misc.mount
automount 如何工作
systemd 通过 automount 实现了对文件系统挂载点进行自动挂载和控制的特性, 在用户访问指定目录的时候, 由 automount 判断自动进行挂载, nfs, sshfs 等使用较多, 目前为止在 centos7 系统中我们仅发现 binfmt_msic 类型是操作系统需要自动挂载的. 详见systemd.automount
问题原因说明
从上述搜集信息来看, 更像是 systemd 认为proc-sys-fs-binfmt_misc.mount已经关闭, 不过系统或内核还持有/proc/sys/fs/binfmt_misc挂载点, 引起竞争, 这样 df 在访问挂载点的时候则一直处于挂起状态. 这个问题类似 nfs 服务端异常断掉, client 端直接访问挂载点也会挂起一样. 没有做超时处理则 df 一直处于等待状态。
目前已知的触发条件包含以下两种方式:
1、人为
1. 修改 proc-sys-fs-binfmt_misc.automount 的 TimeoutIdleSec 为大于 0 的值, 219-30 版本默认300, 不用修改;
2. 访问 /proc/sys/fs/binfmt_misc/ 目录触发 aumount 自动挂载;
3. 在1中还没有超时的时候执行 systemctl stop proc-sys-fs-binfmt_misc.mount, 手动 unmount 掉挂载点;
在执行第三步的时候 systemd 报以下异常, unmount 操作不能注册, 而系统内核会继续持有挂载点, 进而引起 df 卡住. 另外在默认 timeout 为 0 的情况下人为制造的异常不会引起 hang 住
2、系统
问题主机的 umount 日志显示不是正常的 stop 操作, 从整个 systemd 日志来看 umount 操作更像是属于mount_sigchld_event函数的行为, 即在 systemd 的状态为UNMOUNTING, 或者收到SIGKILL,SIGTERM信号的时候, 而系统或内核认为当前状态为 SUCCESS (f 变量), 在从/etc/mtab(mtab 为/proc/self/mountinfo的软链) 读取到 mount 信息的时候, 当前的重试次数(n_retry_umount) 小于 RETRY_UMOUNT_MAX (32) 的时候则进行一次mount_enter_unmounting函数调用. 不过问题主机上 df 等命令已经卡住了, 不能保证还会走到这个函数里, 另外也不明确什么情况下系统内核会和 systemd 的状态相反.
这种方式没有好的重现方法, 不过处理方式应该和第一种一样, 重启proc-sys-fsbinfmt_misc.automount即可.
解决方式
目前并没有找到真正的触发条件, 不过我们认为 df 卡住问题在本质上还是由于 systemd 和 kernel 之间存在竞争而引起的, 导致其它程序访问挂载点的时候出现 hang 住的现象, 根据redhat bugzilla
的描述, 只要解决掉 mount 和 automount 过程中可能产生的竞争即可, 我们可以通过关闭proc-sys-fs-binfmt_misc.automount,释放已经存在的竞争来解决 df hang 住的问题, 所以整体上包含以下三种解决方式:
1. systemctl restart proc-sys-fs-binfmt_misc.automount;
2. 升级到最新 systemd-219-57 版本;
3. 按照红帽知识库的步骤对 proc-sys-fs-binfmt_misc.automount 进行 mask 操作, 只进行静态的 mount 操作;
这几种方式对应用程序无害, 第一种方式影响最小. 不过我们在排错的过程中发现了一些其它相关的 bug, 所以采取第二种方式会更稳妥,新版的 systemd 对1354410和1498318两个 bug 做了状态反馈处理, 即便有问题也不会出现 hang 住的现象, 另外默认超时时间为 0, 对程序来讲相当于只做了重启操作, 不过后续的版本可能存在变更的可能, 所以保险起见可以将在proc-sys-fs-binfmt_misc.automount 配置中指定 TimeoutIdleSec=0 参数值, 避免自动进行 unmount 操作. 最后重启机器即可; 第三种操作则可能影响其它有 automount 需求的软件(比如新版本的 postgresql), 不过很多软件在检测到没有启动 automount 的情况下会进行额外的 mount 操作, 不会有严重的影响。
网友评论