log = logging.getLogger(__name__)
-
# Refer mount.py for docstrings.
class FuseMount(CephFSMount):
def __init__(self, ctx, client_config, test_dir, client_id,
self.inst = None
self.addr = None
- def mount(self, mntopts=[], createfs=True, **kwargs):
+ def mount(self, mntopts=[], createfs=True, check_status=True, **kwargs):
self.update_attrs(**kwargs)
self.assert_and_log_minimum_mount_details()
self.setupfs(name=self.cephfs_name)
try:
- return self._mount(mntopts)
+ return self._mount(mntopts, check_status)
except RuntimeError:
# Catch exceptions by the mount() logic (i.e. not remote command
# failures) and ensure the mount is not left half-up.
self.umount_wait(force=True)
raise
- def _mount(self, mntopts):
+ def _mount(self, mntopts, check_status):
log.info("Client client.%s config is %s" % (self.client_id,
self.client_config))
pre_mount_conns = list_connections()
log.info("Pre-mount connections: {0}".format(pre_mount_conns))
- proc = self.client_remote.run(
+ mountcmd_stdout, mountcmd_stderr = StringIO(), StringIO()
+ self.fuse_daemon = self.client_remote.run(
args=run_cmd,
cwd=cwd,
logger=log.getChild('ceph-fuse.{id}'.format(id=self.client_id)),
stdin=run.PIPE,
- wait=False,
+ stdout=mountcmd_stdout,
+ stderr=mountcmd_stderr,
+ wait=False
)
- self.fuse_daemon = proc
# Wait for the connection reference to appear in /sys
mount_wait = self.client_config.get('mount_wait', 0)
if self.fuse_daemon.finished:
# Did mount fail? Raise the CommandFailedError instead of
# hitting the "failed to populate /sys/" timeout
- self.fuse_daemon.wait()
+ try:
+ self.fuse_daemon.wait()
+ except CommandFailedError as e:
+ log.info('mount command failed.')
+ if check_status:
+ raise
+ else:
+ return (e, mountcmd_stdout.getvalue(),
+ mountcmd_stderr.getvalue())
time.sleep(1)
waited += 1
if waited > timeout:
- raise RuntimeError("Fuse mount failed to populate /sys/ after {0} seconds".format(
- waited
- ))
+ raise RuntimeError(
+ "Fuse mount failed to populate/sys/ after {} "
+ "seconds".format(waited))
else:
post_mount_conns = list_connections()
client_keyring_path=client_keyring_path, hostfs_mntpt=hostfs_mntpt,
cephfs_name=cephfs_name, cephfs_mntpt=cephfs_mntpt, brxnet=brxnet)
- def mount(self, mntopts=[], createfs=True, **kwargs):
+ def mount(self, mntopts=[], createfs=True, check_status=True, **kwargs):
self.update_attrs(**kwargs)
self.assert_and_log_minimum_mount_details()
if 'file exists' not in stderr.getvalue().lower():
raise
- opts = 'name=' + self.client_id
- if self.client_keyring_path and self.client_id is not None:
- opts += 'secret=' + self.get_key_from_keyfile()
- opts += ',norequire_active_mds,conf=' + self.config_path
+ retval = self._run_mount_cmd(mntopts, check_status)
+ if retval:
+ return retval
- if self.cephfs_name is not None:
- opts += ",mds_namespace={0}".format(self.cephfs_name)
+ self.client_remote.run(
+ args=['sudo', 'chmod', '1777', self.hostfs_mntpt], timeout=(5*60))
+
+ self.mounted = True
+ def _run_mount_cmd(self, mntopts, check_status):
+ opts = 'norequire_active_mds,'
+ if self.client_id:
+ opts += 'name=' + self.client_id
+ if self.client_keyring_path and self.client_id:
+ opts += ',secret=' + self.get_key_from_keyfile()
+ if self.config_path:
+ opts += ',conf=' + self.config_path
+ if self.cephfs_name:
+ opts += ",mds_namespace=" + self.cephfs_name
if mntopts:
opts += ',' + ','.join(mntopts)
- self.client_remote.run(
- args=[
- 'sudo',
- 'adjust-ulimits',
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=self.test_dir),
- 'nsenter',
- '--net=/var/run/netns/{0}'.format(self.netns_name),
- '/bin/mount',
- '-t',
- 'ceph',
- ':' + self.cephfs_mntpt,
- self.hostfs_mntpt,
- '-v',
- '-o',
- opts
- ],
- timeout=(30*60),
- )
+ mount_dev = ':' + self.cephfs_mntpt
+ prefix = ['sudo', 'adjust-ulimits', 'ceph-coverage',
+ self.test_dir + '/archive/coverage',
+ 'nsenter',
+ '--net=/var/run/netns/{0}'.format(self.netns_name)]
+ cmdargs = prefix + ['/bin/mount', '-t', 'ceph', mount_dev,
+ self.hostfs_mntpt, '-v', '-o', opts]
- self.client_remote.run(
- args=['sudo', 'chmod', '1777', self.hostfs_mntpt], timeout=(5*60))
-
- self.mounted = True
+ mountcmd_stdout, mountcmd_stderr = StringIO(), StringIO()
+ try:
+ self.client_remote.run(args=cmdargs, timeout=(30*60),
+ stdout=mountcmd_stdout,
+ stderr=mountcmd_stderr)
+ except CommandFailedError as e:
+ log.info('mount command failed')
+ if check_status:
+ raise
+ else:
+ return (e, mountcmd_stdout.getvalue(),
+ mountcmd_stderr.getvalue())
+ log.info('mount command passed')
def umount(self, force=False):
if not self.is_mounted():
args = ['sudo', 'ip', 'link', 'set', 'brx.{0}'.format(self.nsid), 'up']
self.client_remote.run(args=args, timeout=(5*60), omit_sudo=False)
- def mount(self, mntopts=[], createfs=True, **kwargs):
+ def mount(self, mntopts=[], createfs=True, check_status=True, **kwargs):
"""
kwargs expects its members to be same as the arguments accepted by
self.update_attrs().
mntopts = kwargs.pop('mntopts', [])
createfs = kwargs.pop('createfs', False)
+ check_status = kwargs.pop('check_status', True)
wait = kwargs.pop('wait', True)
self.update_attrs(**kwargs)
- retval = self.mount(mntopts=mntopts, createfs=createfs)
+ retval = self.mount(mntopts=mntopts, createfs=createfs,
+ check_status=check_status)
# avoid this scenario (again): mount command might've failed and
# check_status might have silenced the exception, yet we attempt to
# wait which might lead to an error.
import sys
import errno
from IPy import IP
-from unittest import suite, loader
import unittest
import platform
+import logging
+
+from unittest import suite, loader
+
from teuthology.orchestra.run import Raw, quote
from teuthology.orchestra.daemon import DaemonGroup
from teuthology.orchestra.remote import Remote
from teuthology.config import config as teuth_config
from teuthology.contextutil import safe_while
from teuthology.contextutil import MaxWhileTries
-import logging
+from teuthology.orchestra.run import CommandFailedError
def init_log():
global log
try:
- from teuthology.exceptions import CommandFailedError
from tasks.ceph_manager import CephManager
from tasks.cephfs.fuse_mount import FuseMount
from tasks.cephfs.kernel_mount import KernelMount
path = "{0}/client.{1}.*.asok".format(d, self.client_id)
return path
- def mount(self, mntopts=[], createfs=True, **kwargs):
+ def mount(self, mntopts=[], createfs=True, check_status=True, **kwargs):
self.update_attrs(**kwargs)
self.assert_and_log_minimum_mount_details()
if createfs:
self.setupfs(name=self.cephfs_name)
- opts = 'name=' + self.client_id
- if self.client_keyring_path:
+ opts = 'norequire_active_mds'
+ if self.client_id:
+ opts += ',name=' + self.client_id
+ if self.client_keyring_path and self.client_id:
opts += ",secret=" + self.get_key_from_keyfile()
- opts += ',norequire_active_mds,conf=' + self.config_path
- if self.cephfs_name is not None:
+ if self.config_path:
+ opts += ',conf=' + self.config_path
+ if self.cephfs_name:
opts += ",mds_namespace={0}".format(self.cephfs_name)
if mntopts:
opts += ',' + ','.join(mntopts)
if 'file exists' not in stderr.getvalue().lower():
raise
+ if self.cephfs_mntpt is None:
+ self.cephfs_mntpt = "/"
cmdargs = ['sudo']
if self.using_namespace:
cmdargs += ['nsenter',
'--net=/var/run/netns/{0}'.format(self.netns_name)]
cmdargs += ['./bin/mount.ceph', ':' + self.cephfs_mntpt,
self.hostfs_mntpt, '-v', '-o', opts]
- self.client_remote.run(args=cmdargs, timeout=(30*60), omit_sudo=False)
+
+ mountcmd_stdout, mountcmd_stderr = StringIO(), StringIO()
+ try:
+ self.client_remote.run(args=cmdargs, timeout=(30*60),
+ omit_sudo=False, stdout=mountcmd_stdout,
+ stderr=mountcmd_stderr)
+ except CommandFailedError as e:
+ if check_status:
+ raise
+ else:
+ return (e, mountcmd_stdout.getvalue(),
+ mountcmd_stderr.getvalue())
self.client_remote.run(args=['sudo', 'chmod', '1777',
self.hostfs_mntpt], timeout=(5*60))
-
self.mounted = True
def cleanup_netns(self):
path = "{0}/client.{1}.*.asok".format(d, self.client_id)
return path
- def mount(self, mntopts=[], createfs=True, **kwargs):
+ def mount(self, mntopts=[], createfs=True, check_status=True, **kwargs):
self.update_attrs(**kwargs)
self.assert_and_log_minimum_mount_details()
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_mds_namespace=" + self.cephfs_name]
+ cmdargs += ["--client_fs=" + self.cephfs_name]
if self.cephfs_mntpt:
- cmdargs += ["--client_fs=" + 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)
- self._set_fuse_daemon_pid()
+ omit_sudo=False, stdout=mountcmd_stdout, stderr=mountcmd_stderr)
+ self._set_fuse_daemon_pid(check_status)
log.info("Mounting client.{0} with pid "
"{1}".format(self.client_id, self.fuse_daemon.subproc.pid))
if self.fuse_daemon.finished:
# Did mount fail? Raise the CommandFailedError instead of
# hitting the "failed to populate /sys/" timeout
- self.fuse_daemon.wait()
+ 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:
self.mounted = True
- def _set_fuse_daemon_pid(self):
+ def _set_fuse_daemon_pid(self, check_status):
# NOTE: When a command <args> is launched with sudo, two processes are
# launched, one with sudo in <args> and other without. Make sure we
# get the PID of latter one.
- with safe_while(sleep=1, tries=15) as proceed:
- while proceed():
- try:
- sock = self.find_admin_socket()
- except (RuntimeError, CommandFailedError):
- continue
-
- self.fuse_daemon.fuse_pid = int(re.match(".*\.(\d+)\.asok$",
- sock).group(1))
- break
+ try:
+ with safe_while(sleep=1, tries=15) as proceed:
+ while proceed():
+ try:
+ sock = self.find_admin_socket()
+ except (RuntimeError, CommandFailedError):
+ continue
+
+ self.fuse_daemon.fuse_pid = int(re.match(".*\.(\d+)\.asok$",
+ sock).group(1))
+ break
+ except MaxWhileTries:
+ if check_status:
+ raise
+ else:
+ pass
def cleanup_netns(self):
if self.using_namespace: