If you spawn something like

  mkdir -p a
  mkdir -p a/b
  mkdir -p a/b/c

in parallel on a multiprocessor box, you will sometimes get an error
like "mkdir: a/b: File exists".

The whole point of mkdir(1)'s -p option is that this shouldn't
happen.

The problem was already fixed in revision 1.20 of src/bin/mkdir/mkdir.c.
Then Todd tweaked it in 1.21 to avoid breaking systrace policies,
but added back a race condition.

The diff below backs out the change from 1.21 and restores the
previous, more robust behavior.  Todd is fine with it.

Any comments from the people who actually use systrace?

--------
Index: mkdir.c
===================================================================
RCS file: /cvs/src/bin/mkdir/mkdir.c,v
retrieving revision 1.24
diff -u -p -r1.24 mkdir.c
--- mkdir.c     27 Oct 2009 23:59:22 -0000      1.24
+++ mkdir.c     1 Apr 2013 23:55:41 -0000
@@ -126,7 +126,7 @@ mkpath(char *path, mode_t mode, mode_t d
 {
        struct stat sb;
        char *slash;
-       int done, exists;
+       int done;
 
        slash = path;
 
@@ -137,19 +137,15 @@ mkpath(char *path, mode_t mode, mode_t d
                done = (*slash == '\0');
                *slash = '\0';
 
-               /* skip existing path components */
-               exists = !stat(path, &sb);
-               if (!done && exists && S_ISDIR(sb.st_mode)) {
-                       *slash = '/';
-                       continue;
-               }
-
                if (mkdir(path, done ? mode : dir_mode) == 0) {
                        if (mode > 0777 && chmod(path, mode) < 0)
                                return (-1);
                } else {
-                       if (!exists) {
-                               /* Not there */
+                       int mkdir_errno = errno;
+
+                       if (stat(path, &sb)) {
+                               /* Not there; use mkdir()s errno */
+                               errno = mkdir_errno;
                                return (-1);
                        }
                        if (!S_ISDIR(sb.st_mode)) {

-- 
Christian "naddy" Weisgerber                          na...@mips.inka.de

Reply via email to