4 # Copyright (C) 2015 Ubuntu Kylin
6 # Author: Min Chen <minchen@ubuntukylin.com>
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)
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.
19 my_dir=$(dirname "$0")
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
31 # admin node: image snap & nosnap
32 nosnap= #$rbd_image/<image_name>/nosnap
33 snap= #rbd_image/<image_name>/<snap_name>
36 job_path=/var/rbd_tool/osd_job
37 single_node=/var/rbd_tool/single_node
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
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
59 ssh_option="-o ConnectTimeout=1"
64 echo $1|md5sum|awk '{print $1}'
68 # check ceph enviroment: ssh, ceph-kvstore-tool, osd_data_path
69 function check_ceph_env()
71 local func="check_ceph_env"
73 echo "$func: parameters: <node> <data_path>"
81 trap 'echo [$node]: ssh failed; exit' INT HUP
82 ssh -o ConnectTimeout=1 $node "echo -n" </dev/null
84 if [ $res -ne 0 ];then
85 echo "[$node]: ssh failed"
90 trap 'echo [$node]: $cmd failed; exit' INT HUP
91 ssh -o ConnectTimeout=1 $node "$cmd &>/dev/null;" </dev/null
93 # ceph-kvstore-tool will return 1 with no parameters input
94 if [ $res -ne 1 ];then
95 echo "[$node]: $cmd not installed"
99 trap 'echo [$node]: stat $data_path failed; exit' INT HUP
100 ssh -o ConnectTimeout=1 $node "stat $data_path &>/dev/null;" </dev/null
102 if [ $res -ne 0 ];then
103 echo "[$node]: $data_path not exists"
108 # osd node context : osd_data_path
109 function init_env_osd()
111 local func="init_env_osd"
112 if [ "$1"x = ""x ];then
113 echo "$func: no osd_data_path input"
117 omap_path=$osd_data/current/omap
119 if [ ! -e $single_node ];then
120 mkdir -p $single_node
123 local osd_id=`gen_md5 $osd_data`
124 local osd_dir=$single_node/$osd_id
126 if [ ! -e $osd_dir ];then
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
139 # admin node process file: osd_host_path
140 function init_env_admin()
142 local func="init_env_admin"
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"
149 if [ ! -e $rbd_image ];then
152 if [ ! -e $images ];then
156 if [ ! -s $mon_host ];then
157 echo "$func: config/mon_host not exists or empty"
160 if [ ! -e $mds_host ];then
161 echo "$func: config/mds_host not exists"
165 # we just judge if osd_host is needed to be updated
166 if [ -s $osd_host ] && [ $osd_host -nt $osd_host_path ];then
169 echo "$func: create osd_host ..."
170 # create file: osd_host and osd_host_mapping
177 lineno=$(($lineno + 1))
178 if [ "$line"x = ""x ];then
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
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
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
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
209 if [ $lines = 0 ];then
210 echo "$func: no osd host path valid"
215 function admin_parse_osd()
217 local func="admin_parse_osd"
218 if [ -s $osd_host ];then
221 # create file: osd_host
227 lineno=$(($lineno + 1))
228 if [ "$line"x = ""x ];then
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"
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"
241 lines=$(($lines + 1))
242 echo $node >> $osd_host
243 done < $osd_host_path
247 function get_omap_list()
249 ceph-kvstore-tool $omap_path list > $omap_list
252 function convert_underline()
254 if [ "$1"x = ""x ];then
258 echo $1|sed -e 's/_/\\u/gp'|head -n 1
261 function dump_backslash()
263 echo $*|sed -e 's/\\/\\\\/gp'|head -n 1
266 function dump_dump_backslash()
268 echo $*|sed -e 's/\\/\\\\\\\\/gp'|head -n 1
271 function char_convert()
273 if [ "$1"x = ""x ];then
277 echo $1|sed -e 's/_/\\u/gp' -e 's/\./%e/gp' -e 's/%/%p/gp'|head -n 1
280 function check_osd_process()
282 local func="check_osd_process"
284 if [ "$1"x = ""x ];then
287 local cmds="ps aux|grep ceph-osd|grep -v grep"
288 local ret=/tmp/ret.$$$$
289 ssh $ssh_option $host $cmds |tee $ret
291 echo "$func: [$host] ceph-osd process is not killed"
297 function get_map_header_prefix()
302 function get_map_header_key()
304 local func="get_map_header_key"
305 if [ "$1"x = ""x ];then
306 #echo $func': no keyword input'
310 local res=`cat $omap_list| grep $keyword`
311 if [ "$res"x = ""x ];then
312 #echo "$func: map_header_key = $keyword not exisits"
315 echo $res|awk -F ":" '{print $2}'
318 function get_header_seq()
320 local func="get_header_seq"
321 if [ "$1"x == ""x ];then
322 #echo "$func: no prefix input"
324 elif [ "$2"x == ""x ];then
325 #echo "$func: no key input"
330 local res=/tmp/header_seq.$$$$
332 ceph-kvstore-tool $omap_path get $prefix $key 2>/dev/null 1>$res
334 #echo "$func: <$prefix , $key> not exists" ;
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| \
352 # header_seq uint64 : 8 bytes
353 for (x=7; x>=0; --x) {
360 if [ "$seq"x = ""x ];then
361 #echo "$func: get <$prefix , $key> failed"
368 # get header info key/value
369 function get_header_kv()
371 local func="get_header_kv"
372 if [ "$1"x = ""x ];then
373 #echo "$func: no prefix input"
375 elif [ "$2"x = ""x ];then
376 #echo "$func: no key input"
378 elif [ "$3"x != "string"x ] && [ "$3"x != "int"x ];then
379 #echo "$func: no valid type input, use type (string|int)"
386 local res=/tmp/kv.$$$$
388 ceph-kvstore-tool $omap_path get $prefix $key 2>/dev/null 1>$res
390 #echo "$func: <$prefix , $key> not exists"
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'`
397 elif [ "$types"x = "int"x ];then
398 local value=`cat $res |tail -n +2|head -n -1| \
405 for (i=len; i>0; --i) {