]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_recover_tool/common_h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / tools / rbd_recover_tool / common_h
1 #!/bin/bash
2 # file: common_h
3 #
4 # Copyright (C) 2015 Ubuntu Kylin
5 #
6 # Author: Min Chen <minchen@ubuntukylin.com>
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU Library Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
11 # any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Library Public License for more details.
17 #
18
19 my_dir=$(dirname "$0")
20
21 # admin node init path
22 rbd_image=/var/rbd_tool/rbd_image
23 database=$rbd_image/database
24 image_coll_v1=$rbd_image/image_coll_v1
25 image_coll_v2=$rbd_image/image_coll_v2
26 pg_coll=$rbd_image/pg_coll
27 images=$rbd_image/images
28 images_meta=$rbd_image/images_meta
29 default_backup_dir=/var/rbd_tool/default_backup_dir
30
31 # admin node: image snap & nosnap
32 nosnap= #$rbd_image/<image_name>/nosnap
33 snap= #rbd_image/<image_name>/<snap_name>
34
35 # osd node init path
36 job_path=/var/rbd_tool/osd_job
37 single_node=/var/rbd_tool/single_node
38
39 # osd node vars
40 osd_env= #single_node/$cluster$id/osd_env
41 osd_data= #/var/lib/ceph/osd/$cluster-$id
42 omap_path= #$osd_data/current/omap
43 image_list_v1= #single_node/$cluster-$id/image_list_v1
44 image_list_v2= #single_node/$cluster-$id/image_list_v2
45 image_v1= #$single_node/$cluster-$id/image_v1
46 image_v2= #$single_node/$cluster-$id/image_v2
47 pgid_list= #$single_node/$cluster-$id/pgid_list
48 node_pg_epoch= #$single_node/$cluster-$id/node_pg_epoch
49 omap_list= #$single_node/$cluster-$id/omap_list
50
51 # admin node config file
52 osd_host_path=$my_dir/config/osd_host_path
53 osd_host_mapping= #$pwd_path/config/osd_host_mapping # host --> host_remote: by init_env_admin()
54 osd_host=$my_dir/config/osd_host #generated by function init_env_admin()
55 mon_host=$my_dir/config/mon_host
56 mds_host=$my_dir/config/mds_host
57
58 # ssh option
59 ssh_option="-o ConnectTimeout=1"
60
61 # gen md5sum
62 function gen_md5()
63 {
64 echo $1|md5sum|awk '{print $1}'
65 }
66
67 # on each osd node
68 # check ceph enviroment: ssh, ceph-kvstore-tool, osd_data_path
69 function check_ceph_env()
70 {
71 local func="check_ceph_env"
72 if [ $# -lt 2 ];then
73 echo "$func: parameters: <node> <data_path>"
74 exit
75 fi
76 local node=$1
77 local data_path=$2
78 local res=
79 local cmd=
80
81 trap 'echo [$node]: ssh failed; exit' INT HUP
82 ssh -o ConnectTimeout=1 $node "echo -n" </dev/null
83 res=$?
84 if [ $res -ne 0 ];then
85 echo "[$node]: ssh failed"
86 exit
87 fi
88
89 cmd=ceph-kvstore-tool
90 trap 'echo [$node]: $cmd failed; exit' INT HUP
91 ssh -o ConnectTimeout=1 $node "$cmd &>/dev/null;" </dev/null
92 res=$?
93 # ceph-kvstore-tool will return 1 with no parameters input
94 if [ $res -ne 1 ];then
95 echo "[$node]: $cmd not installed"
96 exit
97 fi
98
99 trap 'echo [$node]: stat $data_path failed; exit' INT HUP
100 ssh -o ConnectTimeout=1 $node "stat $data_path &>/dev/null;" </dev/null
101 res=$?
102 if [ $res -ne 0 ];then
103 echo "[$node]: $data_path not exists"
104 exit
105 fi
106 }
107
108 # osd node context : osd_data_path
109 function init_env_osd()
110 {
111 local func="init_env_osd"
112 if [ "$1"x = ""x ];then
113 echo "$func: no osd_data_path input"
114 exit
115 fi
116 osd_data=$1
117 omap_path=$osd_data/current/omap
118
119 if [ ! -e $single_node ];then
120 mkdir -p $single_node
121 fi
122
123 local osd_id=`gen_md5 $osd_data`
124 local osd_dir=$single_node/$osd_id
125
126 if [ ! -e $osd_dir ];then
127 mkdir -p $osd_dir
128 fi
129
130 image_list_v1=$osd_dir/image_list_v1
131 image_list_v2=$osd_dir/image_list_v2
132 image_v1=$osd_dir/image_v1
133 image_v2=$osd_dir/image_v2
134 pgid_list=$osd_dir/pgid_list
135 node_pg_epoch=$osd_dir/node_pg_epoch
136 omap_list=$osd_dir/omap_list
137 }
138
139 # admin node process file: osd_host_path
140 function init_env_admin()
141 {
142 local func="init_env_admin"
143 local pwd_path=`pwd`
144 osd_host_mapping=$pwd_path/config/osd_host_mapping
145 if [ ! -s $osd_host_path ];then
146 echo "$func: config/osd_host_path not exists or empty"
147 exit
148 fi
149 if [ ! -e $rbd_image ];then
150 mkdir -p $rbd_image
151 fi
152 if [ ! -e $images ];then
153 mkdir -p $images
154 fi
155
156 if [ ! -s $mon_host ];then
157 echo "$func: config/mon_host not exists or empty"
158 exit
159 fi
160 if [ ! -e $mds_host ];then
161 echo "$func: config/mds_host not exists"
162 exit
163 fi
164
165 # we just judge if osd_host is needed to be updated
166 if [ -s $osd_host ] && [ $osd_host -nt $osd_host_path ];then
167 return
168 fi
169 echo "$func: create osd_host ..."
170 # create file: osd_host and osd_host_mapping
171 >$osd_host
172 >$osd_host_mapping
173 local lines=0
174 local lineno=0
175 while read line
176 do
177 lineno=$(($lineno + 1))
178 if [ "$line"x = ""x ];then
179 continue;
180 fi
181 local node=`echo $line|awk '{print $1}'`
182 if [ "$node"x = ""x ];then
183 echo "$func: osd_host_path : line $lineno: osd hostname not input"
184 rm -rf $osd_host $osd_host_mapping
185 exit
186 fi
187 local data_path=`echo $line|awk '{print $2}'`
188 if [ "$data_path"x = ""x ];then
189 echo "$func: osd_host_path : line $lineno: osd data_path not input"
190 rm -rf $osd_host $osd_host_mapping
191 exit
192 fi
193 lines=$(($lines + 1))
194 # in case : there are servral hostnames on the same node
195 # just need output of `hostname`
196 local hostname_alias=
197 hostname_alias=`ssh $ssh_option $node "hostname" 2>/dev/null </dev/null`
198 if [ "$hostname_alias"x = ""x ];then
199 echo "$func: osd_host_path: line $lineno: $node: get remote hostname alias failed"
200 rm -rf $osd_host $osd_host_mapping
201 exit
202 fi
203 echo "$node $hostname_alias" >>$osd_host_mapping
204 echo $node >> $osd_host
205 # check ceph env on remote osd
206 check_ceph_env $node $data_path
207 done < $osd_host_path
208
209 if [ $lines = 0 ];then
210 echo "$func: no osd host path valid"
211 exit
212 fi
213 }
214
215 function admin_parse_osd()
216 {
217 local func="admin_parse_osd"
218 if [ -s $osd_host ];then
219 return
220 fi
221 # create file: osd_host
222 >$osd_host
223 local lines=0
224 local lineno=0
225 while read line
226 do
227 lineno=$(($lineno + 1))
228 if [ "$line"x = ""x ];then
229 continue;
230 fi
231 local node=`echo $line|awk '{print $1}'`
232 if [ "$node"x = ""x ];then
233 echo "$func: osd_host_path : line $lineno: osd_host not input"
234 exit
235 fi
236 local data_path=`echo $line|awk '{print $2}'`
237 if [ "$data_path"x = ""x ];then
238 echo "$func: osd_host_path : line $lineno: osd_data not input"
239 exit
240 fi
241 lines=$(($lines + 1))
242 echo $node >> $osd_host
243 done < $osd_host_path
244 }
245
246 # for osd node
247 function get_omap_list()
248 {
249 ceph-kvstore-tool $omap_path list > $omap_list
250 }
251
252 function convert_underline()
253 {
254 if [ "$1"x = ""x ];then
255 return
256 fi
257
258 echo $1|sed -e 's/_/\\u/gp'|head -n 1
259 }
260
261 function dump_backslash()
262 {
263 echo $*|sed -e 's/\\/\\\\/gp'|head -n 1
264 }
265
266 function dump_dump_backslash()
267 {
268 echo $*|sed -e 's/\\/\\\\\\\\/gp'|head -n 1
269 }
270
271 function char_convert()
272 {
273 if [ "$1"x = ""x ];then
274 return
275 fi
276
277 echo $1|sed -e 's/_/\\u/gp' -e 's/\./%e/gp' -e 's/%/%p/gp'|head -n 1
278 }
279
280 function check_osd_process()
281 {
282 local func="check_osd_process"
283 local host=$1
284 if [ "$1"x = ""x ];then
285 exit
286 fi
287 local cmds="ps aux|grep ceph-osd|grep -v grep"
288 local ret=/tmp/ret.$$$$
289 ssh $ssh_option $host $cmds |tee $ret
290 if [ -s $ret ];then
291 echo "$func: [$host] ceph-osd process is not killed"
292 exit
293 fi
294 rm -f $ret
295 }
296
297 function get_map_header_prefix()
298 {
299 echo "_HOBJTOSEQ_"
300 }
301
302 function get_map_header_key()
303 {
304 local func="get_map_header_key"
305 if [ "$1"x = ""x ];then
306 #echo $func': no keyword input'
307 exit
308 fi
309 local keyword=$1
310 local res=`cat $omap_list| grep $keyword`
311 if [ "$res"x = ""x ];then
312 #echo "$func: map_header_key = $keyword not exisits"
313 exit
314 fi
315 echo $res|awk -F ":" '{print $2}'
316 }
317
318 function get_header_seq()
319 {
320 local func="get_header_seq"
321 if [ "$1"x == ""x ];then
322 #echo "$func: no prefix input"
323 exit;
324 elif [ "$2"x == ""x ];then
325 #echo "$func: no key input"
326 exit;
327 fi
328 local prefix=$1;
329 local key=$2;
330 local res=/tmp/header_seq.$$$$
331
332 ceph-kvstore-tool $omap_path get $prefix $key 2>/dev/null 1>$res
333 if [ $? != 0 ]; then
334 #echo "$func: <$prefix , $key> not exists" ;
335 exit;
336 fi
337
338 # ceph-kvstore-tool get result like this:
339 # 02 01 7e 00 00 00 12 44 00 00 00 00 00 00 00 00
340 # get header seq bytes:
341 # 12 44 00 00 00 00 00 00
342 # -> 00 00 00 00 00 00 44 12
343 # echo $((16#0000000000004412)) -> 17426 == header_seq
344 local seq=`cat $res |head -n 2|tail -n 1| \
345 awk '
346 BEGIN {
347 FS=":"
348 seq="";
349 i=7;
350 } {
351 split($2, arr, " ")
352 # header_seq uint64 : 8 bytes
353 for (x=7; x>=0; --x) {
354 seq=seq""arr[i+x];
355 }
356 }
357 END {
358 print seq
359 }'`
360 if [ "$seq"x = ""x ];then
361 #echo "$func: get <$prefix , $key> failed"
362 exit;
363 fi
364 rm -f $res
365 echo $((16#$seq))
366 }
367
368 # get header info key/value
369 function get_header_kv()
370 {
371 local func="get_header_kv"
372 if [ "$1"x = ""x ];then
373 #echo "$func: no prefix input"
374 exit
375 elif [ "$2"x = ""x ];then
376 #echo "$func: no key input"
377 exit
378 elif [ "$3"x != "string"x ] && [ "$3"x != "int"x ];then
379 #echo "$func: no valid type input, use type (string|int)"
380 exit
381 fi
382
383 local prefix=$1
384 local key=$2
385 local types=$3
386 local res=/tmp/kv.$$$$
387
388 ceph-kvstore-tool $omap_path get $prefix $key 2>/dev/null 1>$res
389 if [ $? != 0 ];then
390 #echo "$func: <$prefix , $key> not exists"
391 exit
392 fi
393
394 if [ "$types"x = "string"x ];then
395 local value=`cat $res |tail -n +2|head -n -1|awk -F ": " '{printf $3}'|sed -n 's/^\.\{4\}//p'`
396 echo $value
397 elif [ "$types"x = "int"x ];then
398 local value=`cat $res |tail -n +2|head -n -1| \
399 awk '
400 BEGIN{
401 FS=":"
402 } {
403 split($2, arr, " ");
404 len=length(arr)
405 for (i=len; i>0; --i) {
406 printf arr[i];
407 }
408 }'`
409 echo $((16#$value))
410 fi
411 rm -f $res
412 }