|
|
cf07b3 |
diff --git a/heartbeat/VirtualDomain b/heartbeat/VirtualDomain
|
|
|
cf07b3 |
index 50c1eaa..6582a16 100755
|
|
|
cf07b3 |
--- a/heartbeat/VirtualDomain
|
|
|
cf07b3 |
+++ b/heartbeat/VirtualDomain
|
|
|
cf07b3 |
@@ -18,13 +18,11 @@
|
|
|
cf07b3 |
|
|
|
cf07b3 |
# Defaults
|
|
|
cf07b3 |
OCF_RESKEY_force_stop_default=0
|
|
|
cf07b3 |
-OCF_RESKEY_hypervisor_default="$(virsh --quiet uri)"
|
|
|
cf07b3 |
OCF_RESKEY_autoset_utilization_cpu_default="true"
|
|
|
cf07b3 |
OCF_RESKEY_autoset_utilization_hv_memory_default="true"
|
|
|
cf07b3 |
OCF_RESKEY_migrateport_default=$(( 49152 + $(ocf_maybe_random) % 64 ))
|
|
|
cf07b3 |
|
|
|
cf07b3 |
: ${OCF_RESKEY_force_stop=${OCF_RESKEY_force_stop_default}}
|
|
|
cf07b3 |
-: ${OCF_RESKEY_hypervisor=${OCF_RESKEY_hypervisor_default}}
|
|
|
cf07b3 |
: ${OCF_RESKEY_autoset_utilization_cpu=${OCF_RESKEY_autoset_utilization_cpu_default}}
|
|
|
cf07b3 |
: ${OCF_RESKEY_autoset_utilization_hv_memory=${OCF_RESKEY_autoset_utilization_hv_memory_default}}
|
|
|
cf07b3 |
: ${OCF_RESKEY_migrateport=${OCF_RESKEY_migrateport_default}}
|
|
|
cf07b3 |
@@ -67,9 +65,10 @@ for this virtual domain.
|
|
|
cf07b3 |
<longdesc lang="en">
|
|
|
cf07b3 |
Hypervisor URI to connect to. See the libvirt documentation for
|
|
|
cf07b3 |
details on supported URI formats. The default is system dependent.
|
|
|
cf07b3 |
+Determine your systems default uri by running 'virsh --quiet uri'
|
|
|
cf07b3 |
</longdesc>
|
|
|
cf07b3 |
<shortdesc lang="en">Hypervisor URI</shortdesc>
|
|
|
cf07b3 |
-<content type="string" default="${OCF_RESKEY_hypervisor_default}"/>
|
|
|
cf07b3 |
+<content type="string" />
|
|
|
cf07b3 |
</parameter>
|
|
|
cf07b3 |
|
|
|
cf07b3 |
<parameter name="force_stop" unique="0" required="0">
|
|
|
cf07b3 |
@@ -206,52 +205,18 @@ update_utilization() {
|
|
|
cf07b3 |
# Set options to be passed to virsh:
|
|
|
cf07b3 |
VIRSH_OPTIONS="--connect=${OCF_RESKEY_hypervisor} --quiet"
|
|
|
cf07b3 |
|
|
|
cf07b3 |
-# A state file where we record the domain name:
|
|
|
cf07b3 |
-STATEFILE="${HA_RSCTMP}/VirtualDomain-${OCF_RESOURCE_INSTANCE}.state"
|
|
|
cf07b3 |
-
|
|
|
cf07b3 |
-VirtualDomain_Define() {
|
|
|
cf07b3 |
- local virsh_output
|
|
|
cf07b3 |
- local domain_name
|
|
|
cf07b3 |
- # Note: passing in the domain name from outside the script is
|
|
|
cf07b3 |
- # intended for testing and debugging purposes only. Don't do this
|
|
|
cf07b3 |
- # in production, instead let the script figure out the domain name
|
|
|
cf07b3 |
- # from the config file. You have been warned.
|
|
|
cf07b3 |
- if [ -z "$DOMAIN_NAME" ]; then
|
|
|
cf07b3 |
- # Spin until we have a domain name
|
|
|
cf07b3 |
- while true; do
|
|
|
cf07b3 |
- virsh_output=$( (virsh ${VIRSH_OPTIONS} define ${OCF_RESKEY_config}) 2>&1)
|
|
|
cf07b3 |
- domain_name=`echo "$virsh_output" | sed -n -e 's/Domain \(.*\) defined from .*$/\1/p'`
|
|
|
cf07b3 |
- if [ -n "$domain_name" ]; then
|
|
|
cf07b3 |
- break;
|
|
|
cf07b3 |
- fi
|
|
|
cf07b3 |
- domain_name=`echo $virsh_output | sed -n -e "s/.* '\(.*\)' already exists .*/\1/p"`
|
|
|
cf07b3 |
- if [ -n "$domain_name" ]; then
|
|
|
cf07b3 |
- break;
|
|
|
cf07b3 |
- fi
|
|
|
cf07b3 |
- ocf_log debug "Domain not defined yet, probably unable to connect to hypervisor. Retrying."
|
|
|
cf07b3 |
- sleep 1
|
|
|
cf07b3 |
- done
|
|
|
cf07b3 |
- echo "$domain_name" > $STATEFILE
|
|
|
cf07b3 |
- ocf_log info "Domain name \"$domain_name\" saved to $STATEFILE."
|
|
|
cf07b3 |
- else
|
|
|
cf07b3 |
- ocf_log warn "Domain name ${DOMAIN_NAME} already defined, overriding configuration file ${OCF_RESKEY_config}. You should do this for testing only."
|
|
|
cf07b3 |
- fi
|
|
|
cf07b3 |
-}
|
|
|
cf07b3 |
-
|
|
|
cf07b3 |
-VirtualDomain_Cleanup_Statefile() {
|
|
|
cf07b3 |
- rm -f $STATEFILE || ocf_log warn "Failed to remove $STATEFILE during $__OCF_ACTION."
|
|
|
cf07b3 |
-}
|
|
|
cf07b3 |
-
|
|
|
cf07b3 |
VirtualDomain_Status() {
|
|
|
cf07b3 |
local try=0
|
|
|
cf07b3 |
rc=$OCF_ERR_GENERIC
|
|
|
cf07b3 |
status="no state"
|
|
|
cf07b3 |
while [ "$status" = "no state" ]; do
|
|
|
cf07b3 |
try=$(($try + 1 ))
|
|
|
cf07b3 |
- status="`virsh $VIRSH_OPTIONS domstate $DOMAIN_NAME`"
|
|
|
cf07b3 |
+ status="`virsh $VIRSH_OPTIONS domstate $DOMAIN_NAME 2>&1`"
|
|
|
cf07b3 |
case "$status" in
|
|
|
cf07b3 |
- "shut off")
|
|
|
cf07b3 |
- # shut off: domain is defined, but not started
|
|
|
cf07b3 |
+ *"error:"*"Domain not found"*|"shut off")
|
|
|
cf07b3 |
+ # shut off: domain is defined, but not started, will not happen if
|
|
|
cf07b3 |
+ # domain is created but not defined
|
|
|
cf07b3 |
+ # Domain not found: domain is not defined and thus not started
|
|
|
cf07b3 |
ocf_log debug "Virtual domain $DOMAIN_NAME is currently $status."
|
|
|
cf07b3 |
rc=$OCF_NOT_RUNNING
|
|
|
cf07b3 |
;;
|
|
|
cf07b3 |
@@ -264,7 +229,7 @@ VirtualDomain_Status() {
|
|
|
cf07b3 |
ocf_log debug "Virtual domain $DOMAIN_NAME is currently $status."
|
|
|
cf07b3 |
rc=$OCF_SUCCESS
|
|
|
cf07b3 |
;;
|
|
|
cf07b3 |
- ""|"no state")
|
|
|
cf07b3 |
+ ""|*"Failed to reconnect to the hypervisor"*|"no state")
|
|
|
cf07b3 |
# Empty string may be returned when virsh does not
|
|
|
cf07b3 |
# receive a reply from libvirtd.
|
|
|
cf07b3 |
# "no state" may occur when the domain is currently
|
|
|
cf07b3 |
@@ -314,7 +279,7 @@ VirtualDomain_Start() {
|
|
|
cf07b3 |
return $OCF_ERR_GENERIC
|
|
|
cf07b3 |
fi
|
|
|
cf07b3 |
|
|
|
cf07b3 |
- virsh $VIRSH_OPTIONS start ${DOMAIN_NAME}
|
|
|
cf07b3 |
+ virsh $VIRSH_OPTIONS create ${OCF_RESKEY_config}
|
|
|
cf07b3 |
rc=$?
|
|
|
cf07b3 |
if [ $rc -ne 0 ]; then
|
|
|
cf07b3 |
ocf_log error "Failed to start virtual domain ${DOMAIN_NAME}."
|
|
|
cf07b3 |
@@ -327,11 +292,33 @@ VirtualDomain_Start() {
|
|
|
cf07b3 |
return $OCF_SUCCESS
|
|
|
cf07b3 |
}
|
|
|
cf07b3 |
|
|
|
cf07b3 |
+force_stop()
|
|
|
cf07b3 |
+{
|
|
|
cf07b3 |
+ local out ex
|
|
|
cf07b3 |
+ local status
|
|
|
cf07b3 |
+
|
|
|
cf07b3 |
+ ocf_log info "Issuing forced shutdown (destroy) request for domain ${DOMAIN_NAME}."
|
|
|
cf07b3 |
+ out=$(virsh $VIRSH_OPTIONS destroy ${DOMAIN_NAME} 2>&1)
|
|
|
cf07b3 |
+ ex=$?
|
|
|
cf07b3 |
+ echo >&2 "$out"
|
|
|
cf07b3 |
+ case $ex$out in
|
|
|
cf07b3 |
+ *"error:"*"domain is not running"*|*"error:"*"Domain not found"*)
|
|
|
cf07b3 |
+ : ;; # unexpected path to the intended outcome, all is well
|
|
|
cf07b3 |
+ [!0]*)
|
|
|
cf07b3 |
+ return $OCF_ERR_GENERIC ;;
|
|
|
cf07b3 |
+ 0*)
|
|
|
cf07b3 |
+ while [ $status != $OCF_NOT_RUNNING ]; do
|
|
|
cf07b3 |
+ VirtualDomain_Status
|
|
|
cf07b3 |
+ status=$?
|
|
|
cf07b3 |
+ done ;;
|
|
|
cf07b3 |
+ esac
|
|
|
cf07b3 |
+ return $OCF_SUCCESS
|
|
|
cf07b3 |
+}
|
|
|
cf07b3 |
+
|
|
|
cf07b3 |
VirtualDomain_Stop() {
|
|
|
cf07b3 |
local i
|
|
|
cf07b3 |
local status
|
|
|
cf07b3 |
local shutdown_timeout
|
|
|
cf07b3 |
- local out ex
|
|
|
cf07b3 |
local needshutdown=1
|
|
|
cf07b3 |
|
|
|
cf07b3 |
VirtualDomain_Status
|
|
|
cf07b3 |
@@ -341,7 +328,8 @@ VirtualDomain_Stop() {
|
|
|
cf07b3 |
$OCF_SUCCESS)
|
|
|
cf07b3 |
if ocf_is_true $OCF_RESKEY_force_stop; then
|
|
|
cf07b3 |
# if force stop, don't bother attempting graceful shutdown.
|
|
|
cf07b3 |
- break;
|
|
|
cf07b3 |
+ force_stop
|
|
|
cf07b3 |
+ return $?
|
|
|
cf07b3 |
fi
|
|
|
cf07b3 |
|
|
|
cf07b3 |
ocf_log info "Issuing graceful shutdown request for domain ${DOMAIN_NAME}."
|
|
|
cf07b3 |
@@ -370,9 +358,7 @@ VirtualDomain_Stop() {
|
|
|
cf07b3 |
status=$?
|
|
|
cf07b3 |
case $status in
|
|
|
cf07b3 |
$OCF_NOT_RUNNING)
|
|
|
cf07b3 |
- # This was a graceful shutdown. Clean
|
|
|
cf07b3 |
- # up and return.
|
|
|
cf07b3 |
- VirtualDomain_Cleanup_Statefile
|
|
|
cf07b3 |
+ # This was a graceful shutdown.
|
|
|
cf07b3 |
return $OCF_SUCCESS
|
|
|
cf07b3 |
;;
|
|
|
cf07b3 |
$OCF_SUCCESS)
|
|
|
cf07b3 |
@@ -393,27 +379,11 @@ VirtualDomain_Stop() {
|
|
|
cf07b3 |
ocf_log info "Domain $DOMAIN_NAME already stopped."
|
|
|
cf07b3 |
return $OCF_SUCCESS
|
|
|
cf07b3 |
esac
|
|
|
cf07b3 |
+
|
|
|
cf07b3 |
# OK. Now if the above graceful shutdown hasn't worked, kill
|
|
|
cf07b3 |
# off the domain with destroy. If that too does not work,
|
|
|
cf07b3 |
# have the LRM time us out.
|
|
|
cf07b3 |
- ocf_log info "Issuing forced shutdown (destroy) request for domain ${DOMAIN_NAME}."
|
|
|
cf07b3 |
- out=$(virsh $VIRSH_OPTIONS destroy ${DOMAIN_NAME} 2>&1)
|
|
|
cf07b3 |
- ex=$?
|
|
|
cf07b3 |
- echo >&2 "$out"
|
|
|
cf07b3 |
- # unconditionally clean up.
|
|
|
cf07b3 |
- VirtualDomain_Cleanup_Statefile
|
|
|
cf07b3 |
- case $ex$out in
|
|
|
cf07b3 |
- *"error:"*"domain is not running"*)
|
|
|
cf07b3 |
- : ;; # unexpected path to the intended outcome, all is well
|
|
|
cf07b3 |
- [!0]*)
|
|
|
cf07b3 |
- return $OCF_ERR_GENERIC ;;
|
|
|
cf07b3 |
- 0*)
|
|
|
cf07b3 |
- while [ $status != $OCF_NOT_RUNNING ]; do
|
|
|
cf07b3 |
- VirtualDomain_Status
|
|
|
cf07b3 |
- status=$?
|
|
|
cf07b3 |
- done ;;
|
|
|
cf07b3 |
- esac
|
|
|
cf07b3 |
- return $OCF_SUCCESS
|
|
|
cf07b3 |
+ force_stop
|
|
|
cf07b3 |
}
|
|
|
cf07b3 |
|
|
|
cf07b3 |
VirtualDomain_Migrate_To() {
|
|
|
cf07b3 |
@@ -469,7 +439,6 @@ VirtualDomain_Migrate_To() {
|
|
|
cf07b3 |
return $OCF_ERR_GENERIC
|
|
|
cf07b3 |
else
|
|
|
cf07b3 |
ocf_log info "$DOMAIN_NAME: live migration to ${target_node} succeeded."
|
|
|
cf07b3 |
- VirtualDomain_Cleanup_Statefile
|
|
|
cf07b3 |
return $OCF_SUCCESS
|
|
|
cf07b3 |
fi
|
|
|
cf07b3 |
else
|
|
|
cf07b3 |
@@ -561,12 +530,15 @@ case $1 in
|
|
|
cf07b3 |
;;
|
|
|
cf07b3 |
esac
|
|
|
cf07b3 |
|
|
|
cf07b3 |
+OCF_RESKEY_hypervisor_default="$(virsh --quiet uri)"
|
|
|
cf07b3 |
+: ${OCF_RESKEY_hypervisor=${OCF_RESKEY_hypervisor_default}}
|
|
|
cf07b3 |
+
|
|
|
cf07b3 |
# Everything except usage and meta-data must pass the validate test
|
|
|
cf07b3 |
VirtualDomain_Validate_All || exit $?
|
|
|
cf07b3 |
|
|
|
cf07b3 |
# During a probe, it is permissible for the config file to not be
|
|
|
cf07b3 |
# readable (it might be on shared storage not available during the
|
|
|
cf07b3 |
-# probe). In that case, VirtualDomain_Define can't work and we're
|
|
|
cf07b3 |
+# probe). In that case, we're
|
|
|
cf07b3 |
# unable to get the domain name. Thus, we also can't check whether the
|
|
|
cf07b3 |
# domain is running. The only thing we can do here is to assume that
|
|
|
cf07b3 |
# it is not running.
|
|
|
cf07b3 |
@@ -575,21 +547,10 @@ if [ ! -r $OCF_RESKEY_config ]; then
|
|
|
cf07b3 |
[ "$__OCF_ACTION" = "stop" ] && exit $OCF_SUCCESS
|
|
|
cf07b3 |
fi
|
|
|
cf07b3 |
|
|
|
cf07b3 |
-# Define the domain on startup, and re-define whenever someone deleted
|
|
|
cf07b3 |
-# the state file, or touched the config.
|
|
|
cf07b3 |
-if [ ! -e $STATEFILE ] || [ $OCF_RESKEY_config -nt $STATEFILE ]; then
|
|
|
cf07b3 |
- VirtualDomain_Define
|
|
|
cf07b3 |
-fi
|
|
|
cf07b3 |
-# By now, we should definitely be able to read from the state file.
|
|
|
cf07b3 |
-# If not, something went wrong.
|
|
|
cf07b3 |
-if [ ! -r $STATEFILE ]; then
|
|
|
cf07b3 |
- ocf_log err "$STATEFILE not found or unreadable. This is unexpected. Cannot determine domain name."
|
|
|
cf07b3 |
- exit $OCF_ERR_GENERIC
|
|
|
cf07b3 |
-fi
|
|
|
cf07b3 |
-# Finally, retrieve the domain name from the state file.
|
|
|
cf07b3 |
-DOMAIN_NAME=`cat $STATEFILE 2>/dev/null`
|
|
|
cf07b3 |
+# Retrieve the domain name from the xml file.
|
|
|
cf07b3 |
+DOMAIN_NAME=`egrep '.*<name>.*</name>$' ${OCF_RESKEY_config} | sed -e 's/.*<name>\(.*\)<\/name>$/\1/' 2>/dev/null`
|
|
|
cf07b3 |
if [ -z $DOMAIN_NAME ]; then
|
|
|
cf07b3 |
- ocf_log err "$STATEFILE is empty. This is unexpected. Cannot determine domain name."
|
|
|
cf07b3 |
+ ocf_log err "This is unexpected. Cannot determine domain name."
|
|
|
cf07b3 |
exit $OCF_ERR_GENERIC
|
|
|
cf07b3 |
fi
|
|
|
cf07b3 |
|
|
|
cf07b3 |
@@ -620,3 +581,4 @@ case $1 in
|
|
|
cf07b3 |
;;
|
|
|
cf07b3 |
esac
|
|
|
cf07b3 |
exit $?
|
|
|
cf07b3 |
+
|