查找占用大量 AFS 卷配额的目录

查找占用大量 AFS 卷配额的目录

我们的一位计算机用户几乎超出了 AFS 卷配额。运行fs listquotafs lq向他发出警告:

olifri@ubuntu:~$ fs listquota ~
Volume Name                    Quota       Used %Used   Partition
H.olifri                      500000     492787   99%<<       38% <<WARNING

我想与他分享一个 shell 脚本,该脚本可以检测他的哪些目录消耗了最多的 AFS 卷配额。这样他就能更好地了解从哪里开始删除文件。

请注意,在 AFS 文件系统中,用户可以在 AFS 卷内挂载其他 AFS 卷。这意味着使用/usr/bin/find可能会进入我们不感兴趣的其他 AFS 卷。

我们的 AFS 客户端软件是 Openafs 1.6.1,它在 Ubuntu 12.04 计算机上运行。我们没有 AFS 文件服务器的管理员权限,因为它们由另一个部门管理。

命令/usr/bin/du似乎不知道 AFS 卷的概念。我现在最好的想法是编写一个脚本,针对每个子目录测试该目录是否是 AFS 卷的挂载点。例如,fs lsmount可以使用该命令。对于普通目录,fs lsmount结果如下

esjolund@ubuntu:~$ mkdir ~/testdir
esjolund@ubuntu:~$ fs lsmount ~/testdir
'/afs/pdc.kth.se/home/e/esjolund/testdir' is not a mount point.

对于 AFS 挂载点,fs lsmount会产生以下结果

esjolund@ubuntu:~$ fs mkmount -dir ~/testmount -vol prj.sbc.esjolund00
esjolund@ubuntu:~$ fs lsmount ~/testmount
'/afs/pdc.kth.se/home/e/esjolund/testmount' is a mount point for volume '#prj.sbc.esjolund00'

在开始编写 shell 脚本之前,我想听听您是否对如何解决问题有更好的想法?

答案1

#!/usr/bin/python                                                                                                                  
import os
import sys
import subprocess

if len(sys.argv) != 2:
  print >> sys.stderr, "error: Wrong number of arguments. One argument expected (the directory name)"
  sys.exit(1)

for dirpath, dirnames, filenames in os.walk(sys.argv[1]):
  for dirname in dirnames:
    subdirpath = os.path.join(dirpath, dirname)
    p = subprocess.Popen(["fs", "lsmount", subdirpath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    # It seems we can distinguish an AFS volume mount point from a normal directory by just                                        
    # looking at the return code.                                                                                                  
    # Maybe we should also look at the stdout and stderr?                                                                          
    # (In other words the variables out and err)                                                                                   
    out, err = p.communicate()
    if ( p.returncode == 0 ):
      dirnames.remove(dirname)
  total_size = 0
  for filename in filenames:
    filepath = os.path.join(dirpath, filename)
    statinfo = os.lstat(filepath)
    total_size += statinfo.st_size
  print "%i %s" % (total_size, dirpath)

使用如下命令

olifri@ubuntu:~$ python /tmp/script.py  ~ | sort -n

相关内容