Здесь размещено описание одного из функциональных блоков инструкции с примером управления виртуальными машинами "Qemu-KVM" через простейшие BASH-скрипты. Отдельно неприменимо.
Пример опций конфигурационного файла виртуальной машины:
# vi /usr/local/etc/kvm/conf.d/mashine0.cnf
....
# Задаём необходимые (только те, что реально нужны) параметры дискового устройства (в качестве уникального локального идентификатора указывая его индекс)
# Образец для HDD IDE или SCSI
#
# drive.if={ide|scsi}
# drive.if.bus= // аналог адреса шины
# drive.if.bus.bay= // аналог адреса порта шины
#
# drive.if.bus.bay.file= // адрес файла или блочного устройства
# drive.if.bus.bay.media={disk|cdrom}
# drive.if.bus.bay.format={raw|qcow|qcow2|cow|vmdk|cloop}
# drive.if.bus.bay.cache={none|writeback|writethrough}
# drive.if.bus.bay.aio={threads|native}
drive.if=ide
drive.ide.bus=0
drive.ide.0.bay=0
#
drive.ide.0.0.file=/mnt/storage0/kvm/mashine0/mashine0.hdd0.raw
drive.ide.0.0.media=disk
drive.ide.0.0.format=raw
drive.ide.0.0.cache=none
drive.ide.0.0.aio=threads
drive.if=ide
drive.ide.bus=1
drive.ide.1.bay=0
#
drive.ide.1.0.file=/mnt/storage0/kvm/mashine0/mashine0.cd0.iso
drive.ide.1.0.media=cdrom
drive.if=scsi
drive.scsi.bus=0
drive.scsi.0.bay=0
#
drive.scsi.0.0.file=/mnt/storage0/kvm/mashine0/mashine0.shdd0.raw
drive.scsi.0.0.media=disk
drive.scsi.0.0.format=raw
drive.scsi.0.0.cache=none
drive.scsi.0.0.aio=threads
....
# Задаём необходимые (только те, что реально нужны) параметры дискового устройства (в качестве уникального локального идентификатора указывая его индекс)
# Образец для HDD IDE или SCSI
#
# drive.if={ide|scsi}
# drive.if.bus= // аналог адреса шины
# drive.if.bus.bay= // аналог адреса порта шины
#
# drive.if.bus.bay.file= // адрес файла или блочного устройства
# drive.if.bus.bay.media={disk|cdrom}
# drive.if.bus.bay.format={raw|qcow|qcow2|cow|vmdk|cloop}
# drive.if.bus.bay.cache={none|writeback|writethrough}
# drive.if.bus.bay.aio={threads|native}
drive.if=ide
drive.ide.bus=0
drive.ide.0.bay=0
#
drive.ide.0.0.file=/mnt/storage0/kvm/mashine0/mashine0.hdd0.raw
drive.ide.0.0.media=disk
drive.ide.0.0.format=raw
drive.ide.0.0.cache=none
drive.ide.0.0.aio=threads
drive.if=ide
drive.ide.bus=1
drive.ide.1.bay=0
#
drive.ide.1.0.file=/mnt/storage0/kvm/mashine0/mashine0.cd0.iso
drive.ide.1.0.media=cdrom
drive.if=scsi
drive.scsi.bus=0
drive.scsi.0.bay=0
#
drive.scsi.0.0.file=/mnt/storage0/kvm/mashine0/mashine0.shdd0.raw
drive.scsi.0.0.media=disk
drive.scsi.0.0.format=raw
drive.scsi.0.0.cache=none
drive.scsi.0.0.aio=threads
....
Фрагмент кода с функциями формирования строки инициализации дисковых устройств виртуальной машины:
# vi /etc/kvm/fnc.d/4.drive.fnc
#!/bin/bash
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)
# Функция инициализации виртуальных HDD
function start-hdd() {
# Зачищаем исходящую строку описания от результатов работы предыдущей итерации
DSTRING=""
# Перебираем все строки типов интерфейсов HDD
for DIFS in `grep --ignore-case "^drive.if=" "${CNF}" | uniq`
do
DIF=`echo ${DIFS} | awk -F = '{print $2}'`
# Выбираем для дальнейшей обработки типы интерфейсов IDE и SCSI
if [ "${DIF}" == "ide" -o "${DIF}" == "scsi" ] ; then
# Перебираем все строки адресов шин HDD
for DBUSS in `grep --ignore-case "^drive.${DIF}.bus=" "${CNF}" | uniq`
do
DBUS=`echo ${DBUSS} | awk -F = '{print $2}'`
# Перебираем все строки адресов портов шин HDD
for DBAYS in `grep --ignore-case "^drive.${DIF}.${DBUS}.bay=" "${CNF}" | uniq`
do
DBAY=`echo ${DBAYS} | awk -F = '{print $2}'`
# Перебираем все строки параметров виртуальных HDD
for DPARAMS in `grep --ignore-case "^drive.${DIF}.${DBUS}.${DBAY}." "${CNF}" | uniq` ; do
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".file=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DFILE="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".media=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DMEDIA="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".format=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DFORMAT="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".cache=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DCACHE="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".aio=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DAIO="${BUFFER}"
fi
done
# Удостоверяемся в наличии обязательных параметров
if [ "${DIF}" != "" -a "${DBUS}" != "" -a "${DBAY}" != "" -a "${DFILE}" != "" -a "${DMEDIA}" != "" ]; then
DSTRING="${DSTRING} -drive if=${DIF},bus=${DBUS},unit=${DBAY},file=${DFILE},media=${DMEDIA}"
# Добиваем строку инициализации необязательными опциями, по наличию
if [ "${DFORMAT}" != "" ]; then
DSTRING="${DSTRING},format=${DFORMAT}"
fi
if [ "${DCACHE}" != "" ]; then
DSTRING="${DSTRING},cache=${DCACHE}"
fi
if [ "${DAIO}" != "" ]; then
DSTRING="${DSTRING},aio=${DAIO}"
fi
else
echo "${DATE}: No full details of a HDD environment. Abort operations." | tee -a "${LOGT}"
return 1
fi
done
done
fi
done
return 0
}
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)
# Функция инициализации виртуальных HDD
function start-hdd() {
# Зачищаем исходящую строку описания от результатов работы предыдущей итерации
DSTRING=""
# Перебираем все строки типов интерфейсов HDD
for DIFS in `grep --ignore-case "^drive.if=" "${CNF}" | uniq`
do
DIF=`echo ${DIFS} | awk -F = '{print $2}'`
# Выбираем для дальнейшей обработки типы интерфейсов IDE и SCSI
if [ "${DIF}" == "ide" -o "${DIF}" == "scsi" ] ; then
# Перебираем все строки адресов шин HDD
for DBUSS in `grep --ignore-case "^drive.${DIF}.bus=" "${CNF}" | uniq`
do
DBUS=`echo ${DBUSS} | awk -F = '{print $2}'`
# Перебираем все строки адресов портов шин HDD
for DBAYS in `grep --ignore-case "^drive.${DIF}.${DBUS}.bay=" "${CNF}" | uniq`
do
DBAY=`echo ${DBAYS} | awk -F = '{print $2}'`
# Перебираем все строки параметров виртуальных HDD
for DPARAMS in `grep --ignore-case "^drive.${DIF}.${DBUS}.${DBAY}." "${CNF}" | uniq` ; do
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".file=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DFILE="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".media=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DMEDIA="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".format=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DFORMAT="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".cache=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DCACHE="${BUFFER}"
fi
BUFFER=`echo ${DPARAMS} | grep --ignore-case ".aio=" | awk -F = '{print $2}'`
if [ "${BUFFER}" != "" ]; then
DAIO="${BUFFER}"
fi
done
# Удостоверяемся в наличии обязательных параметров
if [ "${DIF}" != "" -a "${DBUS}" != "" -a "${DBAY}" != "" -a "${DFILE}" != "" -a "${DMEDIA}" != "" ]; then
DSTRING="${DSTRING} -drive if=${DIF},bus=${DBUS},unit=${DBAY},file=${DFILE},media=${DMEDIA}"
# Добиваем строку инициализации необязательными опциями, по наличию
if [ "${DFORMAT}" != "" ]; then
DSTRING="${DSTRING},format=${DFORMAT}"
fi
if [ "${DCACHE}" != "" ]; then
DSTRING="${DSTRING},cache=${DCACHE}"
fi
if [ "${DAIO}" != "" ]; then
DSTRING="${DSTRING},aio=${DAIO}"
fi
else
echo "${DATE}: No full details of a HDD environment. Abort operations." | tee -a "${LOGT}"
return 1
fi
done
done
fi
done
return 0
}