21356: Remove all Python 2/3 compatibility imports
[arvados.git] / services / fuse / arvados_fuse / command.py
index 53e8c26fc7b40c20290a7442d371582edc4981e9..8004e8303f624eaa5acd17f616826b3197e92af7 100644 (file)
@@ -2,9 +2,6 @@
 #
 # SPDX-License-Identifier: AGPL-3.0
 
-from future.utils import native_str
-from builtins import range
-from builtins import object
 import argparse
 import arvados
 import daemon
@@ -50,8 +47,8 @@ class ArgumentParser(argparse.ArgumentParser):
             const='all',
             dest='mode',
             help="""
-Mount a subdirectory for each mode: home, shared, by_id, and by_tag
-(default if no --mount-* options are given)
+Mount a subdirectory for each mode: `home`, `shared`, `by_id`, and `by_tag`
+(default if no `--mount-*` options are given)
 """,
         )
         mode.add_argument(
@@ -60,8 +57,8 @@ Mount a subdirectory for each mode: home, shared, by_id, and by_tag
             const=None,
             dest='mode',
             help="""
-Mount a subdirectory for each mode specified by a --mount-* option
-(default if any --mount-* options are given;
+Mount a subdirectory for each mode specified by a `--mount-*` option
+(default if any `--mount-*` options are given;
 see "Mount custom layout and filtering" section)
 """,
         )
@@ -132,14 +129,14 @@ The JSON object should be a list of filters in Arvados API list filter syntax.
             metavar='PATH',
             action='append',
             default=[],
-            help="Make your home project available under the mount at PATH",
+            help="Make your home project available under the mount at `PATH`",
         )
         mounts.add_argument(
             '--mount-shared',
             metavar='PATH',
             action='append',
             default=[],
-            help="Make projects shared with you available under the mount at PATH",
+            help="Make projects shared with you available under the mount at `PATH`",
         )
         mounts.add_argument(
             '--mount-tmp',
@@ -147,7 +144,7 @@ The JSON object should be a list of filters in Arvados API list filter syntax.
             action='append',
             default=[],
             help="""
-Make a new temporary writable collection available under the mount at PATH.
+Make a new temporary writable collection available under the mount at `PATH`.
 This collection is deleted when the mount is unmounted.
 """,
         )
@@ -157,7 +154,7 @@ This collection is deleted when the mount is unmounted.
             action='append',
             default=[],
             help="""
-Make a magic directory available under the mount at PATH where collections and
+Make a magic directory available under the mount at `PATH` where collections and
 projects are accessible through subdirectories named after their UUID or
 portable data hash
 """,
@@ -168,7 +165,7 @@ portable data hash
             action='append',
             default=[],
             help="""
-Make a magic directory available under the mount at PATH where collections
+Make a magic directory available under the mount at `PATH` where collections
 are accessible through subdirectories named after portable data hash
 """,
         )
@@ -179,7 +176,7 @@ are accessible through subdirectories named after portable data hash
             default=[],
             help="""
 Make a subdirectory for each tag attached to a collection or project available
-under the mount at PATH
+under the mount at `PATH`
 """ ,
         )
 
@@ -211,10 +208,10 @@ under the mount at PATH
             dest="exec_args",
             help="""
 Mount data, run the specified command, then unmount and exit.
---exec reads all remaining options as the command to run,
+`--exec` reads all remaining options as the command to run,
 so it must be the last option you specify.
 Either end your command arguments (and other options) with a `--` argument,
-or specify --exec after your mount point.
+or specify `--exec` after your mount point.
 """,
         )
         lifecycle.add_argument(
@@ -235,7 +232,7 @@ or specify --exec after your mount point.
             help="""
 If a FUSE mount is already mounted at the given directory,
 unmount it before mounting the requested data.
-If --subtype is specified, unmount only if the mount has that subtype.
+If `--subtype` is specified, unmount only if the mount has that subtype.
 WARNING: This command can affect any kind of FUSE mount, not just arv-mount.
 """,
         )
@@ -245,7 +242,7 @@ WARNING: This command can affect any kind of FUSE mount, not just arv-mount.
             default=False,
             help="""
 If a FUSE mount is already mounted at the given directory, unmount it and exit.
-If --subtype is specified, unmount only if the mount has that subtype.
+If `--subtype` is specified, unmount only if the mount has that subtype.
 WARNING: This command can affect any kind of FUSE mount, not just arv-mount.
 """,
         )
@@ -255,7 +252,7 @@ WARNING: This command can affect any kind of FUSE mount, not just arv-mount.
             default=False,
             help="""
 Unmount all FUSE mounts at or below the given directory, then exit.
-If --subtype is specified, unmount only if the mount has that subtype.
+If `--subtype` is specified, unmount only if the mount has that subtype.
 WARNING: This command can affect any kind of FUSE mount, not just arv-mount.
 """,
         )
@@ -265,7 +262,7 @@ WARNING: This command can affect any kind of FUSE mount, not just arv-mount.
             default=2.0,
             metavar='SECONDS',
             help="""
-The number of seconds to wait for a clean unmount after an --exec command has
+The number of seconds to wait for a clean unmount after an `--exec` command has
 exited (default %(default).01f).
 After this time, the mount will be forcefully unmounted.
 """,
@@ -308,7 +305,7 @@ After this time, the mount will be forcefully unmounted.
         cache.add_argument(
             '--disk-cache-dir',
             metavar="DIRECTORY",
-            help="Filesystem cache location (default ~/.cache/arvados/keep)",
+            help="Filesystem cache location (default `~/.cache/arvados/keep`)",
         )
         cache.add_argument(
             '--directory-cache',
@@ -349,7 +346,15 @@ Filesystem character encoding
             metavar='CLASSES',
             help="Comma-separated list of storage classes to request for new collections",
         )
-
+        # This is a hidden argument used by tests.  Normally this
+        # value will be extracted from the cluster config, but mocking
+        # the cluster config under the presence of multiple threads
+        # and processes turned out to be too complicated and brittle.
+        plumbing.add_argument(
+            '--fsns',
+            type=str,
+            default=None,
+            help=argparse.SUPPRESS)
 
 class Mount(object):
     def __init__(self, args, logger=logging.getLogger('arvados.arv-mount')):
@@ -402,7 +407,7 @@ class Mount(object):
         if self.args.replace:
             unmount(path=self.args.mountpoint,
                     timeout=self.args.unmount_timeout)
-        llfuse.init(self.operations, native_str(self.args.mountpoint), self._fuse_options())
+        llfuse.init(self.operations, str(self.args.mountpoint), self._fuse_options())
         if self.daemon:
             daemon.DaemonContext(
                 working_directory=os.path.dirname(self.args.mountpoint),
@@ -482,13 +487,6 @@ class Mount(object):
                                                       disk_cache=self.args.disk_cache,
                                                       disk_cache_dir=self.args.disk_cache_dir)
 
-            # If there's too many prefetch threads and you
-            # max out the CPU, delivering data to the FUSE
-            # layer actually ends up being slower.
-            # Experimentally, capping 7 threads seems to
-            # be a sweet spot.
-            prefetch_threads = min(max((block_cache.cache_max // (64 * 1024 * 1024)) - 1, 1), 7)
-
             self.api = arvados.safeapi.ThreadSafeApiCache(
                 apiconfig=arvados.config.settings(),
                 api_params={
@@ -496,7 +494,6 @@ class Mount(object):
                 },
                 keep_params={
                     'block_cache': block_cache,
-                    'num_prefetch_threads': prefetch_threads,
                     'num_retries': self.args.retries,
                 },
                 version='v1',
@@ -514,7 +511,8 @@ class Mount(object):
             api_client=self.api,
             encoding=self.args.encoding,
             inode_cache=InodeCache(cap=self.args.directory_cache),
-            enable_write=self.args.enable_write)
+            enable_write=self.args.enable_write,
+            fsns=self.args.fsns)
 
         if self.args.crunchstat_interval:
             statsthread = threading.Thread(
@@ -603,7 +601,6 @@ class Mount(object):
         e = self.operations.inodes.add_entry(Directory(
             llfuse.ROOT_INODE,
             self.operations.inodes,
-            self.api.config,
             self.args.enable_write,
             self.args.filters,
         ))
@@ -688,8 +685,9 @@ From here, the following directories are available:
 
     def _llfuse_main(self):
         try:
-            llfuse.main()
+            llfuse.main(workers=10)
         except:
             llfuse.close(unmount=False)
             raise
+        self.operations.begin_shutdown()
         llfuse.close()