有没有一种很好的方法来检测过时的NFS挂载

Che*_*evy 18 unix linux bash shell nfs

我有一个我想要启动的程序,只有几个测试成功完成.

我需要的一个测试是我所有的NFS挂载都很活跃.

我能比蛮力方法做得更好:


mount | sed -n "s/^.* on \(.*\) type nfs .*$/\1/p" | 
while read mount_point ; do 
  timeout 10 ls $mount_point >& /dev/null || echo "stale $mount_point" ; 
done
Run Code Online (Sandbox Code Playgroud)

timeout是一个在后台运行命令的实用程序,如果SIGCHLD在时间限制之前没有捕获,则在给定时间后将其终止,以显而易见的方式返回成功/失败.


英文:解析mount每个NFS挂载点的输出,检查(以超时为限).可选(不在上面的代码中)打破第一个陈旧的安装.

小智 7

我的一位同事遇到了你的剧本.这并不能避免"蛮力"的做法,但如果我可能在Bash:

while read _ _ mount _; do 
  read -t1 < <(stat -t "$mount") || echo "$mount timeout"; 
done < <(mount -t nfs)
Run Code Online (Sandbox Code Playgroud)

mount可以直接列出NFS挂载. read -t(内置shell)可以超时命令. stat -t(简洁输出)仍然像ls*一样挂起. ls产生不必要的输出,存在巨大/慢速目录列表的误报,并且需要访问权限 - 如果没有它们,也会引发误报.

while read _ _ mount _; do 
  read -t1 < <(stat -t "$mount") || lsof -b 2>/dev/null|grep "$mount"; 
done < <(mount -t nfs)
Run Code Online (Sandbox Code Playgroud)

我们正在使用它lsof -b(非阻塞,所以它也不会挂起)以确定挂起的来源.

谢谢你的指针!

  • test -d(内置shell)也可以代替stat(标准外部),但read -t只有在没有超时并读取输入行时才返回成功.由于test -d不使用stdout,(( $? > 128 ))因此需要对其进行错误级别检查 - 不值得易读性,IMO.


Oz1*_*123 6

花了我一些时间,但这是我在Python中发现的:

import signal, os, subprocess
class Alarm(Exception):
    pass

def alarm_handler(signum, frame):
    raise Alarm

pathToNFSMount = '/mnt/server1/' # or you can implement some function 
                                 # to find all the mounts...

signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(3)  # 3 seconds
try:
    proc = subprocess.call('stat '+pathToNFSMount, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 
    stdoutdata, stderrdata = proc.communicate()
    signal.alarm(0)  # reset the alarm
except Alarm:
    print "Oops, taking too long!"
Run Code Online (Sandbox Code Playgroud)

备注:

  1. 相信这里答案.
  2. 您也可以使用替代方案:

    os.fork()os.stat()

检查叉子是否完成,如果超时则可以杀死它.您需要使用time.time()等等.


Ted*_*ddy 5

您可以编写一个 C 程序并检查ESTALE.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iso646.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(){
    struct stat st;
    int ret;
    ret = stat("/mnt/some_stale", &st);
    if(ret == -1 and errno == ESTALE){
        printf("/mnt/some_stale is stale\n");
        return EXIT_SUCCESS;
    } else {
        return EXIT_FAILURE;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Teddy,实际上,您是否尝试过您的代码?在我的 Linux 机器中,如果有一个陈旧的 NFS,命令 stat 将挂起,就像你的函数 stat("/mnt/some_stale", &amp;st) 一样,所以代码永远不会返回...... (3认同)
  • 我在 python 中为这个答案制作了一个真正的黑客代码(并在我有一个陈旧的文件系统时设法测试它):https://github.com/guysoft/stale_mount_checker (2认同)

小智 5

除了在某些情况下会挂起的先前答案之外,此代码段还会检查所有合适的安装,并用信号KILL杀死,并使用CIFS进行测试:

grep -v tracefs /proc/mounts | cut -d' ' -f2 | \
  while read m; do \
    timeout --signal=KILL 1 ls -d $m > /dev/null || echo "$m"; \
  done
Run Code Online (Sandbox Code Playgroud)