Thursday, August 27, 2026

Attempt to setup KVM Host on Sparky 2026.06 tolerant to Timeshift rollbacks (Assisted by Google AI )

 This post is an immediate follow up for  Sparky Linux 2026 06 OverlayFS BTRFS with Timeshift setup   We presume that KVM has been already setup on Sparky 2026.06, however neither one KVM guests have been created yet. Modern virtual machines use OVMF (Open Virtual Machine Firmware) to simulate an industry-standard UEFI environment rather than an old legacy BIOS.The Role of NVRAM: UEFI requires a non-volatile random-access memory (NVRAM) variables store to keep track of boot orders, hardware configurations, and Secure Boot certificates.Separation of Files: In KVM, the UEFI firmware itself is read-only (e.g., OVMF_CODE.fd), while the companion NVRAM file (e.g., OVMF_VARS.fd) stores the unique, writable state data for that specific VM.

In particular case, it would finally look like
root@devs-LV8664:~# uname -a
Linux devs-LV8664 7.1.8+deb14.1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 7.1.8-2 (2026-08-15) x86_64 GNU/Linux

boris@devs-LV8664:~$ sudo su -
[sudo] password for boris:  
root@devs-LV8664:~# lsattr /var/lib/libvirt/qemu/nvram
---------------C------ /var/lib/libvirt/qemu/nvram/Garuda0827_VARS.fd
root@devs-LV8664:~# lsattr -d /var/lib/libvirt/qemu/nvram
---------------C------ /var/lib/libvirt/qemu/nvram
root@devs-LV8664:~# lsattr /var/lib/libvirt/images/*.qcow2
---------------C------ /var/lib/libvirt/images/Garuda0827.qcow2

 ===================================================

$ sudo mkdir -p /mnt/btrfs_top
$ sudo mount -o subvolid=5 /dev/vda3 /mnt/btrfs_top
$ sudo btrfs subvolume create /mnt/btrfs_top/@images
$ sudo btrfs subvolume create /mnt/btrfs_top/@qemu
$ sudo umount /mnt/btrfs_top
$ sudo rmdir /mnt/btrfs_top

Then add to /etc/fstab two rows
# DECOUPLED VM DATA & CONFIGS (Completely skipped during Timeshift rollbacks)
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /var/lib/libvirt/images  btrfs  subvol=@images,defaults,nodatacow  0  0
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /etc/libvirt/qemu        btrfs  subvol=@qemu,defaults,compress=zstd:1 0  0
                           

 $ sudo systemctl daemon-reload                                                           $ sudo mount -a
 $ sudo reboot
==================================================
Disable CoW on /var/lib/libvirt/images and nvram setup
==================================================
# 1. Clean up old failed files/folders to start fresh
rm -f /var/lib/libvirt/images/* 2>/dev/null

# 2. Apply the No-CoW flag to the images storage subvolume
chattr +C /var/lib/libvirt/images

# 3. Build the persistent NVRAM storage inside the isolated @qemu subvolume and 
 create the hypervisor NVRAM endpoint path
mkdir -p /etc/libvirt/qemu/nvram
chown libvirt-qemu:kvm /etc/libvirt/qemu/nvram
chmod 755 /etc/libvirt/qemu/nvram
mkdir -p /var/lib/libvirt/qemu/nvram
chmod 755 /var/libvirt/qemu/nvram

 
# 4. Strip BTRFS compression inheritance and apply No-CoW to the source directory
btrfs property set /etc/libvirt/qemu/nvram compression ""
chattr +C /etc/libvirt/qemu/nvram

# Set proper ownership and permissions
chown -R libvirt-qemu:kvm /etc/libvirt/qemu/nvram
chown -R libvirt-qemu:kvm /var/lib/libvirt/qemu/nvram
chmod 755 /etc/libvirt/qemu/nvram
chmod 755 /var/lib/libvirt/qemu/nvram

# 5. Execute the kernel directory bind mount
mount --bind /etc/libvirt/qemu/nvram /var/lib/libvirt/qemu/nvram

# 6. Ensure the mount persists across system restarts (FSTAB)
sed -i '\|/etc/libvirt/qemu/nvram|d' /etc/fstab
echo "/etc/libvirt/qemu/nvram  /var/lib/libvirt/qemu/nvram  none  bind  0  0" >> /etc/fstab

# 7. Completely disable AppArmor for QEMU to avoid profile load crashes
sed -i 's/^#\?security_driver =.*/security_driver = "none"/' /etc/libvirt/qemu.conf
if ! grep -q '^security_driver = "none"' /etc/libvirt/qemu.conf; then
    echo 'security_driver = "none"' >> /etc/libvirt/qemu.conf
fi
#8. Cycle the daemons to completely finalize initialization
systemctl daemon-reload
mount -a
systemctl restart apparmor
systemctl restart libvirtd

root@devs-LV8664:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
# <file system>             <mount point>  <type>  <options>  <dump>  <pass>
UUID=97E5-166D                             /boot/efi      vfat    defaults,umask=0077 0 2
UUID=66ed69e1-91ff-47e7-9a4f-88afb3fdc5ac  /boot          ext4    defaults   0 2
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /              btrfs   subvol=/@,defaults,compress=zstd:1 0 0
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /home          btrfs   subvol=/@home,defaults,compress=zstd:1 0 0
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /var/cache     btrfs   subvol=/@cache,defaults,compress=zstd:1 0 0
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /var/log       btrfs   subvol=/@log,defaults,compress=zstd:1 0 0
# DECOUPLED VM DATA & CONFIGS (Completely skipped during Timeshift rollbacks)
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /var/lib/libvirt/images  btrfs  subvol=@images,defaults,nodatacow  0  0
UUID=f85d880c-2c08-4a56-b645-ff030bd29433  /etc/libvirt/qemu        btrfs  subvol=@qemu,defaults,compress=zstd:1 0  0
/etc/libvirt/qemu/nvram  /var/lib/libvirt/qemu/nvram  none  bind
 0  0

Finally we get 

root@devs-LV8664:~# uname -a
Linux devs-LV8664 7.1.8+deb14.1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 7.1.8-2 (2026-08-15) x86_64 GNU/Linux
root@devs-LV8664:~# findmnt -t btrfs
TARGET                 SOURCE               FSTYPE OPTIONS
/                      /dev/vda3[/@]        btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=317,subvol=/@
├─/var/lib/libvirt/qemu/nvram
│                      /dev/vda3[/@qemu/nvram]
│                                           btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=308,subvol=/@qemu

├─/home                /dev/vda3[/@home]    btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=298,subvol=/@home
├─/etc/libvirt/qemu    /dev/vda3[/@qemu]    btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=308,subvol=/@qemu
├─/var/cache           /dev/vda3[/@cache]   btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=258,subvol=/@cache
├─/var/lib/libvirt/images
│                      /dev/vda3[/@images]  btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=307,subvol=/@image
└─/var/log             /dev/vda3[/@log]     btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=259,subvol=/@log

 
root@devs-LV8664:~# lsattr -d /var/lib/libvirt/images
---------------C------ /var/lib/libvirt/images
root@devs-LV8664:~# lsattr /var/lib/libvirt/images/*.qcow2
---------------C------ /var/lib/libvirt/images/VM01CH.qcow2

 
root@devs-LV8664:~# # Create Timeshift snapshot at this point
root@devs-LV8664:~# # After deployment the first KVM Guest

 
root@devs-LV8664:~# cat Verification.sh
echo -e "\n=== 1. Verifying Automated NVRAM Bind Mount ==="
findmnt /var/lib/libvirt/qemu/nvram

echo -e "\n=== 2. Verifying Persistent NVRAM File Status ==="
lsattr  /etc/libvirt/qemu/nvram/

echo -e "\n=== 3. Verifying AppArmor Disablement Protection ==="
grep "^security_driver" /etc/libvirt/qemu.conf

root@devs-LV8664:~# ./Verification.sh

=== 1. Verifying Automated NVRAM Bind Mount ===
TARGET                     SOURCE                 FSTYPE OPTIONS
/var/lib/libvirt/qemu/nvram
                          /dev/vda3[/@qemu/nvram]
                                                 btrfs  rw,relatime,compress=zstd:1,discard=async,space_cache=v2,subvolid=308,subvol=/ @qemu


=== 2. Verifying Persistent NVRAM File Status ===
---------------C------ /etc/libvirt/qemu/nvram/VM05CH_VARS.fd

=== 3. Verifying AppArmor Disablement Protection ===
security_driver = "none"



 

 


No comments:

Post a Comment