summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-12-10 14:33:51 +0100
committerLudovic Courtès <ludo@gnu.org>2022-12-10 14:34:35 +0100
commit61b7e9687757aff013b99e4ab15669a950c8b222 (patch)
treef6cfc5888bd57f53bb206ff3b13efe3a7e84b36f
parent1ab48edb1674e0454d4368fdbed16cbbdfd9bf06 (diff)
downloadguix-61b7e9687757aff013b99e4ab15669a950c8b222.tar.gz
install: 'umount-cow-store' retries upon EBUSY.
Possibly fixes <https://issues.guix.gnu.org/59884>.

* gnu/build/install.scm (umount*): New procedure.
(unmount-cow-store): Use it instead of 'umount'.
-rw-r--r--gnu/build/install.scm23
1 files changed, 21 insertions, 2 deletions
diff --git a/gnu/build/install.scm b/gnu/build/install.scm
index 33a9616c0d..d4982650c1 100644
--- a/gnu/build/install.scm
+++ b/gnu/build/install.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013-2020, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
 ;;; Copyright © 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
@@ -282,12 +282,31 @@ disk."
     (mount "/.rw-store" (%store-directory) "" MS_MOVE)
     (rmdir "/.rw-store")))
 
+(define (umount* directory)
+  "Unmount DIRECTORY, but retry a few times upon EBUSY."
+  (let loop ((attempts 5))
+    (catch 'system-error
+      (lambda ()
+        (umount directory))
+      (lambda args
+        (if (and (= EBUSY (system-error-errno args))
+                 (> attempts 0))
+            (begin
+              (sleep 1)
+              (loop (- attempts 1)))
+            (apply throw args))))))
+
 (define (unmount-cow-store target backing-directory)
   "Unmount copy-on-write store."
   (let ((tmp-dir "/remove"))
     (mkdir-p tmp-dir)
     (mount (%store-directory) tmp-dir "" MS_MOVE)
-    (umount tmp-dir)
+
+    ;; We might get EBUSY at this point, possibly because of lingering
+    ;; processes with open file descriptors.  Use 'umount*' to retry upon
+    ;; EBUSY, leaving a bit of time.  See <https://issues.guix.gnu.org/59884>.
+    (umount* tmp-dir)
+
     (rmdir tmp-dir)
     (delete-file-recursively
      (string-append target backing-directory))))