Здесь размещено описание одного из функциональных блоков инструкции с примером управления виртуальными машинами "Qemu-KVM" через простейшие BASH-скрипты. Отдельно неприменимо.
Пример опций конфигурационного файла виртуальной машины:
# vi /usr/local/etc/kvm/cnf.d/mashine0.cnf
....
# Явно указываем KVM тип процессора
cpu.type=host
# Включим "симметричное мультипроцессирование" (Symmetric Multiprocessing, SMP) с заданным общим количеством виртуальных процессоров:
cpu.smp.processors=8
# Уточним конфигурацию, задав количество процессорных "сокетов" и "ядер" установленных виртуальных процессоров (похоже на то, что Qemu по умолчанию эмулирует одноядерные процессоры и, если хочется дать возможность "обычным" серверным Windows использовать более четырёх процессоров, придётся явно указывать, сколько у нас сокетов "процессоров" (например: четыре), и сколько "ядер" в этих процессорах (например: по два ядра), в множителе получая желаемое общее количество)
cpu.smp.sockets=4
cpu.smp.cores=2
# Указываем доступный виртуальной машине объём оперативной памяти (в мегабайтах)
memory=1536
# Явно указываем тип VGA адаптера, подревнее, чтобы его распознала даже Windows 95 {cirrus|std|vmware|none}
vga=cirrus
# VNC port, relatively: 1 (absolutely: 5901) (example: 2 => 5902, 3 => 5903). Set "0" for disable VNC
vnc=1
# Уточняем тип источника временных тактов и тип подаваемого в виртуальную машину времени (clock.vm: {utc|localtime})
clock.source=unix
clock.vm=localtime
# Перечень источников загрузки операционной системы ("с" - первый в списке условный HDD, "d" - первый условный CD-ROM)
boot.order=cd
....
# Явно указываем KVM тип процессора
cpu.type=host
# Включим "симметричное мультипроцессирование" (Symmetric Multiprocessing, SMP) с заданным общим количеством виртуальных процессоров:
cpu.smp.processors=8
# Уточним конфигурацию, задав количество процессорных "сокетов" и "ядер" установленных виртуальных процессоров (похоже на то, что Qemu по умолчанию эмулирует одноядерные процессоры и, если хочется дать возможность "обычным" серверным Windows использовать более четырёх процессоров, придётся явно указывать, сколько у нас сокетов "процессоров" (например: четыре), и сколько "ядер" в этих процессорах (например: по два ядра), в множителе получая желаемое общее количество)
cpu.smp.sockets=4
cpu.smp.cores=2
# Указываем доступный виртуальной машине объём оперативной памяти (в мегабайтах)
memory=1536
# Явно указываем тип VGA адаптера, подревнее, чтобы его распознала даже Windows 95 {cirrus|std|vmware|none}
vga=cirrus
# VNC port, relatively: 1 (absolutely: 5901) (example: 2 => 5902, 3 => 5903). Set "0" for disable VNC
vnc=1
# Уточняем тип источника временных тактов и тип подаваемого в виртуальную машину времени (clock.vm: {utc|localtime})
clock.source=unix
clock.vm=localtime
# Перечень источников загрузки операционной системы ("с" - первый в списке условный HDD, "d" - первый условный CD-ROM)
boot.order=cd
....
Если указать в качестве типа процессора "host", то в виртуальную машину будет транслироваться параметры и возможности реального процессора несущей машины - вариант с максимальной производительностью. Иногда это неудобно - виртуализируемая "MS Windows OEM" запросто может отказаться запускаться после миграции на виртуализатор с другим аппаратным обеспечением, потребовав подтвердить лицензию для работы на изменившейся конфигурации - унификация в этом смысле полезна и я указываю KVM эмулировать процессор "Intel Core2Duo", во избежание.
Фрагмент кода с функциями предварительной инициализации строки параметров виртуальной машины:
# vi /etc/kvm/fnc.d/3.preset.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 start-preset() {
# Зачищаем исходящую строку описания от результатов работы предыдущей итерации
PSTRING=""
# Получаем тип процессора, количество процессоров, количество ядер на каждый процессор
PCPUTYPE=`grep --ignore-case "^cpu.type=" "${CNF}" | awk -F = '{print $2}'`
PCPUSMPPROCESSORS=`grep --ignore-case "^cpu.smp.processors=" "${CNF}" | awk -F = '{print $2}'`
PCPUSMPSOCKETS=`grep --ignore-case "^cpu.smp.sockets=" "${CNF}" | awk -F = '{print $2}'`
PCPUSMPCORES=`grep --ignore-case "^cpu.smp.cores=" "${CNF}" | awk -F = '{print $2}'`
# Получаем значение доступного виртуальной машине объёма оперативной памяти (в мегабайтах)
PMEMORY=`grep --ignore-case "^memory=" "${CNF}" | awk -F = '{print $2}'`
# Получаем тип VGA адаптера
PVGA=`grep --ignore-case "^vga=" "${CNF}" | awk -F = '{print $2}'`
# Получаем значение относительного номера VNC порта
PVNC=`grep --ignore-case "^vnc=" "${CNF}" | awk -F = '{print $2}'`
# Получаем тип источника временных тактов и тип подаваемого в виртуальную машину времени
PCLOCKSOURCE=`grep --ignore-case "^clock.source=" "${CNF}" | awk -F = '{print $2}'`
PCLOCKVM=`grep --ignore-case "^clock.vm=" "${CNF}" | awk -F = '{print $2}'`
# Получаем перечень источников загрузки виртуальной машины
PBOOTORDER=`grep --ignore-case "^boot.order=" "${CNF}" | awk -F = '{print $2}'`
# Далее обрабатываем полученные переменные и формируем строку описания подсистем окружения виртуальной машины
# Формируем строку описания процессора и ОЗУ виртуальной машины
if [ "${PMEMORY}" != "" -a "${PCPUTYPE}" != "" -a "${PCPUSMPPROCESSORS}" != "" ]; then
PSTRING="${PSTRING} -m ${PMEMORY} -balloon none -cpu ${PCPUTYPE} -smp ${PCPUSMPPROCESSORS}"
# Уточняем конфигурацию процессоров
if [ "${PCPUSMPSOCKETS}" != "" -a "${PCPUSMPCORES}" != "" ]; then
PSTRING="${PSTRING},sockets=${PCPUSMPSOCKETS},cores=${PCPUSMPCORES}"
fi
else
echo "${DATE}: No full details of a CPU and RAM environment. Abort operations." | tee -a "${LOGT}"
return 1
fi
# Формируем строку описания терминала (видео, клавиатура)
PSTRING="${PSTRING} -vga ${PVGA}"
if [ "${PVNC}" == "" -o "${PVNC}" == "0" ]; then
PSTRING="${PSTRING} -nographic"
else
PSTRING="${PSTRING} -vnc :${PVNC}"
fi
# Формируем строку описания подсистемы времени виртуальной машины
if [ "${PCLOCKSOURCE}" != "" -a "${PCLOCKVM}" != "" ]; then
PSTRING="${PSTRING} -clock ${PCLOCKSOURCE} -rtc base=${PCLOCKVM},clock=vm -no-hpet"
else
echo "${DATE}: No full details of a clock environment. Abort operations." | tee -a "${LOGT}"
return 1
fi
# Формируем строку описания параметров загрузчика виртуальной машины
if [ "${OPERATION}" != "install" ] ; then
PSTRING="${PSTRING} -boot order=cd,menu=off"
else
PSTRING="${PSTRING} -boot order=dc,menu=off"
fi
# Добиваем строку описания окружения уточняющими опциями
# Здесь можно описать индивидуальные или не полностью закреплённые в спецификации параметры. Например, указать на необходимость инициирования стека "USB 2.0" или "USB 3.0", которые ещё не во всех сборках KVM работают стабильно (USB 2.0: usb-ehci, USB 3.0: nec-usb-xhci)
#
# PSTRING="${PSTRING} -usb -usbdevice tablet -device usb-ehci -parallel none -serial none"
PSTRING="${PSTRING} -usb -usbdevice tablet -parallel none -serial none"
return 0
}
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)
# Функция предварительной инициализации
function start-preset() {
# Зачищаем исходящую строку описания от результатов работы предыдущей итерации
PSTRING=""
# Получаем тип процессора, количество процессоров, количество ядер на каждый процессор
PCPUTYPE=`grep --ignore-case "^cpu.type=" "${CNF}" | awk -F = '{print $2}'`
PCPUSMPPROCESSORS=`grep --ignore-case "^cpu.smp.processors=" "${CNF}" | awk -F = '{print $2}'`
PCPUSMPSOCKETS=`grep --ignore-case "^cpu.smp.sockets=" "${CNF}" | awk -F = '{print $2}'`
PCPUSMPCORES=`grep --ignore-case "^cpu.smp.cores=" "${CNF}" | awk -F = '{print $2}'`
# Получаем значение доступного виртуальной машине объёма оперативной памяти (в мегабайтах)
PMEMORY=`grep --ignore-case "^memory=" "${CNF}" | awk -F = '{print $2}'`
# Получаем тип VGA адаптера
PVGA=`grep --ignore-case "^vga=" "${CNF}" | awk -F = '{print $2}'`
# Получаем значение относительного номера VNC порта
PVNC=`grep --ignore-case "^vnc=" "${CNF}" | awk -F = '{print $2}'`
# Получаем тип источника временных тактов и тип подаваемого в виртуальную машину времени
PCLOCKSOURCE=`grep --ignore-case "^clock.source=" "${CNF}" | awk -F = '{print $2}'`
PCLOCKVM=`grep --ignore-case "^clock.vm=" "${CNF}" | awk -F = '{print $2}'`
# Получаем перечень источников загрузки виртуальной машины
PBOOTORDER=`grep --ignore-case "^boot.order=" "${CNF}" | awk -F = '{print $2}'`
# Далее обрабатываем полученные переменные и формируем строку описания подсистем окружения виртуальной машины
# Формируем строку описания процессора и ОЗУ виртуальной машины
if [ "${PMEMORY}" != "" -a "${PCPUTYPE}" != "" -a "${PCPUSMPPROCESSORS}" != "" ]; then
PSTRING="${PSTRING} -m ${PMEMORY} -balloon none -cpu ${PCPUTYPE} -smp ${PCPUSMPPROCESSORS}"
# Уточняем конфигурацию процессоров
if [ "${PCPUSMPSOCKETS}" != "" -a "${PCPUSMPCORES}" != "" ]; then
PSTRING="${PSTRING},sockets=${PCPUSMPSOCKETS},cores=${PCPUSMPCORES}"
fi
else
echo "${DATE}: No full details of a CPU and RAM environment. Abort operations." | tee -a "${LOGT}"
return 1
fi
# Формируем строку описания терминала (видео, клавиатура)
PSTRING="${PSTRING} -vga ${PVGA}"
if [ "${PVNC}" == "" -o "${PVNC}" == "0" ]; then
PSTRING="${PSTRING} -nographic"
else
PSTRING="${PSTRING} -vnc :${PVNC}"
fi
# Формируем строку описания подсистемы времени виртуальной машины
if [ "${PCLOCKSOURCE}" != "" -a "${PCLOCKVM}" != "" ]; then
PSTRING="${PSTRING} -clock ${PCLOCKSOURCE} -rtc base=${PCLOCKVM},clock=vm -no-hpet"
else
echo "${DATE}: No full details of a clock environment. Abort operations." | tee -a "${LOGT}"
return 1
fi
# Формируем строку описания параметров загрузчика виртуальной машины
if [ "${OPERATION}" != "install" ] ; then
PSTRING="${PSTRING} -boot order=cd,menu=off"
else
PSTRING="${PSTRING} -boot order=dc,menu=off"
fi
# Добиваем строку описания окружения уточняющими опциями
# Здесь можно описать индивидуальные или не полностью закреплённые в спецификации параметры. Например, указать на необходимость инициирования стека "USB 2.0" или "USB 3.0", которые ещё не во всех сборках KVM работают стабильно (USB 2.0: usb-ehci, USB 3.0: nec-usb-xhci)
#
# PSTRING="${PSTRING} -usb -usbdevice tablet -device usb-ehci -parallel none -serial none"
PSTRING="${PSTRING} -usb -usbdevice tablet -parallel none -serial none"
return 0
}