#-----------------------------------------------------------------------------
# /var/install/include/xenlib
#
# - Not meant to be executet itself. It bears only functions.
# - This file should only be included in other scripts from eisxen package
# - interpreted with /bin/bash or /bin/sh
#
# Creation: 2007-10-07 rg
# Last Update: $Id$
#
# Copyright (c) 2007-2012 the eisfair team, team(at)eisfair(dot)org
#
# 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.
#-----------------------------------------------------------------------------
#============================================================================
# only include this file once
#============================================================================
if [ "$_XENLIB" != "true" ]
then
_XENLIB='true'
#============================================================================
#============================================================================
# here we read the eislib for all other files:
. /var/install/include/eislib
bridgeDevice="eth"
debugLvl="short" # possible values are short or verbose
# this is for bootup process while HOME is not yet set
if [ "$HOME" = "" ]
then
HOME='/root'
fi
#
#
xenDataPath='/data/xen'
configd='/etc/config.d'
defaultd='/etc/default.d'
xmd='/etc/xen'
#
#
configfile="$configd/xen"
defaultConfigfile="$defaultd/xen"
#
#
#
delimiter="-" # Invalid Values are any ".", [A-Za-z0-9]. Allowed is "-".
vmConfigPrefix='xm'
domUConfigPrefix="${vmConfigPrefix}domu"
domUConfigfile="$configd/${domUConfigPrefix}"
defaultDomUConfigfile="$defaultd/${domUConfigPrefix}"
#
#
xendConfigfile="$xmd/xend-config.sxp"
xmConfigfile="$xmd/xm-config.xml"
vmConfigPath="$xmd/${vmConfigPrefix}"
netsave="$xmd/netsave"
#
#
#
xenTemplatePath="$xenDataPath/templates"
xenImagePath="$xenDataPath/images"
fli4lPath="$xenDataPath/fli4l/fli4l"
#
#
defaultDomUkernel='/boot/vmlinuz-xen'
#
#
varrun='/var/run/xen.domu'
phyMem='/var/run/xen.phym'
#
#
#
XEN_API_SOCKET='yes'
XEN_API_XML='yes'
#
#
# fli4lver='3.4.0'
# fli4lTarbal="$xenTemplatePath/fli4l-$fli4lver.tar.gz"
# fli4lKernelVersion=`uname -r`
# fli4lKernelVersion=`basename /boot/vmlinuz-*-xen | sed -e 's#vmlinuz-##' -e 's#\([a-z0-9.\-]*\)_\([a-z0-9.\-]*\).*#\1#'`
extension='txt' # MUST be without leading dot!
#
#
# This should only run if a xen hypervisor is running
[ -d /sys/hypervisor/version ] && {
#
xenMajor=`cat /sys/hypervisor/version/major`
xenMinor=`cat /sys/hypervisor/version/minor`
xenExtra=`cat /sys/hypervisor/version/extra`
xenVersion=$xenMajor.$xenMinor$xenExtra
#
#
#
}
#
#
_RESET="$_EISLIB_COLOR_TTY_RESET" # default values (reset)
_INFO="$_EISLIB_COLOR_TTY_INFO" # green, like mecho --info
_ERROR="$_EISLIB_COLOR_TTY_ERROR" # White with red background
_BOLD="$_EISLIB_COLOR_TTY_MODE_BRIGHT" # Bold
_DARK="$_EISLIB_COLOR_TTY_MODE_DARK" # Darker
#
# After a VM is started the script will wait this time in seconds
# until the next vm will get started:
waitTime=2
# false - for use of xen-pre-setup.sh (slow),
# true - for use of xen-pre-setup.bin (fast)
usebin='true'
#
volumeGroup='vg'
#############
# functions #
#############
trapdebug () {
case "$1" in
on) trap 'echo -n "dbg> "; read cmd; eval $cmd' DEBUG ;;
off) trap '' DEBUG ;;
esac
}
preSetup() {
$usebin && {
/var/install/bin/xen-pre-setup.bin $domUConfigPrefix $delimiter
} || {
/var/install/bin/xen-pre-setup.sh
}
}
secureMountpoint () {
echo "$1" | grep -qs '^/tmp/[[:alnum:]]' && return 0 || {
mecho --warn "Unsecure mointpoint for this action. Aborting.!"
exit 1
}
}
# This function assures, that we remove files in a secure whay
remove () {
[ -L "$1" ] && rm -f "$1" && ${2:-false} && $3 $4 " - $1 - link successfully removed"
[ -f "$1" ] && rm -f "$1" && ${2:-false} && $3 $4 " - $1 - file successfully removed"
[ -d "$1" ] && rm -fr "$1" && ${2:-false} && $3 $4 " - $1 - directory successfully removed"
return 0
}
move () {
local bup=$2
[ $# -eq 1 ] && bup="$1~"
[ -f "$1" ] && mv -f "$1" "$bup"
return $?
}
repeat_sh_cmd () {
local cnt="$1" cmd="$2" arg1="$3" arg2="$4" oldopts=$-
set +vx
while [ $cnt -gt 0 ]
do
$cmd "$arg1" "$arg2"
cnt=`expr $cnt - 1`
done
set -$oldopts
}
# create relative links
ln_relative () {
local lnopts="$1" lntarget="$2" lnname="$3" nametoken targettoken ne_tokens oldopts=$-
if echo $lntarget | grep -qs ^/
then
set +vx
while :
do
nametoken="$(echo `dirname ${lnname#/}` | awk -F "/" '{ print $1 }')"
targettoken="$(echo `dirname ${lntarget#/}` | awk -F "/" '{ print $1 }')"
if [ "$nametoken" = "$targettoken" -a "$nametoken" != \. -a "$targettoken" != \. ]
then
eval lnname=\$\{lnname#/$nametoken\}
eval lntarget=\$\{lntarget#/$targettoken\}
else
ne_tokens="$(echo `dirname ${lnname#/}` | awk -F "/" '$0 == "." { print "0"; } { print NF }')"
lntarget="`repeat_sh_cmd $ne_tokens echo -n ../`${lntarget#/}"
break
fi
done
set -$oldopts
fi
ln "$lnopts" "$lntarget" "$3"
return $?
}
setVariable() {
local configFile="$1" variableName="$2" variableValue="$3"
grep -qs "$variableName='[^']*'" $configFile && {
sed -i "s#$variableName='[^']*'#$variableName='$variableValue'#" $configFile
} || {
echo "$variableName=\"$variableValue\"" >> $configFile
}
}
getFileTypeModifier() {
local tarbal="$1" comp r=0
case `file -bi $tarbal` in
application/x-gzip) comp=z ;;
application/x-bzip2) comp=j ;;
application/x-xz) comp=J ;;
application/x-tar) comp='' ;;
*) case ${tarbal##*\.} in
gz|tgz) comp=z ;;
bz2|tbz2) comp=j ;;
lzma|tlz|xz) comp=J ;;
taz|Z|taZ|tz2|tbz|lzo) comp=a ;;
*) r=1 ;;
esac ;;
esac
echo "$comp"
return $r
}
# this function removes this file extensions:
# .tar.*|.gz|.tgz|.bz2|.tbz|.tbz2|.tz2|.taz|.tlz|.Z|.taZ|.xz|.lzo|.lzma
remove_tarfile_extension () {
echo "$1" |
sed -e 's/\.tar\.\{0,1\}[^\.]*//'\
-e 's/\.t\{0,1\}[abglx]\{0,1\}[zZ]\{1\}2\{0,1\}o\{0,1\}\(ma\)\{0,1\}//'
}
# findDefaultname $template
# returns basename to be used as defaultName for domU
findDefaultname () {
local templ="$1" defname=
[ "${templ%%-*}" = "fli4l" ] && echo fli4l || {
defname=`remove_tarfile_extension ${templ##*/}`
echo ${defname%.disk}
}
}
# notValidHostname hostname
# return 1 if arg1 is a valid hostname, 0 otherwise
notValidHostname () {
echo -e "$1" | grep -qs '[^a-zA-Z0-9-]' && return 0 || return 1
}
getNextFreeDomainNameIndex() {
local prefix="$1" i=2
[ -f $xenImagePath/$prefix.disk -o -f "$domUConfigfile$delimiter$prefix" ] && {
while [ -f $xenImagePath/$prefix-$i.disk -o -f "$domUConfigfile$delimiter$prefix-$i" ]; do
i=`expr $i + 1`
done
echo "-$i"
}
}
# customizeHostname wantedName. This removes all unsupported characters and replace them with sensefull content
# if possible. Returns name="customizedName" This works for utf-8 and iso encoding
customizeHostname () {
local givenName="$1" oldopts=$-
set +vx
customizedName=`echo -e "$givenName" |
sed \
-e \$'s#\\303\\200#A#g' \
-e \$'s#\\303\\201#A#g' \
-e \$'s#\\303\\202#A#g' \
-e \$'s#\\303\\203#A#g' \
-e \$'s#\\303\\204#Ae#g' -e \$'s#\\304#Ae#g' \
-e \$'s#\\303\\205#A#g' \
-e \$'s#\\303\\206#AE#g' \
-e \$'s#\\303\\207#C#g' \
-e \$'s#\\303\\210#E#g' \
-e \$'s#\\303\\211#E#g' \
-e \$'s#\\303\\212#E#g' \
-e \$'s#\\303\\213#E#g' \
-e \$'s#\\303\\214#I#g' \
-e \$'s#\\303\\215#I#g' \
-e \$'s#\\303\\216#I#g' \
-e \$'s#\\303\\217#I#g' \
-e \$'s#\\303\\220#D#g' \
-e \$'s#\\303\\221#N#g' \
-e \$'s#\\303\\222#O#g' \
-e \$'s#\\303\\223#O#g' \
-e \$'s#\\303\\224#O#g' \
-e \$'s#\\303\\225#O#g' \
-e \$'s#\\303\\226#Oe#g' -e \$'s#\\326#Oe#g' \
-e \$'s#\\303\\227#x#g' \
-e \$'s#\\303\\230#O#g' \
-e \$'s#\\303\\231#U#g' \
-e \$'s#\\303\\232#U#g' \
-e \$'s#\\303\\233#U#g' \
-e \$'s#\\303\\234#Ue#g' -e \$'s#\\334#Ue#g' \
-e \$'s#\\303\\235#Y#g' \
-e \$'s#\\303\\236#-#g' \
-e \$'s#\\303\\237#ss#g' -e \$'s#\\337#ss#g' \
-e \$'s#\\303\\240#a#g' \
-e \$'s#\\303\\241#a#g' \
-e \$'s#\\303\\242#a#g' \
-e \$'s#\\303\\243#a#g' \
-e \$'s#\\303\\244#ae#g' -e \$'s#\\344#ae#g' \
-e \$'s#\\303\\245#a#g' \
-e \$'s#\\303\\246#ae#g' \
-e \$'s#\\303\\247#c#g' \
-e \$'s#\\303\\250#e#g' \
-e \$'s#\\303\\251#e#g' \
-e \$'s#\\303\\252#e#g' \
-e \$'s#\\303\\253#e#g' \
-e \$'s#\\303\\254#i#g' \
-e \$'s#\\303\\255#i#g' \
-e \$'s#\\303\\256#i#g' \
-e \$'s#\\303\\257#i#g' \
-e \$'s#\\303\\260#o#g' \
-e \$'s#\\303\\261#n#g' \
-e \$'s#\\303\\262#o#g' \
-e \$'s#\\303\\263#o#g' \
-e \$'s#\\303\\264#o#g' \
-e \$'s#\\303\\265#o#g' \
-e \$'s#\\303\\266#oe#g' -e \$'s#\\366#oe#g' \
-e \$'s#\\303\\267#-#g' \
-e \$'s#\\303\\270#o#g' \
-e \$'s#\\303\\271#u#g' \
-e \$'s#\\303\\272#u#g' \
-e \$'s#\\303\\273#u#g' \
-e \$'s#\\303\\274#ue#g' -e \$'s#\\374#ue#g' \
-e \$'s#\\303\\275#y#g' \
-e \$'s#\\303\\276#-#g' \
-e \$'s#\\303\\277#y#g' \
-e \$'s#\\302\\245#Yen#g' \
-e \$'s#\\302\\247#Paragraph#g' \
-e \$'s#\\302\\260#grad#g' \
-e \$'s#\\302\\261#PlusMinus#g' \
-e \$'s#\\302\\262#2#g' \
-e \$'s#\\302\\263#3#g' \
-e \$'s#\\302\\264#-#g' \
-e \$'s#\\302\\265#micro#g' \
-e \$'s#\\342\\202\\254#Euro#g' \
-e 's#@#-at-#g' \
-e 's#[^[:alnum:]]#-#g' \
-e 's#--*#-#g' \
-e 's#^-##g' \
-e 's#-$##g'`
set -$oldopts
[ "$2" = index ] && customizedName="$customizedName`getNextFreeDomainNameIndex $customizedName`"
echo "$customizedName"
}
# Checks whether the parameter contains a valid ip
isValidIp () {
echo "$1" |
grep -Eqs '\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b' && return 0 || return 1
}
askIP() {
local IP= question= type= proposal=
while [ $# -gt 0 ]
do
eval ${1%%=*}=\"${1#*=}\"
shift
done
IP=`/var/install/bin/ask --tty --info "Please enter $question" "$proposal" "+"`
until isValidIp $IP
do
mecho --error "Please enter a valid $type."
IP=`/var/install/bin/ask --tty --info "$question" "$proposal" "+"`
done
echo "$IP"
}
# checks if a domain allready exists.
# returns 0 if the domains already exists, 1 otherwise
isExistingDomainName () {
[ -f "$domUConfigfile$delimiter$1" ] && return 0 || return 1
}
passwordTemplateScriptInput() {
local pw1 pw2 oldopts=$-
mecho --info "Determine login/password:"
set +vx
while :; do
pw1=`/var/install/bin/ask --tty --info "Please enter the new root password: " "" "+hidden+"`
pw2=`/var/install/bin/ask --tty --info "\nPlease enter the password again: " "" "+hidden+"`
[ "$pw1" = "$pw2" ] && break || mecho --error "Sorry, passwords do not match."
done
newPassword=`mkpasswd $pw1`
set -$oldopts
echo
}
check_if_xend_runing () {
[ "$1" = verbose ] && mecho --info "\nChecking if xend is running$_RESET .."
xend status >/dev/null 2>&1 || /etc/init.d/xen startxend
}
checkIfVMIsUp () {
local domain="$1"
isUp="`xm list | awk '$1 == "'$domain'" && $2 != -1 && NF == 6 { print "true" }'`"
}
checkIsMem () {
local domain="${1:-Domain-0}"
xm list | awk '/'$domain'/ { print $3 }'
}
checkFreeMem () {
xm info | awk '/free_memory/ { print $3 }'
}
set_dom0_mem () {
local isMem=`checkIsMem` freeMem=`checkFreeMem` maxSetMem=2047
if [ $isMem -lt $maxSetMem ] && [ $freeMem -gt 1 ]; then
local setMem=`expr $isMem + $freeMem`
[ $setMem -gt $maxSetMem ] && setMem=$maxSetMem
xm mem-set Domain-0 "$setMem"
fi
}
unMount () {
local rc=1 oldopts=$-
[ -d "$1" ] && mount | grep -qs "$1" && {
cd
umount -d "$1" 2>/dev/null || {
set +vx
until [ $rc -eq 0 ]
do
mecho -n .
sleep 1
umount -d "$1" 2>/dev/null
rc=$?
done
set -$oldopts
}
}
}
# Run as job in background while showing progress and providing error messages
runasJob () {
local verbose=false short=false cmdline oldopts=$- diemsg tmpjob r=0
[ "$1" = verbose ] && { verbose=true; shift; }
[ "$1" = short ] && { short=true; shift; }
cmdline=$@
if $short; then
mecho -n " \$/>$_DARK $1 ..$_RESET"
verbose=true
elif $verbose; then
mecho -n " \$/>$_DARK $cmdline ..$_RESET"
fi
diemsg="`mktemp`" tmpjob="`mktemp`"
set +vx
eval $cmdline >"$diemsg" 2>&1 &
jobs >"$tmpjob"
until grep -qs "eval \$cmdline.*[^&]$" "$tmpjob"; do
$verbose && mecho -n "$_DARK.$_RESET"
sleep 1
jobs >"$tmpjob"
done
set -$oldopts
grep -qs "Exit[[:space:]][[:digit:]]" "$tmpjob" && {
mecho --error " failed!"
mecho --warn "${0##*/}: error running \"$cmdline\": "
mecho --warn "`cat "$diemsg"`"
remove "$tmpjob"
remove "$diemsg"
r=1
} || $verbose && mecho "$_DARK done.$_RESET"
remove "$tmpjob"
remove "$diemsg"
return $r
}
# XXX: api handling
registrate_domain () {
local quiet=false verbose=$debugLvl
[ $1 = --quiet ] && { quiet=true; verbose=; shift; }
[ $1 = --noxendcheck ] && shift || check_if_xend_runing # here no 'verbose'
$quiet || mecho --info "Registrate Domain $1$_RESET .."
# remove xm-config when xen api is disabled. Otherwise this file causes problems
[ "$XEN_API_XML" = no ] && remove "$xmConfigfile" # 'remove' checks if file exists
xm list | grep -qs "^$1 " || {
move "$xmConfigfile" "$xmConfigfile.disabled" # 'move' checks if file exists
runasJob $verbose xm new --path="$vmConfigPath" "$vmConfigPrefix$1"
[ "$XEN_API_XML" = yes ] && move "$xmConfigfile.disabled" "$xmConfigfile"
}
return 0
}
unpack () {
while [ $# -gt 0 ]
do
eval local ${1%%=*}=\"${1#*=}\"
shift
done
[ -z "$info" ] || mecho --info "$info"
runasJob $verbose "tar -xp`getFileTypeModifier "$tarbal"`f $tarbal" && return 0 || return 1
}
# copies kernel modules into the domU
copy_modules () {
local r=0
# check if $mountpoint is valid:
secureMountpoint $mountpoint
mecho --info "Copying kernel modules...$_RESET"
# remove $mountpoint/lib/modules # keep the old modules from other kernels for reuse.
remove $mountpoint/lib/modules/`uname -r`
mkdir -pm 0755 $mountpoint/lib/modules
runasJob $debugLvl cp -ar /lib/modules/`uname -r` --target-directory=$mountpoint/lib/modules/ || r=1
return $r
}
check_modules () {
local quiet=false verbose=$debugLvl
[ $1 = --quiet ] && { quiet=true; verbose=; shift; }
. $domUConfigfile$delimiter$1
if [ "$IS_FLI4L" = no -a "$HVM" = no -a "$USE_CUSTOM_KERNEL" = no ]
then
# first check the filesystem if not broken
$quiet || mecho --info "Checking filesystem on $DISK_1_UNAME$_RESET .."
runasJob $verbose e2fsck -y $DISK_1_UNAME
$quiet || mecho --info "Checking kernel modules$_RESET .."
mountpoint=$(mktemp -d)
trap 'unMount "$mountpoint" && remove "$mountpoint" && mountpoint=; exit 1' EXIT
if echo $DISK_1_UNAME | grep -Eqs "$xenImagePath/[[:alnum:]]([.-]?[[:alnum:]])*\.(disk|img)\$"
then
mountargs='-o loop'
elif echo $DISK_1_UNAME | grep -qs /dev/; then
mountargs='-t ext3'
fi
[ -n "$mountargs" ] && mount $mountargs $DISK_1_UNAME $mountpoint || {
mecho --error "Check of Kernel Modules failed"
$quiet && return 1 || exit 1
}
if [ ! -d $mountpoint/lib/modules/ ] # We could be in a wrong disk or image
then
# TODO: More posibilities to handle this. First only a simple warning:
mecho --warn "Directory /lib/modules/ not found. Is this a Linux filesystem?"
elif [ ! -d "$mountpoint/lib/modules/`uname -r`/" -a "$2" = "" ] || [ "$2" = "force" ]; then
copy_modules
fi
unMount "$mountpoint"
remove "$mountpoint"
mountpoint=
elif [ "$IS_FLI4L" = "yes" ]
then
$quiet || mecho --info "This is a fli4l domain."
elif [ "$HVM" = "yes" ]
then
mecho --info "This is a Fully virtualized domain"
elif [ "$USE_CUSTOM_KERNEL" = "yes" ]
then
$quiet || mecho --info "This domain uses its own kernel"
fi
return 0
}
isfli4l () {
ls "$fli4lPath/config.$1" >/dev/null 2>&1 && return 0 || return 1
}
prepare_fli4l () {
local fli4lVersion=${1}
[ -d `dirname $fli4lPath` ] || {
mkdir -p `dirname $fli4lPath`
cd `dirname $fli4lPath`
unpack verbose=$debugLvl "tarbal=$xenTemplatePath/fli4l-$fli4lVersion.tar.gz" "info=Extracting fli4l distribution. Please wait." && {
cd
ln_relative -sf $fli4lPath-$fli4lVersion $fli4lPath
# ln_relative -sf /lib/modules/ $fli4lPath/opt/files/lib/
# cp -R /lib/modules/`uname -r` $fli4lPath/opt/files/lib/modules/`uname -r`
# ln_relative -sf /boot/vmlinuz-$fli4lKernelVersion $fli4lPath/img/kernel-$fli4lKernelVersion.gz
# ln_relative -sf /boot/System.map-$fli4lKernelVersion $fli4lPath/img/System.map-$fli4lKernelVersion.gz
} || {
mecho --error "Couldn't extract $fli4lTarbal !"
anykey
exit 1
}
}
# preSetup
sh /var/install/config.d/xmdomu${delimiter}fli4l.sh 2>/dev/null
}
customizeNames () {
cd "$xenTemplatePath"
for j in `ls 2>/dev/null | grep -Es ".*\.(tar\.(bz2|gz|xz|lzo)|tgz|tbz|tbz2|tz2|taz|tlz|taZ)"`
do
[ "$j" = "${fli4lTarbal##*/}" ] || {
customizedTemplate=`echo "$j" | sed -e 's/(/[/g' -e 's/)/]/g' -e 's/\( \)\{1,\}/ /g' -e 's/\( \)\././g'`
[ "$j" = "$customizedTemplate" ] || move "$xenTemplatePath/$j" "$xenTemplatePath/$customizedTemplate"
}
done
[ -d "$xenImagePath" ] && {
cd "$xenImagePath"
for j in `ls 2>/dev/null | grep -Es ".*\.(disk|img)"`
do
customizedImage=`echo "$j" | sed -e 's#(#[#g' -e 's#)#]#g' -e 's#\( \)\{1,\}# #g' -e 's#\( \)\.#.#g'`
[ "$j" = "$customizedImage" ] || move "$xenImagePath/$j" "$xenImagePath/$customizedImage"
done
}
cd # back to $HOME
}
# user dialog to find vallid host- or domain names
# wantedName=`determineName $defaultName`
determineName () {
local index=false givenName="$1" wantedName=
local defName="$givenName"
shift
[ "$1" = index ] && index=true
while :
do
wantedName="`/var/install/bin/ask --tty --info "Name of domain" "$defName" "+"`"
if notValidHostname "$wantedName"
then
mecho --error "Sorry, but this name is not allowed" >/dev/tty
elif isExistingDomainName "$wantedName"
then
mecho --error "A domain with the name '$wantedName' already exists!" >/dev/tty
elif [ "$defName" = "$wantedName" ]
then
break
fi
defName="`customizeHostname "$wantedName"`"
if [ "$defName" != "$givenName" ] && "$index"
then
defName="$defName`getNextFreeDomainNameIndex "$defName"`"
elif [ -z "$defName" ]
then
defName="$givenName"
fi
[ "$defName" = "$wantedName" ] && break
done
echo "$wantedName"
}
search_4_configfiles () {
# [ -f ${domUConfigfile}${delimiter}fli4l ] && {
# ls "${domUConfigfile}"_[0-9][0-9]_fli4l >/dev/null 2>&1 || ln_relative -s ${domUConfigfile}-fli4l ${domUConfigfile}_00_fli4l
# }
for dom in `ls ${domUConfigfile}${delimiter}* 2>/dev/null`
do
name=`echo $dom | sed 's#^'${domUConfigfile}${delimiter}'##'`
ls "${domUConfigfile}_[0-9][0-9]_$name" >/dev/null 2>&1 || ln_relative -s ${domUConfigfile}${delimiter}${name} ${domUConfigfile}_50_$name
done
}
createFSonImage () {
local type="$1" img="$2"
case "$type" in
disk) runasJob $debugLvl "echo y | mkfs.ext3 $img"
sleep 1
runasJob $debugLvl "tune2fs -c0 -i0 $img" ;;
swap) runasJob $debugLvl "mkswap $img" ;;
esac
}
useExistingDiskImage () {
local r=0 image="$1"
[ -e "$image" ] && {
createFSonImage ${image##*\.} "$image"
} || {
mecho --error "Image $image does not exist!"
r=1
}
return $r
}
createDiskImage () {
local type="$1" domuName="$2" sizeK="$3" fs="$4" diskName
diskname="$xenImagePath/$domuName.$type"
[ -f "diskname" ] && {
mecho --error "Image $domuName.$type already exists!"
return 1
} || {
runasJob $debugLvl dd if=/dev/zero of=$diskname bs=1k seek=$sizeK count=1
if [ "$fs" != none ]
then
createFSonImage $type "$diskname"
fi
}
}
createLvmImage () {
local type="$1" domuName="$2" vgName="$3" sizeK="$4" fs="$5"
[ "$type" = swap ] && domuName="$domuName-swap"
modprobe dm_mod
[ -e "/dev/$vgName/$domuName" ] && {
mecho --error "Logical Volume \"/dev/$vgName/$domuName\" already exists!"
return 1
} || {
runasJob $debugLvl lvcreate -n $domuName -L ${sizeK}K $vgName
if [ "$fs" != none ]
then
createFSonImage $type "/dev/$vgName/$domuName"
fi
}
}
checkSwap () {
swapimage=$xenImagePath/$name.swap
swapsizeM=`expr ${MEMORY:-$mem} \* 2`
swapsize=`expr $swapsizeM \* 1024`
[ -e "$swapimage" ] && sizeM=`ls -l $1 | awk '{ print $5 / 1048576 }'` || sizeM="0"
[ $sizeM -ne $swapsizeM ] && {
remove "$swapimage"
vgs | grep -qs $volumeGroup &&
createLvmImage swap $name $volumeGroup $swapsize ||
createDiskImage swap $name $swapsize
}
}
generateMac () {
# generating random Media Access Control-(mac-)address from official Xensource Address-Pool
dd if=/dev/urandom bs=1 count=3 2>/dev/null | od -tx1 | awk 'NR == 1 { print "00:16:3e:"$2":"$3":"$4 }'
}
# This is important to free unused devices for reimport
cleanvmConfigPath () {
local name
for vmConfig in `ls $vmConfigPath/$vmConfigPrefix* 2>/dev/null`
do
name=`echo "$vmConfig" | sed 's#^'$vmConfigPath/$vmConfigPrefix'##'`
[ -f "$domUConfigfile$delimiter$name" ] || remove $vmConfig
done
}
unusedSwapPartitions=/tmp/unusedSwapPartitions
searchUnusedSwapPartitions () {
remove "$unusedSwapPartitions"
# Already mounted in the host or in use for other xenmdomain??
for swappartition in `fdisk -l | grep -vs raid | awk '/swap/ { print $1 }'`
do
grep -qs "$swappartition" /etc/fstab || {
UUID=`blkid -s UUID $swappartition | sed -e 's#^'$swappartition': UUID="##' -e 's#[^a-zA-Z0-9-]##g'`
[ -n "$UUID" ] && ! grep -qs "$UUID" /etc/fstab && {
grep -qs phy:$swappartition $vmConfigPath/* || echo $swappartition >>$unusedSwapPartitions
}
}
done
}
unusedPartitions=/tmp/unusedPartitions
unusedLVMPartitions=/tmp/unusedLVMPartitions
searchUnusedPartitions () {
local path tempDisks=/tmp/foundDisks tempLVM=/tmp/foundLVMdisks
for path in $unusedPartitions $unusedLVMPartitions $tempDisks $tempLVM; do remove $path
done
lvm pvs -v > $tempLVM 2>/dev/null
fdisk -l | grep -Evs 'raid|swap' | awk '/\/dev\// { sub(/Disk/,""); print $1 }' | grep -vs ':' >$tempDisks
fdisk -l | awk '/\/dev\/[^[:space:]]+:/ { sub(/Disk/,""); print $1 }' | sed 's#:$##g' >$unusedPartitions
# do exist partitions or is it a complete disk?
for disk in `grep -s /dev/ $unusedPartitions`; do grep -qs $disk $tempDisks || echo $disk >>$tempDisks
done
remove $unusedPartitions
# Already mounted in the host or in use for other xenmdomain or part of a lvm-vg?
for partition in `grep -s /dev/ $tempDisks`
do
grep -qs $partition /etc/fstab || {
UUID=`blkid -s UUID $partition | sed -e 's#^'$partition': UUID="##' -e 's#[^a-zA-Z0-9-]##g'`
[ -n "$UUID" ] && ! grep -qs $UUID /etc/fstab && ! grep -qs phy:$partition $vmConfigPath/* && ! grep -qs $UUID $tempLVM &&
echo $partition >>$unusedPartitions
}
done
for path in $tempDisks $tempLVM; do remove $path; done
# scanning for lvm volumes:
for lv in `lvm lvscan | sed 's# #_#g'`
do
lv=${lv#*\'}
lv=${lv%%\'*}
UUID=`blkid -s UUID $lv | sed -e 's#^'$lv': UUID="##' -e 's#[^a-zA-Z0-9-]##g'`
[ -n "$UUID" ] && ! grep -qs $UUID /etc/fstab && ! grep -qs phy:$lv $vmConfigPath/* && echo $lv >>$unusedLVMPartitions
done
}
unusedImages=/tmp/unusedImages
searchUnusedImages () {
remove $unusedImages
[ -d $xenImagePath ] && {
# Already used in other xenmdomain?
for image in `ls $xenImagePath | grep -Es '\.(disk|img)$'`
do
grep -qs :$xenImagePath/$image $vmConfigPath/* || echo $image >>$unusedImages
done
}
}
#============================================================================
# end only include once
#============================================================================
fi
#============================================================================
# end
#============================================================================