Re: clone() <-> getpid() bug in 2.6?

Linus Torvalds
2004-06-06T16:57:41Z

On Sun, 6 Jun 2004, Erik Andersen wrote:
>
> http://sources.redhat.com/cgi-bin/cvsweb.cgi/~checkout~/libc/sysdeps/posix/tempname.c?rev=1.36&content-type=text/plain&cvsroot=glibc
>
> /* Get some more or less random data. */
> random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
> value += random_time_bits ^ __getpid ();

This one is historically at least a bit understandable: it's quite common
for various programs to create their lockfiles with the "unique"
identifier that is the pid of the locker. So the algorithm used to be
roughly (used by various things, ranging from tty subsystem locking to
whatever):

int fd, len;
int pid = getpid();

len = sprintf(name, "lockfile.%d", pid);
fd = open(name, O_EXCL | O_CREAT | O_WRONLY, 0644);
if (fd < 0) {
if (errno == EEXIST) {
fprintf(stderr, "Stale lockfile %s. Remove me\n", name);
exit(1); /* Or just "unlink + repeat" */
}
perror("lockfile");
exit(1);
}

/* Write the pid into the lockfile, fsync it */
write(fd, name + 9, len - 9);
fsync(fd);

/* Try to move it atomically */
while (rename("lockfile", name) < 0) {
if (errno != EEXIST) {
perror("lockfile");
exit(1);
}
/* Try again later */
sleep(1);
}

... We now have an exclusive lock ..

and here "pid" is in fact a good system-wide unique identifier. It's not
random, and it works badly with networked filesystems (which is why you'll
find versions of this algorithm that use the hostname in addition to the
pid too), but it's "obvious".

I think the original "mktemp()" also used to start off with "pid" as a
"unique" identifier. Because while it's not random, it _is_ system-wide
unique, so getpid() actually makes _sense_ in that respect.

In other words: getpid() makes little sense as a random value, but it does
make some sense as a unique value. Maybe less now than it did 20 years ago
due to the prevalence of networking, but history is powerful.

Linus