16.01 文件扩展属性 EA getfattr setfattr

什么是扩展属性

扩展属性(Extended Attributes)可以将任何字符串键和任何数据值的信息和文件 inode 关联起来,值可以不是零结尾的字符串。其键的命名方式是 namespace.name,其中 namespace 只能是以下四种之一:

  1. user:权限管理方式和读写文件的内容是一样的。
  2. trusted:和 user 类似,但是需要管理员权限,即 CAP_SYS_ADMIN
  3. system:键的第二分量只能是内核认可的字符串。
  4. security:用来支持操作系统的安全模块。

在 ext2、ext3、ext4 或 Reiserfs 文件系统上,如欲将 user EA 与一文件关联,在装配底层文件系统时需带有 user_xattr 选项。 比如:

mount -o user_xattr <device> <directory>

Note

书上没有说扩展属性在 Linux 中是怎么实现的。

扩展属性和 inode 中其他信息的比较

主要是和 inode 模式位(st_mode)、inode 标志(flags)来对比:

  • inode 模式中的访问权限是 UNIX 规定的访问权限;inode 标志是某些 UNIX 在某些文件系统支持的功能,也是按位的形式存储的。
  • EA 允许存储任意类型的数据,而不只是 bool 类型。
  • EA 是用户可扩展的,不是系统调用手册里定死的,任何程序可以给文件附加元信息并为其提供含义。
  • inode 模式位是存储在 struct stat 中的,inode 标志和 EA 是在部分文件系统才支持、而且要用其他系统调用获取的。另外操作 inode 标志的命令(lsattr / chattr)和操作 inode 扩展属性的命令(setfacl / getfacl)在 Debian 上都是需要额外安装的

如何操作扩展属性

在 shell 中,可执行 setfattr(1)getfattr(1) 命令来设置和查看文件的 EA(扩展属性)。

Tip

setfattrgetfattr 命令可能需要额外安装。我的 Debian 系统里面就没有,要用 sudo apt install attr 来安装。

一些限制

  • user 命名空间的 EA 只能施加于普通文件或者目录,不能施加于(块或字符)设备、socket、符号链接、fifo。
  • 如果目录有 sticky 位,那么非特权且非 owner 的进程是不能给目录增加 user EA 的。
  • EA 的名称长度、内容长度都有对应的限制。

对应的系统调用

在头文件 sys/xattr.h 中,支持 setxattr / getxattr / removexattr / listxattr 四种操作,每个操作都有普通版本、l 前缀版本、f 前缀版本。

由于存储的属性值可以是任何类型,不是靠末尾零来对字符串长度计数的,所以在设置 xattr 时,需要显式传递缓冲区的长度。在获取时,为了防止缓冲区溢出,也要给出缓冲区的长度。

出于安全考虑,list 中返回的 EA 名称可能不包含调用进程无权访问的属性名。

有的文件系统会返回进程无权访问的属性名,这个时候操作这个属性就会失败。