Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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 }