Use existing nvram path in libvirt driver to support session daemon mode

When libvirtd is started as a non-root user it does not have access to
folder /var/lib/libvirt. By default, libvirtd in session daemon mode
creates a nvram file at path ~/.config/libvirt/qemu/nvram/\
[DOMAIN]_VARS[EXT] instead [0],[1].

Querying the nvram path in session daemon mode is difficult because
libvirtd does not expose it nor $HOME of the user that runs the daemon.
As a workaround, this change will let libvirtd create the nvram file
path if it has not been previously defined [2]. However, if it had been
defined earlier then the path will be changed to enforce regenerating
it from the template.

[0] 2b148748c2/src/qemu/qemu_conf.c (L203)
[1] 2b148748c2/src/qemu/qemu_firmware.c (L1124)
[2] 2b148748c2/src/qemu/qemu_firmware.c (L1065)

Change-Id: Id78101f5c1f5fdf4b365d2d270dbde8877b05dbf
This commit is contained in:
Jakob Meng 2023-12-01 12:52:49 +01:00
parent feb88a5c46
commit 1b80ef8e39
4 changed files with 22 additions and 10 deletions

View File

@ -598,6 +598,11 @@ class LibvirtDriver(AbstractSystemsDriver):
boot_mode, os_arch)
loader_path = None
nvram_element = os_element.find('nvram')
nvram_path = None
if nvram_element:
nvram_path = nvram_element.text
# delete loader and nvram elements to rebuild from stratch
for element in os_element.findall('loader'):
os_element.remove(element)
@ -617,16 +622,23 @@ class LibvirtDriver(AbstractSystemsDriver):
loader_element.set('secure', 'yes')
nvram_element.set('template', self.SECURE_BOOT_ENABLED_NVRAM)
else:
nvram_suffix = '.fd'
nvram_suffix = '.nosecboot.fd'
loader_element.set('secure', 'no')
nvram_element.set('template', self.SECURE_BOOT_DISABLED_NVRAM)
# force a different nvram path for secure vs not. This will ensure
# it gets regenerated from the template when secure boot mode
# changes
nvram_path = "/var/lib/libvirt/nvram-%s%s" % (identity,
nvram_suffix)
nvram_element.text = nvram_path
if nvram_path:
nvram_file = os.path.basename(nvram_path)
if not nvram_file.endswith(nvram_suffix):
nvram_file = nvram_file.\
removesuffix('.secboot.fd').\
removesuffix('.nosecboot.fd').\
removesuffix('.fd') + nvram_suffix
nvram_element.text = os.path.join(os.path.dirname(nvram_path),
nvram_file)
def get_secure_boot(self, identity):
"""Get computer system secure boot state for UEFI boot mode.

View File

@ -7,7 +7,7 @@
<os>
<type arch="x86_64" machine="q35">hvm</type>
<loader readonly="yes" type="pflash">/usr/share/OVMF/OVMF_CODE.fd</loader>
<nvram template="/usr/share/OVMF/OVMF_VARS.fd"/>
<nvram template="/usr/share/OVMF/OVMF_VARS.fd">/var/lib/libvirt/nvram/QEmu-fedora-i686_VARS.fd</nvram>
<boot dev="disk"/>
</os>
<devices>

View File

@ -7,7 +7,7 @@
<os>
<type arch="x86_64" machine="q35">hvm</type>
<loader secure="yes" readonly="yes" type="pflash">/usr/share/OVMF/OVMF_CODE.secboot.fd</loader>
<nvram template="/usr/share/OVMF/OVMF_VARS.secboot.fd"/>
<nvram template="/usr/share/OVMF/OVMF_VARS.secboot.fd">/var/lib/libvirt/nvram/QEmu-fedora-i686_VARS.fd</nvram>
<boot dev="disk"/>
</os>
<devices>

View File

@ -1203,8 +1203,8 @@ class LibvirtDriverTestCase(base.BaseTestCase):
loader_element.text)
self.assertEqual('/usr/share/OVMF/OVMF_VARS.secboot.fd',
nvram_element.get('template'))
self.assertEqual('/var/lib/libvirt/nvram-%s.secboot.fd' %
self.uuid, nvram_element.text)
self.assertEqual('/var/lib/libvirt/nvram/%s_VARS.secboot.fd' %
self.name, nvram_element.text)
@mock.patch('libvirt.open', autospec=True)
@mock.patch('libvirt.openReadOnly', autospec=True)
@ -1230,8 +1230,8 @@ class LibvirtDriverTestCase(base.BaseTestCase):
loader_element.text)
self.assertEqual('/usr/share/OVMF/OVMF_VARS.fd',
nvram_element.get('template'))
self.assertEqual('/var/lib/libvirt/nvram-%s.fd' %
self.uuid, nvram_element.text)
self.assertEqual('/var/lib/libvirt/nvram/%s_VARS.nosecboot.fd' %
self.name, nvram_element.text)
@mock.patch('libvirt.open', autospec=True)
@mock.patch('libvirt.openReadOnly', autospec=True)