UMGUM.COM 

KVM + Bash-Supervisor + Stoping ( Функция остановки виртуальной машины. )

21 июля 2011  (обновлено 28 октября 2018)

Эта публикация скрыта. Она доступна только по прямой ссылке.

Здесь размещено описание одного из функциональных блоков инструкции с примером управления виртуальными машинами "Qemu-KVM" через простейшие BASH-скрипты. Отдельно неприменимо.

Пример опций конфигурационного файла виртуальной машины:

# vi /usr/local/etc/kvm/cnf.d/mashine0.cnf

....
# Лимит времени (в секундах) выделенный виртуальной машине на завершение работы
shutdown.timeout=300
....

Фрагмент кода с функциями формирования строки инициализации остановки виртуальной машины:

# vi /etc/kvm/fnc.d/8.stop.fnc

#!/bin/bash
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)

function stop-precheck() {

  # Проверяем, запущена ли целевая виртуальная машина
  STATE=`ps wax | grep --invert-match grep | grep --ignore-case --count --extended-regexp "kvm[ ]+\-name[ ]+${NAME}[ ]+"`
  if [ ${STATE} -eq 0 ]; then

    # Виртуальная машина не запущена и дальнейшие процедуры не имеют смысла
    return 1

  fi

  # Узнаём лимит времени (в секундах) выделенный виртуальной машине на прохождение заврешение работы
  SHTIMEOUT=`grep --ignore-case "^shutdown.timeout=" "${CNF}" | awk -F = '{print $2}'`

return 0
}

# Определяем функцию остановки виртуальной машины, по возможности со стороны клиента, пытаясь остановить машину с помощью сигнала ACPI (сработает только если гостевая система поддерживает завершение работы по нажатию кнопки)
function stop-acpi() {

  # Узнаём месторасположение "локального сокета" для управления виртуальной машиной локальным скриптом
  MSOCKETL="/tmp/kvm/monitor/${NAME}.local.socket"

  # Посылаем через "сокет" сигнал завершения работы гостевой ОС
  echo "system_powerdown" | socat - UNIX-CONNECT:${MSOCKETL} > /dev/null

  # Проверяем успешность отрабатывания сеанса связи с "локальным сокетом"
  if [ "${?}" = "0" ]; then

    echo "${DATE}: Shutdown signal send succeeded." | tee -a "${LOGT}"

    # Ожидаем завершения работы виртуальной машины
    # В цикле используется C-подобный синтаксис (двойные обрамляющие скобки и переменные в операндах без знака "$")
    for ((COUNT=1 ; COUNT <= SHTIMEOUT ; COUNT++))
    do

      echo "  Wait for shutdown VM: ${NAME}... ${COUNT} sec."
      sleep 1

      # Проверяем, работает ли ещё целевая виртуальная машина
      STATE=`ps wax | grep --invert-match grep | grep --ignore-case --count --extended-regexp "kvm[ ]+\-name[ ]+${NAME}[ ]+"`
      if [ ${STATE} -eq 0 ]; then

        echo "${DATE}: Виртуальная машина ${NAME} успешно остановлена." | tee -a "${LOGT}"
        return 0

      fi

    done

    # Учитывая то, что за установленное время виртуальная машина не завершила свою работу, считаем операцию не выполненной
    echo "${DATE}: Виртуальная машина ${NAME} за установленное время не завершила свою работу. Операция не выполнена." | tee -a "${LOGT}"
    return 1

  else
    echo "${DATE}: Shutdown ACPI signal send error." | tee -a "${LOGT}"
    return 1
  fi

return 0
}

# Определяем функцию остановки машины с помощью подсистемы SMB
function stop-smb() {
  echo "${DATE}: SMB" | tee -a "${LOGT}"
  return 1
return 0
}

# Определяем функцию остановки машины уничтожением процесса (последний аргумент)
function stop-kill() {

  # Узнаём месторасположения PID-файла виртуальной машины
  MPID="/tmp/kvm/run/${NAME}.pid"

  # Запускаем процедуру остановки процесса виртуальной машины путём перебора вариантов сигнала разной степени жёсткости, по нарастанию действующей силы
  for SIGNAL in TERM INT HUP KILL
  do

    # Посылаем сигнал процессу
    /bin/kill -s ${SIGNAL} `head -1 ${MPID}`

    echo "${DATE}: Shutdown SIGKILL ${SIGNAL} signal send succeeded." | tee -a "${LOGT}"

    # Ожидаем завершения процесса в течении десяти секунд
    for COUNT in {1..10}
    do

      echo "  Wait for shutdown VM with SIGKILL ${SIGNAL} signal: ${NAME}... ${COUNT} sec."
      sleep 1

      # Проверяем, работает ли ещё целевая виртуальная машина
      STATE=`ps wax | grep --invert-match grep | grep --ignore-case --count --extended-regexp "kvm[ ]+\-name[ ]+${NAME}[ ]+"`
      if [ ${STATE} -eq 0 ]; then

        echo "${DATE}: Процесс виртуальной машины ${NAME} успешно завершён сигналом SIGKILL ${SIGNAL}." | tee -a "${LOGT}"
        return 0

      fi

    done

  done

  # Уведомляем о неудачном результате попыток завершения работы виртуальной машины
  echo "${DATE}: Не удалось завершить работу виртуальной машины ${NAME}." | tee -a "${LOGT}"
  return 1

return 0
}


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )