#!/bin/bash LVM_DEFINED=0 LVM_PREFIX="patchy_snap" LVM_COUNT=0 VHD_SIZE="300M" #This function will init B# bricks #This is used when launch_cluster is #not called to init B#. Call it before #setup_lvm function init_n_bricks() { local count=$1 for i in `seq 1 $count`; do eval "B$i=/d/backends/$i" done } count_snaps () { ls $1/.snaps | wc -l } function init_lvm() { if [ "$1" == "" ]; then echo "Error: Invalid argument supplied" return 1 fi LVM_COUNT=$1 if [ "$2" != "" ]; then VHD_SIZE=$2 fi local b local i if [ "$B1" = "" ]; then B1=$B0 fi for i in `seq 1 $LVM_COUNT`; do b="B$i" if [ "${!b}" = "" ]; then echo "Error: $b not defined." echo "Please run launch_cluster with atleast $LVM_COUNT nodes" return 1 fi eval "L$i=${!b}/${LVM_PREFIX}_mnt" l="L$i" mkdir -p ${!l} if [ $? -ne 0 ]; then echo "Error: failed to create dir ${!l}" return 1 fi eval "VG$i=${LVM_PREFIX}_vg_${i}" done LVM_DEFINED=1 return 0 } function verify_lvm_version() { if `/sbin/lvcreate --help | grep -q thin`; then return 0; fi return 1; } function setup_lvm() { init_lvm $@ || return 1 _setup_lvm return 0 } function cleanup_lvm() { pkill gluster sleep 2 if [ "$LVM_DEFINED" = "1" ]; then _cleanup_lvm >/dev/null 2>&1 fi _cleanup_lvm_again >/dev/null 2>&1 # TODO Delete cleanup has open bug # once fixed delete this mount | grep "run/gluster/snaps" | awk '{print $3}' | xargs umount 2> /dev/null mount | grep "patchy_snap" | awk '{print $3}' | xargs umount 2> /dev/null \rm -rf /var/run/gluster/snaps/* lvscan | grep "/dev/patchy_snap" | awk '{print $2}'| xargs lvremove -f 2> /dev/null vgs | grep patchy_snap | awk '{print $1}' | xargs vgremove -f 2>/dev/null \rm -rf /dev/patchy* return 0 } # Find out how this file was sourced, source traps.rc the same way, and use # push_trapfunc to make sure cleanup_lvm gets called before we exit. . $(dirname ${BASH_SOURCE[0]})/traps.rc push_trapfunc cleanup_lvm ######################################################## # Private Functions ######################################################## function _setup_lvm() { local count=$LVM_COUNT local b local i for i in `seq 1 $count`; do b="B$i" _create_vhd ${!b} $i _create_lv ${!b} $i _mount_lv $i done } function _cleanup_lvm() { local count=$LVM_COUNT local b local i for i in `seq 1 $count`; do b="B$i" _umount_lv $i _remove_lv $i _remove_vhd ${!b} done } function _cleanup_lvm_again() { local file mount | grep $LVM_PREFIX | awk '{print $3}' | xargs -r ${UMOUNT_F} /sbin/vgs | grep $LVM_PREFIX | awk '{print $1}' | xargs -r vgremove -f find $B0 -name "${LVM_PREFIX}_loop" | xargs -r losetup -d find $B0 -name "${LVM_PREFIX}*" | xargs -r rm -rf find /run/gluster/snaps -name "*${LVM_PREFIX}*" | xargs -r rm -rf for file in `ls /run/gluster/snaps`; do find /run/gluster/snaps/$file -mmin -2 | xargs -r rm -rf done } ######################################################## ######################################################## function _create_vhd() { local dir=$1 local num=$2 local loop_num=`expr $2 + 8` fallocate -l${VHD_SIZE} $dir/${LVM_PREFIX}_vhd mknod -m660 $dir/${LVM_PREFIX}_loop b 7 $loop_num /sbin/losetup $dir/${LVM_PREFIX}_loop $dir/${LVM_PREFIX}_vhd } function _create_lv() { local dir=$1 local num=$2 local vg="VG$num" local thinpoolsize="200M" local virtualsize="150M" /sbin/pvcreate $dir/${LVM_PREFIX}_loop /sbin/vgcreate ${!vg} $dir/${LVM_PREFIX}_loop /sbin/lvcreate -L ${thinpoolsize} -T /dev/${!vg}/thinpool /sbin/lvcreate -V ${virtualsize} -T /dev/${!vg}/thinpool -n brick_lvm mkfs.xfs -f /dev/${!vg}/brick_lvm } function _mount_lv() { local num=$1 local vg="VG$num" local l="L$num" mount -t xfs -o nouuid /dev/${!vg}/brick_lvm ${!l} } function _umount_lv() { local num=$1 local l="L$num" ${UMOUNT_F} ${!l} 2>/dev/null || true rmdir ${!l} 2>/dev/null || true } function _remove_lv() { local num=$1 local vg="VG$num" vgremove -f ${!vg} } function _remove_vhd() { local dir=$1 losetup -d $dir/${LVM_PREFIX}_loop rm -f $dir/${LVM_PREFIX}_loop rm -f $dir/${LVM_PREFIX}_vhd } ######################################################## # Utility Functions ######################################################## function snapshot_exists() { local clitype=$1 local snapname=$2 local cli=$CLI if [ "$clitype" == "1" ]; then cli=$CLI_1; fi if [ "$clitype" == "2" ]; then cli=$CLI_2; fi $cli snapshot list | egrep -q "^$snapname\$" return $? } #Create N number of snaps in a given volume #Arg1 : #Arg2 : #Arg3 : #Return: Returns 0 if all snaps are created , # if not will return exit code of last failed # snap create command. function create_n_snapshots() { local cli=$1 local vol=$1 local snap_count=$2 local snap_name=$3 local ret=0 for i in `seq 1 $snap_count`; do $CLI_1 snapshot create $snap_name$i ${vol} no-timestamp & PID_1=$! wait $PID_1 ret=$? if [ "$ret" != "0" ]; then break fi done return $ret } #Delete N number of snaps in a given volume #Arg1 : #Arg2 : #Arg3 : #Return: Returns 0 if all snaps are Delete, # if not will return exit code of last failed # snap delete command. function delete_n_snapshots() { local vol=$1 local snap_count=$2 local snap_name=$3 local ret=0 for i in `seq 1 $snap_count`; do $CLI_1 snapshot delete $snap_name$i & PID_1=$! wait $PID_1 temp=$? if [ "$temp" != "0" ]; then ret=$temp fi done return $ret } #Check for the existance of N number of snaps in a given volume #Arg1 : #Arg2 : #Arg3 : #Return: Returns 0 if all snaps exists, # if not will return exit code of last failed # snapshot_exists(). function snapshot_n_exists() { local vol=$1 local snap_count=$2 local snap_name=$3 local ret=0 for i in `seq 1 $snap_count`; do snapshot_exists 1 $snap_name$i ret=$? if [ "$ret" != "0" ]; then break fi done return $ret } #Check for the status of snapshot for a volume #Arg1 : function snapshot_status() { local snap=$1; local cli=$CLI_1; if [ "$cli" = "" ]; then cli=$CLI fi #TODO: Right now just fetches the status of the single snap volume. #When snapshot will have multiple snap volumes, should have a #cummulative logic for status $cli snapshot info $snap | grep "Status" | sed 's/.*: //'; } #Check the different status of a particular snapshot #Arg1 : #Arg2 : #Arg3 : function snapshot_snap_status() { local snap=$1; local cli=$CLI_1; local field=$2; local expected=$3; if [ "$cli" = "" ]; then cli=$CLI fi for i in $($cli snapshot status $snap | grep "$field" | \ cut -d ':' -f2 | awk '{print $1}') ; do if [ "$i" != "$expected" ]; then echo "Failed" return 1; fi; done; echo "Success" return 0; } # TODO: Cleanup code duplication function volinfo_field() { local vol=$1; local field=$2; $CLI_1 volume info $vol | grep "^$field: " | sed 's/.*: //'; } function volume_exists() { $CLI_1 volume info $1 > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "Y" else echo "N" fi } # arg-1 : From which node the command should be trigerred # Ex : $CLI_1, $CLI_2, etc. # arg-2 : Volume name # arg-3 : Starting index for the snapname "snap$i" # arg-4 : Number of snapshots to be taken function snap_create() { eval local cli_index=\$$1 local volname=$2 local i=$3 local limit=$[$i + $4] while [ $i -lt $limit ] do $cli_index snapshot create snap$i $volname no-timestamp i=$[$i+1] done } # arg-1 : From which node the command should be trigerred # Ex : $CLI_1. $CLI_2, etc. # arg-2 : Volume name. function get_snap_count() { eval local cli_index=\$$1 local volname=$2 if [ -z "$2" ] then $cli_index snapshot list | grep -v "No snapshots present"\ | wc -l else $cli_index snapshot list $volname\ | grep -v "No snapshots present"\ | wc -l fi } # arg-1 : From which node the command should be trigerred # Ex : $CLI_1, $CLI_2, etc. # arg-2 : Starting index for the snapname "snap$i" # arg-3 : Number of snapshots to be deleted. function snap_delete() { eval local cli_index=\$$1 local i=$2 local limit=$[$i + $3] while [ $i -lt $limit ] do $cli_index snapshot delete snap$i i=$[$i+1] done } # arg-1 : From which node the command should be triggered # Ex : $CLI_1, $CLI_2, etc. # arg-2 : key value function snap_config() { eval local cli_index=\$$1 local var=$2 $cli_index snapshot config | grep "^$var" | sed 's/.*: //' } function check_if_snapd_exist() { local pid pid=$(ps aux | grep "snapd" | grep -v grep | awk '{print $2}') if [ -n "$pid" ]; then echo "Y"; else echo "N"; fi } # returns number of snapshot being displayed in ".snaps" directory function uss_count_snap_displayed() { local path=$1 ls $path/.snaps | wc -l } function snap_info_volume() { eval local cli_index=\$$1 local var=$2 local vol=$3 $cli_index snapshot info volume $vol | grep "^$var" | sed 's/.*: //' } function snap_config_volume() { eval local cli_index=\$$1 local var=$2 local vol=$3 $cli_index snapshot config $vol| grep "^$var" | sed 's/.*: //' } #return specific fields of xml output function get-cmd-field-xml() { local cli=$CLI_1; if [ "$cli" = "" ]; then cli=$CLI fi COMMAND=$1 PATTERN=$2 $cli $COMMAND --xml | xmllint --format - | grep $PATTERN } function get_snap_brick_status() { local snap=$1; $CLI snapshot status $snap | grep "Brick Running" | sed 's/.*: //'; } case $OSTYPE in NetBSD) echo "Skip test on LVM which is not available on NetBSD" >&2 SKIP_TESTS exit 0 ;; *) ;; esac