Назад | Перейти на главную страницу

Горячая замена физических дисков, переданных на виртуальную машину qemu

У меня есть виртуальный сервер, работающий в qemu на proxmox. Он имеет два физических диска, подключенных к хосту с помощью директивы virtio: в 101.cfg, как показано ниже.

virtio2: /dev/disk/by-id/ata-vol1,backup=0 
virtio3: /dev/disk/by-id/ata-vol2,backup=0

Они содержат зеркальный том ZFS, с которого мои файлы обслуживаются с помощью nextcloud. Все это прекрасно работает, потому что эти диски никогда не удаляются из гостевой системы.

У меня также есть ротация трех других физических дисков, на которые я выполняю резервное копирование (физический контроллер - это рейд-контроллер LSI в конфигурации JBOD, физическое оборудование - HP Proiliant DL380e Gen8). Я делаю это, отправляя zfs обновленный снимок из массива хранения на любой резервный диск, присутствующий в системе. Я добавил их в виртуальную машину следующим образом:

virtio4: /dev/disk/by-id/ata-backup1-volname,backup=0
virtio5: /dev/disk/by-id/ata-backup2-volname,backup=0
virtio6: /dev/disk/by-id/ata-backup3-volname,backup=0

Это работает, но проблема в том, что ни один из этих дисков не поддерживает горячую замену, поэтому, если я извлекаю и вставляю диски поочередно, гость перестает их видеть. В моей конфигурации qemu включено горячее подключение диска.

У меня вопрос: как правильно динамически подключать и отсоединять эти диски от моей виртуальной машины по мере их вставки и удаления?

Мне удалось найти частичное решение, используя «qm monitor» для присоединения и отсоединения извлекаемого диска путем присоединения и отсоединения «pci-карт» virtio-scsi следующим образом:

Приложить

qm> drive_add 0 file=/dev/disk/by-id/ata-<disk-id>,if=none,id=backup_vol,cache=none,detect-zeroes=on
qm> device_add virtio-blk-pci,drive=backup_vol,id=backup_scsi_controller

Отсоединить

qm> device_del backup_scsi_controller

(Источник: https://blog.chrishowie.com/2019/09/19/hot-swapping-virtio-disks-on-qemu/ через кеш Google)

Я думал, что потенциально могу добавить их в свои сценарии резервного копирования, но, похоже, это невозможно, однако, запускать команды монитора qm из сценария оболочки, а монитор qm не будет принимать аргументы или ввод от stdin. После чтения aroud можно было бы создать сокет в qemu-agent на гостевой машине и внедрить его с помощью JSON, но я ничего не знаю о JSON и очень надеюсь, что есть более простой способ.

Я был немного в домах на этом, и действительно дошел до того момента, когда я смог отправлять команды QMP гостю через сокет UNIX. Это поддерживается конфигурацией Proxmox по умолчанию с использованием сокета в / var / run / qemu-server / <server-id> .qmp. Затем я могу интерактивно отправлять сообщения QMP JSON, используя

rlwrap -C qmp socat - UNIX:/var/run/qemu-server/101.qmp

(rlwrap не устанавливается по умолчанию, но может быть установлен с помощью "apt install rlwrap")

Однако формат сообщения QMP был таким непрозрачным, как я думал, и не имел прямого эквивалента "drive_add" по причинам идеологической чистоты (что, возможно, понятно, но тем не менее крайне бесполезно в контексте моих нынешних трудностей). Есть команда "blockdev_add", которая вполне могла сделать то, что я хотел, если предположить, что я смогу выработать правильный синтаксис.

Поэтому я сделал шаг назад и пришел к выводу, что «qm monitor», вероятно, не принимает ввод от стандартного ввода из-за поддержки строки чтения. Это заставило меня задуматься о «ожидании». После быстрой «подходящей установки» я смог создать сценарии для подключения и отключения дисков следующим образом:

qemu-drive-attach <vm-id> <device-name> <path-to-block-device>

со скриптом qemu-drive-attach (имя устройства произвольное - я использую "virtio8" для согласованности со схемой именования Proxmox)

!/usr/bin/expect
set vm_id               [lindex $argv 0];
set device_name         [lindex $argv 1];
set device_file         [lindex $argv 2];

spawn qm monitor $vm_id
expect "qm> "
send "drive_add 0 file=$device_file,if=none,id=drive-$device_name,cache=none,detect-zeroes=on\r"

expect "OK" {
    expect "qm> "
    send "device_add virtio-blk-pci,drive=drive-$device_name,id=$device_name\r"
}

expect "qm> "
send "quit\r"

send_user "\n"

И для отсоединения

qemu-drive-detach <vm-id> <device-name>

со скриптом qemu-drive-detach

#!/usr/bin/expect
set vm_id               [lindex $argv 0];
set device_name         [lindex $argv 1];

spawn qm monitor $vm_id
expect "qm> "
send "device_del $device_name\r"

expect "qm> "
send "quit\r"

send_user "\n"

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

virtio-blk не поддерживает горячую замену.

Чтобы использовать диски с возможностью горячей замены, вам необходимо использовать драйвер с такой поддержкой, как SATA или virtio-scsi (которые реализуют протокол SCSI). Тогда вы можете использовать что-нибудь как virsh (отредактируйте: как вы правильно заметили, это не поддерживается в Proxmox) или Qemu HMP (универсально поддерживается, но потенциально более подвержено ошибкам) ​​для горячего добавления / удаления дисков.