Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:GA
xen.3878
block-dmmd
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File block-dmmd of Package xen.3878
#! /bin/bash # Usage: block-dmmd [add args | remove args] # # the dmmd device syntax (in xm/xl commands/configs) is something like: # dmmd:md;/dev/md0;md;/dev/md1;lvm;/dev/vg1/lv1 # or # dmmd:lvm;/dev/vg1/lv1;lvm;/dev/vg1/lv2;md;/dev/md0 # device pairs (type;dev) are processed in order, with the last device # assigned to the VM # # md devices can optionally: # specify a config file through: # md;/dev/md100(/var/xen/config/mdadm.conf) # use an array name (mdadm -N option): # dmmd:md;My-MD-name;lvm;/dev/vg1/lv1 # # History: # 2016-05-27, mlatimer@suse.com: # Merge improvements by loic.devulder@mpsa.com. Highlights include: # - Re-write and simplification to speed up the script! # - Add some (useful) logging messages and comments # Minor tweaks and logging improvements # 2016-05-26, mlatimer@suse.com: # Verify MD activation if mdadm returns 2 # 2016-05-20, mlatimer@suse.com: # Strip leading "dmmd:" if present in xenstore params value # 2013-07-03, loic.devulder@mpsa.com: # Partial rewrite of the script for supporting MD activation by name # 2009-06-09, mh@novell.com: # Emit debugging messages into a temporary file; if no longer needed, # just comment the exec I/O redirection below # Make variables used in functions local to avoid global overridings # Use vgscan and vgchange where required # Use the C locale to avoid dealing with localized messages # Assign output from assembling an MD device to a variable to aid # debugging # We do not want to deal with localized messages # We use LC_ALL because LC_ALL superse LANG # But we also use LANG because some applications may still use LANG... export LC_ALL=C export LANG=${LC_ALL} # Loading common libraries . $(dirname $0)/block-common.sh # Constants typeset -rx MDADM_BIN=/sbin/mdadm typeset -rx LVCHANGE_BIN=/sbin/lvchange typeset -rx PVSCAN_BIN=/sbin/pvscan typeset -rx VGSCAN_BIN=/sbin/vgscan typeset -rx VGCHANGE_BIN=/sbin/vgchange typeset -rx DATE_LOG="date +%F_%T.%N" typeset -rx DATE_SEC="date +%s" # Uncomment for debugging purposes # exec >> /tmp/block-dmmd-$(${DATE_LOG}).log 2>&1 # echo shell-flags: $- # We check for errors ourselves set +e function run_mdadm() { local mdadm_cmd=$1 local msg local rc msg="$(${MDADM_BIN} ${mdadm_cmd} 2>&1)" rc=$? case "${msg}" in *"has been started"* | *"already active"*) return 0 ;; *"is already in use"*) # Hmm, might be used by another device in this domU # Leave it to upper layers to detect a real error return 2 ;; *) return ${rc} ;; esac # Normally we should not get here, but if this happens # we have to return an error return 1 } function activate_md() { # Make it explicitly local local par=$1 local cfg dev dev_path rc t mdadm_opts if [[ ${par} == ${par%%(*} ]]; then # No configuration file specified dev=${par} cfg="" else dev=${par%%(*} t=${par#*(} cfg="-c ${t%%)*}" fi # Looking for device name or aliase if [[ ${dev:0:1} == / ]]; then dev_path=${dev%/*} mdadm_opts="" else dev_path=/dev/md mdadm_opts="-s -N" fi # Logging message echo "[$(${DATE_LOG})] activate MD device ${dev}..." >&2 # Is MD device already active? # We need to use full path name, aliase is not possible... if [ -e $dev_path/${dev##*/} ]; then ${MDADM_BIN} -Q -D $dev_path/${dev##*/} 2>/dev/null \ | grep -iq state.*\:.*inactive || return 0 fi # Activate MD device run_mdadm "-A ${mdadm_opts} ${dev} ${cfg}" rc=$? # A return code of 2 can indicate the array configuration was incorrect if [[ ${rc} == 2 ]]; then # Logging message echo "[$(${DATE_LOG})] verifying MD device ${dev} activation..." >&2 # If the array is active, return 0, otherwise return an error ${MDADM_BIN} -Q -D $dev_path/${dev##*/} &>/dev/null && return 0 \ || return 1 fi return ${rc} } function deactivate_md() { local par=$1 local dev if [[ ${par} == ${par%%(*} ]]; then # No configuration file specified dev=${par} else dev=${par%%(*} fi # Looking for device name or aliase if [[ ${dev:0:1} == / ]]; then dev_path=${dev%/*} else dev_path=/dev/md fi # Logging message echo "[$(${DATE_LOG})] deactivate MD device ${dev}..." >&2 # We need the device name only while deactivating ${MDADM_BIN} -S ${dev_path}/${dev##*/} > /dev/null 2>&1 return $? } function activate_lvm() { local run_timeout=90 local parsed_timeout local end_time # If /etc/xen/xend-config.sxp exists (e.g. SLES11), use # device-create-timeout, instead of the default setting if [[ -f /etc/xen/xend-config.sxp ]]; then parsed_timeout=$(grep -v "^[ \t]*#.*" /etc/xen/xend-config.sxp \ |sed -n 's/(device-create-timeout \+\([0-9]\+\))/\1/p') if [[ ! -z $parsed_timeout ]]; then run_timeout=$((${parsed_timeout}*9/10)) fi fi # First scan for PVs and VGs # We need this for using MD device as PV ${PVSCAN_BIN} > /dev/null 2>&1 # ${VGSCAN_BIN} --mknodes > /dev/null 2>&1 # Logging message echo "[$(${DATE_LOG})] activate LVM device ${dev}..." >&2 # Set end_time for the loop (( end_time = $(${DATE_SEC}) + run_timeout )) while true; do ${LVCHANGE_BIN} -aey $1 > /dev/null 2>&1 if [ $? -eq 0 -a -e $1 ]; then return 0 fi sleep 0.1 # If it takes too long we need to return an error if (( $(${DATE_SEC}) >= end_time )); then log err "Failed to activate $1 within ${run_timeout} seconds" return 1 fi done # Normally we should not get here, but if this happens # we have to return an error return 1 } function deactivate_lvm() { # Logging message echo "[$(${DATE_LOG})] deactivate LVM device ${dev}..." >&2 ${LVCHANGE_BIN} -aen $1 > /dev/null 2>&1 if [ $? -eq 0 ]; then # We may have to deactivate the VG now, but can ignore errors: # ${VGCHANGE_BIN} -an ${1%/*} || : # Maybe we need to cleanup the LVM cache: # ${VGSCAN_BIN} --mknodes || : return 0 fi return 1 } # Variables typeset command=$1 typeset BP=100 typeset SP=${BP} typeset VBD typeset -a stack function push() { local value="$1" [[ -n "${value}" ]] \ && stack[$((--SP))]="${value}" return 0 } function pop() { [[ "${SP}" != "${BP}" ]] \ && VBD=${stack[$((SP++))]} \ || VBD="" return 0 } function activate_dmmd() { case "$1" in "md") activate_md $2 return $? ;; "lvm") activate_lvm $2 return $? ;; esac # Normally we should not get here, but if this happens # we have to return an error return 1 } function deactivate_dmmd() { case "$1" in "md") deactivate_md $2 return $? ;; "lvm") deactivate_lvm $2 return $? ;; esac # Normally we should not get here, but if this happens # we have to return an error return 1 } function cleanup_stack() { while true; do pop [[ -z "${VBD}" ]] && break deactivate_dmmd ${VBD} done } function parse_par() { # Make these vars explicitly local local ac par rc s t ac=$1 par="$2" par="${par};" while true; do t=${par%%;*} [[ -z "${t}" ]] && return 0 par=${par#*;} s=${par%%;*} [[ -z "${s}" ]] && return 1 par=${par#*;} if [[ "${ac}" == "activate" ]]; then activate_dmmd ${t} ${s} \ || return 1 fi push "${t} ${s}" done } case "${command}" in "add") p=$(xenstore-read ${XENBUS_PATH}/params) || true claim_lock "dmmd" dmmd=${p#dmmd:} if ! parse_par activate "${dmmd}"; then cleanup_stack release_lock "dmmd" exit 1 fi lastparam=${dmmd##*;} usedevice=${lastparam%(*} xenstore-write ${XENBUS_PATH}/node "${usedevice}" write_dev "${usedevice}" release_lock "dmmd" exit 0 ;; "remove") p=$(xenstore-read ${XENBUS_PATH}/params) || true claim_lock "dmmd" dmmd=${p#dmmd:} parse_par noactivate "${dmmd}" cleanup_stack release_lock "dmmd" exit 0 ;; esac # Normally we should not get here, but if this happens # we have to return an error return 1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor