Created
January 31, 2017 13:04
-
-
Save jcsp/fe9ad9201c8586add89628979f07845b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Copyright 2017 Red Hat, Inc | |
Author: John Spray <john.spray@redhat.com> | |
License: LGPLv2 | |
Middle name: Danger | |
""" | |
import rados | |
import cephfs | |
import sys | |
import json | |
import logging | |
import os | |
log = logging.getLogger("schwack_dentries") | |
log.addHandler(logging.StreamHandler()) | |
log.setLevel(logging.DEBUG) | |
#CEPH_CONF = "/etc/ceph/ceph.conf" | |
CEPH_CONF = "./ceph.conf" | |
SEARCH_PATH = "/teuthology-archive" | |
METADATA_POOL = "metadata" | |
damage_json_path = sys.argv[1] | |
damage_json = json.load(open(damage_json_path, "r")) | |
dirs_damaged = [d['ino'] for d in damage_json if d['damage_type'] == "dir_frag" and d['frag'] == "*"] | |
def find_dentries(dir_damaged_inos): | |
""" | |
Given a list of inode numbers of directories whose * dirfrag could not be found, | |
find dentries linking to those directories, and remove these dentries from the | |
OMAP of the parent. | |
""" | |
commands = [] | |
commands.append("ceph daemon mds.mira049 flush journal") | |
r = rados.Rados(conffile=CEPH_CONF) | |
r.connect() | |
metadata_io = r.open_ioctx(METADATA_POOL) | |
assert metadata_io | |
c = cephfs.LibCephFS(rados_inst=r) | |
c.mount() | |
s = c.stat(SEARCH_PATH) | |
parent_ino = s.st_ino | |
d = c.opendir(SEARCH_PATH) | |
dentry = c.readdir(d) | |
while dentry: | |
if dentry.d_ino in dir_damaged_inos: | |
log.debug("Found ino 0x%x at %x/%s" % (dentry.d_ino, parent_ino, dentry.d_name)) | |
path = os.path.join(SEARCH_PATH, dentry.d_name) | |
parent_frag_obj = "%x.00000000" % parent_ino | |
omap_key = "%s_head" % dentry.d_name | |
rop = metadata_io.create_read_op() | |
with rados.ReadOpCtx(metadata_io) as rop: | |
it, prval = metadata_io.get_omap_vals_by_keys(rop, (omap_key,)) | |
assert prval == 0 | |
try: | |
metadata_io.operate_read_op(rop, parent_frag_obj) | |
old_val = list(it)[0][1] | |
except rados.ObjectNotFound, IndexError: | |
log.warn("OMAP key '%s' not found in dirfrag object %s for inode 0x%x linked at %s" % (omap_key, parent_frag_obj, dentry.d_ino, path)) | |
else: | |
open("%s_%s.bin" % (parent_frag_obj, omap_key), "w").write(old_val) | |
commands.append("rados -p {0} rmomapkey {1} {2}".format(METADATA_POOL, parent_frag_obj, omap_key)) | |
#old_val = list(it)[0] | |
#print old_val | |
dentry = c.readdir(d) | |
c.closedir(d) | |
c.unmount() | |
if len(commands): | |
commands.append("systemctl restart ceph-mds@mira049") | |
commands.append("ceph daemon mds.mira049 scrub_path %s repair" % SEARCH_PATH) | |
return commands | |
commands = find_dentries(dirs_damaged) | |
print "#!/bin/bash" | |
print "set -e" | |
print "\n".join(commands) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment