mirror of
https://github.com/schoebel/mars
synced 2024-12-14 18:55:19 +00:00
241 lines
9.0 KiB
Bash
241 lines
9.0 KiB
Bash
#!/bin/bash
|
|
# Copyright 2010-2013 Frank Liepold / 1&1 Internet AG
|
|
#
|
|
# Email: frank.liepold@1und1.de
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, 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 General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
#####################################################################
|
|
|
|
# starts an endless loop which creates and removes files in a given directory
|
|
# on remote host
|
|
# the pid of the started process will be returned in the variable named by $4
|
|
# the name of the started script will be returned in the variable named by $5
|
|
function lib_rw_write_and_delete_loop
|
|
{
|
|
[ $# -eq 8 ] || lib_exit 1 "wrong number $# of arguments (args = $*)"
|
|
local host=$1 target_file=$2 file_size_in_gb=$3 part_of_size_to_write=$4
|
|
local varname_pid=$5 varname_script=$6 no_of_loops=$7 sleeptime=$8
|
|
local bs=1024
|
|
local dd_count=$(($file_size_in_gb * 1024 * 1024 / $part_of_size_to_write))
|
|
local dir="$(dirname $target_file)"
|
|
local script=$lib_rw_write_and_delete_script
|
|
lib_vmsg " checking directory of $host:$target_file"
|
|
dir="$(dirname $target_file)"
|
|
lib_remote_idfile $host "test -d $dir " || \
|
|
lib_exit 1 "directory $host:$dir not found"
|
|
|
|
# this script will be started
|
|
# after no_of_loops a sleep 1 is executed instead of the dd, because the
|
|
# script should be explizitly killed
|
|
#
|
|
# the stderror output of dd is filtered
|
|
echo '#/bin/bash
|
|
no_of_loops='$no_of_loops'
|
|
sleeptime='$sleeptime'
|
|
count=1
|
|
while true; do
|
|
if [ $no_of_loops -ne 0 -a $count -gt $no_of_loops ]; then
|
|
# we do nothing more than waiting for to be killed
|
|
sleep 1
|
|
continue
|
|
fi
|
|
yes $(printf "%0.1024d" $count) | dd of='"$target_file"'.$count bs='"$bs"' count='"$dd_count"' conv=fsync status=noxfer 3>&2 2>&1 >&3 | grep -v records 3>&2 2>&1 >&3
|
|
rm -f '"$target_file"'.*
|
|
echo count=$count
|
|
sleep $sleeptime
|
|
let count+=1
|
|
done' >$script
|
|
lib_start_script_remote_bg $host $script $varname_pid \
|
|
$varname_script "rm"
|
|
main_error_recovery_functions["lib_rw_stop_scripts"]+="$host $script "
|
|
}
|
|
|
|
function lib_rw_stop_scripts
|
|
{
|
|
local host script rc write_count
|
|
while [ $# -gt 0 ]; do
|
|
host=$1
|
|
script=$2
|
|
shift 2
|
|
lib_rw_stop_one_script $host $script "write_count"
|
|
rc=$?
|
|
main_error_recovery_functions["lib_rw_stop_scripts"]=
|
|
if [ $rc -ne 0 ]; then
|
|
lib_exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
function lib_rw_stop_one_script
|
|
{
|
|
local host=$1 script=$2 varname_write_count=$3
|
|
local my_write_count grep_out rc
|
|
lib_vmsg " determine pid of script $script on $host"
|
|
pid=$(lib_remote_idfile $host pgrep -f $script)
|
|
rc=$?
|
|
[ $rc -ne 0 ] && return $rc
|
|
|
|
lib_vmsg " stopping script $script (pid=$pid) on $host"
|
|
lib_remote_idfile $host kill -9 $pid
|
|
rc=$?
|
|
[ $rc -ne 0 ] && return $rc
|
|
|
|
grep_out=$(lib_remote_idfile $host \
|
|
"grep '^count=[0-9][0-9]*$' $script.out | tail -1")
|
|
if [ -n "$grep_out" ]; then
|
|
my_write_count=${grep_out#count=}
|
|
lib_vmsg " write_count: $my_write_count"
|
|
eval $varname_write_count=$my_write_count
|
|
fi
|
|
lib_vmsg " removing files $script* on $host"
|
|
lib_remote_idfile $host "rm -f $script*"
|
|
}
|
|
|
|
function lib_rw_start_writing_data_device
|
|
{
|
|
[ $# -eq 6 ] || lib_exit 1 "wrong number $# of arguments (args = $*)"
|
|
local host=$1 varname_pid=$2 varname_script=$3 no_of_loops=$4 sleeptime=$5
|
|
local res=$6
|
|
lib_rw_write_and_delete_loop $host \
|
|
${resource_mount_point_list[$res]}/$lib_rw_file_to_write \
|
|
$(lv_config_get_lv_size_from_name ${resource_name_list[0]}) \
|
|
$lib_rw_part_of_device_size_written_per_loop \
|
|
$varname_pid $varname_script $no_of_loops $sleeptime
|
|
}
|
|
|
|
function lib_rw_stop_writing_data_device
|
|
{
|
|
local host=$1 script=$2 varname_write_count=$3
|
|
lib_rw_stop_one_script $host $script $varname_write_count
|
|
}
|
|
|
|
function lib_rw_cksum
|
|
{
|
|
local host=$1 dev=$2 varname_cksum=$3 my_cksum_out
|
|
lib_vmsg " calculating cksum for $dev on $host"
|
|
my_cksum_out=($(lib_remote_idfile $host cksum $dev)) || lib_exit 1
|
|
lib_vmsg " cksum = ${my_cksum_out[@]}"
|
|
eval $varname_cksum='('${my_cksum_out[0]}' '${my_cksum_out[1]}')'
|
|
}
|
|
|
|
# if the size to compare equals 0 we take the mars size of the
|
|
# data devices
|
|
function lib_rw_compare_checksums
|
|
{
|
|
[ $# -eq 6 ] || lib_exit 1 "wrong number $# of arguments (args = $*)"
|
|
local primary_host=$1 secondary_host=$2 res=$3 cmp_size=$4
|
|
local varname_cksum_primary=$5 varname_cksum_secondary=$6
|
|
local dev=$(lv_config_get_lv_device $res)
|
|
local host role primary_cksum_out secondary_cksum_out cksum_out
|
|
local cksum_dev=$dev
|
|
local dd_bsize=4096 dd_count
|
|
|
|
for role in "primary" "secondary"; do
|
|
local dummy_file
|
|
eval host='$'${role}_host
|
|
dummy_file=$main_mars_directory/dummy-$host
|
|
marsadm_do_cmd $host "down" $res || lib_exit 1
|
|
if [ $cmp_size -eq 0 ]; then
|
|
local link_value
|
|
local link="${resource_dir_list[$res]}/size"
|
|
lib_vmsg " reading link $host:$link"
|
|
link_value=$(lib_remote_idfile $primary_host "readlink $link") || \
|
|
lib_exit 1
|
|
if ! expr "$link_value" : '^[0-9][0-9]*$' >/dev/null; then
|
|
lib_exit 1 " $link_value is not a numeric value"
|
|
fi
|
|
if [ $((($link_value / $dd_bsize) * $dd_bsize)) -ne $link_value ]
|
|
then
|
|
lib_exit 1 "value $link_value not divsible by $dd_bsize"
|
|
fi
|
|
dd_count=$(($link_value / $dd_bsize))
|
|
else
|
|
dd_count=$((($cmp_size * 1024 * 1024 * 1024) / $dd_bsize))
|
|
fi
|
|
lib_vmsg " dumping $(($dd_count * $dd_bsize)) bytes of $dev to $dummy_file"
|
|
lib_remote_idfile $host \
|
|
"dd if=$dev of=$dummy_file bs=$dd_bsize count=$dd_count" || \
|
|
lib_exit 1
|
|
lib_remote_idfile $host "ls -l $dummy_file"
|
|
cksum_dev=$dummy_file
|
|
lib_rw_cksum $host $cksum_dev "cksum_out"
|
|
eval ${role}_cksum_out='"${cksum_out[*]}"'
|
|
lib_remote_idfile $host "rm -f $dummy_file" || lib_exit 1
|
|
marsadm_do_cmd $host "up" $res || lib_exit 1
|
|
done
|
|
if [ "$primary_cksum_out" != "$secondary_cksum_out" ]; then
|
|
lib_exit 1 "cksum primary: '$primary_cksum_out' != '$secondary_cksum_out' = cksum secondary"
|
|
fi
|
|
if [ -n "$varname_cksum_primary" ]; then
|
|
for role in "primary" "secondary"; do
|
|
eval eval '$varname_cksum_'$role='\"\$${role}_cksum_out\"'
|
|
done
|
|
fi
|
|
}
|
|
|
|
function lib_rw_mount_data_device
|
|
{
|
|
local host=$1 dev=$2 mount_point=$3
|
|
local res=${resource_name_list[0]}
|
|
local mount_point
|
|
if ! mount_is_device_mounted $host $dev "mount_point"; then
|
|
mount_mount $host $dev $mount_point ${resource_fs_type_list[$res]} || \
|
|
lib_exit 1
|
|
fi
|
|
}
|
|
|
|
function lib_wait_until_replay_has_exceeded
|
|
{
|
|
local secondary_host=$1 logfile_primary=$2 logfile_length_primary=$3 maxwait=$4
|
|
|
|
}
|
|
|
|
function lib_rw_round_to_gb
|
|
{
|
|
local number=$1
|
|
echo $((($number + (512 * 1024 * 1024)) / (1024 * 1024 * 1024)))
|
|
}
|
|
|
|
|
|
function lib_rw_remote_check_device_fs
|
|
{
|
|
[ $# -eq 3 ] || lib_exit 1 "wrong number $# of arguments (args = $*)"
|
|
local host=$1 dev=$2 fs_type=$3
|
|
local tmp_dir=/mnt/mars_tmp_mountpoint
|
|
lib_vmsg " checking existence of directory $host:$tmp_dir"
|
|
lib_remote_idfile $host "if test ! -d $tmp_dir; then mkdir $tmp_dir;fi" \
|
|
|| lib_exit 1
|
|
lib_vmsg " checking whether $host:$dev is mountable as $fs_type filesystem on $tmp_dir"
|
|
lib_remote_idfile $host mount -t $fs_type $dev $tmp_dir
|
|
rc=$?
|
|
if [ $rc -eq 0 ]; then
|
|
mount_umount $host $dev $tmp_dir || lib_exit 1
|
|
return
|
|
fi
|
|
local mount_point
|
|
if mount_is_device_mounted $host $dev "mount_point"; then
|
|
mount_umount $host $dev $mount_point
|
|
fi
|
|
lib_vmsg " creating $fs_type filesystem on $dev"
|
|
lib_remote_idfile $host "mkfs.$fs_type ${lv_config_mkfs_option_list[$fs_type]} $dev" || lib_exit 1
|
|
if [ -n "${lv_config_fs_type_tune_cmd_list[$fs_type]}" ];then
|
|
local cmd=${lv_config_fs_type_tune_cmd_list[$fs_type]/<dev>/$dev}
|
|
lib_vmsg " tuning $dev on $host: $cmd"
|
|
lib_remote_idfile $host "$cmd" || lib_exit 1
|
|
fi
|
|
}
|
|
|