LINUX.ORG.RU
ФорумAdmin

VirtualDomain и KVM (Ubuntu Server 10.10)


0

2

Здрасти это опять я с вопросом про кластер
Если выполнить такой код:

 /usr/lib/ocf/resource.d/heartbeat/VirtualDomain start
error: Failed to define domain from /home/cluster/mt.domain
error: operation failed: domain 'mt' already exists with uuid 4084ab99-b90d-bfea-be1a-7875e5ce59da
VirtualDomain[4118]: INFO: Domain name "" saved to /var/run/heartbeat/rsctmp/VirtualDomain-Domain.state.
VirtualDomain[4118]: ERROR: /var/run/heartbeat/rsctmp/VirtualDomain-Domain.state is empty. This is unexpected. Cannot determine domain name.
Я рассмотрел код VirtualDomain под микроскопом и понял алгортим его работы, в нем ошибки. При старте скрипт ищет этот файл и читает из него название домена, но есть ситуация когда этот файл оказывается пуст. Ситуация возникает когда скрипт стартует и пытается define домен сделать, ему в ответ что такой домен уже есть и output не правильно разбирается и в файл ни чего не пишется (см. выше). Странность в том что всегда при старте скрипт определяет домен но не запускает (команда define), а когда останавливает не удаляет определение а удаляет только один файл состояния. И следующий раз ищет файл и думает что домен не определен и определяет его, но у него не получается и файл создается пустой.
Мне кажется я просто не допонимаю логику работы скрипта, ну не может в этом скрипте допущена ошибка у многих то он работает.
По моей логике скрипт должен использовать команду create в функции старта домена, а не команду define в начале работы скрипта. И этот файл состояния тоже лишний.

★★★★★

error: operation failed: domain 'mt' already exists with uuid 4084ab99-b90d-bfea-be1a-7875e5ce59da
VirtualDomain[4118]: INFO: Domain name «» saved to /var/run/heartbeat/rsctmp/VirtualDomain-Domain.state.

Я полагаю, это прекрасный повод написать несколько добрых слов в багзилле разработчика. Или хотя бы в рассылке. (В обоих случаях нужно зарегаться/подписаться.)

Что касается имеющегося у меня опыта — на центосе с пакетами из собственной репы разработчика таких проблем не встречалось. Правда, там были кое-какие проблемы по поводу масштабируемости, но разбирался с ними уже не я.

nnz ★★★★ ()
Ответ на: комментарий от nnz

написал агента. описал функции стоп старт монитор, запустилось без ошибок. опишу функции migrate_to migrate_from наверное из за этого на standby не реагирует только если узел вырубить все поднимается на втором, а после включения переползает обратно. Отработаю все ошибки скрипт с описание выложу.

petav ★★★★★ ()
Ответ на: комментарий от petav

>опишу функции migrate_to migrate_from наверное из за этого на standby не реагирует только если узел вырубить все поднимается на втором

Пока их нет, лучше allow-migrate=false задать.

nnz ★★★★ ()
Ответ на: комментарий от nnz

Пока их нет, лучше allow-migrate=false задать.

верно

Написал функционал живой миграции, проверил из строки работает в pacemaker нет. Проблема в том что в момент живой миграции оба диск должен быть в p/p а как это организовать, сейчас у меня примитив

ms DataClone Data \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" target-role="Started" is-managed="true"

сейчас попробую allow-migrate=false

petav ★★★★★ ()
Ответ на: комментарий от petav

ну да, как я и думал с параметром false переключается, а живая миграция нет. Все дело в дисках, как я думаю

petav ★★★★★ ()
Ответ на: комментарий от petav

Вот теперь собственно мы и подошли в давным-давно сказанным мною словам о пользе iscsi... :)

Но в принципе можно попытаться продолжить твоим методом — идея ведь интересная, хотя и не лишена некоторого безумия. Выкладывай скрипт, подумаем.

nnz ★★★★ ()
Ответ на: комментарий от nnz

Вот теперь собственно мы и подошли в давным-давно сказанным мною словам о пользе iscsi... :)

припоминаю :)

Эту задачу конфигурированием pacemaker не решить. Логика работы ocf:linbit:drbd скорее всего не сможет держать два диска в primary на момент миграции. Нужно либо переделывать этот скрипт. Либо что более симпатизирует мне сейчас дописать функционал управления дисками скрипту управляющему доменами.

  • В функцию старт перед запуском домена добавить выставление диска в primary.
  • В функцию стоп после остановки домена добавить выставление диска в secondary.
  • В функцию migrate_to добавить переключение диска в secondary после успешной миграции
  • А вот Функцию migrate_from при старте сделать (самое главное) выставить диск в primary

По моим наблюдениям функции migrate_to и migrate_from должны запуcкаться pacemaker синхронно на обоих узлах. Если нет , то мой алгоритм не сработает.

Пока стеснюсь скрипт выкладывать он не «допилен». Там многое не красиво на мой взгляд, просто красиво написать это дольше, а сейчас хочется понять возможность самого принципа

P.S.: Сейчас отойти надо, придется позже продолжить...

petav ★★★★★ ()
Ответ на: комментарий от nnz

Надеюсь так же что pacemaker[\i] сам решает как мигрировать домен. т.е. если второй узел в ауте он не будет пытаться мигрировать а просто старт домена сделает на работающем узле

petav ★★★★★ ()
Ответ на: комментарий от petav

>Либо что более симпатизирует мне сейчас дописать функционал управления дисками скрипту управляющему доменами.

Собственно, у меня была та же мысль. А чтобы дефолтный агент drbd не мешался, его функции лучше тоже перенести в твой скрипт. Все равно в твоем случае drbd и виртуалка связаны неразрывно и могут рассматриваться как один ресурс.

nnz ★★★★ ()
Ответ на: комментарий от nnz

Собственно, у меня была та же мысль. А чтобы дефолтный агент drbd не мешался, его функции лучше тоже перенести в твой скрипт. Все равно в твоем случае drbd и виртуалка связаны неразрывно и могут рассматриваться как один ресурс.

да да... Вечерком займусь

petav ★★★★★ ()
Ответ на: комментарий от petav

ну собственно получилось, но вот что смущает скрипт ocf:linbit::drbd очень умный и отслеживает различные состояния DRBD в том числе Unconfigured и т.п. поэтому при его использование надежность системы в целом повышается. Мой скрипт пока далек от этого

VirtualDomain_Migrate_To() {
	ssh ${OCF_RESKEY_CRM_meta_migrate_target} drbdadm primary ${OCF_RESOURCE_INSTANCE}
	virsh migrate --live ${OCF_RESOURCE_INSTANCE} qemu+ssh://${OCF_RESKEY_CRM_meta_migrate_target}/system
	if [ $? -ne 0 ]; then
		ocf_log err "${OCF_RESOURCE_INSTANCE}: live migration to ${OCF_RESKEY_CRM_meta_migrate_target} failed"
		return $OCF_ERR_GENERIC
	else
		ocf_log info "${OCF_RESOURCE_INSTANCE}: live migration to ${OCF_RESKEY_CRM_meta_migrate_target} succeeded."
		drbdadm secondary ${OCF_RESOURCE_INSTANCE}
		return $OCF_SUCCESS
	fi
}

Как оказалось функция migrate_from не запускается на втором узле одновременно с migrate_to поэтому и пришлось использовать ssh
Посмотрел на код ocf:linbit::drbd (уж очень много чего) и вот о чем я подумал может скрипт поддерживает состояния p/p нужно только с этими параметрами поиграться

ms DataClone Data \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" target-role="Started" is-managed="true"

petav ★★★★★ ()
Ответ на: комментарий от nnz
#!/bin/sh

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
LC_ALL="C"
LANG="C"
VIRSH_OPTIONS="--connect=qemu:///system --quiet"
DOMAIN_NAME="${OCF_RESOURCE_INSTANCE}"

usage() {
  echo "usage: $0 {start|stop|monitor|migrate_to|migrate_from|meta-data}"
}

meta_data() {
	cat <<EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="VirtualDomain">
<version>1.0</version>

<longdesc lang="en">
Resource agent for a virtual domain (a.k.a. domU, virtual machine,
virtual environment etc., depending on context) managed by libvirtd.
</longdesc>
<shortdesc lang="en">Manages virtual domains through the libvirt virtualization framework</shortdesc>

<parameters>

<parameter name="config" unique="1" required="1">
<longdesc lang="en">
Absolute path to the libvirt configuration file,
for this virtual domain.
</longdesc>
<shortdesc lang="en">Virtual domain configuration file</shortdesc>
<content type="string" default="" />
</parameter>

</parameters>

<actions>
<action name="start" timeout="90" />
<action name="stop" timeout="90" />
<action name="monitor" depth="0" timeout="30" interval="10" />
<action name="migrate_from" timeout="60" />
<action name="migrate_to" timeout="120" />
<action name="meta-data" timeout="5" />
</actions>
</resource-agent>
EOF
}

VirtualDomain_Status ()	{
	output=`virsh ${VIRSH_OPTIONS} domstate ${DOMAIN_NAME} 2>/dev/null`
    if [ $? -ne 0 ]; then
		#ocf_log info "Domain ${DOMAIN_NAME} not found."
		echo "not found"
	else
		#ocf_log info "Domain ${DOMAIN_NAME} ${output}."
		echo $output
    fi
}

VirtualDomain_Start() {
	case $(VirtualDomain_Status) in
	"not found")
		virsh ${VIRSH_OPTIONS} create ${OCF_RESKEY_config}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	"shut off")
		virsh ${VIRSH_OPTIONS} start ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	"running")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} running."	
		;;
	"paused")
		virsh ${VIRSH_OPTIONS} resume ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	esac
	return $OCF_SUCCESS
}

VirtualDomain_Stop ()	{
	case $(VirtualDomain_Status) in
	"not found")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} not found."	
		;;
	"shut off")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} shut off."
		;;
	"running")
		#Выявляем интревал ожидания
#		if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
#			timeout=$((OCF_RESKEY_CRM_meta_timeout/1500))
#			#Посылаем команду выключения
#			virsh ${VIRSH_OPTIONS} shutdown ${DOMAIN_NAME}
#			if [ $? -ne 0 ]; then
#				return $OCF_ERR_GENERIC
#			fi
#			#Цикл ожидания
#			echo $OCF_RESKEY_CRM_meta_timeout
#			local n=0
#			while [ $n -lt $timeout ]; do
#				if [ "$(VirtualDomain_Status)" == "running" ]; then 
#					echo -n "."
#					sleep 1
#				else
#					return $OCF_SUCCESS
#					break
#				fi
#				n=$(expr $n + 1)
#			done
#		fi
		
		#Интервал ожидания прошел
		virsh ${VIRSH_OPTIONS} destroy ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	"paused")
		virsh ${VIRSH_OPTIONS} destroy ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	esac
	return $OCF_SUCCESS
}

VirtualDomain_Monitor ()	{
	case $(VirtualDomain_Status) in
	"not found")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} not running."
		return $OCF_NOT_RUNNING
		;;
	"shut off")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} shut."
		return $OCF_NOT_RUNNING
		;;
	"running")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} running."	
		return $OCF_SUCCESS
		;;
	"paused")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} not running."	
		return $OCF_NOT_RUNNING
		;;
	*)
		ocf_log error "Do not understand the state of domain ${OCF_RESOURCE_INSTANCE}."	
		return $OCF_ERR_GENERIC
		;;
	esac
}

VirtualDomain_Migrate_From() {
    while ! VirtualDomain_Monitor; do
		sleep 1
    done
    ocf_log info "Live migration domain ${DOMAIN_NAME} from ${OCF_RESKEY_CRM_meta_migrate_source} succeeded."
    return $OCF_SUCCESS
}

VirtualDomain_Migrate_To() {
	virsh migrate --live ${DOMAIN_NAME} qemu+ssh://${OCF_RESKEY_CRM_meta_migrate_target}/system
	if [ $? -ne 0 ]; then
		ocf_log err "Live migration domain ${DOMAIN_NAME} to ${OCF_RESKEY_CRM_meta_migrate_target} failed"
		return $OCF_ERR_GENERIC
	else
		ocf_log info "Live migration domain ${DOMAIN_NAME} to ${OCF_RESKEY_CRM_meta_migrate_target} succeeded."
		return $OCF_SUCCESS
	fi
}

if [ $# -ne 1 ]; then
  usage
  exit $OCF_ERR_ARGS
fi

case $1 in
	meta-data)		
	meta_data
	exit $OCF_SUCCESS
	;;
	usage)
	usage
	exit $OCF_SUCCESS
	;;
esac

case $1 in
    start)
	VirtualDomain_Start
	;;
    stop)
	VirtualDomain_Stop
	;;
    migrate_to)
	VirtualDomain_Migrate_To
	;;
    migrate_from)
	VirtualDomain_Migrate_From
	;;
    monitor)
	VirtualDomain_Monitor
    ;;
    *)	
	usage
	exit $OCF_ERR_UNIMPLEMENTED
	;;
esac
exit $?

Вот скрипт который у меня управляет виртуальными доменами, единственное что пока не получилось это часть кода

VirtualDomain_Stop ()   {
      .....
      #Выявляем интревал ожидания
      ......
Как только раскомментирую эту ветку (либо вручную в коде добавляю timeout, я пока не понял где указать OCF_RESKEY_CRM_meta_timeout) то сразу наблюдаю ошибки, первая это drbd demote, drbd уже хочет переключить состояние, но домен еще не выключился и тут ошибки одна за другой. Я не могу понять ведь по коду пока домен не выключится функция stop ни чего не возвращает, а ждет в цикле этого самого выключения. По моему мнению связанная функции drbd не должны запускаться пока, но они запускаются по видимому. Единственно что в глову приходит указать timeout для promote и demote

petav ★★★★★ ()
Ответ на: комментарий от petav

Я ж говорю — засунь управление drbd в тот же скрипт, так логичнее будет.

Кроме того, надо поотлаживать твой stop. Пробовал напрямую из консоли запускать? Оно действительно ждет?

nnz ★★★★ ()
Ответ на: комментарий от nnz

насчет логичности я уже и не знаю как лучше сделать. Просто живая миграция не очень то и нужна, всего 3 домена будет. И только в случае аварии переселить их надо будет. А если авария произойдет, то тут миграция ни как не получится живая. Напрямую то все работает. Ждет сколько нужно. И если drbd в мой скрипт засунуть, то проблема сама собой отпадет и живую миграцию можно использовать. Но меня останавливает мощность скрипта drbd, я такое не опишу. Я плохо понимаю какие состояния возможны и как при них действовать. Вот на что решиться искать проблему с интревалами в связке drbd+мой скрипт или засунуть drbd в мой скрипт. Первый подход стандартный путь, меньше ошибок. Второй вариант писать скрипт, возможно пропустить неопределенные состояния устройств.

petav ★★★★★ ()
Ответ на: комментарий от petav

Вообщем в связке drbd+мой скрипт разобрался в чем дело

primitive Data ocf:linbit:drbd \
        params drbd_resource="mt" \
        op monitor interval="20s" \
        op demote interval="0" timeout="90s" \
        op promote interval="0" timeout="90s"
primitive mt ocf:my:VirtualDomain \
        params config="/home/cluster/mt.domain" \
        meta allow-migrate="false" target-role="Started" \
        op start interval="0" timeout="90" \
        op stop interval="0" timeout="90" \
        op monitor interval="10" timeout="30" depth="0"

timeout destroy домена в скрипте 35 секунд, timeout в конфиге pacemaker были что-то около 20s по умолчанию. pacemaker смотрит на

order mt-after-Data inf: DataClone:promote mt:start
и запускает сначала DataClone потом mt. Теперь суть дела pacemaker для того что бы обезопасить себя использует временные ограничения. Так вотв моем случае по умолчанию DataClone ждал 20s, а машина выключалась через 35 секунд, и естественно диск drbd не мог быть переведен в состояние противоположное, а увеличив эти значения
 op demote interval="0" timeout="90s" \
        op promote interval="0" timeout="90s"
drbd ждет сколько нужно.

petav ★★★★★ ()
Ответ на: комментарий от petav

а со стоп действительно проблемы, вручную работает, а под управлением pacemaker нет. Вывожу отсчет в файл, так вот вручную tail -f показывает отсчет, а автоматом файл не изменяется. Оказывается

#!/bin/bash
и
#!/bin/sh
это разное. Я по лени не назначил тестируемому скрипту права на исполнение и запускал его bash <script>
Теперь заметил что скрипт drbd перед переключением состояния переводит диск в s/s. Так вот если добиться что бы перед переключением было состояние p/p то это условия для живой миграции.

petav ★★★★★ ()
Ответ на: комментарий от petav

nnz, а подскажи как реализовать такое.
Сейчас в скрипте переменная

DOMAIN_NAME="${OCF_RESOURCE_INSTANCE}"
равна имени примитива, а правильнее брать имя домена из конфигурационного файла ${OCF_RESOURCE_config}. Для меня это просто слишком сложно пока.

petav ★★★★★ ()
Ответ на: комментарий от petav

Я почти готов выложить скрипт
Осталось решить несколько вещей:

  • Разобрать файл конфигурации домена и вытащить его имя.
  • Понять как pacemaker предоставляет интерфейс для записи логов в файл. На экран сейчас выводит в ручном режиме, а когда под pacemaker ни чего не видать. Надо как я думаю какую либо переменную определить
  • Понять возможно ли на момент переключения состояния drbd переводит его не в s/s а p/p, если да то протестировать такую возможность
  • Создать описание скрипта и конфигурации pacemaker.

По первому нашел такое решение:

DOMAIN_NAME=`awk '$1~/^name(=|$)/{print}' ${OCF_RESKEY_xmfile} | sed 's/.*=[[:space:]]*//' | tr -d "[\"']"`
но это для xen у меня не срабатывает

petav ★★★★★ ()
Ответ на: комментарий от petav

К сожалению пока нет времени оформить все как нужно, пока привожу код моего скрипта RA Pacemaker управления доменами KVM.

#!/bin/bash

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
: ${OCF_RESKEY_hypervisor=${OCF_RESKEY_hypervisor_default}}
: ${OCF_RESKEY_migration_transport=${OCF_RESKEY_migration_transport_default}}

. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

LC_ALL="C"
LANG="C"
OCF_RESKEY_hypervisor_default="$(virsh --quiet uri)"
OCF_RESKEY_migration_transport_default="ssh"
VIRSH_OPTIONS="--connect=${OCF_RESKEY_hypervisor} --quiet"
#DOMAIN_NAME="${OCF_RESOURCE_INSTANCE}"	
DOMAIN_NAME=`cat ${OCF_RESKEY_config} |awk -F "<name>" {'print $2'}|awk -F "</name>" {'print $1'}|grep -v ^$`

usage() {
  echo "usage: $0 {start|stop|status|monitor|migrate_to|migrate_from|meta-data|validate-all}"
}

meta_data() {
	cat <<EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="VirtualDomain">
<version>1.0</version>

<longdesc lang="en">
Resource agent for a virtual domain (a.k.a. domU, virtual machine,
virtual environment etc., depending on context) managed by libvirtd.
</longdesc>
<shortdesc lang="en">Manages virtual domains through the libvirt virtualization framework</shortdesc>

<parameters>

<parameter name="config" unique="1" required="1">
<longdesc lang="en">
Absolute path to the libvirt configuration file,
for this virtual domain.
</longdesc>
<shortdesc lang="en">Virtual domain configuration file</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="hypervisor" unique="0" required="0">
<longdesc lang="en">
Hypervisor URI to connect to. See the libvirt documentation for
details on supported URI formats. The default is system dependent.
</longdesc>
<shortdesc lang="en">Hypervisor URI</shortdesc>
<content type="string" default="${OCF_RESKEY_hypervisor_default}"/>
</parameter>

<parameter name="shutdown_timeout" unique="1" required="1">
<longdesc lang="en">
shutdown_timeout
</longdesc>
<shortdesc lang="en">shutdown_timeout</shortdesc>
<content type="number" default="" />
</parameter>

<parameter name="migration_transport" unique="0" required="0">
<longdesc lang="en">
Transport used to connect to the remote hypervisor while
migrating. Please refer to the libvirt documentation for details on
transports available. If this parameter is omitted, the resource will
use libvirt's default transport to connect to the remote hypervisor.
</longdesc>
<shortdesc lang="en">Remote hypervisor transport</shortdesc>
<content type="string" default="${OCF_RESKEY_migration_transport_default}" />
</parameter>

</parameters>

<actions>
<action name="start" timeout="90" />
<action name="stop" timeout="90" />
<action name="status" depth="0" timeout="30" interval="10" />
<action name="monitor" depth="0" timeout="30" interval="10" />
<action name="migrate_from" timeout="60" />
<action name="migrate_to" timeout="120" />
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="5" />
</actions>
</resource-agent>
EOF
}

VirtualDomain_Status ()	{
	output=`virsh ${VIRSH_OPTIONS} domstate ${DOMAIN_NAME} 2>/dev/null`
    if [ $? -ne 0 ]; then
		#ocf_log info "Domain ${DOMAIN_NAME} not found."
		echo "not found"
	else
		#ocf_log info "Domain ${DOMAIN_NAME} ${output}."
		echo $output
    fi
}

VirtualDomain_Start() {
	case $(VirtualDomain_Status) in
	"not found")
		virsh ${VIRSH_OPTIONS} create ${OCF_RESKEY_config}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	"shut off")
		virsh ${VIRSH_OPTIONS} start ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	"running")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} running."	
		;;
	"paused")
		virsh ${VIRSH_OPTIONS} resume ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	esac
	return $OCF_SUCCESS
}

VirtualDomain_Stop ()	{
	local n
	local timeout
	
	case $(VirtualDomain_Status) in
	"not found")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} not found."	
		;;
	"shut off")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} shut off."
		;;
	"running")
		#Выявляем интревал ожидания
		if [ -n "$OCF_RESKEY_shutdown_timeout" ]; then
			timeout=$OCF_RESKEY_shutdown_timeout
#			timeout=35
			#Посылаем команду выключения
			virsh ${VIRSH_OPTIONS} shutdown ${DOMAIN_NAME}
			if [ $? -ne 0 ]; then
				return $OCF_ERR_GENERIC
			fi
			#Цикл ожидания
			local n=0
			while [ $n -lt $timeout ]; do
				if [ "$(VirtualDomain_Status)" == "running" ]; then 
					echo -n "." 
					sleep 1
				else
					return $OCF_SUCCESS
					break
				fi
				n=$(expr $n + 1)
			done
		fi
		#Интервал ожидания прошел
		virsh ${VIRSH_OPTIONS} destroy ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	"paused")
		virsh ${VIRSH_OPTIONS} destroy ${DOMAIN_NAME}
		if [ $? -ne 0 ]; then
			return $OCF_ERR_GENERIC
		fi
		;;
	esac
	return $OCF_SUCCESS
}

VirtualDomain_Monitor ()	{
	case $(VirtualDomain_Status) in
	"not found"|"shut off"|"paused")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} not running."
		return $OCF_NOT_RUNNING
		;;
	"running")
		ocf_log info "Domain ${OCF_RESOURCE_INSTANCE} running."	
		return $OCF_SUCCESS
		;;
	*)
		ocf_log error "Do not understand the state of domain ${OCF_RESOURCE_INSTANCE}."	
		return $OCF_ERR_GENERIC
		;;
	esac
}

VirtualDomain_Migrate_From() {
    while ! VirtualDomain_Monitor; do
		sleep 1
    done
    ocf_log info "Live migration domain ${DOMAIN_NAME} from ${OCF_RESKEY_CRM_meta_migrate_source} succeeded."
    return $OCF_SUCCESS
}

VirtualDomain_Migrate_To() {
	local target_node
    local remoteuri
    local transport_suffix
	
	if [ "$(VirtualDomain_Status)"  !=  "running" ]; then
		ocf_log err "$DOMAIN_NAME: migrate_to: Not active locally!"
		return $OCF_ERR_GENERIC
	fi
	
	target_node="$OCF_RESKEY_CRM_meta_migrate_target"
	if [ -n "${OCF_RESKEY_migration_transport}" ]; then
	    transport_suffix="+${OCF_RESKEY_migration_transport}"
	fi
	remoteuri=$(echo ${OCF_RESKEY_hypervisor} | sed -e "s,\(.*\)://[^/:]*\(:\?[0-9]*\)/\(.*\),\1${transport_suffix}://${target_node}\2/\3,")
	
	ocf_log info "$DOMAIN_NAME: Starting live migration to ${target_node} (using remote hypervisor URI ${remoteuri})."
	virsh ${VIRSH_OPTIONS} migrate --live $DOMAIN_NAME ${remoteuri}
	if [ $? -ne 0 ]; then
		ocf_log err "$DOMAIN_NAME: live migration to ${remoteuri} failed"
		return $OCF_ERR_GENERIC
	else
		ocf_log info "$DOMAIN_NAME: live migration to ${target_node} succeeded."
		return $OCF_SUCCESS
	fi
}

VirtualDomain_Validate_All() {
    # Required binaries:
    for binary in virsh sed; do
        check_binary $binary
    done

    if [ -z $OCF_RESKEY_config ]; then
	ocf_log error "Missing configuration parameter \"config\"."
	return $OCF_ERR_CONFIGURED
    fi

    # check if we can read the config file (otherwise we're unable to
    # deduce $DOMAIN_NAME from it, see below)
    if [ ! -r $OCF_RESKEY_config ]; then
	if ocf_is_probe; then
	    ocf_log info "Configuration file $OCF_RESKEY_config not readable during probe."
	else
	    ocf_log error "Configuration file $OCF_RESKEY_config does not exist or is not readable."
	    return $OCF_ERR_INSTALLED
	fi
    fi
}

if [ $# -ne 1 ]; then
  usage
  exit $OCF_ERR_ARGS
fi

case $1 in
	meta-data)		
	meta_data
	exit $OCF_SUCCESS
	;;
	usage)
	usage
	exit $OCF_SUCCESS
	;;
esac

VirtualDomain_Validate_All || exit $?

case $1 in
    start)
	VirtualDomain_Start
	;;
    stop)
	VirtualDomain_Stop
	;;
    migrate_to)
	VirtualDomain_Migrate_To
	;;
    migrate_from)
	VirtualDomain_Migrate_From
	;;
    status)
	VirtualDomain_Status
	;;
    monitor)
	VirtualDomain_Monitor
        ;;
    validate-all)		
	;;
    *)	
	usage
	exit $OCF_ERR_UNIMPLEMENTED
	;;

esac
exit $?

petav ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.