+++ /dev/null
-#!/bin/bash
-#
-# Copyright (C) 2015 Red Hat <contact@redhat.com>
-#
-# Author: Kefu Chai <kchai@redhat.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Library Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Library Public License for more details.
-#
-
-verbose=
-
-test -d ../src && export PATH=$PATH:.
-
-if ! which jq ; then
- echo "Missing jq binary!"
- exit 1
-fi
-
-if [ `uname` = FreeBSD ]; then
- GETOPT=/usr/local/bin/getopt
-else
- GETOPT=getopt
-fi
-
-function osdmap_get() {
- local store_path=$1
- local query=$2
- local epoch=${3:+-v $3}
- local osdmap=`mktemp`
-
- $CEPH_BIN/ceph-monstore-tool $store_path get osdmap -- \
- $epoch -o $osdmap > /dev/null || return
-
- echo $($CEPH_BIN/osdmaptool --dump json $osdmap 2> /dev/null | \
- jq "$query")
-
- rm -f $osdmap
-}
-
-function test_crush() {
- local store_path=$1
- local epoch=$2
- local max_osd=$3
- local crush=$4
- local osdmap=`mktemp`
-
- $CEPH_BIN/ceph-monstore-tool $store_path get osdmap -- \
- -v $epoch -o $osdmap > /dev/null
- $CEPH_BIN/osdmaptool --export-crush $crush $osdmap &> /dev/null
-
- if $CEPH_BIN/crushtool --test --check $max_osd -i $crush > /dev/null; then
- good=true
- else
- good=false
- fi
- rm -f $osdmap
- $good || return 1
-}
-
-function die() {
- local retval=$?
- echo "$@" >&2
- exit $retval
-}
-
-function usage() {
- [ $# -gt 0 ] && echo -e "\n$@"
- cat <<EOF
-
-Usage: $0 [options ...] <mon-store>
-
-Search backward for a latest known-good epoch in monstore. Rewrite the osdmap
-epochs after it with the crush map in the found epoch if asked to do so. By
-default, print out the crush map in the good epoch.
-
- [-h|--help] display this message
- [--out] write the found crush map to given file (default: stdout)
- [--rewrite] rewrite the monitor storage with the found crush map
- [--verbose] be more chatty
-EOF
- [ $# -gt 0 ] && exit 1
- exit 0
-}
-
-function main() {
- local temp
- temp=$($GETOPT -o h --long verbose,help,mon-store:,out:,rewrite -n $0 -- "$@") || return 1
-
- eval set -- "$temp"
- local rewrite
- while [ "$1" != "--" ]; do
- case "$1" in
- --verbose)
- verbose=true
- # set -xe
- # PS4='${FUNCNAME[0]}: $LINENO: '
- shift;;
- -h|--help)
- usage
- return 0;;
- --out)
- output=$2
- shift 2;;
- --osdmap-epoch)
- osdmap_epoch=$2
- shift 2;;
- --rewrite)
- rewrite=true
- shift;;
- *)
- usage "unexpected argument $1"
- shift;;
- esac
- done
- shift
-
- local store_path="$1"
- test $store_path || usage "I need the path to mon-store."
-
- # try accessing the store; if it fails, likely means a mon is running
- local last_osdmap_epoch
- local max_osd
- last_osdmap_epoch=$(osdmap_get $store_path ".epoch") || \
- die "error accessing mon store at $store_path"
- # get the max_osd # in last osdmap epoch, crushtool will use it to check
- # the crush maps in previous osdmaps
- max_osd=$(osdmap_get $store_path ".max_osd" $last_osdmap_epoch)
-
- local good_crush
- local good_epoch
- test $verbose && echo "the latest osdmap epoch is $last_osdmap_epoch"
- for epoch in `seq $last_osdmap_epoch -1 1`; do
- local crush_path=`mktemp`
- test $verbose && echo "checking crush map #$epoch"
- if test_crush $store_path $epoch $max_osd $crush_path; then
- test $verbose && echo "crush map version #$epoch works with osdmap epoch #$osdmap_epoch"
- good_epoch=$epoch
- good_crush=$crush_path
- break
- fi
- rm -f $crush_path
- done
-
- if test $good_epoch; then
- echo "good crush map found at epoch $epoch/$last_osdmap_epoch"
- else
- echo "Unable to find a crush map for osdmap version #$osdmap_epoch." 2>&1
- return 1
- fi
-
- if test $good_epoch -eq $last_osdmap_epoch; then
- echo "and mon store has no faulty crush maps."
- elif test $output; then
- $CEPH_BIN/crushtool --decompile $good_crush --outfn $output
- elif test $rewrite; then
- $CEPH_BIN/ceph-monstore-tool $store_path rewrite-crush -- \
- --crush $good_crush \
- --good-epoch $good_epoch
- else
- echo
- $CEPH_BIN/crushtool --decompile $good_crush
- fi
- rm -f $good_crush
-}
-
-main "$@"