lib/repo: Verify txn stagedir existence after locking
authorColin Walters <walters@verbum.org>
Tue, 28 Nov 2017 18:03:00 +0000 (13:03 -0500)
committerAtomic Bot <atomic-devel@projectatomic.io>
Fri, 1 Dec 2017 19:00:18 +0000 (19:00 +0000)
This squashes the last race condition I was actively hitting while running
`test-concurrency.py` in a loop. The race is when process A finds a tmpdir to
reuse, and goes to lock it. Meanwhile process B deletes it and unlocks the lock.
Process A then succeeds at grabbing a lock, but the tmpdir is deleted.

Closes: #1352
Approved by: dbnicholson

src/libostree/ostree-repo.c

index 6e3421256145ab6ed7a6d4499860e65878833864..afd56e4c6f4a03ebe3c26aa0e16d1fb39f9902fc 100644 (file)
@@ -4904,7 +4904,16 @@ _ostree_repo_try_lock_tmpdir (int            tmpdir_dfd,
     }
   else
     {
-      did_lock = TRUE;
+      /* It's possible that we got a lock after seeing the directory, but
+       * another process deleted the tmpdir, so verify it still exists.
+       */
+      struct stat stbuf;
+      if (!glnx_fstatat_allow_noent (tmpdir_dfd, tmpdir_name, &stbuf, AT_SYMLINK_NOFOLLOW, error))
+        return FALSE;
+      if (errno == 0 && S_ISDIR (stbuf.st_mode))
+        did_lock = TRUE;
+      else
+        glnx_release_lock_file (file_lock_out);
     }
 
   *out_did_lock = did_lock;