当前位置:嗨网首页>书籍在线阅读

06-扩展属性

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.1.4 扩展属性

“扩展属性(Extended attributes)”也称作xattrs,提供一种把文件与键/值对相关联的机制。本章中,我们已经讨论了各种与文件关联的键/值元数据的情况:文件大小,所有者,最后修改时间戳等等。扩展属性支持已有文件系统支持最初设计中未实现的新特性,例如出于安全目的的强制访问控制。扩展属性的很有趣的一点在于用户空间的应用可能任意创建和读写键/值对。

扩展属性是与文件系统无关的,这是指应用程序可以使用标准接口操作它们,接口对所有的文件系统都没有区别。因此,应用程序在使用扩展属性时无需考虑文件所在的文件系统,或文件系统如何内部存储键与值。但是,扩展属性的实现是与文件系统相关的。不同的文件系统以不同的方式存储扩展属性,但内核隐藏了这些差别,把它们从扩展属性接口抽象出来。

例如ext4文件系统,在文件inode的空闲空间存储其扩展属性[2]。该特性是读取文件属性非常快。因为应用程序无论何时访问文件,包含inode的文件系统块都会从磁盘被读入内存,因此扩展属性会“自动”被读入内存,且被访问时没有额外的开销。

其他文件系统,例如FAT和minixfs,根本不支持扩展属性。当对这些文件系统的文件调用扩展属性时,这些文件系统会返回ENOTSUP。

键与值

每个扩展属性都对应一个唯一的键(key)。键必须是合法的UTF-8字符。它们采用namespace.attribute的形式。每一个键都必须包含完整的名称,也就是说,它必须以有效的命名空间开头,并接着一个句点。一个有效的键名的例子是user.mime_type,该键的命名空间是user,属性名是mime_type。

存储MIME类型的更好方式 GUI文件管理器,例如GNOME的文件管理器,对不同类型的文件,其处理方式完全不同:图标不同,默认点击行为不同,可执行操作列表不同等等。为了实现这些,文件管理器必须知道每个文件的格式。为了确定文件格式,Windows文件系统往往只是简单地查看文件的扩展名。但出于传统和安全的双重原因,UNIX系统倾向于检查文件并解释其类型,这个过程被称作MIME类型监听(MIME type sniffing)。 键可能是已定义的,也可能是未定义的。如果一个键已定义,其值可能是空值,也可能是非空值。也就是说,未定义的键与已定义但未指定值的键之间是有区别的。正如我们所看到的,这意味着删除一个键需要特殊的接口(仅仅给该键赋空值是不够的)。

与键相关联的值,如果是非空值,可能是任意的字节序列。因为关联值不一定是字符串,它没必要以'\0'结尾,尽管当你选用C字符串存储键值时以'\0'结尾很合理。既然键值不保证以'\0'结尾,所有对扩展属性的操作需要该值的长度。当读取属性时,内核提供长度;当写入属性时,必须提供属性的长度。

Linux对键的数目,键的长度,值的大小,或被与文件相关联的所有键与值消耗的空间大小上都没有任何限制。但在文件系统上却有实际的限制。这些限制通常体现在与给定文件相关联的所有键与值的总长度上。

举个例子,对于ext3文件系统,给定文件的所有扩展属性都必须适合文件inode的剩余空间,最多达到一个额外的文件系统块大小。(更老版本的ext3限制在一个文件系统块,而不再在inode内保存。)这个限制依赖于文件系统的块大小,相当于每个文件实际限制是从1KB至8KB。而在XFS中,则没有实际限制。由于大多数键与值都是较短的文本字符串,在ext3中这些限制一般也不是问题。尽管如此,还是应该记住这些限制,在把某个项目的整个版本修订历史保存到文件的扩展属性之前,要还是要慎重考虑这些限制条件。

扩展的属性命名空间

与扩展属性相关联的命名空间不仅仅是组织文件的工具。依赖于命名空间,内核可以执行不同访问策略。

Linux当前定义四种扩展属性命名空间,将来可能会定义更多。目前分别有以下四种扩展:

system

命名空间system通常利用扩展属性实现内核特性,例如访问控制列表(ACLs)。在命名空间的扩展属性的一个例子是 system.posix_acl_access。无论用户是读取这些属性还是写入这些属性,都依赖于相应位置的安全模块。最糟糕的情况是,没有用户(包括root)可以读取这些属性。

security

命名空间security通常实现安全模块,例如SELinux。用户空间应用程序访问这些属性也依赖于相应位置的安全模块。默认情况下,所有进程能读取这些属性,但只有具有CAP_SYS_ADMIN权限的进程能写入它们。

trusted

命名空间trusted存储用户空间限制的信息。只有具有CAP_SYS_ADMIN权限的进程能读写这些属性。

user

命名空间user是普通进程所使用的标准命名空间。内核通过普通的文件权限位来控制访问该命名空间。为了从已有的键中读取值,进程必须具有给定文件的读权限。要创建一个新键,或者向已有的键写入值,进程必须具有给定文件的写权限。在用户命名空间只能对普通文件指派扩展属性,符号链接或设备文件则不可以。当设计一个能使用扩展属性的用户空间应用程序时,命名空间正是你所需要采用的。