[ARVADOS] updated: 5752685c137c5e37e13845f5328e9a3930fa3100
Git user
git at public.curoverse.com
Fri Mar 17 16:32:21 EDT 2017
Summary of changes:
services/fuse/arvados_fuse/command.py | 6 ++--
services/fuse/arvados_fuse/unmount.py | 55 +++++++++++++++++++++++++++++------
2 files changed, 49 insertions(+), 12 deletions(-)
via 5752685c137c5e37e13845f5328e9a3930fa3100 (commit)
from c733e426aaa4581c266aef15add3cc70c54061dd (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 5752685c137c5e37e13845f5328e9a3930fa3100
Author: Tom Clegg <tom at curoverse.com>
Date: Fri Mar 17 16:32:10 2017 -0400
11209: "--unmount /path/..." unmounts /path and all fuse mounts below it.
diff --git a/services/fuse/arvados_fuse/command.py b/services/fuse/arvados_fuse/command.py
index c9a090c..883af36 100644
--- a/services/fuse/arvados_fuse/command.py
+++ b/services/fuse/arvados_fuse/command.py
@@ -91,9 +91,9 @@ class ArgumentParser(argparse.ArgumentParser):
self.add_argument('--crunchstat-interval', type=float, help="Write stats to stderr every N seconds (default disabled)", default=0)
self.add_argument('--unmount', action='store_true', default=False,
- help="Forcefully unmount the specified mountpoint (if it's a fuse mount) and exit")
+ help="Forcefully unmount the specified mountpoint (if it's a fuse mount) and exit. Use /path/... to unmount all fuse mounts below /path as well as /path itself.")
self.add_argument('--replace', action='store_true', default=False,
- help="Forcefully unmount any existing fuse mount before mounting")
+ help="If a fuse mount is already present at mountpoint, forcefully unmount it before mounting")
self.add_argument('--unmount-timeout',
type=float, default=2.0,
help="Time to wait for graceful shutdown after --exec program exits and filesystem is unmounted")
@@ -146,7 +146,7 @@ class Mount(object):
def run(self):
if self.args.unmount:
- unmount(self.args.mountpoint, timeout=self.args.unmount_timeout)
+ unmount_all(self.args.mountpoint, timeout=self.args.unmount_timeout)
elif self.args.exec_args:
self._run_exec()
else:
diff --git a/services/fuse/arvados_fuse/unmount.py b/services/fuse/arvados_fuse/unmount.py
index 8be549e..ab5ce4f 100644
--- a/services/fuse/arvados_fuse/unmount.py
+++ b/services/fuse/arvados_fuse/unmount.py
@@ -1,8 +1,49 @@
+import collections
import errno
import os
import subprocess
import time
+
+MountInfo = collections.namedtuple(
+ 'MountInfo', ['is_fuse', 'major', 'minor', 'mnttype', 'path'])
+
+
+def mountinfo():
+ mi = []
+ with open('/proc/self/mountinfo') as f:
+ for m in f.readlines():
+ mntid, pmntid, dev, root, path, extra = m.split(" ", 5)
+ mnttype = extra.split(" - ")[1].split(" ", 1)[0]
+ major, minor = dev.split(":")
+ mi.append(MountInfo(
+ is_fuse=(mnttype == "fuse" or mnttype.startswith("fuse.")),
+ major=major,
+ minor=minor,
+ mnttype=mnttype,
+ path=path,
+ ))
+ return mi
+
+
+def unmount_all(path, timeout=10):
+ if not path.endswith("/..."):
+ return unmount(path, timeout=timeout)
+ root = os.path.realpath(path[:-4])
+
+ paths = []
+ for m in mountinfo():
+ if m.path == root or m.path.startswith(root+"/"):
+ paths.append(m.path)
+ if not m.is_fuse:
+ raise Exception(
+ "cannot unmount {}: non-fuse mountpoint {}".format(
+ path, m))
+ for path in sorted(paths, key=len, reverse=True):
+ unmount(path, timeout=timeout)
+ return len(paths) > 0
+
+
def unmount(path, timeout=10):
"""Unmount the fuse mount at path.
@@ -28,14 +69,10 @@ def unmount(path, timeout=10):
raise Exception("timed out")
mounted = False
- with open('/proc/self/mountinfo') as mi:
- for m in mi.readlines():
- mntid, pmntid, dev, root, mnt, extra = m.split(" ", 5)
- mnttype = extra.split(" - ")[1].split(" ")[0]
- if not (mnttype == "fuse" or mnttype.startswith("fuse.")):
- continue
+ for m in mountinfo():
+ if m.is_fuse:
try:
- if os.path.realpath(mnt) == path:
+ if os.path.realpath(m.path) == path:
was_mounted = True
mounted = True
break
@@ -44,9 +81,9 @@ def unmount(path, timeout=10):
if not mounted:
return was_mounted
- major, minor = dev.split(":")
try:
- with open('/sys/fs/fuse/connections/'+str(minor)+'/abort', 'w') as f:
+ with open('/sys/fs/fuse/connections/{}/abort'.format(m.minor),
+ 'w') as f:
f.write("1")
except OSError as e:
if e.errno != errno.ENOENT:
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list