9fans archive / 1998 / 02 / 17 /    prev next

From: G. David Butler gdb@dbS...
Subject: [9fans] create(2)/open(2) race for file creation
Date: Sat, 7 Feb 1998 18:27:03 -0600

What is the best way for many processes to race for a file create
with only one winner?

In /sys/src/9/port/chan.c we have in namec():

/*
 * protect against the open/create race.  This is not a complete
 * fix.  It just reduces the window.
 */

In man open(5) the algorithm for create(2) is:
if walk(5) is good {
	return open(5, OTRUNC)
} else {
	if ret = create(5) is good {
		return ret
	} else {
		return open(5, OTRUNC)
	}
}

The first idea would be to stat(2) the file and if that fails
then create(2) (That is what ape does), but if the second process
stats before the first creates... NOT!

Using the fact that one can create a file O_WRITE with permissions
that do not allow writing, one can use a stat(2), create(2, mode 0),
chmod(2) sequence as long as the amout of time between the create and
the chmod are "long enough" for the other process... NOT!

One could create the file with CHEXCL then clear the flag later
as long as you wait "long enough" for the other process to create(2)
after the stat(2)... NOT!

It would seem that what is needed is the old *NIX O_EXCL flag.

Another alternative would be to change create(2) to simply call
create(5) and return the results.  There will need to be some
cleanup of programs that assume that a create on a existing file
is OK, but if that is the case it is easy to change:

if ((fd = create(file, mode, perm)) < 0) {
	error...
}

to:

if ((fd = create(file, mode, perm)) < 0 ||
    (fd = open(file, mode|OTRUNC) < 0)) {
	error...
}

In those programs.

Any comments?

David Butler
gdb@dbS...