sudo=True).decode())
def is_blocked(self):
+ if not self.addr:
+ # can't infer if our addr is blocklisted - let the caller try to
+ # umount without lazy/force. If the client was blocklisted, then
+ # the umount would be stuck and the test would fail on timeout.
+ # happens only with Ubuntu 20.04 (missing kclient patches :/).
+ return False
self.fs = Filesystem(self.ctx, name=self.cephfs_name)
try:
))
p.wait()
- def open_background(self, basename="background_file", write=True):
+ def open_background(self, basename="background_file", write=True, content="content"):
"""
Open a file for writing, then block such that the client
will hold a capability.
import time
with open("{path}", 'w') as f:
- f.write('content')
+ f.write("{content}")
f.flush()
- f.write('content2')
while True:
time.sleep(1)
- """).format(path=path)
+ """).format(path=path, content=content)
else:
pyscript = dedent("""
import time
# This wait would not be sufficient if the file had already
# existed, but it's simple and in practice users of open_background
# are not using it on existing files.
- self.wait_for_visible(basename)
+ if write:
+ self.wait_for_visible(basename, size=len(content))
+ else:
+ self.wait_for_visible(basename)
return rproc
if nr_links == 2:
return
- def wait_for_visible(self, basename="background_file", timeout=30):
+ def wait_for_visible(self, basename="background_file", size=None, timeout=30):
i = 0
+ args = ['stat']
+ if size is not None:
+ args += ['--printf=%s']
+ args += [os.path.join(self.hostfs_mntpt, basename)]
while i < timeout:
- r = self.client_remote.run(args=[
- 'stat', os.path.join(self.hostfs_mntpt, basename)
- ], check_status=False)
- if r.exitstatus == 0:
- log.debug("File {0} became visible from {1} after {2}s".format(
- basename, self.client_id, i))
- return
- else:
- time.sleep(1)
- i += 1
+ p = self.client_remote.run(args=args, stdout=StringIO(), check_status=False)
+ if p.exitstatus == 0:
+ if size is not None:
+ s = p.stdout.getvalue().strip()
+ if int(s) == size:
+ log.info(f"File {basename} became visible with size {size} from {self.client_id} after {i}s")
+ return
+ else:
+ log.error(f"File {basename} became visible but with size {int(s)} not {size}")
+ else:
+ log.info(f"File {basename} became visible from {self.client_id} after {i}s")
+ return
+ time.sleep(1)
+ i += 1
raise RuntimeError("Timed out after {0}s waiting for {1} to become visible from {2}".format(
i, basename, self.client_id))
self.background_procs.append(rproc)
return rproc
- def create_n_files(self, fs_path, count, sync=False, dirsync=False, unlink=False, finaldirsync=False):
+ def create_n_files(self, fs_path, count, sync=False, dirsync=False,
+ unlink=False, finaldirsync=False, hard_links=0):
"""
Create n files.
:param dirsync: sync the containing directory after closing the file
:param unlink: unlink the file after closing
:param finaldirsync: sync the containing directory after closing the last file
+ :param hard_links: create given number of hard link(s) for each file
"""
assert(self.is_mounted())
pyscript = dedent(f"""
import os
+ import uuid
n = {count}
+ create_hard_links = False
+ if {hard_links} > 0:
+ create_hard_links = True
path = "{abs_path}"
dpath = os.path.dirname(path)
os.unlink(fpath)
if {dirsync}:
os.fsync(dirfd)
+ if create_hard_links:
+ for j in range({hard_links}):
+ os.system(f"ln {{fpath}} {{dpath}}/{{fnameprefix}}_{{i}}_{{uuid.uuid4()}}")
if {finaldirsync}:
os.fsync(dirfd)
finally: