]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/cephfs/kernel_mount.py
4 from textwrap
import dedent
5 from teuthology
.orchestra
.run
import CommandFailedError
6 from teuthology
import misc
8 from teuthology
.orchestra
import remote
as orchestra_remote
9 from teuthology
.orchestra
import run
10 from teuthology
.contextutil
import MaxWhileTries
11 from tasks
.cephfs
.mount
import CephFSMount
13 log
= logging
.getLogger(__name__
)
19 class KernelMount(CephFSMount
):
20 def __init__(self
, ctx
, test_dir
, client_id
, client_remote
,
21 ipmi_user
, ipmi_password
, ipmi_domain
):
22 super(KernelMount
, self
).__init
__(ctx
, test_dir
, client_id
, client_remote
)
25 self
.ipmi_user
= ipmi_user
26 self
.ipmi_password
= ipmi_password
27 self
.ipmi_domain
= ipmi_domain
29 def mount(self
, mount_path
=None, mount_fs_name
=None, mountpoint
=None, mount_options
=[]):
30 if mountpoint
is not None:
31 self
.mountpoint
= mountpoint
32 self
.setupfs(name
=mount_fs_name
)
34 log
.info('Mounting kclient client.{id} at {remote} {mnt}...'.format(
35 id=self
.client_id
, remote
=self
.client_remote
, mnt
=self
.mountpoint
))
37 self
.client_remote
.run(args
=['mkdir', '-p', self
.mountpoint
],
40 if mount_path
is None:
43 opts
= 'name={id},norequire_active_mds,conf={conf}'.format(id=self
.client_id
,
44 conf
=self
.config_path
)
46 if mount_fs_name
is not None:
47 opts
+= ",mds_namespace={0}".format(mount_fs_name
)
49 for mount_opt
in mount_options
:
50 opts
+= ",{0}".format(mount_opt
)
52 self
.client_remote
.run(
57 '{tdir}/archive/coverage'.format(tdir
=self
.test_dir
),
61 ':{mount_path}'.format(mount_path
=mount_path
),
70 self
.client_remote
.run(
71 args
=['sudo', 'chmod', '1777', self
.mountpoint
], timeout
=(5*60))
75 def umount(self
, force
=False):
76 if not self
.is_mounted():
79 log
.debug('Unmounting client client.{id}...'.format(id=self
.client_id
))
81 cmd
=['sudo', 'umount', self
.mountpoint
]
86 self
.client_remote
.run(args
=cmd
, timeout
=(15*60))
87 except Exception as e
:
88 self
.client_remote
.run(args
=[
90 run
.Raw('PATH=/usr/sbin:$PATH'),
97 rproc
= self
.client_remote
.run(
105 run
.wait([rproc
], UMOUNT_TIMEOUT
)
111 def umount_wait(self
, force
=False, require_clean
=False, timeout
=900):
113 Unlike the fuse client, the kernel client's umount is immediate
115 if not self
.is_mounted():
120 except (CommandFailedError
, MaxWhileTries
):
129 def is_mounted(self
):
132 def wait_until_mounted(self
):
134 Unlike the fuse client, the kernel client is up and running as soon
135 as the initial mount() function returns.
140 super(KernelMount
, self
).teardown()
146 The Ceph kernel client doesn't have a mechanism to kill itself (doing
147 that in side the kernel would be weird anyway), so we reboot the whole node
148 to get the same effect.
150 We use IPMI to reboot, because we don't want the client to send any
151 releases of capabilities.
154 con
= orchestra_remote
.getRemoteConsole(self
.client_remote
.hostname
,
158 con
.hard_reset(wait_for_login
=False)
162 def kill_cleanup(self
):
163 assert not self
.mounted
165 # We need to do a sleep here because we don't know how long it will
166 # take for a hard_reset to be effected.
170 # Wait for node to come back up after reboot
171 misc
.reconnect(None, 300, [self
.client_remote
])
173 # attempt to get some useful debug output:
174 con
= orchestra_remote
.getRemoteConsole(self
.client_remote
.hostname
,
178 con
.check_status(timeout
=60)
181 # Remove mount directory
182 self
.client_remote
.run(args
=['uptime'], timeout
=10)
184 # Remove mount directory
185 self
.client_remote
.run(
195 def _find_debug_dir(self
):
197 Find the debugfs folder for this mount
199 pyscript
= dedent("""
206 for dir in glob.glob("/sys/kernel/debug/ceph/*"):
207 mds_sessions_lines = open(os.path.join(dir, "mds_sessions")).readlines()
208 client_id = mds_sessions_lines[1].split()[1].strip('"')
210 result[client_id] = dir
213 print(json.dumps(get_id_to_dir()))
216 output
= self
.client_remote
.sh([
217 'sudo', 'python3', '-c', pyscript
219 client_id_to_dir
= json
.loads(output
)
222 return client_id_to_dir
[self
.client_id
]
224 log
.error("Client id '{0}' debug dir not found (clients seen were: {1})".format(
225 self
.client_id
, ",".join(client_id_to_dir
.keys())
229 def _read_debug_file(self
, filename
):
230 debug_dir
= self
._find
_debug
_dir
()
232 pyscript
= dedent("""
235 print(open(os.path.join("{debug_dir}", "{filename}")).read())
236 """).format(debug_dir
=debug_dir
, filename
=filename
)
238 output
= self
.client_remote
.sh([
239 'sudo', 'python3', '-c', pyscript
243 def get_global_id(self
):
245 Look up the CephFS client ID for this mount, using debugfs.
250 mds_sessions
= self
._read
_debug
_file
("mds_sessions")
251 lines
= mds_sessions
.split("\n")
252 return int(lines
[0].split()[1])
254 def get_osd_epoch(self
):
256 Return 2-tuple of osd_epoch, osd_epoch_barrier
258 osd_map
= self
._read
_debug
_file
("osdmap")
259 lines
= osd_map
.split("\n")
260 first_line_tokens
= lines
[0].split()
261 epoch
, barrier
= int(first_line_tokens
[1]), int(first_line_tokens
[3])
263 return epoch
, barrier