From 2716c98ce9a5870ef425ff7c151bd5e977781ab4 Mon Sep 17 00:00:00 2001 From: Rishabh Dave Date: Thu, 15 Oct 2020 12:18:50 +0530 Subject: [PATCH] vstart_runner: reuse FuseMount methods in LocalFuseMount Signed-off-by: Rishabh Dave --- qa/tasks/vstart_runner.py | 166 +++++++++++--------------------------- 1 file changed, 46 insertions(+), 120 deletions(-) diff --git a/qa/tasks/vstart_runner.py b/qa/tasks/vstart_runner.py index 37ca57e5ece..3d593181b1b 100644 --- a/qa/tasks/vstart_runner.py +++ b/qa/tasks/vstart_runner.py @@ -687,6 +687,52 @@ class LocalFuseMount(FuseMount): client_remote=LocalRemote(), hostfs_mntpt=hostfs_mntpt, cephfs_name=cephfs_name, cephfs_mntpt=cephfs_mntpt, brxnet=brxnet) + # Following block makes tests meant for teuthology compatible with + # vstart_runner. + self._mount_bin = [os.path.join(BIN_PREFIX, 'ceph-fuse')] + self._mount_cmd_cwd, self._mount_cmd_logger, \ + self._mount_cmd_stdin = None, None, None + + def setup_netns(self): + if opt_use_ns: + super(type(self), self).setup_netns() + + def _create_mntpt(self, cwd=None): + stderr = StringIO() + script = f'mkdir -p -v {self.hostfs_mntpt}'.split() + try: + self.client_remote.run(args=script, cwd=self.test_dir, + stderr=stderr) + except CommandFailedError: + if 'file exists' not in stderr.getvalue().lower(): + raise + + def _run_mount_cmd(self, mntopts, check_status): + super(type(self), self)._run_mount_cmd(mntopts, check_status) + self._set_fuse_daemon_pid(check_status) + + def _get_mount_cmd(self, mntopts): + mount_cmd = super(type(self), self)._get_mount_cmd(mntopts) + + if os.getuid() != 0: + mount_cmd += ['--client_die_on_failed_dentry_invalidate=false'] + + return mount_cmd + + @property + def _nsenter_args(self): + if opt_use_ns: + return super(type(self), self)._nsenter_args + else: + return [] + + @property + def _fuse_conn_check_timeout(self): + return 30 + + def _add_valgrind_args(self, mount_cmd): + return [] + @property def config_path(self): return "./ceph.conf" @@ -696,15 +742,6 @@ class LocalFuseMount(FuseMount): # to avoid assumptions about daemons' pwd return os.path.abspath("./client.{0}.keyring".format(self.client_id)) - def setupfs(self, name=None): - if name is None and self.fs is not None: - # Previous mount existed, reuse the old name - name = self.fs.name - self.fs = LocalFilesystem(self.ctx, name=name) - log.debug('Wait for MDS to reach steady state...') - self.fs.wait_for_daemons() - log.debug('Ready to start {}...'.format(type(self).__name__)) - @property def _prefix(self): return BIN_PREFIX @@ -729,113 +766,6 @@ class LocalFuseMount(FuseMount): path = "{0}/client.{1}.*.asok".format(d, self.client_id) return path - def mount(self, mntopts=[], check_status=True, **kwargs): - self.update_attrs(**kwargs) - self.assert_and_log_minimum_mount_details() - - if opt_use_ns: - self.using_namespace = True - self.setup_netns() - else: - self.using_namespace = False - - stderr = StringIO() - try: - self.client_remote.run(args=['mkdir', '-p', self.hostfs_mntpt], - stderr=stderr) - except CommandFailedError: - if 'file exists' not in stderr.getvalue().lower(): - raise - - def list_connections(): - self.client_remote.run( - args=["mount", "-t", "fusectl", "/sys/fs/fuse/connections", "/sys/fs/fuse/connections"], - check_status=False - ) - - p = self.client_remote.run(args=["ls", "/sys/fs/fuse/connections"], - check_status=False, stdout=StringIO()) - if p.exitstatus != 0: - log.warning("ls conns failed with {0}, assuming none".format(p.exitstatus)) - return [] - - ls_str = p.stdout.getvalue().strip() - if ls_str: - return [int(n) for n in ls_str.split("\n")] - else: - return [] - - # Before starting ceph-fuse process, note the contents of - # /sys/fs/fuse/connections - pre_mount_conns = list_connections() - log.debug("Pre-mount connections: {0}".format(pre_mount_conns)) - - cmdargs = [] - if self.using_namespace: - cmdargs = ['sudo', 'nsenter', - '--net=/var/run/netns/{0}'.format(self.netns_name), - '--setuid', str(os.getuid())] - cmdargs += [os.path.join(BIN_PREFIX, 'ceph-fuse'), self.hostfs_mntpt, - '-f'] - if self.client_id is not None: - cmdargs += ["--id", self.client_id] - if self.client_keyring_path and self.client_id is not None: - cmdargs.extend(['-k', self.client_keyring_path]) - if self.cephfs_name: - cmdargs += ["--client_fs=" + self.cephfs_name] - if self.cephfs_mntpt: - cmdargs += ["--client_mountpoint=" + self.cephfs_mntpt] - if os.getuid() != 0: - cmdargs += ["--client_die_on_failed_dentry_invalidate=false"] - if mntopts: - cmdargs += mntopts - - mountcmd_stdout, mountcmd_stderr = StringIO(), StringIO() - self.fuse_daemon = self.client_remote.run(args=cmdargs, wait=False, - omit_sudo=False, stdout=mountcmd_stdout, stderr=mountcmd_stderr) - self._set_fuse_daemon_pid(check_status) - log.debug("Mounting client.{0} with pid " - "{1}".format(self.client_id, self.fuse_daemon.subproc.pid)) - - # Wait for the connection reference to appear in /sys - waited = 0 - post_mount_conns = list_connections() - while len(post_mount_conns) <= len(pre_mount_conns): - if self.fuse_daemon.finished: - # Did mount fail? Raise the CommandFailedError instead of - # hitting the "failed to populate /sys/" timeout - try: - self.fuse_daemon.wait() - except CommandFailedError as e: - if check_status: - raise - else: - return (e, mountcmd_stdout.getvalue(), - mountcmd_stderr.getvalue()) - time.sleep(1) - waited += 1 - if waited > 30: - raise RuntimeError("Fuse mount failed to populate /sys/ after {0} seconds".format( - waited - )) - post_mount_conns = list_connections() - - log.debug("Post-mount connections: {0}".format(post_mount_conns)) - - # Record our fuse connection number so that we can use it when - # forcing an unmount - new_conns = list(set(post_mount_conns) - set(pre_mount_conns)) - if len(new_conns) == 0: - raise RuntimeError("New fuse connection directory not found ({0})".format(new_conns)) - elif len(new_conns) > 1: - raise RuntimeError("Unexpectedly numerous fuse connections {0}".format(new_conns)) - else: - self._fuse_conn = new_conns[0] - - self.gather_mount_info() - - self.mounted = True - def _set_fuse_daemon_pid(self, check_status): # NOTE: When a command is launched with sudo, two processes are # launched, one with sudo in and other without. Make sure we @@ -857,10 +787,6 @@ class LocalFuseMount(FuseMount): else: pass - def cleanup_netns(self): - if self.using_namespace: - super(type(self), self).cleanup_netns() - def _run_python(self, pyscript, py_version='python'): """ Override this to remove the daemon-helper prefix that is used otherwise -- 2.39.5