У меня есть виртуальный сервер, работающий в 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 (универсально поддерживается, но потенциально более подвержено ошибкам) для горячего добавления / удаления дисков.