[ARVADOS] updated: c733e426aaa4581c266aef15add3cc70c54061dd
Git user
git at public.curoverse.com
Thu Mar 16 16:49:53 EDT 2017
Summary of changes:
services/fuse/arvados_fuse/command.py | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
discards 9a7d92434f19ca790be65685502a3fc3f651a510 (commit)
via c733e426aaa4581c266aef15add3cc70c54061dd (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (9a7d92434f19ca790be65685502a3fc3f651a510)
\
N -- N -- N (c733e426aaa4581c266aef15add3cc70c54061dd)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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 c733e426aaa4581c266aef15add3cc70c54061dd
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Mar 16 16:49:49 2017 -0400
11209: Add arv-mount --unmount and --replace flags
diff --git a/services/fuse/arvados_fuse/command.py b/services/fuse/arvados_fuse/command.py
index 66f8a4d..c9a090c 100644
--- a/services/fuse/arvados_fuse/command.py
+++ b/services/fuse/arvados_fuse/command.py
@@ -90,6 +90,10 @@ 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")
+ self.add_argument('--replace', action='store_true', default=False,
+ help="Forcefully unmount any existing fuse mount 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")
@@ -118,6 +122,8 @@ class Mount(object):
exit(1)
def __enter__(self):
+ if self.args.replace:
+ unmount(self.args.mountpoint, timeout=self.args.unmount_timeout)
llfuse.init(self.operations, self.args.mountpoint, self._fuse_options())
if self.listen_for_events and not self.args.disable_event_listening:
self.operations.listen_for_events()
@@ -139,7 +145,9 @@ class Mount(object):
self.args.unmount_timeout)
def run(self):
- if self.args.exec_args:
+ if self.args.unmount:
+ unmount(self.args.mountpoint, timeout=self.args.unmount_timeout)
+ elif self.args.exec_args:
self._run_exec()
else:
self._run_standalone()
diff --git a/services/fuse/arvados_fuse/unmount.py b/services/fuse/arvados_fuse/unmount.py
new file mode 100644
index 0000000..8be549e
--- /dev/null
+++ b/services/fuse/arvados_fuse/unmount.py
@@ -0,0 +1,61 @@
+import errno
+import os
+import subprocess
+import time
+
+def unmount(path, timeout=10):
+ """Unmount the fuse mount at path.
+
+ Unmounting is done by writing 1 to the "abort" control file in
+ sysfs to kill the fuse driver process, then executing "fusermount
+ -u -z" to detach the mount point, and repeating these steps until
+ the mount is no longer listed in /proc/self/mountinfo.
+
+ This procedure should enable a non-root user to reliably unmount
+ their own fuse filesystem without risk of deadlock.
+
+ Returns True if unmounting was successful, False if it wasn't a
+ fuse mount at all. Raises an exception if it cannot be unmounted.
+ """
+
+ path = os.path.realpath(path)
+
+ was_mounted = False
+ t0 = time.time()
+ delay = 0
+ while True:
+ if timeout and t0 + timeout < time.time():
+ 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
+ try:
+ if os.path.realpath(mnt) == path:
+ was_mounted = True
+ mounted = True
+ break
+ except OSError:
+ continue
+ if not mounted:
+ return was_mounted
+
+ major, minor = dev.split(":")
+ try:
+ with open('/sys/fs/fuse/connections/'+str(minor)+'/abort', 'w') as f:
+ f.write("1")
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ try:
+ subprocess.check_call(["fusermount", "-u", "-z", path])
+ except subprocess.CalledProcessError:
+ pass
+
+ time.sleep(delay)
+ if delay == 0:
+ delay = 1
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list