Lab 38 – VM Linux e QEMU Guest Agent: console seriale, opzioni, spegnimento, fsfreeze e rimozione
Dipendenze
Sezione intitolata “Dipendenze”- Lab precedenti:
- VM e servizi: VM 100
debian01sudesopve01, disco surbd-vm(Ceph, Lab 17); storagenas-nfs(Lab 13) per un job di backup di prova. - Indirizzi: VM 100 su 172.27.199.100; VM di prova 380 senza rete.
- Credenziali:
rootelabuser/<password-lab>→ Appendice B.
Obiettivi
Sezione intitolata “Obiettivi”- Usare le due console di una VM: noVNC (schermo grafico) e xterm.js (porta seriale).
- Installare e attivare il QEMU Guest Agent e capire cosa ci fa Proxmox VE: indirizzi IP, spegnimento pulito, comandi nel guest, password, freeze dei filesystem.
- Vedere con una prova reale come il fsfreeze blocca le scritture del guest durante un backup.
- Impostare avvio automatico, ordine di avvio e protezione di una VM.
- Eliminare una VM in modo completo con purge, e capire cosa succede senza.
Come funziona
Sezione intitolata “Come funziona”Il guest agent. qemu-ga è un piccolo servizio che gira dentro il guest. Proxmox VE gli parla attraverso un canale dedicato, senza passare dalla rete:
nodo: /var/run/qemu-server/100.qga (socket Unix)QEMU: dispositivo virtio-serial ──► porta "org.qemu.guest_agent.0"guest: qemu-ga legge i comandi dalla porta e rispondeCon l’agent attivo Proxmox VE:
- mostra gli IP del guest nel Summary, senza doverli cercare;
- spegne la VM chiedendolo al sistema operativo, invece di simulare il tasto di accensione (ACPI);
- congela i filesystem prima di uno snapshot o di un backup, così i dati su disco sono coerenti;
- dopo uno spostamento del disco o una migrazione può lanciare
fstrimnel guest per restituire lo spazio allo storage thin (Lab 37); - esegue comandi nel guest (
qm guest exec) e ne cambia le password (qm guest passwd).
L’agent va attivato da entrambe le parti: il pacchetto nel guest e l’opzione QEMU Guest Agent nella VM. L’opzione aggiunge il dispositivo virtio-serial, quindi diventa effettiva solo con un nuovo avvio del processo QEMU.
Le console.
- noVNC mostra lo schermo grafico della VM (la scheda video emulata). Funziona sempre, anche durante l’avvio e senza rete.
- xterm.js è un terminale testuale collegato alla porta seriale della VM. Richiede una porta
serial0e ungettyin ascolto suttyS0nel guest. Rispetto a noVNC permette copia e incolla e non ha problemi di layout della tastiera.
Rimozione. qm destroy elimina configurazione e dischi. I riferimenti alla VM in altre configurazioni del cluster (job di backup, replica, HA) restano, a meno di chiedere il purge.
Procedura
Sezione intitolata “Procedura”1. Il punto di partenza: labuser senza sudo
Sezione intitolata “1. Il punto di partenza: labuser senza sudo”Nella VM 100 del Lab 07 l’utente labuser non può diventare amministratore. Non è un errore: se nell’installer Debian si imposta una password per root, l’installer non installa sudo e non aggiunge il primo utente al gruppo sudo. Per root invece l’accesso SSH con password è disattivato di default (PermitRootLogin prohibit-password).
Si rimedia dalla console noVNC (VM 100 → Console), entrando come root:
apt-get update -qq; apt-get install -y -qq sudo qemu-guest-agentusermod -aG sudo labuser; id labuser; dpkg -l sudo qemu-guest-agent
id labuserora mostra il gruppo27(sudo).qemu-guest-agentrisulta già installato (ii): apt ha installato solosudo. Nella VM manca ancora solo l’attivazione dal lato Proxmox.
2. Attivare l’agent nella VM
Sezione intitolata “2. Attivare l’agent nella VM”Options → QEMU Guest Agent → Edit:

- Use QEMU Guest Agent: aggiunge il canale virtio-serial e fa usare l’agent a Proxmox VE.
- Run guest-trim after a disk move or VM migration: dopo Move disk o migrazione lancia
fstrimnel guest. - Freeze/thaw guest filesystems… for consistency: attivo di default, è il freeze usato da backup e snapshot (sezione 6).
Da CLI:
qm set 100 --agent enabled=1,fstrim_cloned_disks=13. Aggiungere la porta seriale
Sezione intitolata “3. Aggiungere la porta seriale”Hardware → Add → Serial Port, porta 0:

Le due modifiche richiedono nuovo hardware nella VM, quindi restano in sospeso: nella vista Hardware la porta seriale appare in arancione.

Nel guest serve un terminale di login sulla seriale:
Created symlink '/etc/systemd/system/getty.target.wants/[email protected]' → '/usr/lib/systemd/system/[email protected]'.Un riavvio dall’interno del guest non basta: il processo QEMU resta lo stesso e il nuovo hardware non compare. Serve spegnere e riaccendere la VM:
qm shutdown 100 && qm start 1004. Verificare l’agent
Sezione intitolata “4. Verificare l’agent”Sul nodo compaiono il socket dell’agent e quello della seriale, e la riga di comando di QEMU contiene i nuovi dispositivi:
srwxr-x--- 1 root root 0 Nov 10 00:54 /var/run/qemu-server/100.qgasrwxr-x--- 1 root root 0 Nov 10 00:54 /var/run/qemu-server/100.serial0 -chardev 'socket,id=serial0,path=/var/run/qemu-server/100.serial0,server=on,wait=off' \ -device 'isa-serial,chardev=serial0' \ -chardev 'socket,path=/var/run/qemu-server/100.qga,server=on,wait=off,id=qga0' \ -device 'virtio-serial,id=qga0,bus=pci.0,addr=0x8' \ -device 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0' \I comandi dell’agent (qm agent è un sinonimo di qm guest cmd):
qm agent 100 ping # nessun output e codice di uscita 0 se l'agent rispondeqm guest cmd 100 get-osinfo{ "id" : "debian", "kernel-release" : "6.12.116+deb13-amd64", "kernel-version" : "#1 SMP PREEMPT_DYNAMIC Debian 6.12.116-1 (2026-11-07)", "machine" : "x86_64", "name" : "Debian GNU/Linux", "pretty-name" : "Debian GNU/Linux 13 (trixie)", "version" : "13 (trixie)", "version-id" : "13"}network-get-interfaces restituisce schede e indirizzi; riassunto:
lo 00:00:00:00:00:00 ['127.0.0.1/8', '::1/128']ens18 bc:24:11:2b:ff:8a ['172.27.199.100/24', 'fd27:199::be24:11ff:fe2b:ff8a/64', 'fe80::be24:11ff:fe2b:ff8a/64']L’indirizzo IPv6 globale è quello SLAAC ricevuto dal router del laboratorio (Lab 25). Gli stessi indirizzi compaiono nel Summary della VM, alla voce IPs:

Un comando eseguito nel guest, con l’output restituito al nodo:
qm guest exec 100 -- uname -r{ "exitcode" : 0, "exited" : 1, "out-data" : "6.12.116+deb13-amd64\n", "out-truncated" : 0}get-fsinfo elenca i filesystem del guest e i dischi su cui stanno: il disco è riconosciuto come drive-scsi0, lo stesso nome usato da Proxmox VE.
/ ext4 sda1 ['0QEMU_QEMU_HARDDISK_drive-scsi0'] 1315024896 150466355205. La console seriale con xterm.js
Sezione intitolata “5. La console seriale con xterm.js”Console → xterm.js (o il menu a tendina del pulsante Console). Si apre direttamente il terminale della porta seriale:

tty risponde /dev/ttyS0: è la porta seriale, non lo schermo. Il testo si copia e incolla come in un terminale SSH, ma la console funziona anche senza rete nel guest.
6. fsfreeze: cosa vede il guest durante un backup
Sezione intitolata “6. fsfreeze: cosa vede il guest durante un backup”Un backup in modalità snapshot (Lab 46) fa questo: congela i filesystem, crea lo snapshot del disco, scongela. Così il disco salvato è coerente, come dopo un sync. La prova con i comandi dell’agent:
- dal nodo:
fsfreeze-freeze, attesa di 12 secondi,fsfreeze-thaw; - nel guest, in una sessione SSH già aperta, una scrittura con
syncche parte durante il freeze.
# sul nodoqm guest cmd 100 fsfreeze-freeze # risponde con il numero di filesystem congelatiqm guest cmd 100 fsfreeze-statussleep 12qm guest cmd 100 fsfreeze-thaw# nel guest, subito dopo il freezedate +%T; dd if=/dev/zero of=~/prova bs=1M count=10 && sync; date +%Tnodo: 00:53:50 freeze1frozenAgent error: Command guest-exec has been disabled: the command is not allowednodo: 00:54:06 thaw1thawedguest: inizio scrittura 00:53:54guest: fine scrittura 00:54:08fsfreeze-freezerisponde con il numero di filesystem congelati (1) e lo stato diventafrozen.- Durante il freeze l’agent rifiuta gli altri comandi, come
guest-exec: accetta solo stato e thaw. - La scrittura nel guest è iniziata alle 00:53:54 ed è rimasta bloccata fino al thaw delle 00:54:06: le applicazioni non ricevono errori, aspettano.
Per questo un backup con agent dura pochi secondi di “pausa” in scrittura. Per i database, qemu-ga può eseguire uno script prima e dopo il freeze (fsfreeze hook), per esempio per far scrivere al database un checkpoint coerente.
7. Spegnimento pulito
Sezione intitolata “7. Spegnimento pulito”Con l’agent attivo qm shutdown (e il pulsante Shutdown) chiede lo spegnimento al guest attraverso l’agent. Il tempo si misura con time qm shutdown 100:
spenta in 7 sNel journal del guest, dopo il riavvio, si vede chi ha chiesto lo spegnimento:
qm guest exec 100 -- journalctl -b -1 --no-pager -g "guest-shutdown|System is powering down"Nov 10 00:54:35 debian01 qemu-ga[586]: info: guest-shutdown called, mode: (null)Nov 10 00:54:35 debian01 systemd-logind[596]: System is powering down (hypervisor initiated shutdown).Senza agent Proxmox VE invia un evento ACPI, come la pressione del tasto di accensione: funziona solo se il guest lo gestisce (con systemd sì). Se il guest non risponde entro il timeout, il task fallisce e serve Stop, che equivale a togliere la corrente.
8. Cambiare la password con l’agent
Sezione intitolata “8. Cambiare la password con l’agent”qm guest passwd imposta la password di un utente del guest senza entrarci. Legge la nuova password due volte da standard input:
qm guest passwd 100 labuserLa prova con una password temporanea e un login SSH:
login con la nuova password: ok (labuser@debian01)Poi la password è stata riportata a <password-lab> con lo stesso comando. È utile quando una password è persa e la VM non ha altri accessi: basta che l’agent sia attivo.
9. Avvio automatico, ordine e protezione
Sezione intitolata “9. Avvio automatico, ordine e protezione”In Options:
- Start at boot (
onboot): la VM parte quando si avvia il nodo. - Start/Shutdown order (
startup):orderè la posizione nella sequenza (prima i numeri bassi; allo spegnimento l’ordine si inverte),upi secondi da aspettare dopo l’avvio prima della VM successiva,downil timeout di spegnimento.
Per la VM 100: avvio automatico, posizione 2, 30 secondi di attesa.

qm set 100 --onboot 1 --startup order=2,up=30Protection impedisce di eliminare la VM e i suoi dischi. Prova su una VM usa e getta, la 380, creata vuota con un disco da 1 GiB:
qm create 380 --name prova-380 --memory 512 --scsihw virtio-scsi-single --scsi0 rbd-vm:1 --ostype l26qm set 380 --protection 1qm destroy 380can't remove VM 380 - protection mode enabledSi toglie con qm set 380 --delete protection.
10. Rimozione: senza e con purge
Sezione intitolata “10. Rimozione: senza e con purge”La VM 380 viene inserita in un job di backup (disattivato, solo per la prova):
pvesh create /cluster/backup --vmid 380 --storage nas-nfs --schedule "sun 03:00" --enabled 0 --mode snapshot --comment "lab 38 prova purge"Prima rimozione, con le opzioni di default. Nel dialogo di rimozione (More → Remove) Purge from job configurations è disattivato. La VM sparisce, il volume su Ceph pure, ma il job resta:
vzdump: 7da86c4c-424f-44c6-98bf-08d52b3a8af1 comment lab 38 prova purge schedule sun 03:00 enabled 0 mode snapshot storage nas-nfs vmid 380Il problema si vede creando una nuova VM con lo stesso ID:
qm create 380 --name nuova-vm --memory 512 --scsihw virtio-scsi-single --scsi0 rbd-vm:1 --ostype l26pvesh get /cluster/backup/7da86c4c-424f-44c6-98bf-08d52b3a8af1 --output-format json \ | python3 -c 'import json,sys; print("job vmid:", json.load(sys.stdin)["vmid"])'job vmid: 380La VM nuova eredita senza avviso il job della vecchia: con un job attivo verrebbe salvata (o, se lo storage non ha spazio, farebbe fallire il job).
Seconda rimozione, con purge. Si attivano Purge from job configurations e Destroy unreferenced disks owned by guest (cerca e cancella anche dischi della VM non collegati nella configurazione):

echo "--- dopo la rimozione con purge"; cat /etc/pve/jobs.cfg; echo "(fine jobs.cfg)"--- dopo la rimozione con purge(fine jobs.cfg)/etc/pve/jobs.cfg è vuoto: il job conteneva solo la VM 380, e il purge lo ha eliminato del tutto. Da CLI:
qm destroy 380 --purge 1 --destroy-unreferenced-disks 1Il purge toglie la VM anche da replica e HA.
Verifica e test
Sezione intitolata “Verifica e test”labuserè nel grupposudo;qemu-guest-agentè attivo nel guest.qm agent 100 pingrisponde; il Summary mostra gli IP della VM.- La console xterm.js apre un login su
/dev/ttyS0. qm shutdownspegne la VM in 7 secondi e il guest registraguest-shutdown called.- Durante un
fsfreezele scritture nel guest restano in attesa fino al thaw e l’agent rifiutaguest-exec. qm guest passwdcambia la password e il login con la nuova funziona.- Una VM protetta non si può eliminare.
- Senza purge un job di backup conserva l’ID della VM eliminata e lo applica a una VM nuova con lo stesso ID; con purge il riferimento sparisce.
Stato finale del lab
Sezione intitolata “Stato finale del lab”- VM 100
debian01sudesopve01, accesa:sudoperlabuser, agent attivo (agent: 1,fstrim_cloned_disks=1), portaserial0con getty suttyS0,onboot: 1,startup: order=2,up=30. Password dilabuseruguale a prima. - VM 380: eliminata, con il job di backup di prova.
- Nessun’altra modifica al cluster.
Cosa hai imparato
Sezione intitolata “Cosa hai imparato”- Il guest agent comunica con il nodo su un canale virtio-serial e va attivato sia nel guest sia nelle opzioni della VM; l’hardware nuovo richiede spegnimento e riaccensione.
- Con l’agent Proxmox VE conosce gli IP del guest, lo spegne in modo pulito, esegue comandi e cambia password.
- Il freeze dei filesystem mette in attesa le scritture del guest per il tempo dello snapshot: è ciò che rende coerenti i backup.
- La console xterm.js usa la porta seriale e si comporta come un terminale vero; noVNC resta l’accesso di emergenza.
onboot,startupeprotectionregolano avvio automatico, sequenza e sicurezza delle VM.- Eliminare una VM senza purge lascia riferimenti orfani nei job, che una VM nuova con lo stesso ID eredita.