mars/test_suite/scripts/modules/80_lib_rw.sh

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
}