Skip to content

Instantly share code, notes, and snippets.

@jcsp
Created January 31, 2017 13:04
Show Gist options
  • Save jcsp/fe9ad9201c8586add89628979f07845b to your computer and use it in GitHub Desktop.
Save jcsp/fe9ad9201c8586add89628979f07845b to your computer and use it in GitHub Desktop.
"""
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