[libvirt] [PATCH] docs: Provide documentation for SEV launch security (DO NOT PUSH)
by Erik Skultety
---
I sent this as a patch to get a review on the contents itself, but I believe it
should live as an article on our wiki page afterwards.
docs/launch_security_sev.html.in | 536 +++++++++++++++++++++++++++++++
1 file changed, 536 insertions(+)
create mode 100644 docs/launch_security_sev.html.in
diff --git a/docs/launch_security_sev.html.in b/docs/launch_security_sev.html.in
new file mode 100644
index 0000000000..42db10b33a
--- /dev/null
+++ b/docs/launch_security_sev.html.in
@@ -0,0 +1,536 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta charset="UTF-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
+ <link rel="stylesheet" type="text/css" href="main.css"/>
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
+ <link rel="manifest" href="/manifest.json"/>
+ <meta name="theme-color" content="#ffffff"/>
+ <title>libvirt: Launch security with AMD SEV</title>
+ <meta name="description" content="libvirt, virtualization, virtualization API"/>
+ <script type="text/javascript" src="js/main.js">
+ <!--// forces non-empty element-->
+ </script>
+ </head>
+ <body onload="pageload()">
+ <div id="body">
+ <div id="content">
+ <h1>Launch security with AMD SEV</h1>
+ <ul>
+ <li>
+ <a href="#Host">Enabling SEV on the host</a>
+ </li>
+ <li>
+ <a href="#Virt">Checking SEV support in the virt stack</a>
+ </li>
+ <li>
+ <a href="#Configuration">VM Configuration</a>
+ </li>
+ <li>
+ <a href="#Limitations">Limitations</a>
+ </li>
+ <li>
+ <a href="#Examples">Full domain XML examples</a>
+ </li>
+ </ul>
+ </div>
+ <p>
+ Storage encryption in modern public cloud computing is a common practice.
+ However, from the point of view of a user of these cloud workloads, a
+ significant amount of trust needs to be put in the cloud platform security as
+ well as integrity (was the hypervisor tampered?). For this reason there's ever
+ rising demand for securing data in use, i.e. memory encryption.
+ One of the solutions addressing this matter is AMD SEV.
+ </p>
+ <h2>AMD SEV</h2>
+ <p>
+ SEV (Secure Encrypted Virtualization) is a feature extension of AMD's SME (Secure
+ Memory Encryption) intended for KVM virtual machines which is supported
+ primarily on AMD's EPYC CPU line. In contrast to SME, SEV uses a unique memory encryption
+ key for each VM. The whole encryption of memory pages is completely transparent
+ to the hypervisor and happens in the AMD firmware.
+ For more details about the technology itself, you can visit
+ <a href="https://developer.amd.com/sev/">AMD's developer portal</a>.
+ </p>
+ <h3>
+ <a id="Host">Enabling SEV on the host</a>
+ <a class="headerlink" href="#Host" title="Permalink to this headline">¶</a>
+ </h3>
+ <p>
+ Before VMs can make use of the SEV feature you need to make sure your
+ AMD CPU does support SEV. You can check whether SEV is among the CPU
+ flags with:
+ </p>
+
+ <pre>
+$ cat /proc/cpuinfo | grep sev
+...
+sme ssbd sev ibpb</pre>
+
+ <p>
+ Next step is to enable SEV in the kernel, because it is disabled by default.
+ This is done by putting the following onto the kernel command line:
+ </p>
+ <pre>
+mem_encrypt=on kvm_amd.sev=1
+ </pre>
+
+ <p>
+ To make the changes persistent, append the above to the variable holding
+ parameters of the kernel command line in
+ <code>/etc/default/grub</code> to preserve SEV settings across reboots
+ </p>
+
+ <pre>
+$ cat /etc/default/grub
+...
+GRUB_CMDLINE_LINUX="... mem_encrypt=on kvm_amd.sev=1"
+$ grub2-mkconfig -o /boot/efi/EFI/<distro>/grub.cfg</pre>
+
+ <p>
+ <code>mem_encrypt=on</code> turns on the SME memory encryption feature on
+ the host which is required for SEV to work. The <code>kvm_amd.sev</code>
+ parameter actually enables SEV in the kvm module. It can be set on the
+ command line alongside <code>mem_encrypt</code> like shown above, or it
+ can be put into a module config under <code>/etc/modprobe.d/</code>
+ </p>
+ <pre>
+$ cat /etc/modprobe.d/sev.conf
+options kvm_amd sev=1
+ </pre>
+ <p>
+ After rebooting the host, you should see SEV being enabled in the kernel:
+ </p>
+ <pre>
+$ cat /sys/module/kvm_amd/parameters/sev
+1
+ </pre>
+
+ <h2>
+ <a id="Virt">Checking SEV support in the virt stack</a>
+ <a class="headerlink" href="#Virt" title="Permalink to this headline">¶</a>
+ </h2>
+ <p>
+ <b>Note: All of the commands bellow need to be run with root privileges.</b>
+ </p>
+ <p>
+ First make sure you have the following packages in the specified versions:
+ </p>
+ <ul>
+ <li>
+ libvirt >= 4.5.0 (>5.1.0 recommended due to additional SEV bugfixes)
+ </li>
+ <li>
+ QEMU >= 2.12.0
+ </li>
+ </ul>
+ <p>
+ To confirm that the virtualization stack supports SEV, run the following:
+ </p>
+ <pre>
+# virsh domcapabilities
+<domainCapabilities>
+...
+ <features>
+ ...
+ <sev supported='yes'>
+ <cbitpos>47</cbitpos>
+ <reducedPhysBits>1</reducedPhysBits>
+ </sev>
+ ...
+ </features>
+</domainCapabilities></pre>
+ <p>
+ Note that if libvirt was already installed and libvirtd running before enabling SEV in the kernel followed by the host reboot you need to force libvirtd
+ to re-probe both the host and QEMU capabilities. First stop libvirtd:
+ </p>
+ <pre>
+# systemctl stop libvirtd.service
+ </pre>
+ <p>
+ Now you need to clean the capabilities cache:
+ </p>
+ <pre>
+# rm -f /var/cache/libvirt/qemu/capabilities/*
+ </pre>
+ <p>
+ If you now restart libvirtd, it will re-probe the capabilities and if
+ you now run:
+ </p>
+ <pre>
+# virsh domcapabilities
+ </pre>
+ <p>
+ SEV should be listed as supported. If you still see:
+ </p>
+ <pre>
+<sev supported='no'/>
+ </pre>
+ <p>
+ it means one of two things:
+ <ol>
+ <li>
+ libvirt does support SEV, but either QEMU or the host does not
+ </li>
+ <li>
+ you have libvirt <=5.1.0 which suffered from getting a
+ <code>'Permission denied'</code> on <code>/dev/sev</code> because
+ of the default permissions on the character device which prevented
+ QEMU from opening it during capabilities probing - you can either
+ manually tweak the permissions so that QEMU has access to it or
+ preferably install libvirt 5.1.0 or higher
+ </li>
+ </ol>
+ </p>
+ <h2>
+ <a id="Configuration">VM Configuration</a>
+ <a class="headerlink" href="#Configuration" title="Permalink to this headline">¶</a>
+ </h2>
+ <p>
+ SEV is enabled in the XML by specifying the
+ <a href="https://libvirt.org/formatdomain.html#launchSecurity"><launchSecurity> </a> element. However, specifying <code>launchSecurity</code> isn't
+ enough to boot an SEV VM. Further configuration requirements are discussed
+ below.
+ </p>
+
+ <h3>Machine type</h3>
+ <p>
+ Even though both Q35 and legacy PC machine types (for PC see also
+ "virtio") can be used with SEV, usage of the legacy PC machine type is
+ strongly discouraged, since depending on how your OVMF package was
+ built (e.g. including features like SecureBoot or SMM) Q35 may even be
+ required.
+ </p>
+
+ <h5>Q35</h5>
+<pre>
+...
+<os>
+ <type arch='x86_64' machine='pc-q35-3.0'>hvm</type>
+ ...
+</os>
+...</pre>
+
+ <h5>i440fx (discouraged)</h5>
+ <pre>
+...
+<os>
+ <type arch='x86_64' machine='pc-i440fx-3.0'>hvm</type>
+ ...
+</os>
+...
+ </pre>
+
+ <h3>Boot loader</h3>
+ <p>
+ SEV is only going to work with OVMF (UEFI), so you'll need to point libvirt to
+ the correct OVMF binary.
+ </p>
+ <pre>
+...
+<os>
+ <type arch='x86_64' machine='pc-q35-3.0'>hvm</type>
+ <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader>
+</os>
+...</pre>
+
+ <h3>Memory</h3>
+ <p>
+ Internally, SEV expects that the encrypted memory pages won't be swapped out or move
+ around so the VM memory needs to be pinned in physical RAM which will be
+ handled by QEMU. Apart from that, certain memory regions allocated by QEMU
+ itself (UEFI pflash, device ROMs, video RAM, etc.) have to be encrypted as
+ well. This causes a conflict in how libvirt tries to protect the host.
+ By default, libvirt enforces a memory hard limit on each VM's cgroup in order
+ to protect the host from malicious QEMU to allocate and lock all the available
+ memory. This limit corresponds to the total memory allocation for the VM given
+ by <code><currentMemory></code> element. However, trying to account for the additional
+ memory regions QEMU allocates when calculating the limit in an automated manner
+ is non-deterministic. One way to resolve this is to set the hard limit manually.
+
+ <p>
+ Note: Figuring out the right number so that your guest boots and isn't killed is
+ challenging, but 256MiB extra memory over the total guest RAM should suffice for
+ most workloads and may serve as a good starting point.
+
+ For example, a domain with 4GB memory with a 256MiB extra hard limit would look
+ like this:
+ </p>
+ </p>
+ <pre>
+# virsh edit <domain>
+<domain>
+ ...
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <memtune>
+ <hard_limit unit='KiB'>4456448</hard_limit>
+ </memtune>
+ ...
+</domain></pre>
+ <p>
+ There's another, preferred method of taking care of the limits by
+ using the<code><memoryBacking></code> element along with the
+ <code><locked/></code> subelement:
+ </p>
+ <pre>
+<domain>
+ ...
+ <memoryBacking>
+ <locked/>
+ </memoryBacking>
+ ...
+</domain></pre>
+ <p>
+ What that does is that it tells libvirt not to force any hard limit (well,
+ unlimited) upon the VM cgroup. The obvious advantage is that one doesn't need
+ to determine the hard limit for every single SEV-enabled VM. However, there is
+ a significant security-related drawback to this approach. Since no hard limit
+ is applied, a malicious QEMU could perform a DoS attack by locking all of the
+ host's available memory. The way to avoid this issue and to protect the host is
+ to enforce a bigger hard limit on the master cgroup containing all of the VMs
+ - on systemd this is <code>machine.slice</code>.
+ </p>
+ <pre>
+# systemctl set-property machine.slice MemoryHigh=<value></pre>
+ <p>
+ To put even stricter measures in place which would involve the OOM killer, use
+ <pre>
+# systemctl set-property machine.slice MemoryMax=<value></pre>
+ instead. Alternatively, you can create a systemd config (don't forget
+ to reload systemd configuration in this case):
+ <pre>
+# cat << EOF > /etc/systemd/system.control/machine.slice.d/90-MemoryMax.conf
+MemoryMax=<value>
+EOF</pre>
+ The trade-off to keep in mind with the second approach is that the VMs
+ can still perform DoS on each other.
+ </p>
+ <h3>Virtio</h3>
+ <p>
+ In order to make virtio devices work, we need to enable emulated IOMMU
+ on the devices so that virtual DMA can work.
+ </p>
+ <pre>
+# virsh edit <domain>
+<domain>
+ ...
+ <controller type='virtio-serial' index='0'>
+ <driver iommu='on'/>
+ </controller>
+ <controller type='scsi' index='0' model='virtio-scsi'>
+ <driver iommu='on'/>
+ </controller>
+ ...
+ <memballoon model='virtio'>
+ <driver iommu='on'/>
+ </memballoon>
+ <rng model='virtio'>
+ <backend model='random'>/dev/urandom</backend>
+ <driver iommu='on'/>
+ </rng>
+ ...
+<domain></pre>
+ <p>
+ If you for some reason want to use the legacy PC machine type, further changes
+ to the virtio
+ configuration is required, because SEV will not work with Virtio <1.0. In
+ libvirt, this is handled by using the virtio-non-transitional device model
+ (libvirt >= 5.2.0 required).
+
+ <p>
+ Note: some devices like video devices don't
+ support non-transitional model, which means that virtio GPU cannot be used.
+ </p>
+ </p>
+ <pre>
+<domain>
+ ...
+ <devices>
+ ...
+ <memballoon model='virtio-non-transitional'>
+ <driver iommu='on'/>
+ </memballoon>
+ </devices>
+ ...
+</domain></pre>
+
+
+ <h2>
+ <a id="Limitations">Limitations</a>
+ <a class="headerlink" href="#Limitations" title="Permalink to this headline">¶</a>
+ </h2>
+ <p>
+ Currently, the boot disk cannot be of type virtio-blk, instead, virtio-scsi
+ needs to be used if virtio is desired. This limitation is expected to be lifted
+ with future releases of kernel (the kernel used at the time of writing the
+ article is 5.0.14).
+ If you still cannot start an SEV VM, it could be because of wrong SELinux label on the <code>/dev/sev</code> device with selinux-policy <3.14.2.40 which prevents QEMU from touching the device. This can be resolved by upgrading the package, tuning the selinux policy rules manually to allow svirt_t to access the device (see <code>audit2allow</code> on how to do that) or putting SELinux into permissive mode (discouraged).
+ </p>
+ <h2>
+ <a id="Examples">Full domain XML examples</a>
+ <a class="headerlink" href="#Examples" title="Permalink to this headline">¶</a>
+ </h2>
+ <h5>Q35 machine</h5>
+ <pre>
+<domain type='kvm'>
+ <name>sev-dummy</name>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <memoryBacking>
+ <locked/>
+ </memoryBacking>
+ <vcpu placement='static'>4</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-q35-3.0'>hvm</type>
+ <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader>
+ <nvram>/var/lib/libvirt/qemu/nvram/sev-dummy_VARS.fd</nvram>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state='off'/>
+ </features>
+ <cpu mode='host-model' check='partial'>
+ <model fallback='allow'/>
+ </cpu>
+ <clock offset='utc'>
+ <timer name='rtc' tickpolicy='catchup'/>
+ <timer name='pit' tickpolicy='delay'/>
+ <timer name='hpet' present='no'/>
+ </clock>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <pm>
+ <suspend-to-mem enabled='no'/>
+ <suspend-to-disk enabled='no'/>
+ </pm>
+ <devices>
+ <emulator>/usr/bin/qemu-kvm</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='/var/lib/libvirt/images/sev-dummy.qcow2'/>
+ <target dev='sda' bus='scsi'/>
+ <boot order='1'/>
+ </disk>
+ <controller type='virtio-serial' index='0'>
+ <driver iommu='on'/>
+ </controller>
+ <controller type='scsi' index='0' model='virtio-scsi'>
+ <driver iommu='on'/>
+ </controller>
+ <interface type='network'>
+ <mac address='52:54:00:cc:56:90'/>
+ <source network='default'/>
+ <model type='virtio'/>
+ <driver iommu='on'/>
+ </interface>
+ <graphics type='spice' autoport='yes'>
+ <listen type='address'/>
+ <gl enable='no'/>
+ </graphics>
+ <video>
+ <model type='qxl'/>
+ </video>
+ <memballoon model='virtio'>
+ <driver iommu='on'/>
+ </memballoon>
+ <rng model='virtio'>
+ <driver iommu='on'/>
+ </rng>
+ </devices>
+ <launchSecurity type='sev'>
+ <cbitpos>47</cbitpos>
+ <reducedPhysBits>1</reducedPhysBits>
+ <policy>0x0003</policy>
+ </launchSecurity>
+</domain></pre>
+
+ <h5>PC-i440fx machine:</h5>
+ <pre>
+<domain type='kvm'>
+ <name>sev-dummy-legacy</name>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <memtune>
+ <hard_limit unit='KiB'>5242880</hard_limit>
+ </memtune>
+ <vcpu placement='static'>4</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-i440fx-3.0'>hvm</type>
+ <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader>
+ <nvram>/var/lib/libvirt/qemu/nvram/sev-dummy_VARS.fd</nvram>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state='off'/>
+ </features>
+ <cpu mode='host-model' check='partial'>
+ <model fallback='allow'/>
+ </cpu>
+ <clock offset='utc'>
+ <timer name='rtc' tickpolicy='catchup'/>
+ <timer name='pit' tickpolicy='delay'/>
+ <timer name='hpet' present='no'/>
+ </clock>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <pm>
+ <suspend-to-mem enabled='no'/>
+ <suspend-to-disk enabled='no'/>
+ </pm>
+ <devices>
+ <emulator>/usr/bin/qemu-kvm</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='/var/lib/libvirt/images/sev-dummy-seabios.qcow2'/>
+ <target dev='sda' bus='sata'/>
+ </disk>
+ <interface type='network'>
+ <mac address='52:54:00:d8:96:c8'/>
+ <source network='default'/>
+ <model type='virtio-non-transitional'/>
+ </interface>
+ <serial type='pty'>
+ <target type='isa-serial' port='0'>
+ <model name='isa-serial'/>
+ </target>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='tablet' bus='usb'>
+ <address type='usb' bus='0' port='1'/>
+ </input>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='spice' autoport='yes'>
+ <listen type='address'/>
+ <gl enable='no'/>
+ </graphics>
+ <video>
+ <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
+ </video>
+ <memballoon model='virtio-non-transitional'>
+ <driver iommu='on'/>
+ </memballoon>
+ <rng model='virtio-non-transitional'>
+ <driver iommu='on'/>
+ </rng>
+ </devices>
+ <launchSecurity type='sev'>
+ <cbitpos>47</cbitpos>
+ <reducedPhysBits>1</reducedPhysBits>
+ <policy>0x0003</policy>
+ </launchSecurity>
+</domain></pre>
+ </div>
+</body>
+</html>
--
2.21.0
5 years, 9 months
[libvirt] [PATCH] news: Update for 5.5.0 release
by Andrea Bolognani
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
docs/news.xml | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml
index cada389092..c6cc27faae 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -40,6 +40,18 @@
<libvirt>
<release version="v5.5.0" date="unreleased">
+ <section title="Security">
+ <change>
+ <summary>
+ api: Prevent access to several APIs over read-only connections
+ </summary>
+ <description>
+ Certain APIs give root-equivalent access to the host, and as such
+ should be limited to privileged users. CVE-2019-10161,
+ CVE-2019-10166, CVE-2019-10167, CVE-2019-10168.
+ </description>
+ </change>
+ </section>
<section title="New features">
<change>
<summary>
@@ -49,6 +61,16 @@
SMMUv3 is an IOMMU implementation for ARM virt guests.
</description>
</change>
+ <change>
+ <summary>
+ network: Introduce the network port API
+ </summary>
+ <description>
+ This new public API can be used by virtualization drivers to
+ manage network resources associated with guests, and is a further
+ step towards splitting libvirtd into multiple daemons.
+ </description>
+ </change>
</section>
<section title="Removed features">
<change>
@@ -62,10 +84,72 @@
from libvirt or otherwise.
</description>
</change>
+ <change>
+ <summary>
+ Stop supporting migration of config files from pre-XDG layout
+ </summary>
+ <description>
+ The new layout was introduced with libvirt 0.9.13 (Jul 2012).
+ </description>
+ </change>
+ <change>
+ <summary>
+ Remove Avahi mDNS support
+ </summary>
+ <description>
+ This feature was never used outside of virt-manager, which has
+ itself stopped using it a while ago.
+ </description>
+ </change>
</section>
<section title="Improvements">
+ <change>
+ <summary>
+ sysinfo: Report SMBIOS information on aarch64
+ </summary>
+ <description>
+ While SMBIOS support has historically been limited to x86_64, modern
+ aarch64 machines often offer access to the same information as well,
+ and libvirt now exposes it to the user when that's the case.
+ </description>
+ </change>
+ <change>
+ <summary>
+ test driver: Expand API coverage
+ </summary>
+ <description>
+ Even more APIs that were missing from the test driver have now been
+ implemented.
+ </description>
+ </change>
+ <change>
+ <summary>
+ virt-xml-validate: Allow input to be read from stdin
+ </summary>
+ </change>
+ <change>
+ <summary>
+ qemu: Validate spapr-vio addresses as 32-bit
+ </summary>
+ <description>
+ libvirt has always considered these addresses (used for pSeries
+ guests) as 64-bit, but the sPAPR specification says that they're
+ 32-bit instead.
+ </description>
+ </change>
</section>
<section title="Bug fixes">
+ <change>
+ <summary>
+ qemu: Set process affinity correctly when using <numatune>
+ </summary>
+ <description>
+ libvirt would mistakenly interpret the <code>nodeset</code>
+ attribute as a list of CPUs instead of as a list of NUMA node, and
+ the process affinity would be set incorrectly as a result; this has
+ now been fixed.
+ </description>
+ </change>
</section>
</release>
<release version="v5.4.0" date="2019-06-03">
--
2.21.0
5 years, 9 months
[libvirt] [PATCH] test_driver: implement virDomainGetNumaParameters
by Ilias Stamatis
Signed-off-by: Ilias Stamatis <stamatis.iliass(a)gmail.com>
---
src/test/test_driver.c | 48 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 4b1f2724a0..d0d4d9e270 100755
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -2405,6 +2405,53 @@ testDomainCoreDump(virDomainPtr domain,
}
+static int
+testDomainGetNumaParameters(virDomainPtr dom,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags)
+{
+ virDomainObjPtr vm = NULL;
+ virDomainNumatuneMemMode mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+ VIR_AUTOFREE(char *) nodeset = NULL;
+ int ret = -1;
+
+ virCheckFlags(VIR_DOMAIN_AFFECT_CURRENT |
+ VIR_DOMAIN_AFFECT_LIVE |
+ VIR_DOMAIN_AFFECT_CONFIG |
+ VIR_TYPED_PARAM_STRING_OKAY, -1);
+
+ if ((*nparams) == 0) {
+ *nparams = 2;
+ return 0;
+ }
+
+ if (!(vm = testDomObjFromDomain(dom)))
+ goto cleanup;
+
+ ignore_value(virDomainNumatuneGetMode(vm->def->numa, -1, &mode));
+ if (0 < *nparams && virTypedParameterAssign(¶ms[0], VIR_DOMAIN_NUMA_MODE,
+ VIR_TYPED_PARAM_INT, mode) < 0)
+ goto cleanup;
+
+ nodeset = virDomainNumatuneFormatNodeset(vm->def->numa, NULL, -1);
+ if (1 < *nparams && (!nodeset || virTypedParameterAssign(¶ms[1],
+ VIR_DOMAIN_NUMA_NODESET,
+ VIR_TYPED_PARAM_STRING,
+ nodeset) < 0))
+ goto cleanup;
+ nodeset = NULL;
+
+ if (*nparams > 2)
+ *nparams = 2;
+
+ ret = 0;
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
+
+
static char *
testDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED)
{
@@ -7251,6 +7298,7 @@ static virHypervisorDriver testHypervisorDriver = {
.domainReboot = testDomainReboot, /* 0.1.1 */
.domainDestroy = testDomainDestroy, /* 0.1.1 */
.domainDestroyFlags = testDomainDestroyFlags, /* 4.2.0 */
+ .domainGetNumaParameters = testDomainGetNumaParameters, /* 5.6.0 */
.domainGetOSType = testDomainGetOSType, /* 0.1.9 */
.domainGetLaunchSecurityInfo = testDomainGetLaunchSecurityInfo, /* 5.5.0 */
.domainGetMaxMemory = testDomainGetMaxMemory, /* 0.1.4 */
--
2.22.0
5 years, 9 months
[libvirt] [BUG] virHostCPUGetInfoPopulateLinux statistics CPU socket inaccuracy
by Yuchen
only the last numa node /sys/devices/system/node/node*/cpu*/topology/physical_package_id
nodeinfo 'CPU socket(s)' is not equal to lscpu 'Socket(s)'
# virsh nodeinfo
CPU model: x86_64
CPU(s): 32
CPU frequency: 2393 MHz
CPU socket(s): 1
Core(s) per socket: 8
Thread(s) per core: 2
NUMA cell(s): 2
Memory size: 131150200 KiB
# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Stepping: 4
CPU MHz: 820.151
BogoMIPS: 4201.57
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 11264K
NUMA node0 CPU(s): 0-7,16-23
NUMA node1 CPU(s): 8-15,24-31
-------------------------------------------------------------------------------------------------------------------------------------
本邮件及其附件含有新华三集团的保密信息,仅限于发送给上面地址中列出
的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、
或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本
邮件!
This e-mail and its attachments contain confidential information from New H3C, which is
intended only for the person or entity whose address is listed above. Any use of the
information contained herein in any way (including, but not limited to, total or partial
disclosure, reproduction, or dissemination) by persons other than the intended
recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender
by phone or email immediately and delete it!
5 years, 9 months
[libvirt] [PATCH 0/2] cgroups v2 fixes
by Pavel Hrdina
Pavel Hrdina (2):
Revert "util: vircgroup: pass parent cgroup into
virCgroupDetectControllersCB"
util: vircgroupv2: stop enabling missing controllers with systemd
src/util/vircgroup.c | 4 ++--
src/util/vircgroupbackend.h | 6 ++++--
src/util/vircgroupv1.c | 3 +--
src/util/vircgroupv2.c | 22 +++++++++++-----------
4 files changed, 18 insertions(+), 17 deletions(-)
--
2.21.0
5 years, 9 months
[libvirt] [PATCH] test_driver: call virCheckFlags on testDomainReboot
by Ilias Stamatis
Currently the flags argument is completely ignored, but it should be
checked for any unsupported flags that might have been passed.
Signed-off-by: Ilias Stamatis <stamatis.iliass(a)gmail.com>
---
src/test/test_driver.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 2a0ffbc6c5..6b1d53b06d 100755
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1850,13 +1850,16 @@ static int testDomainShutdown(virDomainPtr domain)
/* Similar behaviour as shutdown */
static int testDomainReboot(virDomainPtr domain,
- unsigned int action ATTRIBUTE_UNUSED)
+ unsigned int flags)
{
testDriverPtr privconn = domain->conn->privateData;
virDomainObjPtr privdom;
virObjectEventPtr event = NULL;
int ret = -1;
+ virCheckFlags(VIR_DOMAIN_REBOOT_DEFAULT | VIR_DOMAIN_REBOOT_ACPI_POWER_BTN |
+ VIR_DOMAIN_REBOOT_GUEST_AGENT | VIR_DOMAIN_REBOOT_INITCTL |
+ VIR_DOMAIN_REBOOT_SIGNAL | VIR_DOMAIN_REBOOT_PARAVIRT, -1);
if (!(privdom = testDomObjFromDomain(domain)))
goto cleanup;
--
2.22.0
5 years, 9 months
[libvirt] [PATCH] qemu: Validate disk against domain def on coldplug
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1692296#c7
This is a counterpart for ddc72f99027 and implements the same
check for coldplug.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d6ab134196..ed5f832f59 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8082,6 +8082,21 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
return ret;
}
+
+static int
+qemuCheckDiskConfigAgainstDomain(const virDomainDef *def,
+ const virDomainDiskDef *disk)
+{
+ if (virDomainSCSIDriveAddressIsUsed(def, &disk->info.addr.drive)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain already contains a disk with that address"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
virDomainDeviceDefPtr dev,
@@ -8110,6 +8125,8 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
return -1;
if (qemuCheckDiskConfig(disk, NULL) < 0)
return -1;
+ if (qemuCheckDiskConfigAgainstDomain(vmdef, disk) < 0)
+ return -1;
if (virDomainDiskInsert(vmdef, disk) < 0)
return -1;
/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
--
2.21.0
5 years, 9 months
[libvirt] [PATCH] snapshot: Store both config and live XML in the snapshot domain
by Maxiwell S. Garcia
The snapshot-create operation of running guests saves the live
XML and uses it to replace the active and inactive domain in
case of revert. So, the config XML is ignored by the snapshot
process. This commit changes it and adds the config XML in the
snapshot XML as the <inactive/domain> entry.
In case of offline guest, the behavior remains the same and the
config XML is saved in the snapshot XML as <domain> entry. The
behavior of older snapshots of running guests, that don't have
the new <inactive/domain>, remains the same too. The revert, in
this case, overrides both active and inactive domain with the
<domain> entry. So, the <inactive/domain> in the snapshot XML is
not required to snapshot work, but it's useful to preserve the
config XML of running guests.
Signed-off-by: Maxiwell S. Garcia <maxiwell(a)linux.ibm.com>
---
src/conf/moment_conf.c | 1 +
src/conf/moment_conf.h | 1 +
src/conf/snapshot_conf.c | 42 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_driver.c | 29 ++++++++++++++++++++++-----
4 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/src/conf/moment_conf.c b/src/conf/moment_conf.c
index fea13f0f97..f54a44b33e 100644
--- a/src/conf/moment_conf.c
+++ b/src/conf/moment_conf.c
@@ -66,6 +66,7 @@ virDomainMomentDefDispose(void *obj)
VIR_FREE(def->description);
VIR_FREE(def->parent_name);
virDomainDefFree(def->dom);
+ virDomainDefFree(def->inactiveDom);
}
/* Provide defaults for creation time and moment name after parsing XML */
diff --git a/src/conf/moment_conf.h b/src/conf/moment_conf.h
index 00ec1c1904..b8bec7e456 100644
--- a/src/conf/moment_conf.h
+++ b/src/conf/moment_conf.h
@@ -38,6 +38,7 @@ struct _virDomainMomentDef {
long long creationTime; /* in seconds */
virDomainDefPtr dom;
+ virDomainDefPtr inactiveDom;
};
virClassPtr virClassForDomainMomentDef(void);
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index c7f29360e7..c66ee997a4 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -294,6 +294,28 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
} else {
VIR_WARN("parsing older snapshot that lacks domain");
}
+
+ /* /inactive/domain entry saves the config XML present in a running
+ * VM. In case of absent, leave parent.inactiveDom NULL and use
+ * parent.dom for config and live XML. */
+ if ((tmp = virXPathString("string(./inactive/domain/@type)", ctxt))) {
+ int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
+ xmlNodePtr domainNode = virXPathNode("./inactive/domain", ctxt);
+
+ VIR_FREE(tmp);
+ if (!domainNode) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing inactive domain in snapshot"));
+
+ goto cleanup;
+ }
+ def->parent.inactiveDom = virDomainDefParseNode(ctxt->node->doc, domainNode,
+ caps, xmlopt, NULL, domainflags);
+ if (!def->parent.inactiveDom)
+ goto cleanup;
+ }
+
} else if (virDomainXMLOptionRunMomentPostParse(xmlopt, &def->parent) < 0) {
goto cleanup;
}
@@ -511,6 +533,16 @@ virDomainSnapshotRedefineValidate(virDomainSnapshotDefPtr def,
VIR_STEAL_PTR(def->parent.dom, otherdef->parent.dom);
}
}
+ if (otherdef->parent.inactiveDom) {
+ if (def->parent.inactiveDom) {
+ if (!virDomainDefCheckABIStability(otherdef->parent.inactiveDom,
+ def->parent.inactiveDom, xmlopt))
+ return -1;
+ } else {
+ /* Transfer the inactive domain def */
+ VIR_STEAL_PTR(def->parent.inactiveDom, otherdef->parent.inactiveDom);
+ }
+ }
}
if (def->parent.dom) {
@@ -876,6 +908,16 @@ virDomainSnapshotDefFormatInternal(virBufferPtr buf,
virBufferAddLit(buf, "</domain>\n");
}
+ if (def->parent.inactiveDom) {
+ virBufferAddLit(buf, "<inactive>\n");
+ virBufferAdjustIndent(buf, 2);
+ if (virDomainDefFormatInternal(def->parent.inactiveDom, caps,
+ domainflags, buf, xmlopt) < 0)
+ goto error;
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</inactive>\n");
+ }
+
if (virSaveCookieFormatBuf(buf, def->cookie,
virDomainXMLOptionGetSaveCookie(xmlopt)) < 0)
goto error;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 42b1ce2521..1ce7aa7b42 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15707,6 +15707,15 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto endjob;
+ if (vm->newDef) {
+ if (!(xml = qemuDomainDefFormatLive(driver, vm->newDef, priv->origCPU,
+ true, true)) ||
+ !(def->parent.inactiveDom = virDomainDefParseString(xml, caps, driver->xmlopt, NULL,
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
+ goto endjob;
+ }
+
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
align_match = false;
@@ -16241,6 +16250,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
qemuDomainObjPrivatePtr priv;
int rc;
virDomainDefPtr config = NULL;
+ virDomainDefPtr inactiveConfig = NULL;
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
bool was_stopped = false;
@@ -16341,17 +16351,22 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
* in the failure cases where we know there was no change? */
}
- /* Prepare to copy the snapshot inactive xml as the config of this
- * domain.
- *
- * XXX Should domain snapshots track live xml rather
- * than inactive xml? */
+ /* Prepare to copy the snapshot inactive domain as the config XML
+ * and the snapshot domain as the live XML. In case of inactive domain
+ * NULL, both config and live XML will be copied from snapshot domain.
+ */
if (snap->def->dom) {
config = virDomainDefCopy(snap->def->dom, caps,
driver->xmlopt, NULL, true);
if (!config)
goto endjob;
}
+ if (snap->def->inactiveDom) {
+ inactiveConfig = virDomainDefCopy(snap->def->inactiveDom, caps,
+ driver->xmlopt, NULL, true);
+ if (!inactiveConfig)
+ goto endjob;
+ }
cookie = (qemuDomainSaveCookiePtr) snapdef->cookie;
@@ -16602,6 +16617,10 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto endjob;
}
+ if (inactiveConfig) {
+ virDomainDefFree(vm->newDef);
+ VIR_STEAL_PTR(vm->newDef, inactiveConfig);
+ }
ret = 0;
endjob:
--
2.20.1
5 years, 9 months
[libvirt] Encrypted vTPM state
by Stefan Berger
Hello!
Marc-André told me there was interest in encrypting the vTPM state.
I do have some patches along these lines from a long time ago that I
haven't upstreamed. I'd be curious about some feedback on some corner
stones of the design to support this:
- Encryption of the vTPM state must be added when a vTPM's XML is
created. It's not possible to convert existing not-encrypted vTPM state
to encrypted vTPM state. This is due to a limitation of 'swtpm.'
- vTPM state encryption would be based on libvirt's Secret support. I
assume the secrets can migrate along the domain XML.
- The XML for vTPM state encryption is similar to XML used for 'luks':
https://libvirt.org/formatstorageencryption.html#example
- The XML for an encrypted vTPM state could look like this:
<devices>
[...]
<tpm model='tpm-tis'>
<backend type='emulator' version='2.0'>
<encryption format='vtpm'>
<secret type='passphrase'
uuid='32ee7e76-2178-47a1-ab7b-269e6e348015'/>
</encryption>
</backend>
</tpm>
</devices>
Here the user is referencing an already existing Secret. This secret
would NOT be automatically undefined when a VM is undefined.
- Another possibility may be this XML here:
<devices>
[...]
<tpm model='tpm-tis'>
<backend type='emulator' version='2.0'>
<encryption format='default'/>
</backend>
</tpm>
</devices>
In this case the Secret would be automatically generated and this domain
XML be rewritten to look like the one in the first example. The domain
XML would then reference the created secret via usage=vtpm-<vmuuid>,
which would be an indication that this secret can be deleted when the VM
is undefined.
- The Secret XML to be passed to virsh secret-define would look like this:
<secret ephemeral='no' private='yes'>
<description>vTPM passphrase example</description>
<usage type='vtpm'>
<name>vtpm_example</name>
</usage>
</secret>
Regards,
Stefan
5 years, 9 months