[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-users] Xen 4.2.2 /etc/init.d/xendomains save and restore of domains does not work
I have created a created a solution that save and restore domains with xl in sxp and json format. It is only tested on my System: Debian squeeze Kernel 3.9.8 von kernel.org Xen 4.2.2 As the base for my working I took xendomains( http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=543a2657182dbb9237d1feeb1d3193096ab2cb2d ) My System has 5 domains started by symlinks in /etc/xen/auto/* the domain config file names differ from the domain name domain fwgw /etc/xen/auto/00_fwgw -> /etc/xen/fwgw.cfg etc. The new "version" contains some comments starting with #AGThis comments are a little bit unordered loud thinking about my idea an can be removed and sometimes the old implementation. They can be removedThere is one question about an eval instruction where I am not sure if it is save: + #AG I am not a fan of using eval on variables with uncheck content. + #AG Some body could name a domain like "$(touch /tmp/dummy)"+ #AG that is possible xl create --dryrun --defconfig ... except such a domain names + #AG I did not try to create i finally+ #AG I tryed some some combination to do a hack on this expression but I always failed. + #AG I think the `\´ in front of `$´ makes it save but I am not shure if this is always right. eval " case \"\$name\" inOrdered auto starting of domains is not yet implemented. I think about using alphabetic order of /etc/xen/auto/* for starting and reverse order for stopping. I think to implement more dependencies would be to complicated for xendomains and a big project for its own. The patch fix the sxp -1 domain id bug by using xl list -l <domainname> ... The patch fix the empty state problem by using xl list <domainname> ...I replaced the LIST_GREP expression by a function which translate the sxp/json formated output from xl list -l to a stream of lines of `id:<value> name:<value>´. This lines are handled by the new readln implementation. First I thought about to using eval to set the variables. But I think the risk is to high, if there is something bad in the values. I only tested save and restore of domains. I did not test XENDOMAINS_SYSRQ, XENDOMAINS_MIGRATE and XENDOMAINS_SHUTDOWNfor different reasons ( not enough skill, no destination to migrate to, there is nothing changed in this blocks except that state in watchdog has now a value, and my family becomes angry about the up and downs of the server ;-) ) I would be glad if you give it a chance and test it. ThanksQuestion: Is it ok to use local for variable declarations in functions of ? Normally I prefer that. Andreas --vvvv xendomains patch ----------------------------- --- xendomains.4.3 2013-07-01 11:48:41.000000000 +0200 +++ xendomains 2013-07-04 23:55:03.000000000 +0200 @@ -26,15 +26,18 @@ # Description: Start / stop domains automatically when domain 0 # boots / shuts down. ### END INIT INFO +#AG set -x +#AG set -v . /etc/xen/scripts/hotplugpath.sh -CMD=${SBINDIR}/xm +CMD="${SBINDIR}/xm" HEADCOMP="LinuxGuestRecord" + $CMD list &> /dev/null if test $? -ne 0 then - CMD=${SBINDIR}/xl + CMD=${SBINDIR}/xl HEADCOMP="Xen saved domain" fi @@ -185,8 +188,35 @@ # read name from xen config file rdname() { - NM=$($CMD create --quiet --dryrun --defconfig "$1" | - sed -n 's/^.*(name \(.*\))$/\1/p') + #AG the old implementation works only for sxp formated output + #AG NM=$($CMD create --quiet --dryrun --defconfig "$1" | + #AG sed -n 's/^.*(name \(.*\))$/\1/p') + + #AG The new implemnetation works with an pattern matching address range + #AG but only if the output of xl is in correct json or sxp format + #AG For json the output must start with a line containing only a `{´+ #AG and ending with a line containing only a `}´. All lines bevor "start" and after "end" + #AG are ignored. For sxp the output must start with a line containing only a `(domain´ + #AG and ending with a line containing only a `)´ + #AG+ #AG /^[{]$/,/^[}]$/ {...} is an pattern address range match it executes the block {...} + #AG for every line between the start pattern `^[{]$´ and the end pattern `^[}]$´ + #AG including the lines with start and end pattern. `[{]´ is the same as `\{´ . I prefer + #AG the first one for sed scripts in shell scripts because it make its clear that it + #AG belongs to the sed script and not to the shell script.+ #AG Here the first addres range /^[{]$/,/^[}]$/ {...} gets aktive if the output is in + #AG JSON format and the second /^[(]domain$/,/^[)]$/ {...} when the output is in sxp fromat. + #AG Thanks to the author of http://www.grymoire.com/Unix/Sed.html#uh-25 for explaining sed + #AG so clear. + NM=$( + ${CMD} create --quiet --dryrun --defconfig "${1}" \ + | sed -n -e ' + /^[{]$/,/^[}]$/ { + s/^.*"name": "\(.*\)",$/\1/p } + /^[(]domain$/,/^[)]$/ { + s/^.*(name \(.*\))$/\1/p } + ' + ) } rdnames() @@ -206,22 +236,113 @@ done } -LIST_GREP='(domain\|(domid\|(name\|^ {$\|"name":\|"domid":' -parseln() -{ - if [[ "$1" =~ '(domain' ]] || [[ "$1" = "{" ]]; then - name=;id= - elif [[ "$1" =~ '(name' ]]; then - name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/') - elif [[ "$1" =~ '(domid' ]]; then - id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/') - elif [[ "$1" =~ '"name":' ]]; then - name=$(echo $1 | sed -e 's/^.*"name": "\(.*\)",$/\1/') - elif [[ "$1" =~ '"domid":' ]]; then - id=$(echo $1 | sed -e 's/^.*"domid": \(.*\),$/\1/') - fi - [ -n "$name" -a -n "$id" ] && return 0 || return 1 +getDomStateByName () { + local _name= + local _id= + local _mem= + local _vcpu= + local _state= + local _time= + local _dummy= + while read _name _id _mem _vcpu _state _time _dummy; do + [ -n "${_state}" ] && break; + done <<EOF+$( ${CMD} list "${1}" | sed -n -e '/^Name[ ][ ]*ID[ ][ ]*Mem[ ][ ]*VCPUs[ ][ ]*State/! p' ) +EOF + echo "${_state}" +} + +getDomIdByName () { + $CMD list -l "${1}" \ + | sed -n -e '/^{$/,/^}$/ { s/^.*"domid": "\(-\?[0-9][0-9]*\)",$/\1/p } + /^(domain$/,/^)$/ { s/^.*(domid \(-\?[0-9][0-9]*\))$/\1/p }' +} + +#AG LIST_GREP='(domain\|(domid\|(name\|^ {$\|"name":\|"domid":'+#AG list_domians() is the replacement for the expression ($CMD list -l | grep "$LIST_GREP") +#AG here the sxp and json parsing is impelmented +#AG for every domain it produce a line with `id:<value> name:<value>´+#AG Perhaps it is possible to combine the two sed piped sed script to a single one but at +#AG the moment I couldn' see the solution. +list_domains () { + #AG ^[ ] contain a space and a ht 0x09 + $CMD list -l \ + | sed -n -e ' + /^ {$/,/^ },$/ { + s/^[ ][ ]*"domid": \(-\?[0-9][0-9]*\),$/id="\1" / p + s/^[ ][ ]*"name": "\(.*\)",$/name="\1" / p + s/^ }\(,\|\)$/BREAK/ p + } + /^(domain$/,/^)$/ { + s/^[ ][ ]*(domid \(-\?[0-9][0-9]*\))$/id="\1" / p + s/^[ ][ ]*(name \(.*\))$/name="\1" / p + s/^)$/BREAK/ p + } + ' \ + | sed -n -e ' + /BREAK$/! { H } + /BREAK$/ { + x + s/\n//g + p + s/.*// + x + } + ' +} + +#AG parseln() +#AG { +#AG if [[ "$1" =~ '(domain' ]] || [[ "$1" = "{" ]]; then +#AG name=;id= +#AG elif [[ "$1" =~ '(name' ]]; then +#AG name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/') +#AG elif [[ "$1" =~ '(domid' ]]; then +#AG id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/') +#AG elif [[ "$1" =~ '"name":' ]]; then +#AG name=$(echo $1 | sed -e 's/^.*"name": "\(.*\)",$/\1/') +#AG elif [[ "$1" =~ '"domid":' ]]; then +#AG id=$(echo $1 | sed -e 's/^.*"domid": \(.*\),$/\1/') +#AG fi +#AG +#AG [ -n "$name" -a -n "$id" ] && return 0 || return 1 +#AG } +parseln () { + id= + name= + state= + for _i in ${LN}; do + _k="${_i%=*}" + case "${_k}" in + (name) + _v="${_i#${_k}=}" + if [ "${_v}" != "${_i}" ]; then + _v="${_v//\"/}" + name="${_v}" + fi + ;; + (id) + _v="${_i#${_k}=}" + if [ "${_v}" != "${_i}" ]; then + _v="${_v//\"/}" + id="${_v}" + fi + ;; + esac + done + if [ -n "${name}" -a \( -z "${id}" -o "${id}" = "-1" \) ]; then + v="$(getDomIdByName ${name})" + if [ -n "${v}" ]; then + id="${v}" + fi + fi + if [ -n "${name}" -a -n "${id}" ]; then + state="$(getDomStateByName ${name})" + return 0 + else + return 1 + fi } is_running() @@ -237,7 +358,10 @@ RC=0 ;; esac - done < <($CMD list -l | grep "$LIST_GREP") + done <<EOF +$( list_domains ) +EOF + #AG done < <($CMD list -l | grep "$LIST_GREP") return $RC } @@ -319,7 +443,10 @@ if test "$state" != "-b---d" -a "$state" != "-----d"; then return 1; fi - done < <($CMD list -l | grep "$LIST_GREP") + done <<EOF +$( list_domains ) +EOF + #AG done < <($CMD list -l | grep "$LIST_GREP") return 0 } @@ -368,6 +495,12 @@ if test $id = 0; then continue; fi echo -n " $name" if test "$XENDOMAINS_AUTO_ONLY" = "true"; then+ #AG I am not a fan of using eval on variables with uncheck content. + #AG Some body could name a domain like "$(touch /tmp/dummy)"+ #AG that is possible xl create --dryrun --defconfig ... except such a domain names + #AG I did not try to create i finally+ #AG I tryed some some combination to do a hack on this expression but I always failed. + #AG I think the `\´ in front of `$´ makes it save but I am not shure if this is always right. eval " case \"\$name\" in ($NAMES) @@ -450,7 +583,10 @@ fi kill $WDOG_PID >/dev/null 2>&1 fi - done < <($CMD list -l | grep "$LIST_GREP") + done <<EOF +$( list_domains ) +EOF + #AG done < <($CMD list -l | grep "$LIST_GREP") # NB. this shuts down ALL Xen domains (politely), not just the ones in # AUTODIR/* @@ -487,7 +623,10 @@ return 0 ;; esac - done < <($CMD list -l | grep "$LIST_GREP") + done <<EOF +$( list_domains) +EOF + #AG done < <($CMD list -l | grep "$LIST_GREP") return 1 } --^^^^ xendomains patch ----------------------------- On 07/01/13 19:09, Ian Murray wrote: ----- Original Message -----From: Andreas Greve<greve-ml@xxxxxxxxxx> To: Ian Murray<murrayie@xxxxxxxxxxx> Cc: greve-ml@xxxxxxxxxx; xen-users<xen-users@xxxxxxxxxxxxx>; andreas.greve@xxxxxxxxxx Sent: Monday, 1 July 2013, 17:44 Subject: Re: [Xen-users] Xen 4.2.2 /etc/init.d/xendomains save and restoreof domains does not workI have an idea. assumptions: SXP format: root@srv01:~# xl create --quiet --dryrun --defconfig /etc/xen/auto/03_gnomedag | head -10 (domain (domid -1) (create_info) (hvm 0) (hap<default>) (oos<default>) (ssidref 0) (name gnomedag) (uuid<unknown>) (cpupool Pool-0) [...] ) root@srv01:~# JSON format: xl create --quiet --dryrun --defconfig /etc/xen/auto/03_gnomedag | head -10 { "domid": null, "config": { "c_info": { "type": "pv", "hap": "<default>", "oos": "<default>", "ssidref": 0, "name": "gnomedag", "uuid": "d9a9eba0-e7b8-4d16-ad6e-bb4cac05fd14", [...] } Let use sed pattern address ranges to distinguish between JSON and SXP. xl create --quiet --dryrun --defconfig /etc/xen/auto/03_gnomedag \ | sed -n -e '/^[{]$/,/^[}]$/ { s/^.*"name": "\(.*\)",$/\1/p } /^[(]domain$/,/^[)]$/ { s/^.*(name \(.*\))$/\1/p }' /^[{]$/,/^[}]$/ identify JSON /^[(]domain$/,/^[)]$/ identify SXP the line break between ...\1/p} and /^[(]domain$... is syntactical needed by sed. sed -n -e '/^[{]$/,$ { s/^.*"name": "\(.*\)",$/\1/p } /^[(]domain$/,$ { s/^.*(name \(.*\))$/\1/p }'< json.out in the example above ,$ in the address range part means until end of file For the JSON filter perhaps you can use somthing like this /^[ ]*"c_info": [{]$/,$ as address range because `"c_info": {´ is comes close before `"name:" "gnomedag"´ but I know not enough about xl to estimate if that is always true. but further I have to look at the stop() function at the block if test "$XENDOMAINS_AUTO_ONLY" = "true"; then eval [...] fi for bad side effects of the now working rdnames() -> rdname()You've gone beyond my sed/regex skills so I can't really assist on the above. I think the best thing is for you to try to get it into a working patch and I'd be happy to test it, then you could submit it to the dev list for inclusion. Also beware that there is an bug in xl list -l in sxp format. The domain id comes out as -1 for a running domain. I agreed to adapt a commit as a backport when we discussed this on dev list.[...] _______________________________________________ Xen-users mailing list Xen-users@xxxxxxxxxxxxx http://lists.xen.org/xen-users
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |