我们的一位计算机用户几乎超出了 AFS 卷配额。运行fs listquota
或fs 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