Compare commits

...

26 Commits

Author SHA1 Message Date
antonios-f ddb94428c7 Merge branch 'spice-vnc-default-audio-backend' into 'master'
src/qemu/qemu_domain.c: Fix overriding audioBackend in qemuDomainDefSuggestDefaultAudioBackend

See merge request libvirt/libvirt!271
2024-05-07 13:34:45 +00:00
Peter Krempa df9ffb0256 udevListInterfacesByStatus: Don't try to return NULL names
In case when the interface is being detached/reattached it may happen
that udev will return NULL from 'udev_device_get_sysname()'.

As the RPC code requires nonnull strings in the return array it fails to
serialize such reply:

 libvirt: XML-RPC error : Unable to encode message payload

Fix this by simply ignoring such interfaces as there's nothing we can
report in such case.

A similar fix was done to 'udevConnectListAllInterfaces' in commit
2ca94317ac.

Resolves: https://issues.redhat.com/browse/RHEL-34615
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2024-05-07 14:55:57 +02:00
Peter Krempa bc596f2751 interface_udev: Replace udevNumOfInterfacesByStatus by udevListInterfacesByStatus
Make the array-filling operation of udevListInterfacesByStatus optional
and replace the completely redundant udevNumOfInterfacesByStatus by it.

Further patches fixing the listing will not need to be duplicated.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2024-05-07 14:55:57 +02:00
Michal Privoznik e6a5592787 datatypes: Declare g_autoptr cleanup functions for more public objects
Some public objects (like virDomain, virInterface, and so on) are
missing g_autoptr() cleanup functions. Provide missing
declarations. Note, this is only for our internal use - hence
datatypes.h.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2024-05-07 13:03:19 +02:00
Michal Privoznik da95bcb6b2 qemu: Substract isolcpus from all online affinity
When starting a domain and there's no vCPU/emulator pinning set,
we query the list of all online physical CPUs and set affinity of
the child process (which eventually becomes QEMU) to that list.
We can't assume libvirtd itself had affinity to all online CPUs
and since affinity of the child process is inherited, we should
fix it afterwards. But that's not necessarily correct. Users
might isolate some physical CPUs and we should avoid touching
them unless explicitly told so (i.e. vCPU/emulator pinning told
us so).

Therefore, when attempting to set affinity to all online CPUs
subtract the isolated ones.

Before this commit:

  root@localhost:~# cat /sys/devices/system/cpu/isolated
  19,21,23
  root@virtlab414:~# taskset -cp $(pgrep qemu)
  pid 14835's current affinity list: 0-23

After:

  root@virtlab414:~# taskset -cp $(pgrep qemu)
  pid 17153's current affinity list: 0-18,20,22

Resolves: https://issues.redhat.com/browse/RHEL-33082
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2024-05-06 15:38:58 +02:00
Michal Privoznik 3c948ef699 virhostcpu: Introduce virHostCPUGetIsolated()
This is a helper that parses /sys/devices/system/cpu/isolated
into a virBitmap. It's going to be needed soon.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2024-05-06 15:36:17 +02:00
Michal Privoznik f3c6c7623c virfile: Introduce virFileReadValueBitmapAllowEmpty()
Some sysfs files contain either string representation of a bitmap
or just a newline character. An example of such file is:
/sys/devices/system/cpu/isolated. Our current implementation of
virFileReadValueBitmap() fails in the latter case, unfortunately.
Introduce a slightly modified version that accepts empty files.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2024-05-06 15:29:36 +02:00
Michal Privoznik b972cdc1a5 virbitmap: Introduce virBitmapParseUnlimitedAllowEmpty()
Some sysfs files contain either string representation of a bitmap
or just a newline character. An example of such file is:
/sys/devices/system/cpu/isolated. Our current implementation of
virBitmapParseUnlimited() fails in the latter case,
unfortunately. Introduce a slightly modified version that accepts
empty files.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2024-05-06 15:26:58 +02:00
Adam Julis 142ed263c0 qemu_saveimage: add zstd to supported compression formats
Extend the list of supported formats, update and clarify comment
in qemu.conf.in (removed misleading sentence about the order of
compression format types).

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/589
Signed-off-by: Adam Julis <ajulis@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2024-05-06 14:56:58 +02:00
Kristina Hanicova 3db81ffcc2 NEWS: document qemu: ras as a new feature
Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2024-05-06 14:06:31 +02:00
Michal Privoznik cab1e71f01 vsh: Don't init history in cmdComplete()
Recent rework of virshtest uncovered a subtle bug that was
dormant in now vsh but before that even in monolithic virsh.

In vsh.c there's this vshReadlineInit() function that's supposed
to initialize readline library, i.e. set those global rl_*
pointers.  But it also initializes history library. Then, when
virsh/virt-admin quits, vshReadlineDeinit() is called which
writes history into a file (ensuring the parent directory
exists). So far no problem.

Problem arises when cmdComplete() is called (from a bash
completer, for instance). It does not guard call to
vshReadlineInit() with check for interactive shell (and it should
not), but it sets ctl->historyfile which signals to
vshReadlineDeinit() the history should be written.

Now, no real history is written, because nothing was entered on
the stdin, but the parent directory is created nevertheless. With
recent movement in virshtest.c this means some test cases might
create virsh history file which breaks our promise of not
touching user's data in test suite.

Resolves: https://bugs.gentoo.org/931109
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-06 13:18:07 +02:00
Oleg Sviridov a42f11c40b hyperv: prevent potential NULL dereference
Return value of a function 'virDomainChrDefNew' is dereferenced
at hyperv_driver.c without checking for NULL, which can lead to
NULL dereference immediately after.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Oleg Sviridov <oleg.sviridov@red-soft.ru>
Reviewed-by: Kristína Hanicová <khanicov@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2024-05-06 09:35:45 +02:00
Jim Fehlig 3146305fd3 libxl: Fix domxml-to-native conversion
Similar to commit 57d084febe, another case of the libxl driver not
adapting to modular daemons. When converting configuration that
contains a type='network' interface, the converter calls
virNetworkLookupByName, passing the hypervisor connection object
instead of a connection to virtnetworkd. E.g.

> cat dom.xml
...
    <interface type='network'>
      <source network='default'/>
    </interface>
...
> virsh net-info default
Name:           default
UUID:           25a5b089-1e71-4956-99aa-df2213bbb407
Active:         yes
Persistent:     no
Autostart:      no
Bridge:         virbr0
> virsh domxml-to-native xen-xl dom.xml
error: Network not found: default

Acquire a connection to virtnetworkd and use it when calling
virNetwork* APIs.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 15:57:29 -06:00
Tim Wiederhake fa54595178 cpu_map: Drop 'mpx' from x86 cpu models
The mpx feature was removed from the corresponding qemu cpu models.
With mpx in the libvirt cpu models, libvirt believes the feature
to be implicitly enabled when creating qemu VMs, while in fact it is
disabled.

This became an issue when commit 94eacd5a5f introduced new vmx-*
features, of which some are dependent on mpx (see "feature_dependencies"
table in qemu target/i386/cpu.c), e.g. vmx-exit-clear-bndcfgs and
vmx-entry-load-bndcfgs. These features cannot be enabled by qemu
without also mpx being enabled, leading to the error message

    error: Failed to create domain from testdomain.xml
    error: operation failed: guest CPU doesn't match
    specification: missing features: mpx,vmx-exit-clear-bndcfgs,
    vmx-entry-load-bndcfgs

when trying to create a VM with a "host-model" cpu on a host that
does support mpx and the mentioned vmx-* features:

    <domain>
      ...
      <cpu mode='host-model' check='full' />
      ...
    </domain>

Resolve the issue by removing mpx from libvirt's cpu models as well.

Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 19:56:45 +02:00
Jiri Denemark a396f76f70 qemu: Enable removing features from CPU models
Features removed from a CPU model are marked with "removed='yes'"
attribute in the CPU map. Such features will always be present in a CPU
definition produced by libvirt regardless on their state. In other words
a running domain (even saved in a file) will always explicitly contain
states of all features removed from the specified CPU model. This
enables migration to older libvirt which would otherwise think the
affected features should be enabled as they are still included in the
CPU model in the older version of CPU map. Migration from an old libvirt
to a new one would be broken as the new libvirt would think the removed
features should be disabled (because they are not included in the CPU
model anymore), which might not be the case on the source host. Thus we
were refusing to remove CPU features unless they were never working and
no domain could even be running with those features enabled.

This patch removes the limitation. When handling CPU definitions with
missing features marked as removed in the specified CPU model, we know
whether it comes from a running domain, in which case it must have been
created by older libvirt where the missing CPU features were not removed
yet. This means the features must have been enabled on the source and we
can automatically fix the definition by adding the missing features with
correct states.

We can safely remove any CPU feature from our CPU models now, but it
should only be used for features removed from all versions of a given
CPU model in QEMU because unversioned models correspond to v1.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 19:56:45 +02:00
Jiri Denemark 30458c6071 cpu: Add removedPolicy parameter to virCPUUpdate
virCPUUpdate check the CPU definition for features that were marked as
removed in the specified CPU model and explicitly adds those that were
not mentioned in the definition. So far such features were added with
VIR_CPU_FEATURE_DISABLE policy, but the caller may want to use a
different policy in some situations, which is now possible via the
removedPolicy parameter.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 19:56:45 +02:00
Jiri Denemark 8c1b07b088 conf: Change return value of some CPU feature APIs
The virCPUDefAddFeatureInternal helper function only fails if it is
called with VIR_CPU_ADD_FEATURE_MODE_EXCLUSIVE, which is only used in
virCPUDefAddFeature. The other callers (virCPUDefUpdateFeature and
virCPUDefAddFeatureIfMissing) will never get anything but 0 from
virCPUDefAddFeatureInternal and their return type can be changed to
void.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 19:56:45 +02:00
Martin Kletzander 23c4794488 vmx: Check serialX.vspc before serialX.fileName
When using vSPC (Virtual Serial Port Concentrator) in vSphere the actual
address for it is saved in serialX.vspc in which case the
serialX.fileName is most probably something we can't get any useful
information from and we also fail during the parsing rendering any
dumpxml and similar tries unsuccessful.

Instead of parsing the vspc URL with something along the lines of
`virURIParse(vspc ? vspc : fileName)`, which could lead to us reporting
information that is very prune to misuse (the vSPC seemingly has a
protocol on top of the telnet connection; redefining the domain would
change the behaviour; the URL might have a fragment we are not saving;
etc.) or adding more XML knobs to indicate vSPC usage (which we would
not be able to configure; we'd have to properly error out everywhere;
etc.) let's just report dummy serial port that leads to nowhere (i.e.
type="null").

Resolves: https://issues.redhat.com/browse/RHEL-32182
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2024-05-02 17:22:37 +02:00
Daniel P. Berrangé 8074d64dc2 rpc: ensure temporary GSource is removed from client event loop
Users are seeing periodic segfaults from libvirt client apps,
especially thread heavy ones like virt-manager. A typical
stack trace would end up in the virNetClientIOEventFD method,
with illegal access to stale stack data. eg

==238721==ERROR: AddressSanitizer: stack-use-after-return on address 0x75cd18709788 at pc 0x75cd3111f907 bp 0x75cd181ff550 sp 0x75cd181ff548
WRITE of size 4 at 0x75cd18709788 thread T11
    #0 0x75cd3111f906 in virNetClientIOEventFD /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1634:15
    #1 0x75cd3210d198  (/usr/lib/libglib-2.0.so.0+0x5a198) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
    #2 0x75cd3216c3be  (/usr/lib/libglib-2.0.so.0+0xb93be) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
    #3 0x75cd3210ddc6 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x5adc6) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
    #4 0x75cd3111a47c in virNetClientIOEventLoop /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1722:9
    #5 0x75cd3111a47c in virNetClientIO /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2002:10
    #6 0x75cd3111a47c in virNetClientSendInternal /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2170:11
    #7 0x75cd311198a8 in virNetClientSendWithReply /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2198:11
    #8 0x75cd31111653 in virNetClientProgramCall /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclientprogram.c:318:9
    #9 0x75cd31241c8f in callFull /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6054:10
    #10 0x75cd31241c8f in call /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6076:12
    #11 0x75cd31241c8f in remoteNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/src/remote/remote_client_bodies.h:5959:9
    #12 0x75cd31410ff7 in virNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/libvirt-network.c:952:15

The root cause is a bad assumption in the virNetClientIOEventLoop
method. This method is run by whichever thread currently owns the
buck, and is responsible for handling I/O. Inside a for(;;) loop,
this method creates a temporary GSource, adds it to the event loop
and runs g_main_loop_run(). When I/O is ready, the GSource callback
(virNetClientIOEventFD) will fire and call g_main_loop_quit(), and
return G_SOURCE_REMOVE which results in the temporary GSource being
destroyed. A g_autoptr() will then remove the last reference.

What was overlooked, is that a second thread can come along and
while it can't enter virNetClientIOEventLoop, it will register an
idle source that uses virNetClientIOWakeup to interrupt the
original thread's 'g_main_loop_run' call. When this happens the
virNetClientIOEventFD callback never runs, and so the temporary
GSource is not destroyed. The g_autoptr() will remove a reference,
but by virtue of still being attached to the event context, there
is an extra reference held causing GSource to be leaked. The
next time 'g_main_loop_run' is called, the original GSource will
trigger its callback, and access data that was allocated on the
stack by the previous thread, and likely SEGV.

To solve this, the thread calling 'g_main_loop_run' must call
g_source_destroy, immediately upon return, to guarantee that
the temporary GSource is removed.

CVE-2024-4418
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reported-by: Martin Shirokov <shirokovmartin@gmail.com>
Tested-by: Martin Shirokov <shirokovmartin@gmail.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2024-05-02 14:46:31 +01:00
Rayhan Faizel a1a3da94f5 qemu: Generate command line for sound devices with model 'virtio'
Allow generation of command line for virtio-sound-pci and virtio-sound-device
devices along with additional virtio options.

A new testcase is added to test virtio-sound-pci. The
arm-vexpressa9-virtio testcase is also extended to test virtio-sound-device.

Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 15:38:34 +02:00
Rayhan Faizel bb593e3743 conf: Introduce support for virtio-sound devices
This patch adds parsing of the virtio sound model, along with parsing
of virtio options and PCI/virtio-mmio address assignment.

A new 'streams' attribute is added for configuring number of PCM streams
(default is 2) in virtio sound devices. QEMU additionally has jacks and chmaps
parameters but these are currently stubbed, hence they are excluded in this
patch series.

Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 15:38:32 +02:00
Rayhan Faizel 9081320b53 qemu_capabilities: Add QEMU_CAPS_DEVICE_VIRTIO_SOUND capability
Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 15:37:53 +02:00
Daniel P. Berrangé d754500e5f ci: drop CentOS 8 Stream and refresh
This drops the CentOS 8 Stream distro target, since that is going EOL
at the end of May, at which point it will cease to be installable
due to package repos being archived.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2024-05-02 13:52:30 +01:00
Daniel P. Berrangé 8132d38120 ci: refresh with latest lcitool manifest
This brings in a fix to the job rules which solves a problem with
jobs getting skipped in merge requests in some scenarios. It also
changes the way Cirrus CI vars are set, which involves a weak to
the way $PATH is set in build.yml.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2024-05-02 13:52:17 +01:00
Michal Privoznik bc70aa1df3 scripts/meson-dist.py: Get builddir from env too
When meson runs a dist script it sets both MESON_BUILD_ROOT and
MESON_DIST_ROOT envvars [1]. But for some reason, we took the
former as an argument and obtained the latter via env. Well,
obtain both via env.

1: https://mesonbuild.com/Reference-manual_builtin_meson.html#mesonadd_dist_script
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-05-02 14:33:20 +02:00
Anton Fadeev 971753af89 src/qemu/qemu_domain.c: Fix overriding audioBackend in qemuDomainDefSuggestDefaultAudioBackend
If we have Spice and VNC graphics in domain XML, and Spice graphics defined before VNC, audioBackend will be overrided in qemuDomainDefSuggestDefaultAudioBackend to VIR_DOMAIN_AUDIO_TYPE_NONE, and we will have no sound in Spice session, like this https://bugs.launchpad.net/qemu/+bug/1900352. If the flag addAudio already set, we do not need to override audioBackend. This commit fix the issue.
2023-06-29 08:52:21 +00:00
149 changed files with 956 additions and 604 deletions

View File

@ -17,6 +17,11 @@ v10.4.0 (unreleased)
* **New features**
* qemu: Support for ras feature for virt machine type
It is now possible to set on/off ``ras`` feature in the domain XML for virt
(Arm) machine type as ``<ras state='on'/>``.
* **Improvements**
* **Bug fixes**

View File

@ -69,7 +69,7 @@ function install_buildenv() {
xen-dev \
yajl-dev
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
apk list | sort > /packages.txt
apk list --installed | sort > /packages.txt
mkdir -p /usr/libexec/ccache-wrappers
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang

View File

@ -69,7 +69,7 @@ function install_buildenv() {
xen-dev \
yajl-dev
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
apk list | sort > /packages.txt
apk list --installed | sort > /packages.txt
mkdir -p /usr/libexec/ccache-wrappers
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang

View File

@ -1,104 +0,0 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool manifest ci/manifest.yml
#
# https://gitlab.com/libvirt/libvirt-ci
function install_buildenv() {
dnf distro-sync -y
dnf install 'dnf-command(config-manager)' -y
dnf config-manager --set-enabled -y powertools
dnf install -y centos-release-advanced-virtualization
dnf install -y epel-release
dnf install -y epel-next-release
dnf install -y \
audit-libs-devel \
augeas \
bash-completion \
ca-certificates \
ccache \
clang \
cpp \
cyrus-sasl-devel \
device-mapper-devel \
diffutils \
dwarves \
ebtables \
firewalld-filesystem \
fuse-devel \
gcc \
gettext \
git \
glib2-devel \
glibc-devel \
glibc-langpack-en \
glusterfs-api-devel \
gnutls-devel \
grep \
iproute \
iproute-tc \
iptables \
iscsi-initiator-utils \
kmod \
libacl-devel \
libattr-devel \
libblkid-devel \
libcap-ng-devel \
libcurl-devel \
libiscsi-devel \
libnbd-devel \
libnl3-devel \
libpcap-devel \
libpciaccess-devel \
librbd-devel \
libselinux-devel \
libssh-devel \
libssh2-devel \
libtirpc-devel \
libwsman-devel \
libxml2 \
libxml2-devel \
libxslt \
lvm2 \
make \
meson \
netcf-devel \
nfs-utils \
ninja-build \
numactl-devel \
numad \
parted-devel \
perl \
pkgconfig \
polkit \
python3 \
python3-docutils \
python3-flake8 \
python3-pip \
python3-pytest \
python3-setuptools \
python3-wheel \
qemu-img \
readline-devel \
rpm-build \
sanlock-devel \
sed \
systemd-devel \
systemd-rpm-macros \
systemtap-sdt-devel \
wireshark-devel \
yajl-devel
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
rpm -qa | sort > /packages.txt
mkdir -p /usr/libexec/ccache-wrappers
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
/usr/bin/pip3 install black
}
export CCACHE_WRAPPERSDIR="/usr/libexec/ccache-wrappers"
export LANG="en_US.UTF-8"
export MAKE="/usr/bin/make"
export NINJA="/usr/bin/ninja"
export PYTHON="/usr/bin/python3"

View File

@ -43,6 +43,7 @@ function install_buildenv() {
libblkid-devel \
libcap-ng-devel \
libcurl-devel \
libiscsi-devel \
libnbd-devel \
libnl3-devel \
libpcap-devel \

View File

@ -6,7 +6,7 @@ env:
CI_COMMIT_REF_NAME: "@CI_COMMIT_REF_NAME@"
CI_MERGE_REQUEST_REF_PATH: "@CI_MERGE_REQUEST_REF_PATH@"
CI_COMMIT_SHA: "@CI_COMMIT_SHA@"
PATH: "@PATH@"
PATH: "@PATH_EXTRA@:$PATH"
PKG_CONFIG_PATH: "@PKG_CONFIG_PATH@"
PYTHON: "@PYTHON@"
MAKE: "@MAKE@"

View File

@ -70,7 +70,7 @@ RUN apk update && \
xen-dev \
yajl-dev && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED && \
apk list | sort > /packages.txt && \
apk list --installed | sort > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \

View File

@ -70,7 +70,7 @@ RUN apk update && \
xen-dev \
yajl-dev && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED && \
apk list | sort > /packages.txt && \
apk list --installed | sort > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \

View File

@ -1,107 +0,0 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool manifest ci/manifest.yml
#
# https://gitlab.com/libvirt/libvirt-ci
FROM quay.io/centos/centos:stream8
RUN dnf distro-sync -y && \
dnf install 'dnf-command(config-manager)' -y && \
dnf config-manager --set-enabled -y powertools && \
dnf install -y centos-release-advanced-virtualization && \
dnf install -y epel-release && \
dnf install -y epel-next-release && \
dnf install -y \
audit-libs-devel \
augeas \
bash-completion \
ca-certificates \
ccache \
clang \
cpp \
cyrus-sasl-devel \
device-mapper-devel \
diffutils \
dwarves \
ebtables \
firewalld-filesystem \
fuse-devel \
gcc \
gettext \
git \
glib2-devel \
glibc-devel \
glibc-langpack-en \
glusterfs-api-devel \
gnutls-devel \
grep \
iproute \
iproute-tc \
iptables \
iscsi-initiator-utils \
kmod \
libacl-devel \
libattr-devel \
libblkid-devel \
libcap-ng-devel \
libcurl-devel \
libiscsi-devel \
libnbd-devel \
libnl3-devel \
libpcap-devel \
libpciaccess-devel \
librbd-devel \
libselinux-devel \
libssh-devel \
libssh2-devel \
libtirpc-devel \
libwsman-devel \
libxml2 \
libxml2-devel \
libxslt \
lvm2 \
make \
meson \
netcf-devel \
nfs-utils \
ninja-build \
numactl-devel \
numad \
parted-devel \
perl \
pkgconfig \
polkit \
python3 \
python3-docutils \
python3-flake8 \
python3-pip \
python3-pytest \
python3-setuptools \
python3-wheel \
qemu-img \
readline-devel \
rpm-build \
sanlock-devel \
sed \
systemd-devel \
systemd-rpm-macros \
systemtap-sdt-devel \
wireshark-devel \
yajl-devel && \
dnf autoremove -y && \
dnf clean all -y && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED && \
rpm -qa | sort > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
RUN /usr/bin/pip3 install black
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
ENV NINJA "/usr/bin/ninja"
ENV PYTHON "/usr/bin/python3"

View File

@ -44,6 +44,7 @@ RUN dnf distro-sync -y && \
libblkid-devel \
libcap-ng-devel \
libcurl-devel \
libiscsi-devel \
libnbd-devel \
libnl3-devel \
libpcap-devel \

View File

@ -37,7 +37,7 @@
variables:
IMAGE: $CI_REGISTRY/$RUN_UPSTREAM_NAMESPACE/libvirt/ci-$NAME:latest
rules:
### Rules where we expect to use pre-built container images
### PUSH events
# upstream: pushes to the default branch
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
@ -53,28 +53,6 @@
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV'
when: on_success
# upstream: other web/api/scheduled pipelines targeting the default branch
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
when: on_success
# upstream+forks: merge requests targeting the default branch, without CI changes
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
changes:
- ci/gitlab/container-templates.yml
- ci/containers/$NAME.Dockerfile
when: never
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: on_success
### Rules where we need to use the target base container image
# forks: pushes to branches with pipeline requested
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE && $JOB_OPTIONAL'
when: manual
@ -86,27 +64,8 @@
variables:
IMAGE: $TARGET_BASE_IMAGE
# upstream: other web/api/scheduled pipelines targeting non-default branches
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
# forks: other web/api/scheduled pipelines
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
### MERGE REQUEST events
# upstream+forks: merge requests targeting the default branch, with CI changes
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
@ -125,6 +84,13 @@
variables:
IMAGE: $TARGET_BASE_IMAGE
# upstream+forks: merge requests targeting the default branch
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: on_success
# upstream+forks: merge requests targeting non-default branches
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
@ -136,7 +102,40 @@
variables:
IMAGE: $TARGET_BASE_IMAGE
### Neither prebuilt or local container images
### WEB / API / SCHEDULED events
# upstream: other web/api/scheduled pipelines targeting the default branch
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
when: on_success
# upstream: other web/api/scheduled pipelines targeting non-default branches
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
# forks: other web/api/scheduled pipelines on any branches
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
### Catch all unhandled events
# upstream+forks: that's all folks
- when: never
@ -174,7 +173,7 @@
variables:
IMAGE: $CI_REGISTRY/$RUN_UPSTREAM_NAMESPACE/libvirt/ci-$NAME-cross-$CROSS:latest
rules:
### Rules where we expect to use pre-built container images
### PUSH events
# upstream: pushes to the default branch
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
@ -190,28 +189,6 @@
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE_UPSTREAM_ENV'
when: on_success
# upstream: other web/api/scheduled pipelines targeting the default branch
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
when: on_success
# upstream+forks: merge requests targeting the default branch, without CI changes
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
changes:
- ci/gitlab/container-templates.yml
- ci/containers/$NAME-cross-$CROSS.Dockerfile
when: never
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: on_success
### Rules where we need to use the target base container image
# forks: pushes to branches with pipeline requested
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE == "push" && $RUN_PIPELINE && $JOB_OPTIONAL'
when: manual
@ -223,27 +200,8 @@
variables:
IMAGE: $TARGET_BASE_IMAGE
# upstream: other web/api/scheduled pipelines targeting non-default branches
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
# forks: other web/api/scheduled pipelines
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
### MERGE REQUEST events
# upstream+forks: merge requests targeting the default branch, with CI changes
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
@ -262,6 +220,13 @@
variables:
IMAGE: $TARGET_BASE_IMAGE
# upstream+forks: merge requests targeting the default branch
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: on_success
# upstream+forks: merge requests targeting non-default branches
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
@ -273,7 +238,40 @@
variables:
IMAGE: $TARGET_BASE_IMAGE
### Neither prebuilt or local container images
### WEB / API / SCHEDULED events
# upstream: other web/api/scheduled pipelines targeting the default branch
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
when: on_success
# upstream: other web/api/scheduled pipelines targeting non-default branches
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE == $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
# forks: other web/api/scheduled pipelines on any branches
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/ && $JOB_OPTIONAL'
when: manual
allow_failure: true
variables:
IMAGE: $TARGET_BASE_IMAGE
- if: '$CI_PROJECT_NAMESPACE != $RUN_UPSTREAM_NAMESPACE && $CI_PIPELINE_SOURCE =~ /(web|api|schedule)/'
when: on_success
variables:
IMAGE: $TARGET_BASE_IMAGE
### Catch all unhandled events
# upstream+forks: that's all folks
- when: never
@ -285,26 +283,10 @@
interruptible: true
needs: []
script:
- set -o allexport
- source ci/cirrus/$NAME.vars
- sed -e "s|[@]CI_REPOSITORY_URL@|$CI_REPOSITORY_URL|g"
-e "s|[@]CI_COMMIT_REF_NAME@|$CI_COMMIT_REF_NAME|g"
-e "s|[@]CI_MERGE_REQUEST_REF_PATH@|$CI_MERGE_REQUEST_REF_PATH|g"
-e "s|[@]CI_COMMIT_SHA@|$CI_COMMIT_SHA|g"
-e "s|[@]CIRRUS_VM_INSTANCE_TYPE@|$CIRRUS_VM_INSTANCE_TYPE|g"
-e "s|[@]CIRRUS_VM_IMAGE_SELECTOR@|$CIRRUS_VM_IMAGE_SELECTOR|g"
-e "s|[@]CIRRUS_VM_IMAGE_NAME@|$CIRRUS_VM_IMAGE_NAME|g"
-e "s|[@]UPDATE_COMMAND@|$UPDATE_COMMAND|g"
-e "s|[@]UPGRADE_COMMAND@|$UPGRADE_COMMAND|g"
-e "s|[@]INSTALL_COMMAND@|$INSTALL_COMMAND|g"
-e "s|[@]PATH@|$PATH_EXTRA${PATH_EXTRA:+:}\$PATH|g"
-e "s|[@]PKG_CONFIG_PATH@|$PKG_CONFIG_PATH|g"
-e "s|[@]PKGS@|$PKGS|g"
-e "s|[@]MAKE@|$MAKE|g"
-e "s|[@]PYTHON@|$PYTHON|g"
-e "s|[@]PIP3@|$PIP3|g"
-e "s|[@]PYPI_PKGS@|$PYPI_PKGS|g"
-e "s|[@]XML_CATALOG_FILES@|$XML_CATALOG_FILES|g"
<ci/cirrus/build.yml >ci/cirrus/$NAME.yml
- set +o allexport
- cirrus-vars <ci/cirrus/build.yml >ci/cirrus/$NAME.yml
- cat ci/cirrus/$NAME.yml
- cirrus-run -v --show-build-log always ci/cirrus/$NAME.yml
rules:

View File

@ -55,21 +55,6 @@ x86_64-alpine-edge:
TARGET_BASE_IMAGE: docker.io/library/alpine:edge
x86_64-centos-stream-8:
extends: .native_build_job
needs:
- job: x86_64-centos-stream-8-container
optional: true
allow_failure: false
variables:
NAME: centos-stream-8
TARGET_BASE_IMAGE: quay.io/centos/centos:stream8
artifacts:
expire_in: 1 day
paths:
- libvirt-rpms
x86_64-centos-stream-9:
extends: .native_build_job
needs:

View File

@ -28,13 +28,6 @@ x86_64-alpine-edge-container:
NAME: alpine-edge
x86_64-centos-stream-8-container:
extends: .container_job
allow_failure: false
variables:
NAME: centos-stream-8
x86_64-centos-stream-9-container:
extends: .container_job
allow_failure: false

View File

@ -1,30 +1,6 @@
include:
- 'ci/integration-template.yml'
# NOTE The integration tests use artifacts produced by the libvirt-perl
# and libvirt-python CI jobs, so the new target needs to be introduced
# there before it can be used here. The VM template for the target
# also needs to be created on the runner host.
centos-stream-8-tests:
extends: .integration_tests
variables:
# needed by libvirt-gitlab-executor
DISTRO: centos-stream-8
# can be overridden in forks to set a different runner tag
LIBVIRT_CI_INTEGRATION_RUNNER_TAG: redhat-vm-host
tags:
- $LIBVIRT_CI_INTEGRATION_RUNNER_TAG
needs:
- x86_64-centos-stream-8
- project: libvirt/libvirt-perl
job: x86_64-centos-stream-8
ref: master
artifacts: true
- project: libvirt/libvirt-python
job: x86_64-centos-stream-8
ref: master
artifacts: true
# NOTE The integration tests use artifacts produced by the libvirt-perl
# and libvirt-python CI jobs, so the new target needs to be introduced
# there before it can be used here. The VM template for the target

View File

@ -26,14 +26,6 @@ targets:
- arch: x86_64
allow-failure: true
centos-stream-8:
jobs:
- arch: x86_64
artifacts:
expire_in: 1 day
paths:
- libvirt-rpms
centos-stream-9:
jobs:
- arch: x86_64

View File

@ -7405,8 +7405,9 @@ A virtual sound card can be attached to the host via the ``sound`` element.
what real sound device is emulated. Valid values are specific to the
underlying hypervisor, though typical choices are ``sb16``, ``es1370``,
``pcspk``, ``ac97`` (:since:`Since 0.6.0`), ``ich6`` (:since:`Since 0.8.8`),
``ich9`` (:since:`Since 1.1.3`), ``usb`` (:since:`Since 1.2.8`) and ``ich7``
(:since:`Since 6.7.0`, bhyve only).
``ich9`` (:since:`Since 1.1.3`), ``usb`` (:since:`Since 1.2.8`), ``ich7``
(:since:`Since 6.7.0`, bhyve only) and ``virtio``
(:since:`Since 10.4.0 and QEMU 8.2.0`).
:since:`Since 0.9.13`, a sound element with ``ich6`` or ``ich9`` models can have
optional sub-elements ``<codec>`` to attach various audio codecs to the audio
@ -7434,6 +7435,12 @@ multi-channel mode by using the ``multichannel`` attribute::
<sound model='usb' multichannel='yes'/>
:since:`Since 10.4.0 and QEMU 8.2.0` the number of PCM streams in a ``virtio``
sound device can be configured by using the ``streams`` attribute, which
defaults to ``2`` if left unspecified::
<sound model='virtio' streams='2'/>
Each ``sound`` element has an optional sub-element ``<address>`` which can tie
the device to a particular PCI slot. See `Device Addresses`_.

View File

@ -815,6 +815,7 @@ Requires: gzip
Requires: bzip2
Requires: lzop
Requires: xz
Requires: zstd
Requires: systemd-container
Requires: swtpm-tools
%if %{with_numad}

View File

@ -2195,8 +2195,8 @@ if git
foreach file : dist_files
meson.add_dist_script(
meson_python_prog.full_path(), python3_prog.full_path(), meson_dist_prog.full_path(),
meson.project_build_root(), file
meson_python_prog.full_path(), python3_prog.full_path(),
meson_dist_prog.full_path(), file
)
endforeach
endif

View File

@ -4,9 +4,9 @@ import os
import shutil
import sys
meson_build_root = sys.argv[1]
file_name = sys.argv[2]
file_name = sys.argv[1]
meson_build_root = os.environ['MESON_BUILD_ROOT']
meson_dist_root = os.environ['MESON_DIST_ROOT']
shutil.copy(os.path.join(meson_build_root, file_name),

View File

@ -938,13 +938,13 @@ virCPUDefAddFeatureInternal(virCPUDef *def,
return 0;
}
int
void
virCPUDefUpdateFeature(virCPUDef *def,
const char *name,
int policy)
{
return virCPUDefAddFeatureInternal(def, name, policy,
VIR_CPU_ADD_FEATURE_MODE_UPDATE);
virCPUDefAddFeatureInternal(def, name, policy,
VIR_CPU_ADD_FEATURE_MODE_UPDATE);
}
int
@ -957,13 +957,13 @@ virCPUDefAddFeature(virCPUDef *def,
}
int
void
virCPUDefAddFeatureIfMissing(virCPUDef *def,
const char *name,
int policy)
{
return virCPUDefAddFeatureInternal(def, name, policy,
VIR_CPU_ADD_FEATURE_MODE_NEW);
virCPUDefAddFeatureInternal(def, name, policy,
VIR_CPU_ADD_FEATURE_MODE_NEW);
}

View File

@ -245,12 +245,12 @@ virCPUDefAddFeature(virCPUDef *cpu,
const char *name,
int policy);
int
void
virCPUDefUpdateFeature(virCPUDef *cpu,
const char *name,
int policy);
int
void
virCPUDefAddFeatureIfMissing(virCPUDef *def,
const char *name,
int policy);

View File

@ -779,6 +779,7 @@ VIR_ENUM_IMPL(virDomainSoundModel,
"ich9",
"usb",
"ich7",
"virtio",
);
VIR_ENUM_IMPL(virDomainAudioType,
@ -3212,6 +3213,7 @@ void virDomainSoundDefFree(virDomainSoundDef *def)
virDomainSoundCodecDefFree(def->codecs[i]);
g_free(def->codecs);
g_free(def->virtio);
g_free(def);
}
@ -11887,6 +11889,13 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt,
return NULL;
}
if (def->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO) {
if (virXMLPropUInt(node, "streams", 10,
VIR_XML_PROP_NONZERO,
&def->streams) < 0)
return NULL;
}
audioNode = virXPathNode("./audio", ctxt);
if (audioNode) {
if (virXMLPropUInt(audioNode, "id", 10,
@ -11898,6 +11907,10 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt,
if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags) < 0)
return NULL;
if (virDomainVirtioOptionsParseXML(virXPathNode("./driver", ctxt),
&def->virtio) < 0)
return NULL;
return g_steal_pointer(&def);
}
@ -11922,6 +11935,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a,
if (a->multichannel != b->multichannel)
return false;
if (a->streams != b->streams)
return false;
if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
!virDomainDeviceInfoAddressIsEqual(&a->info, &b->info))
return false;
@ -24848,6 +24864,7 @@ virDomainSoundDefFormat(virBuffer *buf,
const char *model = virDomainSoundModelTypeToString(def->model);
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
size_t i;
if (!model) {
@ -24872,6 +24889,14 @@ virDomainSoundDefFormat(virBuffer *buf,
virTristateBoolTypeToString(def->multichannel));
}
if (def->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO) {
virBufferAsprintf(&attrBuf, " streams='%d'", def->streams);
virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio);
virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
}
virXMLFormatElement(buf, "sound", &attrBuf, &childBuf);
return 0;

View File

@ -1568,6 +1568,7 @@ typedef enum {
VIR_DOMAIN_SOUND_MODEL_ICH9,
VIR_DOMAIN_SOUND_MODEL_USB,
VIR_DOMAIN_SOUND_MODEL_ICH7,
VIR_DOMAIN_SOUND_MODEL_VIRTIO,
VIR_DOMAIN_SOUND_MODEL_LAST
} virDomainSoundModel;
@ -1589,6 +1590,9 @@ struct _virDomainSoundDef {
virTristateBool multichannel;
unsigned int audioId;
unsigned int streams;
virDomainVirtioOptions *virtio;
};
typedef enum {

View File

@ -677,6 +677,13 @@ virDomainInputDefPostParse(virDomainInputDef *input,
}
}
static void
virDomainSoundDefPostParse(virDomainSoundDef *sound)
{
if (sound->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO && sound->streams == 0)
sound->streams = 2;
}
static int
virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
const virDomainDef *def,
@ -730,9 +737,13 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
ret = 0;
break;
case VIR_DOMAIN_DEVICE_SOUND:
virDomainSoundDefPostParse(dev->data.sound);
ret = 0;
break;
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_NET:
case VIR_DOMAIN_DEVICE_SOUND:
case VIR_DOMAIN_DEVICE_WATCHDOG:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_HUB:

View File

@ -5062,6 +5062,7 @@
<value>ich7</value>
<value>ich9</value>
<value>usb</value>
<value>virtio</value>
</choice>
</attribute>
<optional>
@ -5069,6 +5070,11 @@
<ref name="virYesNo"/>
</attribute>
</optional>
<optional>
<attribute name="streams">
<ref name="uint32"/>
</attribute>
</optional>
<interleave>
<optional>
<ref name="alias"/>
@ -5089,6 +5095,11 @@
<zeroOrMore>
<ref name="codec"/>
</zeroOrMore>
<optional>
<element name="driver">
<ref name="virtioOptions"/>
</element>
</optional>
</interleave>
</element>
</define>

View File

@ -560,19 +560,23 @@ virCPUBaseline(virArch arch,
* @arch: CPU architecture
* @guest: guest CPU definition to be updated
* @host: host CPU definition
* @removedPolicy: default policy for features removed from the CPU model
*
* Updates @guest CPU definition possibly taking @host CPU into account. This
* is required for maintaining compatibility with older libvirt releases or to
* support guest CPU definitions specified relatively to host CPU, such as CPUs
* with VIR_CPU_MODE_CUSTOM and optional features or VIR_CPU_MATCH_MINIMUM, or
* CPUs with VIR_CPU_MODE_HOST_MODEL.
* CPUs with VIR_CPU_MODE_HOST_MODEL. If @guest CPU uses a CPU model which
* specifies some features as removed, such features that were not already
* present in the @guest CPU definition will be added there with @removedPolicy.
*
* Returns 0 on success, -1 on error.
*/
int
virCPUUpdate(virArch arch,
virCPUDef *guest,
const virCPUDef *host)
const virCPUDef *host,
virCPUFeaturePolicy removedPolicy)
{
struct cpuArchDriver *driver;
bool relative;
@ -622,7 +626,7 @@ virCPUUpdate(virArch arch,
return -1;
}
if (driver->update(guest, host, relative) < 0)
if (driver->update(guest, host, relative, removedPolicy) < 0)
return -1;
VIR_DEBUG("model=%s", NULLSTR(guest->model));

View File

@ -81,7 +81,8 @@ typedef virCPUDef *
typedef int
(*virCPUArchUpdate)(virCPUDef *guest,
const virCPUDef *host,
bool relative);
bool relative,
virCPUFeaturePolicy removedPolicy);
typedef int
(*virCPUArchUpdateLive)(virCPUDef *cpu,
@ -229,7 +230,8 @@ virCPUBaseline(virArch arch,
int
virCPUUpdate(virArch arch,
virCPUDef *guest,
const virCPUDef *host)
const virCPUDef *host,
virCPUFeaturePolicy removedPolicy)
ATTRIBUTE_NONNULL(2);
int

View File

@ -448,7 +448,8 @@ virCPUarmGetMap(void)
static int
virCPUarmUpdate(virCPUDef *guest,
const virCPUDef *host,
bool relative)
bool relative,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);

View File

@ -39,7 +39,8 @@ virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED,
static int
virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED,
const virCPUDef *host G_GNUC_UNUSED,
bool relative G_GNUC_UNUSED)
bool relative G_GNUC_UNUSED,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
return 0;
}

View File

@ -654,7 +654,8 @@ virCPUppc64GetHost(virCPUDef *cpu,
static int
virCPUppc64Update(virCPUDef *guest,
const virCPUDef *host G_GNUC_UNUSED,
bool relative G_GNUC_UNUSED)
bool relative G_GNUC_UNUSED,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
/*
* - host-passthrough doesn't even get here

View File

@ -49,7 +49,8 @@ virCPURiscv64ValidateFeatures(virCPUDef *cpu G_GNUC_UNUSED)
static int
virCPURiscv64Update(virCPUDef *guest,
const virCPUDef *host,
bool relative)
bool relative,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);

View File

@ -42,7 +42,8 @@ virCPUs390Compare(virCPUDef *host G_GNUC_UNUSED,
static int
virCPUs390Update(virCPUDef *guest,
const virCPUDef *host,
bool relative)
bool relative,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
size_t i;
@ -72,10 +73,9 @@ virCPUs390Update(virCPUDef *guest,
virCPUDefCopyModel(updated, host, true);
for (i = 0; i < guest->nfeatures; i++) {
if (virCPUDefUpdateFeature(updated,
guest->features[i].name,
guest->features[i].policy) < 0)
return -1;
virCPUDefUpdateFeature(updated,
guest->features[i].name,
guest->features[i].policy);
}
virCPUDefStealModel(guest, updated, false);

View File

@ -829,28 +829,32 @@ x86DataAddSignature(virCPUx86Data *data,
}
/*
* Adds features removed from the CPU @model to @cpu with a specified @policy
* unless the features were already explicitly mentioned in @cpu.
*/
static void
virCPUx86AddRemovedFeatures(virCPUDef *cpu,
virCPUx86Model *model,
virCPUFeaturePolicy policy)
{
char **feat;
for (feat = model->removedFeatures; feat && *feat; feat++)
virCPUDefAddFeatureIfMissing(cpu, *feat, policy);
}
/*
* Disables features removed from the CPU @model unless they are already
* mentioned in @cpu to make sure these features will always be explicitly
* listed in the CPU definition.
*/
static int
static void
virCPUx86DisableRemovedFeatures(virCPUDef *cpu,
virCPUx86Model *model)
{
char **feat = model->removedFeatures;
if (!feat)
return 0;
while (*feat) {
if (virCPUDefAddFeatureIfMissing(cpu, *feat, VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
feat++;
}
return 0;
virCPUx86AddRemovedFeatures(cpu, model, VIR_CPU_FEATURE_DISABLE);
}
@ -901,10 +905,8 @@ x86DataToCPU(const virCPUx86Data *data,
x86DataToCPUFeatures(cpu, VIR_CPU_FEATURE_DISABLE, &modelData, map))
return NULL;
if (cpuType == VIR_CPU_TYPE_GUEST) {
if (virCPUx86DisableRemovedFeatures(cpu, model) < 0)
return NULL;
}
if (cpuType == VIR_CPU_TYPE_GUEST)
virCPUx86DisableRemovedFeatures(cpu, model);
cpu->type = cpuType;
@ -2914,7 +2916,7 @@ virCPUx86Baseline(virCPUDef **cpus,
}
static int
static void
x86UpdateHostModel(virCPUDef *guest,
const virCPUDef *host)
{
@ -2931,25 +2933,23 @@ x86UpdateHostModel(virCPUDef *guest,
}
for (i = 0; i < guest->nfeatures; i++) {
if (virCPUDefUpdateFeature(updated,
guest->features[i].name,
guest->features[i].policy) < 0)
return -1;
virCPUDefUpdateFeature(updated,
guest->features[i].name,
guest->features[i].policy);
}
virCPUDefStealModel(guest, updated,
guest->mode == VIR_CPU_MODE_CUSTOM);
guest->mode = VIR_CPU_MODE_CUSTOM;
guest->match = VIR_CPU_MATCH_EXACT;
return 0;
}
static int
virCPUx86Update(virCPUDef *guest,
const virCPUDef *host,
bool relative)
bool relative,
virCPUFeaturePolicy removedPolicy)
{
g_autoptr(virCPUx86Model) model = NULL;
virCPUx86Model *guestModel;
@ -2984,8 +2984,7 @@ virCPUx86Update(virCPUDef *guest,
if (guest->mode == VIR_CPU_MODE_HOST_MODEL ||
guest->match == VIR_CPU_MATCH_MINIMUM) {
if (x86UpdateHostModel(guest, host) < 0)
return -1;
x86UpdateHostModel(guest, host);
}
}
@ -2995,8 +2994,7 @@ virCPUx86Update(virCPUDef *guest,
return -1;
}
if (virCPUx86DisableRemovedFeatures(guest, guestModel) < 0)
return -1;
virCPUx86AddRemovedFeatures(guest, guestModel, removedPolicy);
return 0;
}
@ -3065,9 +3063,8 @@ virCPUx86UpdateLive(virCPUDef *cpu,
if (cpu->check == VIR_CPU_CHECK_FULL &&
!g_strv_contains((const char **) model->addedFeatures, feature->name)) {
virBufferAsprintf(&bufAdded, "%s,", feature->name);
} else if (virCPUDefUpdateFeature(cpu, feature->name,
VIR_CPU_FEATURE_REQUIRE) < 0) {
return -1;
} else {
virCPUDefUpdateFeature(cpu, feature->name, VIR_CPU_FEATURE_REQUIRE);
}
}
@ -3077,14 +3074,12 @@ virCPUx86UpdateLive(virCPUDef *cpu,
VIR_DEBUG("Feature '%s' disabled by the hypervisor", feature->name);
if (cpu->check == VIR_CPU_CHECK_FULL)
virBufferAsprintf(&bufRemoved, "%s,", feature->name);
else if (virCPUDefUpdateFeature(cpu, feature->name,
VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
else
virCPUDefUpdateFeature(cpu, feature->name, VIR_CPU_FEATURE_DISABLE);
}
}
if (virCPUx86DisableRemovedFeatures(cpu, model) < 0)
return -1;
virCPUx86DisableRemovedFeatures(cpu, model);
virBufferTrim(&bufAdded, ",");
virBufferTrim(&bufRemoved, ",");
@ -3186,8 +3181,7 @@ virCPUx86Translate(virCPUDef *cpu,
for (i = 0; i < cpu->nfeatures; i++) {
virCPUFeatureDef *f = cpu->features + i;
if (virCPUDefUpdateFeature(translated, f->name, f->policy) < 0)
return -1;
virCPUDefUpdateFeature(translated, f->name, f->policy);
}
virCPUDefStealModel(cpu, translated, true);
@ -3229,14 +3223,11 @@ virCPUx86ExpandFeatures(virCPUDef *cpu)
f->policy != VIR_CPU_FEATURE_DISABLE)
continue;
if (virCPUDefUpdateFeature(expanded, f->name, f->policy) < 0)
return -1;
virCPUDefUpdateFeature(expanded, f->name, f->policy);
}
if (!host) {
if (virCPUx86DisableRemovedFeatures(expanded, model) < 0)
return -1;
}
if (!host)
virCPUx86DisableRemovedFeatures(expanded, model);
virCPUDefFreeModel(cpu);

View File

@ -39,7 +39,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -40,7 +40,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -46,7 +46,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -47,7 +47,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -37,7 +37,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -36,7 +36,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -37,7 +37,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -38,7 +38,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -37,7 +37,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -38,7 +38,7 @@
<feature name='mce'/>
<feature name='mmx'/>
<feature name='movbe'/>
<feature name='mpx'/>
<feature name='mpx' removed='yes'/>
<feature name='msr'/>
<feature name='mtrr'/>
<feature name='nx'/>

View File

@ -604,6 +604,9 @@ struct _virDomain {
unsigned char uuid[VIR_UUID_BUFLEN]; /* the domain unique identifier */
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomain, virObjectUnref);
/**
* _virNetwork:
*
@ -647,6 +650,9 @@ struct _virInterface {
char *mac; /* the interface MAC address */
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virInterface, virObjectUnref);
/**
* _virStoragePool:
*
@ -706,6 +712,7 @@ struct _virNodeDevice {
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevice, virObjectUnref);
/**
* _virSecret:
*
@ -751,6 +758,8 @@ struct _virDomainCheckpoint {
virDomainPtr domain;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainCheckpoint, virObjectUnref);
/**
* _virDomainSnapshot
@ -763,6 +772,9 @@ struct _virDomainSnapshot {
virDomainPtr domain;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSnapshot, virObjectUnref);
/**
* _virNWFilter:
*
@ -775,6 +787,8 @@ struct _virNWFilter {
unsigned char uuid[VIR_UUID_BUFLEN]; /* the network filter unique identifier */
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNWFilter, virObjectUnref);
/**
* _virNWFilterBinding:
@ -788,6 +802,8 @@ struct _virNWFilterBinding {
char *filtername; /* the network filter name */
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNWFilterBinding, virObjectUnref);
/*
* Helper APIs for allocating new object instances

View File

@ -1534,7 +1534,8 @@ hypervDomainDefParseSerial(virDomainDef *def, Msvm_ResourceAllocationSettingData
continue;
}
serial = virDomainChrDefNew(NULL);
if (!(serial = virDomainChrDefNew(NULL)))
return -1;
serial->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
serial->source->type = VIR_DOMAIN_CHR_TYPE_PIPE;

View File

@ -137,55 +137,21 @@ udevGetDevices(struct udev *udev, virUdevStatus status)
return enumerate;
}
static int
udevNumOfInterfacesByStatus(virConnectPtr conn, virUdevStatus status,
virInterfaceObjListFilter filter)
{
struct udev *udev = udev_ref(driver->udev);
struct udev_enumerate *enumerate = NULL;
struct udev_list_entry *devices;
struct udev_list_entry *dev_entry;
int count = 0;
enumerate = udevGetDevices(udev, status);
if (!enumerate) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to get number of %1$s interfaces on host"),
virUdevStatusString(status));
count = -1;
goto cleanup;
}
/* Do the scan to load up the enumeration */
udev_enumerate_scan_devices(enumerate);
/* Get a list we can walk */
devices = udev_enumerate_get_list_entry(enumerate);
/* For each item so we can count */
udev_list_entry_foreach(dev_entry, devices) {
struct udev_device *dev;
const char *path;
g_autoptr(virInterfaceDef) def = NULL;
path = udev_list_entry_get_name(dev_entry);
dev = udev_device_new_from_syspath(udev, path);
def = udevGetMinimalDefForDevice(dev);
if (filter(conn, def))
count++;
udev_device_unref(dev);
}
cleanup:
if (enumerate)
udev_enumerate_unref(enumerate);
udev_unref(udev);
return count;
}
/**
* udevListInterfacesByStatus:
*
* @conn: connection object
* @names: optional pointer to array to be filled with interface names
* @names_len: size of @names
* @status: status of interfaces to be listed
* @filter: ACL filter function
*
* Lists interfaces with status matching @status filling them into @names (if
* non-NULL) and returns the number of such interfaces.
*
* In case of an error -1 is returned and no interfaces are filled into @names.
*/
static int
udevListInterfacesByStatus(virConnectPtr conn,
char **const names,
@ -219,18 +185,27 @@ udevListInterfacesByStatus(virConnectPtr conn,
udev_list_entry_foreach(dev_entry, devices) {
struct udev_device *dev;
const char *path;
const char *name;
g_autoptr(virInterfaceDef) def = NULL;
/* Ensure we won't exceed the size of our array */
if (count >= names_len)
if (names && count >= names_len)
break;
path = udev_list_entry_get_name(dev_entry);
dev = udev_device_new_from_syspath(udev, path);
if (!(name = udev_device_get_sysname(dev))) {
/* Name can be NULL in case when the interface is being unbound
* from the driver. The list API requires names to be present */
VIR_DEBUG("Skipping interface '%s', name == NULL", path);
continue;
}
def = udevGetMinimalDefForDevice(dev);
if (filter(conn, def)) {
names[count] = g_strdup(udev_device_get_sysname(dev));
if (names)
names[count] = g_strdup(name);
count++;
}
udev_device_unref(dev);
@ -242,14 +217,15 @@ udevListInterfacesByStatus(virConnectPtr conn,
return count;
}
static int
udevConnectNumOfInterfaces(virConnectPtr conn)
{
if (virConnectNumOfInterfacesEnsureACL(conn) < 0)
return -1;
return udevNumOfInterfacesByStatus(conn, VIR_UDEV_IFACE_ACTIVE,
virConnectNumOfInterfacesCheckACL);
return udevListInterfacesByStatus(conn, NULL, 0, VIR_UDEV_IFACE_ACTIVE,
virConnectNumOfInterfacesCheckACL);
}
static int
@ -271,8 +247,8 @@ udevConnectNumOfDefinedInterfaces(virConnectPtr conn)
if (virConnectNumOfDefinedInterfacesEnsureACL(conn) < 0)
return -1;
return udevNumOfInterfacesByStatus(conn, VIR_UDEV_IFACE_INACTIVE,
virConnectNumOfDefinedInterfacesCheckACL);
return udevListInterfacesByStatus(conn, NULL, 0, VIR_UDEV_IFACE_INACTIVE,
virConnectNumOfDefinedInterfacesCheckACL);
}
static int

View File

@ -1936,6 +1936,7 @@ virBitmapNextSetBit;
virBitmapOverlaps;
virBitmapParse;
virBitmapParseUnlimited;
virBitmapParseUnlimitedAllowEmpty;
virBitmapSetAll;
virBitmapSetBit;
virBitmapSetBitExpand;
@ -2360,6 +2361,7 @@ virFileReadHeaderFD;
virFileReadHeaderQuiet;
virFileReadLimFD;
virFileReadValueBitmap;
virFileReadValueBitmapAllowEmpty;
virFileReadValueInt;
virFileReadValueScaledInt;
virFileReadValueString;
@ -2503,6 +2505,7 @@ virHostCPUGetCount;
virHostCPUGetCPUID;
virHostCPUGetHaltPollTime;
virHostCPUGetInfo;
virHostCPUGetIsolated;
virHostCPUGetKVMMaxVCPUs;
virHostCPUGetMap;
virHostCPUGetMicrocodeVersion;

View File

@ -344,6 +344,7 @@ libxlDomainDefValidate(const virDomainDef *def,
case VIR_DOMAIN_SOUND_MODEL_ICH7:
case VIR_DOMAIN_SOUND_MODEL_USB:
case VIR_DOMAIN_SOUND_MODEL_ICH9:
case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
case VIR_DOMAIN_SOUND_MODEL_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported audio model %1$s"),

View File

@ -2709,10 +2709,10 @@ libxlConnectDomainXMLToNative(virConnectPtr conn, const char * nativeFormat,
goto cleanup;
if (STREQ(nativeFormat, XEN_CONFIG_FORMAT_XL)) {
if (!(conf = xenFormatXL(def, conn)))
if (!(conf = xenFormatXL(def)))
goto cleanup;
} else if (STREQ(nativeFormat, XEN_CONFIG_FORMAT_XM)) {
if (!(conf = xenFormatXM(conn, def)))
if (!(conf = xenFormatXM(def)))
goto cleanup;
} else {

View File

@ -24,6 +24,8 @@
#include <config.h>
#include "datatypes.h"
#include "driver.h"
#include "internal.h"
#include "virerror.h"
#include "virconf.h"
@ -1586,8 +1588,7 @@ xenMakeIPList(virNetDevIPInfo *guestIP)
}
static int
xenFormatNet(virConnectPtr conn,
virConfValue *list,
xenFormatNet(virConfValue *list,
virDomainNetDef *net,
int hvm,
const char *vif_typename)
@ -1649,13 +1650,19 @@ xenFormatNet(virConnectPtr conn,
case VIR_DOMAIN_NET_TYPE_NETWORK:
{
virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
g_autoptr(virConnect) conn = NULL;
virNetworkPtr network;
char *bridge;
if (!network) {
if (!(conn = virGetConnectNetwork()))
return -1;
if (!(network = virNetworkLookupByName(conn, net->data.network.name))) {
virReportError(VIR_ERR_NO_NETWORK, "%s",
net->data.network.name);
return -1;
}
bridge = virNetworkGetBridgeName(network);
virObjectUnref(network);
if (!bridge) {
@ -2304,7 +2311,6 @@ xenFormatSound(virConf *conf, virDomainDef *def)
static int
xenFormatVif(virConf *conf,
virConnectPtr conn,
virDomainDef *def,
const char *vif_typename)
{
@ -2317,8 +2323,7 @@ xenFormatVif(virConf *conf,
netVal->list = NULL;
for (i = 0; i < def->nnets; i++) {
if (xenFormatNet(conn, netVal, def->nets[i],
hvm, vif_typename) < 0)
if (xenFormatNet(netVal, def->nets[i], hvm, vif_typename) < 0)
return -1;
}
@ -2336,7 +2341,6 @@ xenFormatVif(virConf *conf,
int
xenFormatConfigCommon(virConf *conf,
virDomainDef *def,
virConnectPtr conn,
const char *nativeFormat)
{
if (xenFormatGeneralMeta(conf, def) < 0)
@ -2364,10 +2368,10 @@ xenFormatConfigCommon(virConf *conf,
return -1;
if (STREQ(nativeFormat, XEN_CONFIG_FORMAT_XL)) {
if (xenFormatVif(conf, conn, def, "vif") < 0)
if (xenFormatVif(conf, def, "vif") < 0)
return -1;
} else if (STREQ(nativeFormat, XEN_CONFIG_FORMAT_XM)) {
if (xenFormatVif(conf, conn, def, "netfront") < 0)
if (xenFormatVif(conf, def, "netfront") < 0)
return -1;
} else {
virReportError(VIR_ERR_INVALID_ARG,

View File

@ -61,7 +61,6 @@ int xenParseConfigCommon(virConf *conf,
int xenFormatConfigCommon(virConf *conf,
virDomainDef *def,
virConnectPtr conn,
const char *nativeFormat);
char *xenMakeIPList(virNetDevIPInfo *guestIP);

View File

@ -2041,14 +2041,14 @@ xenFormatXLDomainNamespaceData(virConf *conf, virDomainDef *def)
}
virConf *
xenFormatXL(virDomainDef *def, virConnectPtr conn)
xenFormatXL(virDomainDef *def)
{
g_autoptr(virConf) conf = NULL;
if (!(conf = virConfNew()))
return NULL;
if (xenFormatConfigCommon(conf, def, conn, XEN_CONFIG_FORMAT_XL) < 0)
if (xenFormatConfigCommon(conf, def, XEN_CONFIG_FORMAT_XL) < 0)
return NULL;
if (xenFormatXLOS(conf, def) < 0)

View File

@ -29,6 +29,6 @@ virDomainDef *xenParseXL(virConf *conn,
virCaps *caps,
virDomainXMLOption *xmlopt);
virConf *xenFormatXL(virDomainDef *def, virConnectPtr);
virConf *xenFormatXL(virDomainDef *def);
const char *xenTranslateCPUFeature(const char *feature_name, bool from_libxl);

View File

@ -543,15 +543,14 @@ G_STATIC_ASSERT(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
* Convert a virDomainDef object into an XM config record.
*/
virConf *
xenFormatXM(virConnectPtr conn,
virDomainDef *def)
xenFormatXM(virDomainDef *def)
{
g_autoptr(virConf) conf = NULL;
if (!(conf = virConfNew()))
return NULL;
if (xenFormatConfigCommon(conf, def, conn, XEN_CONFIG_FORMAT_XM) < 0)
if (xenFormatConfigCommon(conf, def, XEN_CONFIG_FORMAT_XM) < 0)
return NULL;
if (xenFormatXMOS(conf, def) < 0)

View File

@ -26,7 +26,7 @@
#include "virconf.h"
#include "domain_conf.h"
virConf *xenFormatXM(virConnectPtr conn, virDomainDef *def);
virConf *xenFormatXM(virDomainDef *def);
virDomainDef *xenParseXM(virConf *conf,
virCaps *caps, virDomainXMLOption *xmlopt);

View File

@ -582,10 +582,9 @@
# memory from the domain is dumped out directly to a file. If you have
# guests with a large amount of memory, however, this can take up quite
# a bit of space. If you would like to compress the images while they
# are being saved to disk, you can also set "lzop", "gzip", "bzip2", or "xz"
# for save_image_format. Note that this means you slow down the process of
# saving a domain in order to save disk space; the list above is in descending
# order by performance and ascending order by compression ratio.
# are being saved to disk, you can also set "zstd", "lzop", "gzip", "bzip2",
# or "xz" for save_image_format. Note that this means you slow down the process
# of saving a domain in order to save disk space.
#
# save_image_format is used when you use 'virsh save' or 'virsh managedsave'
# at scheduled saving, and it is an error if the specified save_image_format

View File

@ -707,6 +707,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"display-reload", /* QEMU_CAPS_DISPLAY_RELOAD */
"usb-mtp", /* QEMU_CAPS_DEVICE_USB_MTP */
"machine.virt.ras", /* QEMU_CAPS_MACHINE_VIRT_RAS */
"virtio-sound", /* QEMU_CAPS_DEVICE_VIRTIO_SOUND */
);
@ -1396,6 +1397,8 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "cryptodev-backend-lkcf", QEMU_CAPS_OBJECT_CRYPTO_LKCF },
{ "pvpanic-pci", QEMU_CAPS_DEVICE_PANIC_PCI },
{ "usb-mtp", QEMU_CAPS_DEVICE_USB_MTP },
{ "virtio-sound-pci", QEMU_CAPS_DEVICE_VIRTIO_SOUND },
{ "virtio-sound-device", QEMU_CAPS_DEVICE_VIRTIO_SOUND },
};
@ -3848,10 +3851,9 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
goto error;
for (i = 0; i < cpuExpanded->nfeatures; i++) {
if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE)
virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name,
VIR_CPU_FEATURE_REQUIRE) < 0)
goto error;
VIR_CPU_FEATURE_REQUIRE);
}
}

View File

@ -686,6 +686,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_DISPLAY_RELOAD, /* 'display-reload' qmp command is supported */
QEMU_CAPS_DEVICE_USB_MTP, /* -device usb-mtp */
QEMU_CAPS_MACHINE_VIRT_RAS, /* -machine virt,ras= */
QEMU_CAPS_DEVICE_VIRTIO_SOUND, /* -device virtio-sound-* */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;

View File

@ -952,8 +952,13 @@ qemuBuildVirtioDevGetConfigDev(const virDomainDeviceDef *device,
break;
}
case VIR_DOMAIN_DEVICE_SOUND: {
*baseName = "virtio-sound";
*virtioOptions = device->data.sound->virtio;
break;
}
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_SOUND:
case VIR_DOMAIN_DEVICE_WATCHDOG:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_HUB:
@ -4461,6 +4466,8 @@ qemuBuildSoundDevCmd(virCommand *cmd,
const char *model = NULL;
g_autofree char *audioid = NULL;
virTristateBool multichannel = VIR_TRISTATE_BOOL_ABSENT;
unsigned int streams = 0;
bool virtio = false;
switch (sound->model) {
case VIR_DOMAIN_SOUND_MODEL_ES1370:
@ -4482,6 +4489,10 @@ qemuBuildSoundDevCmd(virCommand *cmd,
case VIR_DOMAIN_SOUND_MODEL_SB16:
model = "sb16";
break;
case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
virtio = true;
streams = sound->streams;
break;
case VIR_DOMAIN_SOUND_MODEL_PCSPK: /* pc-speaker is handled separately */
case VIR_DOMAIN_SOUND_MODEL_ICH7:
case VIR_DOMAIN_SOUND_MODEL_LAST:
@ -4493,11 +4504,21 @@ qemuBuildSoundDevCmd(virCommand *cmd,
return -1;
}
if (!virtio) {
if (virJSONValueObjectAdd(&props,
"s:driver", model,
NULL) < 0)
return -1;
} else {
if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_SOUND, sound, qemuCaps)))
return -1;
}
if (virJSONValueObjectAdd(&props,
"s:driver", model,
"s:id", sound->info.alias,
"S:audiodev", audioid,
"T:multi", multichannel,
"p:streams", streams,
NULL) < 0)
return -1;

View File

@ -3951,7 +3951,9 @@ qemuDomainDefSuggestDefaultAudioBackend(virQEMUDriver *driver,
audioPassthrough = true;
} else {
audioPassthrough = false;
*audioBackend = VIR_DOMAIN_AUDIO_TYPE_NONE;
if (!*addAudio) {
*audioBackend = VIR_DOMAIN_AUDIO_TYPE_NONE;
}
}
*addAudio = true;
break;
@ -6699,8 +6701,7 @@ qemuDomainMakeCPUMigratable(virArch arch,
* would think it was implicitly enabled on the source). New libvirt
* will drop it from the XML before starting the domain on new QEMU.
*/
if (virCPUDefUpdateFeature(cpu, "pconfig", VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
virCPUDefUpdateFeature(cpu, "pconfig", VIR_CPU_FEATURE_DISABLE);
}
if (virCPUx86GetAddedFeatures(cpu->model, &data.added) < 0)
@ -6764,7 +6765,8 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver,
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qCaps, def->virtType,
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
}

View File

@ -324,6 +324,12 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDef *def,
if (def->cryptos[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
def->cryptos[i]->info.type = type;
}
for (i = 0; i < def->nsounds; i++) {
if (def->sounds[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO)
def->sounds[i]->info.type = type;
}
}
@ -694,6 +700,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
case VIR_DOMAIN_SOUND_MODEL_ICH9:
return pciFlags;
case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
return virtioFlags;
case VIR_DOMAIN_SOUND_MODEL_SB16:
case VIR_DOMAIN_SOUND_MODEL_PCSPK:
case VIR_DOMAIN_SOUND_MODEL_USB:

View File

@ -2334,6 +2334,8 @@ qemuProcessDetectIOThreadPIDs(virDomainObj *vm,
static int
qemuProcessGetAllCpuAffinity(virBitmap **cpumapRet)
{
g_autoptr(virBitmap) isolCpus = NULL;
*cpumapRet = NULL;
if (!virHostCPUHasBitmap())
@ -2342,6 +2344,13 @@ qemuProcessGetAllCpuAffinity(virBitmap **cpumapRet)
if (!(*cpumapRet = virHostCPUGetOnlineBitmap()))
return -1;
if (virHostCPUGetIsolated(&isolCpus) < 0)
return -1;
if (isolCpus) {
virBitmapSubtract(*cpumapRet, isolCpus);
}
return 0;
}
@ -6270,6 +6279,7 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
def->cpu->mode != VIR_CPU_MODE_MAXIMUM) {
g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
virCPUFeaturePolicy removedPolicy = VIR_CPU_FEATURE_DISABLE;
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
!virQEMUCapsIsCPUUsable(qemuCaps, def->virtType, def->cpu) &&
@ -6279,9 +6289,22 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
def->cpu, true) < 0)
return -1;
/* When starting a fresh domain we disable all features removed from
* the specified CPU model to make sure they are only used if
* explicitly requested. But when we are restoring a previously running
* domain (migration, snapshot, ...) all removed features were already
* explicitly listed in the CPU definition and if we found a removed
* feature which is missing it must have been removed later and must be
* enabled rather than disabled here match the state described by older
* libvirt.
*/
if (!(flags & VIR_QEMU_PROCESS_START_NEW))
removedPolicy = VIR_CPU_FEATURE_REQUIRE;
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
removedPolicy) < 0)
return -1;
cpuModels = virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NULL, NULL);
@ -8876,13 +8899,27 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
g_autoptr(virCPUDef) host = NULL;
g_autoptr(virCPUDef) hostmig = NULL;
g_autoptr(virCPUDef) cpu = NULL;
virCPUFeaturePolicy removedPolicy;
if (!virQEMUCapsGuestIsNative(driver->hostarch, vm->def->os.arch))
return 0;
/* When reconnecting to a running domain, we know all features marked as
* removed from a CPU model were already explicitly mentioned in the
* definition. If any removed features are missing, they must have been
* removed after the domain was started and thus they have to be enabled
* (otherwise they would be explicitly listed as disabled).
*/
removedPolicy = VIR_CPU_FEATURE_REQUIRE;
if (!vm->def->cpu)
return 0;
if (vm->def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
vm->def->cpu->model &&
virCPUUpdate(vm->def->os.arch, vm->def->cpu, NULL, removedPolicy) < 0)
return -1;
if (!virQEMUCapsGuestIsNative(driver->hostarch, vm->def->os.arch))
return 0;
if (qemuProcessRefreshCPUMigratability(vm, VIR_ASYNC_JOB_NONE) < 0)
return -1;
@ -8914,7 +8951,7 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilterFeatures,
&host->arch);
if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu) < 0)
if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu, removedPolicy) < 0)
return -1;
if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0)

View File

@ -47,6 +47,7 @@ typedef enum {
*/
QEMU_SAVE_FORMAT_XZ = 3,
QEMU_SAVE_FORMAT_LZOP = 4,
QEMU_SAVE_FORMAT_ZSTD = 5,
/* Note: add new members only at the end.
These values are used in the on-disk format.
Do not change or re-use numbers. */
@ -62,6 +63,7 @@ VIR_ENUM_IMPL(qemuSaveCompression,
"bzip2",
"xz",
"lzop",
"zstd",
);
static inline void

View File

@ -4675,6 +4675,14 @@ qemuValidateDomainDeviceDefSound(virDomainSoundDef *sound,
}
break;
case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_SOUND)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("virtio-sound controller is not supported in this QEMU binary"));
return -1;
}
break;
case VIR_DOMAIN_SOUND_MODEL_ES1370:
case VIR_DOMAIN_SOUND_MODEL_AC97:
case VIR_DOMAIN_SOUND_MODEL_ICH6:

View File

@ -1657,7 +1657,7 @@ static int virNetClientIOEventLoop(virNetClient *client,
#endif /* !WIN32 */
int timeout = -1;
virNetMessage *msg = NULL;
g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
g_autoptr(GSource) source = NULL;
GIOCondition ev = 0;
struct virNetClientIOEventData data = {
.client = client,
@ -1721,6 +1721,18 @@ static int virNetClientIOEventLoop(virNetClient *client,
g_main_loop_run(client->eventLoop);
/*
* If virNetClientIOEventFD ran, this GSource will already be
* destroyed due to G_SOURCE_REMOVE. It is harmless to re-destroy
* it, since we still own a reference.
*
* If virNetClientIOWakeup ran, it will have interrupted the
* g_main_loop_run call, before virNetClientIOEventFD could
* run, and thus the GSource is still registered, and we need
* to destroy it since it is referencing stack memory for 'data'
*/
g_source_destroy(source);
#ifndef WIN32
ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
#endif /* !WIN32 */

View File

@ -368,6 +368,7 @@ virBitmapFormat(virBitmap *bitmap)
* @str: points to a string representing a human-readable bitmap
* @bitmap: a bitmap populated from @str
* @limited: Don't use self-expanding APIs, report error if bit exceeds bitmap size
* @allowEmpty: Allow @str to be empty string or contain nothing but spaces
*
* This function is the counterpart of virBitmapFormat. This function creates
* a bitmap, in which bits are set according to the content of @str.
@ -381,7 +382,8 @@ virBitmapFormat(virBitmap *bitmap)
static int
virBitmapParseInternal(const char *str,
virBitmap *bitmap,
bool limited)
bool limited,
bool allowEmpty)
{
bool neg = false;
const char *cur = str;
@ -389,13 +391,19 @@ virBitmapParseInternal(const char *str,
size_t i;
int start, last;
if (!str)
if (!str) {
if (allowEmpty)
return 0;
goto error;
}
virSkipSpaces(&cur);
if (*cur == '\0')
if (*cur == '\0') {
if (allowEmpty)
return 0;
goto error;
}
while (*cur != 0) {
/*
@ -505,7 +513,7 @@ virBitmapParse(const char *str,
{
g_autoptr(virBitmap) tmp = virBitmapNew(bitmapSize);
if (virBitmapParseInternal(str, tmp, true) < 0)
if (virBitmapParseInternal(str, tmp, true, false) < 0)
return -1;
*bitmap = g_steal_pointer(&tmp);
@ -534,7 +542,29 @@ virBitmapParseUnlimited(const char *str)
{
g_autoptr(virBitmap) tmp = virBitmapNew(0);
if (virBitmapParseInternal(str, tmp, false) < 0)
if (virBitmapParseInternal(str, tmp, false, false) < 0)
return NULL;
return g_steal_pointer(&tmp);
}
/**
* virBitmapParseUnlimitedAllowEmpty:
* @str: points to a string representing a human-readable bitmap
*
* Just like virBitmapParseUnlimited() except when the input string @str is
* empty (or contains just spaces) an empty bitmap is returned instead of an
* error.
*
* Returns @bitmap on success, or NULL in cas of error
*/
virBitmap *
virBitmapParseUnlimitedAllowEmpty(const char *str)
{
g_autoptr(virBitmap) tmp = virBitmapNew(0);
if (virBitmapParseInternal(str, tmp, false, true) < 0)
return NULL;
return g_steal_pointer(&tmp);

View File

@ -84,6 +84,9 @@ int virBitmapParse(const char *str,
virBitmap *
virBitmapParseUnlimited(const char *str);
virBitmap *
virBitmapParseUnlimitedAllowEmpty(const char *str);
virBitmap *virBitmapNewCopy(virBitmap *src) ATTRIBUTE_NONNULL(1);
virBitmap *virBitmapNewData(const void *data, int len) ATTRIBUTE_NONNULL(1);

View File

@ -4365,26 +4365,12 @@ virFileReadValueScaledInt(unsigned long long *value, const char *format, ...)
* used for small, interface-like files, so it should not be huge (subjective) */
#define VIR_FILE_READ_VALUE_STRING_MAX 4096
/**
* virFileReadValueBitmap:
* @value: pointer to virBitmap * to be allocated and filled in with the value
* @format, ...: file to read from
*
* Read int from @format and put it into @value.
*
* Return -2 for non-existing file, -1 on other errors and 0 if everything went
* fine.
*/
int
virFileReadValueBitmap(virBitmap **value, const char *format, ...)
static int
virFileReadValueBitmapImpl(virBitmap **value,
const char *path,
bool allowEmpty)
{
g_autofree char *str = NULL;
g_autofree char *path = NULL;
va_list ap;
va_start(ap, format);
path = g_strdup_vprintf(format, ap);
va_end(ap);
if (!virFileExists(path))
return -2;
@ -4394,13 +4380,70 @@ virFileReadValueBitmap(virBitmap **value, const char *format, ...)
virStringTrimOptionalNewline(str);
*value = virBitmapParseUnlimited(str);
if (allowEmpty) {
*value = virBitmapParseUnlimitedAllowEmpty(str);
} else {
*value = virBitmapParseUnlimited(str);
}
if (!*value)
return -1;
return 0;
}
/**
* virFileReadValueBitmap:
* @value: pointer to virBitmap * to be allocated and filled in with the value
* @format, ...: file to read from
*
* Read int from @format and put it into @value.
*
* Returns: -2 for non-existing file,
* -1 on other errors (with error reported),
* 0 otherwise.
*/
int
virFileReadValueBitmap(virBitmap **value, const char *format, ...)
{
g_autofree char *path = NULL;
va_list ap;
va_start(ap, format);
path = g_strdup_vprintf(format, ap);
va_end(ap);
return virFileReadValueBitmapImpl(value, path, false);
}
/**
* virFileReadValueBitmapAllowEmpty:
* @value: pointer to virBitmap * to be allocated and filled in with the value
* @format, ...: file to read from
*
* Just like virFileReadValueBitmap(), except if the file is empty or contains
* nothing but spaces an empty bitmap is returned instead of an error.
*
* Returns: -2 for non-existing file,
* -1 on other errors (with error reported),
* 0 otherwise.
*/
int
virFileReadValueBitmapAllowEmpty(virBitmap **value, const char *format, ...)
{
g_autofree char *path = NULL;
va_list ap;
va_start(ap, format);
path = g_strdup_vprintf(format, ap);
va_end(ap);
return virFileReadValueBitmapImpl(value, path, true);
}
/**
* virFileReadValueString:
* @value: pointer to char * to be allocated and filled in with the value

View File

@ -354,6 +354,8 @@ int virFileReadValueUllongQuiet(unsigned long long *value, const char *format, .
G_GNUC_PRINTF(2, 3);
int virFileReadValueBitmap(virBitmap **value, const char *format, ...)
G_GNUC_PRINTF(2, 3);
int virFileReadValueBitmapAllowEmpty(virBitmap **value, const char *format, ...)
G_GNUC_PRINTF(2, 3);
int virFileReadValueScaledInt(unsigned long long *value, const char *format, ...)
G_GNUC_PRINTF(2, 3);
int virFileReadValueString(char **value, const char *format, ...)

View File

@ -1152,6 +1152,37 @@ virHostCPUGetAvailableCPUsBitmap(void)
}
/**
* virHostCPUGetIsolated:
* @isolated: returned bitmap of isolated CPUs
*
* Sets @isolated to point to a bitmap of isolated CPUs (e.g. those passed to
* isolcpus= kernel cmdline). If the file doesn't exist, @isolated is set to
* NULL and success is returned. If the file does exist but it's empty,
* @isolated is set to an empty bitmap and success is returned.
*
* Returns: 0 on success,
* -1 otherwise (with error reported).
*/
int
virHostCPUGetIsolated(virBitmap **isolated)
{
g_autoptr(virBitmap) bitmap = NULL;
int rc;
rc = virFileReadValueBitmapAllowEmpty(&bitmap, "%s/cpu/isolated", SYSFS_SYSTEM_PATH);
if (rc == -2) {
*isolated = NULL;
return 0;
} else if (rc < 0) {
return -1;
}
*isolated = g_steal_pointer(&bitmap);
return 0;
}
#if WITH_LINUX_KVM_H && defined(KVM_CAP_PPC_SMT)
/* Get the number of threads per subcore.

View File

@ -43,6 +43,7 @@ bool virHostCPUHasBitmap(void);
virBitmap *virHostCPUGetPresentBitmap(void);
virBitmap *virHostCPUGetOnlineBitmap(void);
virBitmap *virHostCPUGetAvailableCPUsBitmap(void);
int virHostCPUGetIsolated(virBitmap **isolated);
int virHostCPUGetCount(void);
int virHostCPUGetThreadsPerSubcore(virArch arch) G_NO_INLINE;

View File

@ -2975,6 +2975,9 @@ virVMXParseSerial(virVMXContext *ctx, virConf *conf, int port,
char fileName_name[48] = "";
g_autofree char *fileName = NULL;
char vspc_name[48] = "";
g_autofree char *vspc = NULL;
char network_endPoint_name[48] = "";
g_autofree char *network_endPoint = NULL;
@ -2997,6 +3000,7 @@ virVMXParseSerial(virVMXContext *ctx, virConf *conf, int port,
VMX_BUILD_NAME(startConnected);
VMX_BUILD_NAME(fileType);
VMX_BUILD_NAME(fileName);
VMX_BUILD_NAME(vspc);
VMX_BUILD_NAME_EXTRA(network_endPoint, "network.endPoint");
/* vmx:present */
@ -3026,6 +3030,10 @@ virVMXParseSerial(virVMXContext *ctx, virConf *conf, int port,
if (virVMXGetConfigString(conf, fileName_name, &fileName, true) < 0)
goto cleanup;
/* vmx:fileName -> def:data.file.path */
if (virVMXGetConfigString(conf, vspc_name, &vspc, true) < 0)
goto cleanup;
/* vmx:network.endPoint -> def:data.tcp.listen */
if (virVMXGetConfigString(conf, network_endPoint_name, &network_endPoint,
true) < 0) {
@ -3057,6 +3065,9 @@ virVMXParseSerial(virVMXContext *ctx, virConf *conf, int port,
(*def)->target.port = port;
(*def)->source->type = VIR_DOMAIN_CHR_TYPE_PIPE;
(*def)->source->data.file.path = g_steal_pointer(&fileName);
} else if (STRCASEEQ(fileType, "network") && vspc) {
(*def)->target.port = port;
(*def)->source->type = VIR_DOMAIN_CHR_TYPE_NULL;
} else if (STRCASEEQ(fileType, "network")) {
(*def)->target.port = port;
(*def)->source->type = VIR_DOMAIN_CHR_TYPE_TCP;

View File

@ -236,7 +236,7 @@ cpuTestGuestCPU(const void *arg)
goto cleanup;
}
if (virCPUUpdate(host->arch, cpu, host) < 0 ||
if (virCPUUpdate(host->arch, cpu, host, VIR_CPU_FEATURE_DISABLE) < 0 ||
virCPUTranslate(host->arch, cpu, data->models) < 0) {
ret = -1;
goto cleanup;
@ -363,7 +363,7 @@ cpuTestUpdate(const void *arg)
if (!(migHost = virCPUCopyMigratable(data->arch, host)))
return -1;
if (virCPUUpdate(host->arch, cpu, migHost) < 0)
if (virCPUUpdate(host->arch, cpu, migHost, VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
result = g_strdup_printf("%s+%s", data->host, data->name);

View File

@ -18,6 +18,7 @@
<feature policy='require' name='tm'/>
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='xsaves'/>

View File

@ -20,6 +20,7 @@
<feature name='tm'/>
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='xsaves'/>

View File

@ -4,6 +4,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='xsaves'/>
<feature policy='require' name='pdpe1gb'/>

View File

@ -19,6 +19,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='stibp'/>

View File

@ -21,6 +21,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='stibp'/>

View File

@ -5,6 +5,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='umip'/>
<feature policy='require' name='ssbd'/>

View File

@ -19,6 +19,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='xsaves'/>

View File

@ -21,6 +21,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='xsaves'/>

View File

@ -4,6 +4,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='pdpe1gb'/>
</cpu>

View File

@ -18,6 +18,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='md-clear'/>

View File

@ -20,6 +20,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='md-clear'/>

View File

@ -5,6 +5,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='umip'/>
<feature policy='require' name='md-clear'/>

View File

@ -19,6 +19,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='sgxlc'/>

View File

@ -21,6 +21,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='sgxlc'/>

View File

@ -4,6 +4,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='umip'/>
<feature policy='require' name='ssbd'/>

View File

@ -21,6 +21,7 @@
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='cmt'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='avx512ifma'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='sha-ni'/>

View File

@ -23,6 +23,7 @@
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='cmt'/>
<feature name='mpx'/>
<feature name='avx512ifma'/>
<feature name='intel-pt'/>
<feature name='sha-ni'/>

View File

@ -4,6 +4,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='avx512ifma'/>
<feature policy='require' name='sha-ni'/>
<feature policy='require' name='stibp'/>

View File

@ -19,6 +19,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='md-clear'/>

View File

@ -21,6 +21,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='md-clear'/>

View File

@ -4,6 +4,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='md-clear'/>
<feature policy='require' name='stibp'/>

View File

@ -19,6 +19,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='sgx'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='xsaves'/>

View File

@ -21,6 +21,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='sgx'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='xsaves'/>

View File

@ -5,6 +5,7 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='xsaves'/>
<feature policy='require' name='pdpe1gb'/>

View File

@ -20,6 +20,7 @@
<feature policy='require' name='pbe'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='cmt'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
<feature policy='require' name='intel-pt'/>
<feature policy='require' name='pku'/>

View File

@ -22,6 +22,7 @@
<feature name='pbe'/>
<feature name='tsc_adjust'/>
<feature name='cmt'/>
<feature name='mpx'/>
<feature name='clflushopt'/>
<feature name='intel-pt'/>
<feature name='pku'/>

View File

@ -4,5 +4,6 @@
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ss'/>
<feature policy='require' name='tsc_adjust'/>
<feature policy='require' name='mpx'/>
<feature policy='require' name='clflushopt'/>
</cpu>

Some files were not shown because too many files have changed in this diff Show More