Extended attribute interfaces (fwd)

Robert Watson rwatson at FreeBSD.org
Sun Jun 18 23:40:41 GMT 2000


On Sun, 18 Jun 2000, Sean Eric Fagan wrote:

> >> I assume this would replace _all_ of the attributes?
> >Setting an attribute is an atomic replacement of the current attribute
> >vaue.  I.e., it's a lot like an environmental variable.  It can be
> >undefined, or defined.  If defined, it can have zero or more bytes of
> >data.  Setting the data replaces the current data, truncating at the
> >length of the replacement data.
> 
> That's what I thought... ugh.  It worries me.  Would a replace call be too
> hard to do?  (That is, it would work like setenv, and replace an existing,
> matching attribute, or add it if it doesn't exist.)
> 
> I never liked the way chmod(1) has to do a stat, change, and then a chmod(2)
> -- people can clobber themselves, that way, and I think this is more likely if
> you've got a very large ACL.

This race condition on chmod() also exists in the acl calls included in
POSIX.1e.  I raised this concern at the recent Capabilities workshop
(needless to say, the race condition also occurs in setting capabilities,
although that is supposed to be only an infrequent event).  For changing
mode, the easy answer is to have a modified chmod() call that sets a
precondition:

	chmod(target, old, new)

The syscall would guarantee atomicity, and only replace the old with the
new if old was the same as the current setting -- i.e., a test-and-set().
For ACLs and extended attributes, the cost of the "test" is fairly high
compared to the four-byte "old" retrieved from stat().  Another
possibility would be to approximate using some sort of versioning scheme
-- a "version number" for the attribute.  Each get() returns a version
number along with the data.  Each replace() accepts a version number, and
if it doesn't match the current, it fails.  A successful replace
increments the version number.  With a sufficiently scalable version
variable size, this would prevent races.  However, it's a little less
pleasing, but would provide atomicity on a get/set (or at least,
serializability).

I.e., something on the order of (pseudo-code):

  (data,version) = getextattr(target, name)

  error = setextattr(target, name, data, oldversion);

oldversion could be set to -1 if the caller did not care about replacement
atomicity.  For calls that result in modification of system attributes
(i.e., capability and ACL setting), similar changes would also have to be
made.

I guess the question to ask then is: which calls need atomicity?  Some,
such as setting capabilities on a process, don't need it as the process
can serialize the calls itself.

  Robert N M Watson 

robert at fledge.watson.org              http://www.watson.org/~robert/
PGP key fingerprint: AF B5 5F FF A6 4A 79 37  ED 5F 55 E9 58 04 6A B1
TIS Labs at Network Associates, Safeport Network Services

To Unsubscribe: send mail to majordomo at cyrus.watson.org
with "unsubscribe posix1e" in the body of the message



More information about the posix1e mailing list