Thursday, 12 March 2015

inodes, statvfs, và các thông số cơ bản về một filesystem

inode là viết tắt của index node, một cấu trúc dữ liệu để biểu diễn một filesystem object trên UNIX-like filesystem. Một inode có thể biểu diễn một file, directory, hoặc object khác (symlink, special block ...). Để dễ hiểu, có thể sử dụng file node thay cho inode.

sử dụng df -i để xem thông tin về inode của các filesystem trên hệ thống bạn đang dùng.
ls -i giúp hiển thị index number của 1 filesystem object.
hvn@ubuntu:~⟫ ls -i /etc/passwd
263212 /etc/passwd
hvn@ubuntu:~⟫ df -i
Filesystem                  Inodes IUsed  IFree IUse% Mounted on
/dev/mapper/ubuntu--vg-root 441504 71768 369736   17% /
none                        127233     2 127231    1% /sys/fs/cgroup
udev                        124422   456 123966    1% /dev
statvfs là một system call tuân theo chuẩn POSIX để lấy thông tin về một file system.
C function statvfs(PATH) sẽ trả về thông tin về file system chứa file được gán trong PATH.

Trên python2.7 có thể lấy thông tin này bằng os.statvfs(PATH)

Python 2.7
In [7]: import os; data = os.statvfs('/')

In [8]: attrs = [attr for attr in dir(data) if not attr.startswith('__')]

In [9]: for a in attrs:
   ...:     print a, getattr(data, a)
   ...:
f_bavail 1281308 # Số block available cho non-superuser
f_bfree 1373621 # Tổng số block free trong filesystem
f_blocks 1703864 # Tổng số block trong filesystem
f_bsize 4096 # Size của một block
f_favail 369735 # Số inode available cho non-superuser
f_ffree 369735 # Số inode free
f_files 441504 # Tổng số inode
f_flag 4096
f_frsize 4096
f_namemax 255 # độ dài tối đa của filename
n_fields 10
n_sequence_fields 10
n_unnamed_fields 0

Để tính tổng dung lượng:

In [16]: data.f_blocks * data.f_bsize
Out[16]: 6979026944 # byte

So với output của ``df``
hvn@ubuntu:~⟫ df
Filesystem                  1K-blocks    Used Available Use% Mounted on
/dev/mapper/ubuntu--vg-root   6815456 1320972   5125232  21% /
output của df là số 1K-blocks, tính ra dung lượng là (nhân với 1K = 1024)
hvn@ubuntu:~⟫ echo $(( 6815456 * 1024 ))
6979026944

Kết quả giống nhau như mong đợi.
Tại sao 1K lại bằng 1024, K ở đây là viết tắt của KiB và nó bằng 2^10.
Trong man df có ghi:
SIZE  is  an integer and optional unit (example: 10M is 10*1024*1024).  Units are K, M, G, T, P, E,  Z, Y (powers of 1024) or KB, MB, ... (powers of 1000).
Giới hạn độ dài filename:
# f_namemax 255
hvn@ubuntu:~⟫ cat nfile | wc -c
256
hvn@ubuntu:~⟫ touch `cat nfile`
touch: cannot touch ‘1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111’: File name too long
Bài viết thực hiện trên:
hvn@ubuntu:~⟫ lsb_release -r ; df --version | grep df; python --version; ls --version | grep ls
Release:        14.04
df (GNU coreutils) 8.21
Python 2.7.6
ls (GNU coreutils) 8.21
Xem thêm ở
https://docs.python.org/2.7/library/statvfs.html#module-statvfs
http://manpages.ubuntu.com/manpages/precise/en/man3/statvfs.3posix.html#