]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/ceph-monstore-update-crush.sh
import 15.2.9
[ceph.git] / ceph / src / tools / ceph-monstore-update-crush.sh
CommitLineData
11fdf7f2 1#!/usr/bin/env bash
7c673cae
FG
2#
3# Copyright (C) 2015 Red Hat <contact@redhat.com>
4#
5# Author: Kefu Chai <kchai@redhat.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU Library Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Library Public License for more details.
16#
17
18verbose=
19
20test -d ../src && export PATH=$PATH:.
21
31f18b77
FG
22if ! which jq ; then
23 echo "Missing jq binary!"
7c673cae
FG
24 exit 1
25fi
26
27if [ `uname` = FreeBSD ]; then
28 GETOPT=/usr/local/bin/getopt
29else
30 GETOPT=getopt
31fi
32
33function osdmap_get() {
34 local store_path=$1
35 local query=$2
36 local epoch=${3:+-v $3}
37 local osdmap=`mktemp`
38
39 $CEPH_BIN/ceph-monstore-tool $store_path get osdmap -- \
40 $epoch -o $osdmap > /dev/null || return
41
31f18b77
FG
42 echo $($CEPH_BIN/osdmaptool --dump json $osdmap 2> /dev/null | \
43 jq "$query")
7c673cae
FG
44
45 rm -f $osdmap
46}
47
48function test_crush() {
49 local store_path=$1
50 local epoch=$2
51 local max_osd=$3
52 local crush=$4
53 local osdmap=`mktemp`
54
55 $CEPH_BIN/ceph-monstore-tool $store_path get osdmap -- \
56 -v $epoch -o $osdmap > /dev/null
57 $CEPH_BIN/osdmaptool --export-crush $crush $osdmap &> /dev/null
58
59 if $CEPH_BIN/crushtool --test --check $max_osd -i $crush > /dev/null; then
60 good=true
61 else
62 good=false
63 fi
64 rm -f $osdmap
65 $good || return 1
66}
67
68function die() {
69 local retval=$?
70 echo "$@" >&2
71 exit $retval
72}
73
74function usage() {
75 [ $# -gt 0 ] && echo -e "\n$@"
76 cat <<EOF
77
78Usage: $0 [options ...] <mon-store>
79
80Search backward for a latest known-good epoch in monstore. Rewrite the osdmap
81epochs after it with the crush map in the found epoch if asked to do so. By
82default, print out the crush map in the good epoch.
83
84 [-h|--help] display this message
85 [--out] write the found crush map to given file (default: stdout)
86 [--rewrite] rewrite the monitor storage with the found crush map
87 [--verbose] be more chatty
88EOF
89 [ $# -gt 0 ] && exit 1
90 exit 0
91}
92
93function main() {
94 local temp
95 temp=$($GETOPT -o h --long verbose,help,mon-store:,out:,rewrite -n $0 -- "$@") || return 1
96
97 eval set -- "$temp"
98 local rewrite
99 while [ "$1" != "--" ]; do
100 case "$1" in
101 --verbose)
102 verbose=true
103 # set -xe
104 # PS4='${FUNCNAME[0]}: $LINENO: '
105 shift;;
106 -h|--help)
107 usage
108 return 0;;
109 --out)
110 output=$2
111 shift 2;;
112 --osdmap-epoch)
113 osdmap_epoch=$2
114 shift 2;;
115 --rewrite)
116 rewrite=true
117 shift;;
118 *)
119 usage "unexpected argument $1"
120 shift;;
121 esac
122 done
123 shift
124
125 local store_path="$1"
126 test $store_path || usage "I need the path to mon-store."
127
128 # try accessing the store; if it fails, likely means a mon is running
129 local last_osdmap_epoch
130 local max_osd
31f18b77 131 last_osdmap_epoch=$(osdmap_get $store_path ".epoch") || \
7c673cae
FG
132 die "error accessing mon store at $store_path"
133 # get the max_osd # in last osdmap epoch, crushtool will use it to check
134 # the crush maps in previous osdmaps
31f18b77 135 max_osd=$(osdmap_get $store_path ".max_osd" $last_osdmap_epoch)
7c673cae
FG
136
137 local good_crush
138 local good_epoch
139 test $verbose && echo "the latest osdmap epoch is $last_osdmap_epoch"
140 for epoch in `seq $last_osdmap_epoch -1 1`; do
141 local crush_path=`mktemp`
142 test $verbose && echo "checking crush map #$epoch"
143 if test_crush $store_path $epoch $max_osd $crush_path; then
144 test $verbose && echo "crush map version #$epoch works with osdmap epoch #$osdmap_epoch"
145 good_epoch=$epoch
146 good_crush=$crush_path
147 break
148 fi
149 rm -f $crush_path
150 done
151
152 if test $good_epoch; then
153 echo "good crush map found at epoch $epoch/$last_osdmap_epoch"
154 else
155 echo "Unable to find a crush map for osdmap version #$osdmap_epoch." 2>&1
156 return 1
157 fi
158
159 if test $good_epoch -eq $last_osdmap_epoch; then
160 echo "and mon store has no faulty crush maps."
161 elif test $output; then
162 $CEPH_BIN/crushtool --decompile $good_crush --outfn $output
163 elif test $rewrite; then
164 $CEPH_BIN/ceph-monstore-tool $store_path rewrite-crush -- \
165 --crush $good_crush \
166 --good-epoch $good_epoch
167 else
168 echo
169 $CEPH_BIN/crushtool --decompile $good_crush
170 fi
171 rm -f $good_crush
172}
173
174main "$@"