PkgBlog: attr

Edit extended filesystem attributes!
Package series/name: a/attr-2.4.47-x86_64-1
Official release: source and package
Blog entry created: 2018-07-20
Tagged: series_a core-system file-utils

This package reminds me a lot of the other file utility package I reviewed recently: acl (Access Control Lists). It’s also used to view/edit file metadata and it also has three command line tools: one for IRIX compatibility and two that do the same thing, but have slightly longer names and split the functionality between reading and writing operations.

ACLs allowed us to attach additional permission metadata to files. The attr tools, on the other hand, allow us to attach arbitrary key=value attribute pairs to a file or directory.

By the way, all three binaries are installed in /usr/bin.

Let’s try it!

I’m going to start with getfattr and setfattr:

Here’s what usage looks like:

$ setfattr -n user.author -v dave foo.txt
$ getfattr -d foo.txt
# file: foo.txt
user.author="dave"

It seems to me that getfattr should just display the attribute values by default rather than requiring the -d switch, but what do I know? Also, when you say it outloud, it sounds like the thing that happens to you when you sit around day after day eating donuts.

Let’s do the exact same procedure with another file using the attr command:

$ attr -s user.author -V dave wiggler.txt
Attribute "user.author" set to a 4 byte value for wiggler.txt:
dave
$ attr -l wiggler.txt
Attribute "user.author" has a 4 byte value for wiggler.txt
$ attr -g user.author wiggler.txt
Attribute "user.author" had a 4 byte value for wiggler.txt:
dave

The output of attr is more verbose (by default) and you’ll notice that to really replicate the entire sequence of listing properties, I first list the attributes by name with the -l option and then get the value of the user.author attribute with the -g option.

Namespaces

I didn’t read man 5 attr (from manual Section 5 "File formats and conventions", not to be confused with man 1 attr, the command’s manual page!) carefully enough the first time and missed this part:

The attribute name is always specified in the fully qualified namespace.attribute form, eg. user.mime_type, trusted.md5sum, system.posix_acl_access, or security.selinux.

So my first attempt looked more like this:

$ setfattr -n author -v dave foo.txt
setfattr: foo.txt: Operation not supported

I tried several variations before I realized that the author attribute name was the problem! Changing it to user.author worked just fine as seen above.

So what are these manditory namespaces for?

Well, everything in a cursory search parrots what’s in the man page: the namespaces prevent clashes between attributes with the same name. Well, that’s not helpful. Generally speaking, that’s what namespaces are always for.

Maybe a better question would be why do the attributes have namespaces?

That’s mostly answered in the man page though I had to read the same thing stated different ways in places such as this Wikipedia page before I really got it: Extended attributes are often used by the OS itself to implement things such as the access control lists (ALCs). These are always prefixed with the system namespace. There are also security and trusted namespaces, but near as I can tell, these aren’t used by Slackware itself.

Interestingly, I tried to use getfattr to get the ACL info from my experiment with the acl package, but it wouldn’t show me anything, even when using the tool as root.

Then I found this Unix & Linux Stack Exchange answer to get SELinux security namespaced attribute listings. It turns out that getfattr, by default, uses a pattern to match only the user. prefix! To override this default, we can specify another pattern with the -m option, or use - as the pattern as a sort of wildcard to display all attributes regardless of namespace. Now I was able to see the ACL I’d set in my previous experiment:

$ getfattr -m - slippery-toots.txt
getfattr: Removing leading '/' from absolute path names
# file: slippery-toots.txt
system.posix_acl_access

And with root permissions, I could see the value as well:

$ sudo getfattr -m - slippery-toots.txt
getfattr: Removing leading '/' from absolute path names
# file: slippery-toots.txt
system.posix_acl_access=0sAgAAAAEABgD/////AgAGAOoDAAAEAAQA/////xAABgD/////IAAEAP////8=

I’ll go updated my acl entry now with a link to this finding.

User metadata: used in the wild?

Now we’ve seen definitively that this metadata is used by the system. But I’m curious if there is any widespread usage of the user. namespace?

Along with this question, I must mention that by default, tools like cp do not copy extended file attributes. So there is some danger in attaching too much importance to them!

Again, the Wikipedia page on extended file attributes was helpful in listing a handful of Linux applications which use user-space extended attributes. One that stuck out at me was Dropbox, which has a pretty obvious need for attaching metadata to files.

Wikipedia also pointed to the freedesktop.org Guidelines for extended attributes. Now this document is mostly just a recommendation, but it does contain three additional examples of current use:

  • user.mime_type - is part of another freedesktop.org recommendation which gives the impression that both GNOME and KDE (and ROX) use compatible formats in this attribute?
  • user.charset - specific to the mod_mime_xattr Apache module, which does not appear to ship with the Apache installation provided by Slackware
  • user.creator - used by the ROX Contact Manager in a completely proprietary and specific way that makes a valid argument for further namespacing application-specific attributes with a prefix as suggested by the freedesktop.org recommendation

The guidelines go on to recommend a series of user.xdg. prefixed attributes (such as user.xdg.comment) to be used as a standard and also lists the 15 "Simple" Dublin Core attributes (such as user.dublincore.title).

I actually like some of the proposed user.xdg.* metadata quite a bit because it allows you to figure out where a file came from (origin.url, origin.email.subject / origin.email.from, creator, and publisher) and add user annotations (comment) to be displayed by file managers.

At first I was put off by the length of some of these attribute names - surely dublincore could be shortened to dc? But I have to admit, the long names certainly prevent fighting over who owns the namespace. And the one thing guaranteed to make sure a standard never takes off would be such disagreements.

By the way, the ROX desktop mentioned above is new to me, but I do want to check it out at some point. I love the idea of treating the file system as a first-class principle on the desktop and I would really like to see how that pans out in practice.

For me, the biggest problem with relying on these metadata attributes at all is the fact that many core utilities don’t (by default) move or copy them when a file is moved or copied. Also, both the Linux kernel and coreutils can be compiled without support for xattr (these extended attributes).

Then again, many things can be compiled without options that I otherwise depend upon. I guess it really comes down to knowing your specific system and knowing its community so that you know the foundation upon which you’re building your skyscraper.

Libraries

I should also mention that packages like this also come with user-space libraries for accessing this functionality. So if you can link to the shared library, /lib64/libattr.so.1.1.0, you can write your own program to add, read, and remove extended attributes.

I think that about covers this package. Until next time, happy hacking!