Merge branch '15317-metrics'
[arvados.git] / services / fuse / arvados_fuse / unmount.py
index a72da3a8dcae93a0699cf79f4e0d65c97438ce03..144c582ddce52017ad14f47e660a9584f086b84c 100644 (file)
@@ -6,6 +6,7 @@ import collections
 import errno
 import os
 import subprocess
+import sys
 import time
 
 
@@ -116,6 +117,7 @@ def unmount(path, subtype=None, timeout=10, recursive=False):
 
     was_mounted = False
     attempted = False
+    fusermount_output = b''
     if timeout is None:
         deadline = None
     else:
@@ -152,9 +154,23 @@ def unmount(path, subtype=None, timeout=10, recursive=False):
             path = os.path.realpath(path)
             continue
         elif not mounted:
+            if was_mounted:
+                # This appears to avoid a race condition where we
+                # return control to the caller after running
+                # "fusermount -u -z" (see below), the caller (e.g.,
+                # arv-mount --replace) immediately tries to attach a
+                # new fuse mount at the same mount point, the
+                # lazy-unmount process unmounts that _new_ mount while
+                # it is being initialized, and the setup code waits
+                # forever for the new mount to be initialized.
+                time.sleep(1)
             return was_mounted
 
         if attempted:
+            # Report buffered stderr from previous call to fusermount,
+            # now that we know it didn't succeed.
+            sys.stderr.buffer.write(fusermount_output)
+
             delay = 1
             if deadline:
                 delay = min(delay, deadline - time.time())
@@ -172,6 +188,10 @@ def unmount(path, subtype=None, timeout=10, recursive=False):
 
         attempted = True
         try:
-            subprocess.check_call(["fusermount", "-u", "-z", path])
-        except subprocess.CalledProcessError:
-            pass
+            subprocess.check_output(
+                ["fusermount", "-u", "-z", path],
+                stderr=subprocess.STDOUT)
+        except subprocess.CalledProcessError as e:
+            fusermount_output = e.output
+        else:
+            fusermount_output = b''