#!/bin/sh # # $Id: $ # # This script is to test issues when starting many hast providers # simultaneously (reported by Freddie Cash fjwcash at gmail.com on # freebsd-curent, subject: ZFS import panic with r219703). # # Config # # Number of HAST resources to create. N=24 # Additional command line ooptions for hastd (e.g. -d). HASTOPT= # YES: set roles using all argumnet; NO: iterate over all resources. USEALL=YES # Make FS on deploy. DO_MAKEFS=NO # Mount FS on deploy. DO_MOUNT=NO # MD units will start after this number. MDBASE=10 # Ports for hastd will start after this number. PORTBASE=7770 HOSTNAME=$(hostname -s) RESOURCE=test DISKSIZE=64M DISKFILE_TEMPLATE="./%{resource}.%{node}.img" CONFNAME_TEMPLATE="/tmp/hast.conf.%{node}" CONFIG_RESOURCE_TEMPLATE=" resource %{resource} { on ${HOSTNAME} { name %{resource}_%{node} local /dev/md%{mdunit} remote tcp4://${HOSTNAME}:%{rport} } } " MOUNT_TEMPLATE="/tmp/mnt/%{resource}" # # Functions # subs() { local node="$1" lport="2" rport="$3" resource="$4" mdunit="$5" sed -e " s/%{node}/${node}/g; s/%{lport}/${lport}/g; s/%{rport}/${rport}/g; s/%{resource}/${resource}/g; s/%{mdunit}/${mdunit}/g; " } deploy() { local node lport rport resource mdunit img set -e echo "Creating devices and configs." for node in 1 2; do conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node} ${lport} ${rport} ${resource} ${mdunit}) lport=$((PORTBASE + node)) rport=$((PORTBASE + node % 2 + 1)) echo "control /var/run/hastctl.test_24.${node}" > "${conf}" echo "listen 0.0.0.0:${lport}" >> "${conf}" for i in `jot "${N}"`; do resource="${RESOURCE}${i}" mdunit=$((MDBASE + (node - 1) * N + i)) if ! test -c /dev/md${mdunit}; then img=$(printf "%s" "${DISKFILE_TEMPLATE}" | subs ${node} ${lport} ${rport} ${resource} ${mdunit}) test -f "${img}" || truncate -s "${DISKSIZE}" "${img}" mdconfig -a -t vnode -f "${img}" -u "${mdunit}" fi printf "%s" "$CONFIG_RESOURCE_TEMPLATE" | subs ${node} ${lport} ${rport} ${resource} ${mdunit} >> "${conf}" done done start if [ "${DO_MAKEFS}" = YES ]; then make_fs if [ "${DO_MOUNT}" = YES ]; then mount_fs fi fi } start () { local conf provname device role test -n "$1" && HASTOPT="$@" echo "Staring hastd." for node in 1 2; do conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node}) [ $node = 1 ] && role=primary || role=secondary hastd $HASTOPT -c "${conf}" -P "/var/run/hastd.test_24.${node}.pid" for i in `jot "${N}"`; do resource="${RESOURCE}${i}" hastctl dump -c "${conf}" "${resource}" >/dev/null 2>&1 || hastctl create -c "${conf}" "${resource}" test "${USEALL}" = NO && hastctl role -c "${conf}" "${role}" "${resource}" done test "${USEALL}" = YES && hastctl role -c "${conf}" "${role}" all if [ "${role}" = primary ]; then resource="${RESOURCE}${i}" for i in `jot "${N}"`; do provname=$(hastctl status -c "${conf}" "${resource}" | awk '$1 == "provname:" {print $2}') if [ -z "$provname" ]; then echo "Can't get provname." >&2 exit 1 fi device="/dev/hast/${provname}" for i in `jot 50`; do [ -c "${device}" ] && break sleep 0.1 done if [ ! -c "${device}" ]; then echo "Device ${device} didn't appear." >&2 exit 1 fi done fi done } stop() { local node resource pid umount_fs for node in 1 2; do conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node}) if [ "${USEALL}" = YES ]; then hastctl role -c "${conf}" init all else for i in `jot "${N}"`; do resource="${RESOURCE}${i}" hastctl role -c "${conf}" init "${resource}" done fi pid=`cat "/var/run/hastd.test_24.${node}.pid"` test -n "$pid" && kill "$pid" done } reload() { for node in 1 2; do pid=`cat "/var/run/hastd.test_24.${node}.pid"` test -n "$pid" && kill -HUP "$pid" done } make_fs() { local node conf resource device for node in 1 2; do conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node}) for i in `jot "${N}"`; do resource="${RESOURCE}${i}" provname=$(hastctl status -c "${conf}" "${resource}" | awk '$1 == "provname:" {print $2}') if [ -z "$provname" ]; then echo "Can't get provname." >&2 exit 1 fi device="/dev/hast/${provname}" if [ -c "${device}" ]; then newfs "${device}" fi done done } mount_fs() { local node conf resource device mount for node in 1 2; do conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node}) for i in `jot "${N}"`; do resource="${RESOURCE}${i}" provname=$(hastctl status -c "${conf}" "${resource}" | awk '$1 == "provname:" {print $2}') if [ -z "$provname" ]; then echo "Can't get provname." >&2 exit 1 fi device="/dev/hast/${provname}" mount=$(printf "%s" "${MOUNT_TEMPLATE}" | subs ${node} X X ${resource}) mkdir -p "${mount}" if [ -c "${device}" ]; then mount "${device}" "${mount}" fi done done } umount_fs() { for i in `jot "${N}"`; do resource="${RESOURCE}${i}" mount=$(printf "%s" "${MOUNT_TEMPLATE}" | subs 1 X X ${resource}) mount | grep -q "^/dev/hast/.* on ${mount} " && umount -f "${mount}" done } status() { local node conf ps auxww | grep '[h]astd' && echo for node in 1 2; do conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node}) echo "NODE ${node}:" echo "-------" echo hastctl status -c "$conf" all echo done mount | grep "^/dev/hast/" && echo } ctl() { local node cmd conf node=$1; shift cmd=$1; shift conf=$(printf "%s" "${CONFNAME_TEMPLATE}" | subs ${node}) hastctl $cmd -c "$conf" $@ } destroy() { stop echo "Destroying devices." for node in 1 2; do for i in `jot "${N}"`; do mdunit=$((MDBASE + (node - 1) * N + i)) mdconfig -d -u "${mdunit}" done done } clean() { local node resource img destroy 2> /dev/null for node in 1 2; do for i in `jot "${N}"`; do resource="${RESOURCE}${i}" img=$(printf "%s" "${DISKFILE_TEMPLATE}" | subs ${node} X X ${resource}) rm -f "${img}" done done } usage() { echo "usage: $0 [options]" >&2 echo "" >&2 echo "commands:" >&2 echo "" >&2 echo " deploy [hastd options] - create devices, start HAST, make and mount FS" >&2 echo " start [hastd options] - start HAST (part of deploy)" >&2 echo " makefs - make FS on HAST (part of deploy)" >&2 echo " mount - mount HAST device (part of deploy)" >&2 echo " status - show current status" >&2 echo " ctl - run hastctl command for the node" >&2 echo " umount - unmount HAST FS" >&2 echo " reload - reload HAST configuration" >&2 echo " stop - stop HAST" >&2 echo " destroy - unmount FS, stop HAST and destroy devices" >&2 echo " destroy - destroy and remove created files" >&2 echo " test_ - Run test" >&2 echo "" >&2 exit 1 } # # Main # case $1 in deploy) shift; deploy $@ ;; start) shift; start $@ ;; makefs) make_fs ;; mount) mount_fs ;; status) status ;; ctl) test -n "$3" || usage shift; ctl $@ ;; umount) umount_fs ;; reload) reload ;; stop) stop ;; destroy) destroy ;; clean) clean ;; test_*) $1 ;; *) usage ;; esac