1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-04-25 10:50:13 +03:00

Compare commits

..

No commits in common. "master" and "v11.2.0-rc2" have entirely different histories.

156 changed files with 1531 additions and 2819 deletions

View File

@ -8,71 +8,11 @@ the changes introduced by each of them.
For a more fine-grained view, use the `git log`_.
v11.3.0 (unreleased)
v11.2.0 (unreleased)
====================
* **Security**
* **Removed features**
* Support for AppArmor versions prior to 3.0.0 has been dropped.
* **New features**
* xen: Support configuration of ``<hyperv/>`` flags for Xen domains.
The following flags are now configurable for Xen: ``vapic``, ``synic``,
``stimer``, ``frequencies``, ``tlbflush`` and ``ipi``.
* bhyve: Support virtio random number generator devices
Domain XMLs can now include virtio random number generator devices.
They are configured with::
<rng model='virtio'>
<backend model='random'/>
</rng>
* bhyve: Support ``<interface type='network'>``
At the moment it doesn't provide any new features compared to
``<interface type='bridge'>``, but allows a more flexible configuration.
* **Improvements**
* **Bug fixes**
* cpu_map: Install Ampere-1 ARM CPU models
The Ampere-1 CPU models added in the previous release were not properly
installed and thus every attempt to start an ARM domain with custom
CPU definition would fail.
* storage: Fix new volume creation
No more errors occur when new storage volume is being created using ``virsh
vol-create`` with ``--validate`` option and/or ``virStorageVolCreateXML()``
with ``VIR_VOL_XML_PARSE_VALIDATE`` flag.
* Don't spam logs with error about ``qemu-rdp`` when starting a qemu VM
On hosts where the ``qemu-rdp`` binary is not installed a start of a VM
would cause an error such as ::
error : qemuRdpNewForHelper:103 : 'qemu-rdp' is not a suitable qemu-rdp helper name: No such file or directory
to be logged in the system log. It is safe to ignore the error. The code
was fixed to avoid the message when probing for support.
* Fix libvirt daemon crash on failure to hotplug a disk into a ``qemu`` VM
Some failures of disk hotplug could cause the libvirt daemon to crash due
to a bug when rolling back disk throttling filters.
v11.2.0 (2025-04-01)
====================
* **Removed features**
* Remove support for qemu-6.1 and older
@ -140,26 +80,6 @@ v11.2.0 (2025-04-01)
system are printed. A user may specify ``--all`` to also print models which
are not supported on the host.
* qemu: Introduce os/shim element
For secure boot environments where ``<loader/>`` is signed, it may be
unfeasible to keep the binary up to date (esp. when revoking certificates
contained within). To address that, new ``<shim/>`` element is introduced
which allows hypervisor to side load another UEFI binary, which can then
contain new certification authorities and/or list of revocations.
* ch: Enable SEV SNP support
Cloud Hypervisor guests can be now started with SEV SNP enabled.
* qemu: Support for Block Disk Along with Throttle Filters
Introduce support for multiple throttle groups per block disk in QEMU,
enhancing I/O control and performance optimization. This update builds
on the existing throttling functionality by allowing more granular control
with the ability to assign different throttle groups to multiple block
devices, improving shared throttling across devices.
* **Improvements**
* qemu: Improved guest agent corner case error reporting
@ -186,14 +106,6 @@ v11.2.0 (2025-04-01)
``virConnectGetAllDomainStats``, ``virDomainListGetStats``, and
``virDomainGetGuestInfo``.
* qemu: Reflect MAC address change in live domain XML
When a guest changes MAC address on one of its vNICs the new MAC address is
now visible in the live XML under ``currentAddress`` attribute of
``<mac/>`` element. At the same time,
``VIR_DOMAIN_EVENT_ID_NIC_MAC_CHANGE`` event is emitted so that management
applications can update their internal state.
* **Bug fixes**
* qemu: attach virtio-mem with CCW address
@ -202,11 +114,6 @@ v11.2.0 (2025-04-01)
default type CCW address assigned. A specified CCW address is now used for
the virtio-mem device instead of getting overwritten by a PCI address.
* ch: Various memory leak fixes
There were some memory leaks identified in the Cloud Hypervisor driver.
They are fixed now.
v11.1.0 (2025-03-03)
====================

View File

@ -123,17 +123,6 @@ img.diagram {
margin-bottom: 1em;
}
#documentation #application-development ul li p {
padding-bottom: 0px;
padding-top: 0px;
}
#documentation #application-development ul {
margin-left: 2em;
padding-top: 0px;
padding-bottom: 0px;
}
.removedhv {
color: darkred;
}

View File

@ -60,46 +60,24 @@ Application development
-----------------------
`API reference <html/index.html>`__
Reference manual for the C public API, split in:
* `common <html/libvirt-libvirt-common.html>`__
* `domain <html/libvirt-libvirt-domain.html>`__
* `domain checkpoint <html/libvirt-libvirt-domain-checkpoint.html>`__
* `domain snapshot <html/libvirt-libvirt-domain-snapshot.html>`__
* `error <html/libvirt-virterror.html>`__
* `event <html/libvirt-libvirt-event.html>`__
* `host <html/libvirt-libvirt-host.html>`__
* `interface <html/libvirt-libvirt-interface.html>`__
* `network <html/libvirt-libvirt-network.html>`__
* `node device <html/libvirt-libvirt-nodedev.html>`__
* `network filter <html/libvirt-libvirt-nwfilter.html>`__
* `secret <html/libvirt-libvirt-secret.html>`__
* `storage <html/libvirt-libvirt-storage.html>`__
* `stream <html/libvirt-libvirt-stream.html>`__
and the documentation for the API of the additional libs:
* `admin <html/libvirt-libvirt-admin.html>`__
* `QEMU <html/libvirt-libvirt-qemu.html>`__
* `LXC <html/libvirt-libvirt-lxc.html>`__
`XML schemas <format.html>`__
Description of the XML schemas for
* `domains <formatdomain.html>`__
* `networks <formatnetwork.html>`__
* `network ports <formatnetworkport.html>`__
* `network filtering <formatnwfilter.html>`__
* `storage <formatstorage.html>`__
* `storage encryption <formatstorageencryption.html>`__
* `capabilities <formatcaps.html>`__
* `domain capabilities <formatdomaincaps.html>`__
* `storage pool capabilities <formatstoragecaps.html>`__
* `node devices <formatnode.html>`__
* `secrets <formatsecret.html>`__
* `snapshots <formatsnapshot.html>`__
* `checkpoints <formatcheckpoint.html>`__
* `backup jobs <formatbackup.html>`__
Reference manual for the C public API, split in
`common <html/libvirt-libvirt-common.html>`__,
`domain <html/libvirt-libvirt-domain.html>`__,
`domain checkpoint <html/libvirt-libvirt-domain-checkpoint.html>`__,
`domain snapshot <html/libvirt-libvirt-domain-snapshot.html>`__,
`error <html/libvirt-virterror.html>`__,
`event <html/libvirt-libvirt-event.html>`__,
`host <html/libvirt-libvirt-host.html>`__,
`interface <html/libvirt-libvirt-interface.html>`__,
`network <html/libvirt-libvirt-network.html>`__,
`node device <html/libvirt-libvirt-nodedev.html>`__,
`network filter <html/libvirt-libvirt-nwfilter.html>`__,
`secret <html/libvirt-libvirt-secret.html>`__,
`storage <html/libvirt-libvirt-storage.html>`__,
`stream <html/libvirt-libvirt-stream.html>`__ and
`admin <html/libvirt-libvirt-admin.html>`__,
`QEMU <html/libvirt-libvirt-qemu.html>`__,
`LXC <html/libvirt-libvirt-lxc.html>`__ libs
`Language bindings and API modules <bindings.html>`__
Bindings of the libvirt API for
@ -114,6 +92,23 @@ Application development
and integration API modules for
`D-Bus <dbus.html>`__
`XML schemas <format.html>`__
Description of the XML schemas for
`domains <formatdomain.html>`__,
`networks <formatnetwork.html>`__,
`network ports <formatnetworkport.html>`__,
`network filtering <formatnwfilter.html>`__,
`storage <formatstorage.html>`__,
`storage encryption <formatstorageencryption.html>`__,
`capabilities <formatcaps.html>`__,
`domain capabilities <formatdomaincaps.html>`__,
`storage pool capabilities <formatstoragecaps.html>`__,
`node devices <formatnode.html>`__,
`secrets <formatsecret.html>`__,
`snapshots <formatsnapshot.html>`__,
`checkpoints <formatcheckpoint.html>`__,
`backup jobs <formatbackup.html>`__
`URI format <uri.html>`__
The URI formats used for connecting to libvirt

View File

@ -7,10 +7,8 @@ Bhyve driver
.. contents::
Bhyve is a FreeBSD hypervisor. It first appeared in FreeBSD 10.0. However, it's
recommended to use the
`latest supported release <https://www.freebsd.org/releases/>`__
to make sure all new features of bhyve are supported.
In order to enable bhyve on your FreeBSD host, you'll need
recommended to keep tracking FreeBSD 10-STABLE to make sure all new features of
bhyve are supported. In order to enable bhyve on your FreeBSD host, you'll need
to load the ``vmm`` kernel module. Additionally, ``if_tap`` and ``if_bridge``
modules should be loaded for networking support. Also, :since:`since 3.2.0` the
``virt-host-validate(1)`` supports the bhyve host validation and could be used
@ -584,18 +582,3 @@ Note that these extensions are for testing and development purposes only. They
are **unsupported**, using them may result in inconsistent state, and upgrading
either bhyve or libvirtd maybe break behavior of a domain that was relying on a
specific commands pass-through.
Random number generator device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:since:`Since 11.3.0` it's possible to use the virtio random number generator devices.
Example:
::
...
<rng model='virtio'>
<backend model='random'/>
</rng>
...

View File

@ -5,7 +5,7 @@
QEMU/KVM/HVF hypervisor driver
==============================
The libvirt KVM/QEMU driver can manage any QEMU emulator from version 6.2.0 or
The libvirt KVM/QEMU driver can manage any QEMU emulator from version 4.2.0 or
later.
It supports multiple QEMU accelerators: software

View File

@ -1,5 +1,3 @@
.. role:: since
Backup XML format
=================
@ -44,25 +42,6 @@ were supplied). The following child elements and attributes are supported:
necessary to set up an NBD server that exposes the content of each disk at
the time the backup is started.
In addition to the above the NBD server used for backups allows using
``transport='fd' fdgroup='NAME'`` where ``NAME`` is the name used with
``virDomainFDAssociate()`` to pass a pre-opened server socket file descriptor
to qemu. :since:`Since 11.3.0`
Example code to pass a socket with libvirt-python bindings::
import socket
import libvirt
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.bind("/path/to/socket")
fdlist = [ s.fileno() ]
conn = libvirt.open()
dom = conn.lookupByName("VMNAME")
dom.FDAssociate("NAME", fdlist)
Note that for the QEMU hypervisor the TLS environment in controlled using
``backup_tls_x509_cert_dir``, ``backup_tls_x509_verify``, and
``backup_tls_x509_secret_uuid`` properties in ``/etc/libvirt/qemu.conf``.

View File

@ -2132,34 +2132,32 @@ are:
based virtualization drivers, such as LXC.
``hyperv``
Enable various features improving behavior of guests running Microsoft
Windows. :since:`Since 11.3.0` some of these flags are also available for
Xen domains running Microsoft Windows.
Windows.
=============== ====================================================================== ============================================ ========================================================================
Feature Description Value Since
=============== ====================================================================== ============================================ ========================================================================
relaxed Relax constraints on timers on, off :since:`1.0.0 (QEMU 2.0), 11.3.0 (Xen, always on)`
vapic Enable virtual APIC on, off :since:`1.1.0 (QEMU 2.0), 11.3.0 (Xen)`
relaxed Relax constraints on timers on, off :since:`1.0.0 (QEMU 2.0)`
vapic Enable virtual APIC on, off :since:`1.1.0 (QEMU 2.0)`
spinlocks Enable spinlock support on, off; retries - at least 4095 :since:`1.1.0 (QEMU 2.0)`
vpindex Virtual processor index on, off :since:`1.3.3 (QEMU 2.5), 11.3.0 (Xen, always on)`
vpindex Virtual processor index on, off :since:`1.3.3 (QEMU 2.5)`
runtime Processor time spent on running guest code and on behalf of guest code on, off :since:`1.3.3 (QEMU 2.5)`
synic Enable Synthetic Interrupt Controller (SynIC) on, off :since:`1.3.3 (QEMU 2.6), 11.3.0 (Xen)`
stimer Enable SynIC timers, optionally with Direct Mode support on, off; direct - on,off :since:`1.3.3 (QEMU 2.6), direct mode 5.7.0 (QEMU 4.1), 11.3.0 (Xen, on/off only)`
synic Enable Synthetic Interrupt Controller (SynIC) on, off :since:`1.3.3 (QEMU 2.6)`
stimer Enable SynIC timers, optionally with Direct Mode support on, off; direct - on,off :since:`1.3.3 (QEMU 2.6), direct mode 5.7.0 (QEMU 4.1)`
reset Enable hypervisor reset on, off :since:`1.3.3 (QEMU 2.5)`
vendor_id Set hypervisor vendor id on, off; value - string, up to 12 characters :since:`1.3.3 (QEMU 2.5)`
frequencies Expose frequency MSRs on, off :since:`4.7.0 (QEMU 2.12), 11.3.0 (Xen)`
frequencies Expose frequency MSRs on, off :since:`4.7.0 (QEMU 2.12)`
reenlightenment Enable re-enlightenment notification on migration on, off :since:`4.7.0 (QEMU 3.0)`
tlbflush Enable PV TLB flush support on, off; direct - on,off; extended - on,off :since:`4.7.0 (QEMU 3.0), direct and extended modes 11.0.0 (QEMU 7.1.0), 11.3.0 (Xen, on/off only)`
ipi Enable PV IPI support on, off :since:`4.10.0 (QEMU 3.1), 11.3.0 (Xen)`
tlbflush Enable PV TLB flush support on, off; direct - on,off; extended - on,off :since:`4.7.0 (QEMU 3.0), direct and extended modes 11.0.0 (QEMU 7.1.0)`
ipi Enable PV IPI support on, off :since:`4.10.0 (QEMU 3.1)`
evmcs Enable Enlightened VMCS on, off :since:`4.10.0 (QEMU 3.1)`
avic Enable use Hyper-V SynIC with hardware APICv/AVIC on, off :since:`8.10.0 (QEMU 6.2)`
emsr_bitmap Avoid unnecessary updates to L2 MSR Bitmap upon vmexits. on, off :since:`10.7.0 (QEMU 7.1)`
xmm_input Enable XMM Fast Hypercall Input on, off :since:`10.7.0 (QEMU 7.1)`
=============== ====================================================================== ============================================ ========================================================================
:since:`Since 8.0.0 (QEMU) Since 11.3.0 (Xen)`, the hypervisor can be
configured further by setting the ``mode`` attribute to one of the following
values:
:since:`Since 8.0.0`, the hypervisor can be configured further by setting
the ``mode`` attribute to one of the following values:
``custom``
Set exactly the specified features.
@ -5056,8 +5054,8 @@ MAC address is outside of the reserved VMWare ranges.
:since:`Since 11.2.0`, the ``<mac/>`` element can optionally contain
``currentAddress`` attribute (output only), which contains new MAC address if the
guest changed it. This is currently implemented only for the model type ``virtio``
in QEMU/KVM and requires setting ``trustGuestRxFilters`` to ``yes``.
guest changed it. This is currently implemented only for QEMU/KVM and requires
setting ``trustGuestRxFilters`` to ``yes``.
:since:`Since 7.3.0`, one can set the ACPI index against network interfaces.
With some operating systems (eg Linux with systemd), the ACPI index is used
@ -5246,7 +5244,15 @@ network address by including an ``ip`` element specifying an IPv4
address in its one mandatory attribute, ``address``. Optionally, a
second ``ip`` element with a ``family`` attribute set to "ipv6" can be
specified to add an IPv6 address to the interface. ``address``.
Optionally, an address ``prefix`` can be specified.
Optionally, an address ``prefix`` can be specified. These settings are
surprisingly **not** used by SLIRP to set the exact IP address;
instead they are used to determine what network/subnet the guest's IP
address should be on, and the guest will be given an address in that
subnet, but the host portion of the address will still be "2.15". In
the example below, for example, the guest will be given the IP address
172.17.2.15 (**note that the '1.1' in the host portion of the address
has been ignored**), default route of 172.17.2.2, and DNS server
172.17.2.3.
::
@ -5262,59 +5268,6 @@ Optionally, an address ``prefix`` can be specified.
</devices>
...
These settings are surprisingly **not** used by SLIRP to set the exact
IP address; instead they are used to determine what **network/subnet**
the guest's IP address should be on, and the guest will be given an
address in that subnet, but the host portion of the address will still
be the host portion of "10.0.2.15" (based on the configured prefix (or
a prefix of 24 if no prefix is specified). The DNS and default gateway
addresses given to the guest will be similarly based on the network
portion of the configuration-provided <ip> combined with the host
portion of SLIRPs default settings for DNS/gateway
(10.0.2.3/10.0.2.2). To help resolve the confusion of the previous
sentences, the table below shows examples of the settings that will be
provided to the guest (via a DHCP response) to use for its interface
config (ip/prefix, DNS, default gateway) for various settings of <ip>
element address and prefix in libvirt's <interface type='user'>
config:
.. list-table::
:header-rows: 1
* - libvirt <ip> element
- guest ip/prefix
- guest DNS
- guest default gateway
* - (unspecified)
- 10.0.2.15/24
- 10.0.2.3
- 10.0.2.2
* - address='172.17.1.1'
prefix='16'
- 172.17.2.15/16
- 172.17.2.3
- 172.17.2.2
* - address='172.17.1.1'
prefix='24'
- 172.17.1.15/24
- 172.17.1.3
- 172.17.1.2
* - address='172.17.1.1'
prefix='8'
- 172.0.2.15/16
- 172.0.2.3
- 172.0.2.2
* - address='172.17.1.1'
prefix='23'
- 172.17.0.15/23
- 172.17.0.3
- 172.17.0.2
Userspace connection using passt
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -5356,10 +5309,8 @@ any conflict).
Also different from SLIRP's behavior: if you do specify IP
address(es), the exact address and netmask/prefix you specify will be
provided to the guest (i.e. passt doesn't interpret the <ip> settings
as a network address like SLIRP does, but as a host address). In the
table of examples given above, the guest IP would be set to exactly
172.17.1.1 in all cases (the DNS and default gateway will be set
the same as they are on the host).
as a network address like SLIRP does, but as a host address). In
example given above, the guest IP would be set to exactly 172.17.1.1.
Just as with SLIRP, though, once traffic from the guest leaves the
host towards the rest of the network, it will always appear as if it

View File

@ -427,25 +427,10 @@ nodeinfo
nodeinfo
Returns basic information about the node, like number and type of CPU,
and size of the physical memory.
Use of this command is strongly discouraged as the information provided
is not guaranteed to be accurate on all hardware platforms.
The *CPU frequency* value merely reflects the speed that the first CPU in the
machine is currently running at. This speed may vary across CPUs and changes
continually as the host OS throttles.
The data structure used to fetch the data is not extensible thus only supports
global nodes/sockets/cores/threads (sockets/cores/threads is per NUMA node)
topology information. If the host CPU has any further groupings (e.g.
dies, clusters, etc) or the NUMA topology is non-symmetrical the data structure
can't faithfully represent the system. In such cases a fake topology
(nodes = 1, sockets = 1, cores = number of host cpus, threads = 1) which
only correctly represents the total host CPU count is reported.
Recommended replacement is to use the *capabilities* command which reports
the data (except frequency) under ``/capabilities/host/topology`` XPath.
and size of the physical memory. The output corresponds to virNodeInfo
structure. Specifically, the "CPU socket(s)" field means number of CPU
sockets per NUMA cell. The information libvirt displays is dependent
upon what each architecture may provide.
nodecpumap

View File

@ -8,9 +8,7 @@
%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x riscv64
%if 0%{?rhel}
%if 0%{?rhel} >= 10
%define arches_qemu_kvm x86_64 aarch64 s390x riscv64
%elif 0%{?rhel} >= 9
%if 0%{?rhel} > 8
%define arches_qemu_kvm x86_64 aarch64 s390x
%else
%define arches_qemu_kvm x86_64 %{power64} aarch64 s390x

View File

@ -1,6 +1,6 @@
project(
'libvirt', 'c',
version: '11.3.0',
version: '11.2.0',
license: 'LGPLv2+',
meson_version: '>= 0.56.0',
default_options: [
@ -258,6 +258,11 @@ alloc_max = run_command(
stack_frame_size = 2048
# clang without optimization enlarges stack frames in certain corner cases
if cc.get_id() == 'clang' and get_option('optimization') == '0'
stack_frame_size = 4096
endif
# sanitizer instrumentation may enlarge stack frames
if get_option('b_sanitize') != 'none'
stack_frame_size = 32768
@ -921,11 +926,12 @@ if acl_dep.found()
conf.set('WITH_LIBACL', 1)
endif
apparmor_version = '3.0.0'
apparmor_dep = dependency('libapparmor', version: '>=' + apparmor_version,
required: get_option('apparmor'))
apparmor_dep = dependency('libapparmor', required: get_option('apparmor'))
if apparmor_dep.found()
conf.set('WITH_APPARMOR', 1)
if apparmor_dep.version().version_compare('>=3.0.0')
conf.set('WITH_APPARMOR_3', 1)
endif
conf.set_quoted('APPARMOR_DIR', sysconfdir / 'apparmor.d')
conf.set_quoted('APPARMOR_PROFILES_PATH', '/sys/kernel/security/apparmor/profiles')
endif

View File

@ -188,6 +188,7 @@ src/qemu/qemu_migration_cookie.c
src/qemu/qemu_migration_params.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c
src/qemu/qemu_namespace.c
src/qemu/qemu_nbdkit.c
src/qemu/qemu_passt.c

View File

@ -13,7 +13,7 @@ msgstr ""
"Project-Id-Version: libvirt 6.0.0\n"
"Report-Msgid-Bugs-To: https://libvirt.org/bugs.html\n"
"POT-Creation-Date: 2025-03-25 10:52+0000\n"
"PO-Revision-Date: 2025-03-29 02:07+0000\n"
"PO-Revision-Date: 2025-03-17 18:31+0000\n"
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
"Language-Team: English (United Kingdom) <https://translate.fedoraproject.org/"
"projects/libvirt/libvirt/en_GB/>\n"
@ -22,7 +22,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.10.2\n"
msgid ""
"\n"
@ -1255,7 +1255,7 @@ msgstr "'%1$s' is not a suitable pr helper"
#, c-format
msgid "'%1$s' is not a suitable qemu-rdp helper name"
msgstr "'%1$s' is not a suitable qemu-rdp helper name"
msgstr ""
#, c-format
msgid "'%1$s' is not supported in this QEMU binary"
@ -1283,7 +1283,7 @@ msgstr "'%1$s' starting from %2$llu has only %3$zd bytes available"
#, c-format
msgid "'%1$s' vanished unexpectedly"
msgstr "'%1$s' vanished unexpectedly"
msgstr ""
msgid ""
"'--copy-storage-synchronous-writes' requires one of '--copy-storage-all', '--"
@ -1508,7 +1508,7 @@ msgid "'return' member missing"
msgstr "'return' member missing"
msgid "'sheepdog' protocol is no longer supported by any hypervisor driver"
msgstr "'sheepdog' protocol is no longer supported by any hypervisor driver"
msgstr ""
#, c-format
msgid ""
@ -1914,11 +1914,11 @@ msgstr "ACPI requires UEFI on this architecture"
#, c-format
msgid "ACPI table type '%1$s' is not supported"
msgstr "ACPI table type '%1$s' is not supported"
msgstr ""
#, c-format
msgid "ACPI table type '%1$s' may only appear once"
msgstr "ACPI table type '%1$s' may only appear once"
msgstr ""
#, c-format
msgid "AES256CBC encryption invalid keylen=%1$zu"
@ -2035,10 +2035,10 @@ msgid "Add or remove vcpus"
msgstr "Add or remove vCPUs"
msgid "Add or update a throttling group."
msgstr "Add or update a throttling group."
msgstr ""
msgid "Add or updte a throttling group."
msgstr "Add or update a throttling group."
msgstr ""
msgid "Added"
msgstr "Added"
@ -2251,7 +2251,7 @@ msgid "Autostart"
msgstr "Autostart"
msgid "Autostart Once:"
msgstr "Autostart Once:"
msgstr ""
msgid "Autostart:"
msgstr "Autostart:"
@ -2767,7 +2767,7 @@ msgid "Can't create initial configuration"
msgstr "Can't create initial configuration"
msgid "Can't define NWFilter bindings in session mode"
msgstr "Can't define NWFilter bindings in session mode"
msgstr ""
msgid "Can't define NWFilters in session mode"
msgstr ""

View File

@ -18,7 +18,7 @@ msgstr ""
"Project-Id-Version: libvirt 6.0.0\n"
"Report-Msgid-Bugs-To: https://libvirt.org/bugs.html\n"
"POT-Creation-Date: 2025-03-25 10:52+0000\n"
"PO-Revision-Date: 2025-03-30 07:26+0000\n"
"PO-Revision-Date: 2025-03-01 03:12+0000\n"
"Last-Translator: 김인수 <simmon@nplob.com>\n"
"Language-Team: Korean <https://translate.fedoraproject.org/projects/libvirt/"
"libvirt/ko/>\n"
@ -27,7 +27,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.10.2\n"
msgid ""
"\n"
@ -1253,7 +1253,7 @@ msgstr "'%1$s' 는 알맞는 도우미가 아닙니다"
#, c-format
msgid "'%1$s' is not a suitable qemu-rdp helper name"
msgstr "'%1$s' 는 적합한 qemu-rdp helper 이름이 없습니다"
msgstr ""
#, c-format
msgid "'%1$s' is not supported in this QEMU binary"
@ -1281,7 +1281,7 @@ msgstr "'%1$s' 시작은(%2$llu에서) 사용 가능한 %3$zd 바이트만을
#, c-format
msgid "'%1$s' vanished unexpectedly"
msgstr "'%1$s' 가 예상치 못하게 사라졌습니다"
msgstr ""
msgid ""
"'--copy-storage-synchronous-writes' requires one of '--copy-storage-all', '--"
@ -1485,8 +1485,6 @@ msgid ""
"'reconnect' attribute is not supported when source mode='server' for "
"<interface type='vhostuser'>"
msgstr ""
"'reconnect' 속성은 <interface type='vhostuser'> 를 위한 source mode='server' "
"일 때에 지원되지 않습니다"
msgid ""
"'restrictive' mode is required in memnode element when mode is 'restrictive' "
@ -1503,11 +1501,10 @@ msgstr ""
"니다"
msgid "'return' member missing"
msgstr "'return' 구성이 누락됨"
msgstr ""
msgid "'sheepdog' protocol is no longer supported by any hypervisor driver"
msgstr "'sheepdog' 통신규약은 모든 하이퍼바이저 드라이버에서 더 이상 지원되지 "
"않습니다"
msgstr ""
#, c-format
msgid ""
@ -1925,11 +1922,11 @@ msgstr "ACPI는 이 구조(아키텍쳐)에서 UEFI가 필요합니다"
#, c-format
msgid "ACPI table type '%1$s' is not supported"
msgstr "ACPI 테이블 유형 '%1$s'는 지원되지 않습니다"
msgstr ""
#, c-format
msgid "ACPI table type '%1$s' may only appear once"
msgstr "ACPI 테이블 유형 '%1$s' 는 한 번만 나타날 것입니다"
msgstr ""
#, c-format
msgid "AES256CBC encryption invalid keylen=%1$zu"
@ -2048,10 +2045,10 @@ msgid "Add or remove vcpus"
msgstr "vcpus를 추가하거나 제거하기"
msgid "Add or update a throttling group."
msgstr "제한 그룹을 추가하거나 최신화합니다."
msgstr ""
msgid "Add or updte a throttling group."
msgstr "제한 그룹을 추가하거나 최신화합니다."
msgstr ""
msgid "Added"
msgstr "추가됨"
@ -2265,7 +2262,7 @@ msgid "Autostart"
msgstr "자동 시작"
msgid "Autostart Once:"
msgstr "한 번 자동시작:"
msgstr ""
msgid "Autostart:"
msgstr "Autostart:"
@ -3033,7 +3030,7 @@ msgid "Cannot create macvlan devices on this platform"
msgstr "이 기술환경에서 macvlan 장치를 생성 할 수 없음"
msgid "Cannot create monitor FIFO"
msgstr "monitor FIFO를 생성 할 수 없습니다"
msgstr ""
#, c-format
msgid "Cannot create resctrl directory '%1$s'"

197
po/uk.po
View File

@ -16,7 +16,7 @@ msgstr ""
"Project-Id-Version: libvirt 6.0.0\n"
"Report-Msgid-Bugs-To: https://libvirt.org/bugs.html\n"
"POT-Creation-Date: 2025-03-25 10:52+0000\n"
"PO-Revision-Date: 2025-04-03 11:20+0000\n"
"PO-Revision-Date: 2025-02-25 14:49+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://translate.fedoraproject.org/projects/"
"libvirt/libvirt/uk/>\n"
@ -26,7 +26,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.10\n"
msgid ""
"\n"
@ -1306,7 +1306,7 @@ msgstr "«%1$s» не є придатним допоміжним засобом
#, c-format
msgid "'%1$s' is not a suitable qemu-rdp helper name"
msgstr "«%1$s» не є придатним до використання допоміжним засобом qemu-rdp"
msgstr ""
#, c-format
msgid "'%1$s' is not supported in this QEMU binary"
@ -1336,7 +1336,7 @@ msgstr "«%1$s» починаючи з %2$llu має лише %3$zd доступ
#, c-format
msgid "'%1$s' vanished unexpectedly"
msgstr "«%1$s» неочікувано зник"
msgstr ""
msgid ""
"'--copy-storage-synchronous-writes' requires one of '--copy-storage-all', '--"
@ -1574,8 +1574,6 @@ msgstr "пропущено член 'return'"
msgid "'sheepdog' protocol is no longer supported by any hypervisor driver"
msgstr ""
"Підтримки протоколу «sheepdog» більше не передбачено у жодному драйвері "
"гіпервізора"
#, c-format
msgid ""
@ -1996,11 +1994,11 @@ msgstr "На цій архітектурі ACPI потребує UEFI"
#, c-format
msgid "ACPI table type '%1$s' is not supported"
msgstr "Підтримки таблиць ACPI типу «%1$s» не передбачено"
msgstr ""
#, c-format
msgid "ACPI table type '%1$s' may only appear once"
msgstr "Таблиця ACPI типу «%1$s» може з'являтися лише раз"
msgstr ""
#, c-format
msgid "AES256CBC encryption invalid keylen=%1$zu"
@ -2122,10 +2120,10 @@ msgid "Add or remove vcpus"
msgstr "Додати або вилучити віртуальні процесори"
msgid "Add or update a throttling group."
msgstr "Додати або оновити групу регулювання."
msgstr ""
msgid "Add or updte a throttling group."
msgstr "Додати або оновити групу регулювання."
msgstr ""
msgid "Added"
msgstr "Додано"
@ -2350,7 +2348,7 @@ msgid "Autostart"
msgstr "Автозапуск"
msgid "Autostart Once:"
msgstr "Одноразовий автозапуск:"
msgstr ""
msgid "Autostart:"
msgstr "Автозапуск:"
@ -3263,8 +3261,6 @@ msgstr "Не вдалося знайти «iothread»: %1$u"
#, c-format
msgid "Cannot find CPU model with PVR 0x%1$03llx, vendor id 0x%2$02llx"
msgstr ""
"Не вдалося знайти модель процесора з PVR 0x%1$03llx, ідентифікатор виробника "
"0x%2$02llx"
#, c-format
msgid "Cannot find CPU model with PVR 0x%1$08x"
@ -5764,7 +5760,7 @@ msgid "Delete a given vol."
msgstr "Вилучити вказаний том."
msgid "Delete a throttling group."
msgstr "Вилучити групу регулювання."
msgstr ""
msgid "Delete an IOThread from the guest domain."
msgstr "Вилучити потік введення-виведення з гостьового домену."
@ -6238,7 +6234,7 @@ msgstr "Домен «%1$s» позначений як домен з автоза
#, c-format
msgid "Domain '%1$s' marked as autostarted on next boot\n"
msgstr "Домен «%1$s» позначено на автозапуск при наступному завантаженні\n"
msgstr ""
#, c-format
msgid "Domain '%1$s' resumed\n"
@ -6270,7 +6266,7 @@ msgstr "Домен «%1$s» не позначений як домен з авт
#, c-format
msgid "Domain '%1$s' unmarked as autostarted on next boot\n"
msgstr "Позначення «%1$s» для автозапуску знято для наступного завантаження\n"
msgstr ""
#, c-format
msgid "Domain '%1$s' was reset\n"
@ -7411,7 +7407,7 @@ msgstr "Не вдалося з'єднати сокет з «%1$s»"
#, c-format
msgid "Failed to connect to dbus-daemon: %1$s"
msgstr "Не вдалося встановити з'єднання з dbus-daemon: %1$s"
msgstr ""
msgid "Failed to connect to mon socket"
msgstr "Не вдалося встановити з'єднання з сокетом mon"
@ -7605,7 +7601,7 @@ msgstr "Не вдалося створити резервне сховище н
#, c-format
msgid "Failed to create rdp state dir %1$s"
msgstr "Не вдалося створити каталог стану rdp %1$s"
msgstr ""
msgid "Failed to create reboot thread, killing domain"
msgstr ""
@ -8382,7 +8378,6 @@ msgstr "Помилка позначення домену «%1$s» як доме
#, c-format
msgid "Failed to mark domain '%1$s' as autostarted on next boot"
msgstr ""
"Не вдалося позначити домен «%1$s» для автозапуску при наступному завантаженні"
#, c-format
msgid "Failed to mkdir %1$s"
@ -9353,8 +9348,6 @@ msgstr "Помилка зняття позначки домену «%1$s» як
#, c-format
msgid "Failed to unmark domain '%1$s' as autostarted on next boot"
msgstr ""
"Не вдалося зняти позначення домену «%1$s» для автозапуску при наступному "
"завантаженні"
#, c-format
msgid "Failed to unmarshall reply: %1$s"
@ -9745,7 +9738,7 @@ msgid "GNUTLS call error"
msgstr "помилка виклику GNUTLS"
msgid "Get a throttling group."
msgstr "Отримати групу регулювання."
msgstr ""
msgid "Get block device size info for a domain."
msgstr "Отримати дані щодо розміру блокового пристрою для домену."
@ -9824,7 +9817,7 @@ msgid "Get the CPU models for an arch."
msgstr "Отримати дані щодо моделей процесорів для архітектури."
msgid "Get the CPU models reported by the hypervisor."
msgstr "Отримати моделі процесорів, про які повідомляє гіпервізор."
msgstr ""
msgid "Get the launch security parameters for a guest domain"
msgstr "Отримати параметри безпеки запуску для гостьового домену"
@ -9847,7 +9840,7 @@ msgid "Get the summary of block devices for a domain."
msgstr "Отримати резюме щодо блокових пристроїв для домену."
msgid "Get the summary of throttle groups for a domain."
msgstr "Отримати резюме груп регулювання для домену."
msgstr ""
msgid "Get the summary of virtual interfaces for a domain."
msgstr "Отримати резюме щодо віртуальних інтерфейсів домену."
@ -10108,7 +10101,7 @@ msgstr ""
"машини «%2$s»"
msgid "Hypervisor reported CPU models"
msgstr "Гіпервізор повідомив про моделі процесорів"
msgstr ""
msgid "I/O Error"
msgstr "Помилка в/в"
@ -10233,8 +10226,6 @@ msgid ""
"IOThread mapping for virtio-scsi controllers is not available with this QEMU "
"binary"
msgstr ""
"Прив'язка IOThread для контролерів virtio-scsi є недоступною для цього "
"виконуваного файла QEMU"
msgid "IOThread to be used by supported device"
msgstr "IOThread, який буде використано підтримуваним пристроєм"
@ -10888,7 +10879,7 @@ msgstr "Некоректний тип драйвера: %1$d"
#, c-format
msgid "Invalid dump_image_format '%1$s'"
msgstr "Некоректне значення dump_image_format «%1$s»"
msgstr ""
msgid "Invalid duration"
msgstr "Неприпустиме значення тривалості"
@ -10970,7 +10961,7 @@ msgstr "Некоректний метод перевірки ключів осн
#, c-format
msgid "Invalid host_data provided. Expected '%1$ld' bytes"
msgstr "Надано некоректне значення host_data. Мало бути «%1$ld» байтів"
msgstr ""
#, c-format
msgid "Invalid hostdev protocol '%1$s'"
@ -10978,7 +10969,7 @@ msgstr "Некоректний протокол пристрою основно
#, c-format
msgid "Invalid image_format '%1$s'"
msgstr "Некоректне значення image_format «%1$s»"
msgstr ""
#, c-format
msgid "Invalid integer value '%1$s' in file '%2$s'"
@ -11204,7 +11195,7 @@ msgstr "Некоректний засіб спостереження resctrl"
#, c-format
msgid "Invalid save_image_format '%1$s'"
msgstr "Некоректне значення save_image_format «%1$s»"
msgstr ""
msgid "Invalid secret"
msgstr "Некоректний ключ"
@ -11230,7 +11221,7 @@ msgstr "Некоректне значення для можливості pserie
#, c-format
msgid "Invalid snapshot_image_format '%1$s'"
msgstr "Некоректне значення snapshot_image_format «%1$s»"
msgstr ""
#, c-format
msgid "Invalid source mode: %1$s"
@ -11533,7 +11524,7 @@ msgid "Kernel image path in this domain is not defined"
msgstr "Шлях до образу ядра у цьому домені не визначено"
msgid "Kernel image path is not defined. With sev_snp=on, pass an igvm path"
msgstr "Шлях до образу ядра не визначено. З sev_snp=on передано шлях igvm"
msgstr ""
msgid "Key file path must be provided for private key authentication"
msgstr ""
@ -12376,7 +12367,7 @@ msgstr "Не вказано типу можливості"
#, c-format
msgid "Missing certificate file '%1$s'"
msgstr "Не вистачає файла сертифіката «%1$s»"
msgstr ""
#, c-format
msgid "Missing check/@partial in CPU model %1$s"
@ -12457,7 +12448,7 @@ msgstr "У документі JSON не вистачає даних keepaliveInt
#, c-format
msgid "Missing key file '%1$s'"
msgstr "Не вистачає файла ключа «%1$s»"
msgstr ""
msgid "Missing listen element"
msgstr "Пропущено елемент listen"
@ -12642,7 +12633,7 @@ msgid "Missing ownerUUID data in JSON document"
msgstr "У документі JSON не вистачає даних щодо UUID власника (ownerUUID)"
msgid "Missing password"
msgstr "Не вистачає пароля"
msgstr ""
msgid "Missing path or lockspace for lease resource"
msgstr "Не вистачає шляху або простору блокування для ресурсу надання"
@ -13878,7 +13869,7 @@ msgid "Only VNC supported"
msgstr "Передбачено підтримку лише VNC"
msgid "Only a single ACPI table is supported"
msgstr "Передбачено підтримку лише єдиної таблиці ACPI"
msgstr ""
msgid "Only a single IDE controller is supported for this machine type"
msgstr "Для цього типу архітектури передбачено лише один контролер IDE"
@ -14338,8 +14329,6 @@ msgstr "Номер паралельного порту, %1$d, не лежить
msgid "Parallel save is only supported with the 'sparse' save image format"
msgstr ""
"Підтримку паралельного збереження передбачено лише для формату образів "
"збереження «sparse»"
#, c-format
msgid "Parameter '%1$s' is not a string"
@ -14718,8 +14707,6 @@ msgstr "на сервері NBD QEMU не передбачено підтрим
#, c-format
msgid "QEMU agent command '%1$s' returned neither error nor success"
msgstr ""
"Команда агента QEMU «%1$s» не повернула ні повідомлення про помилку, ні "
"повідомлення про успіх"
#, c-format
msgid "QEMU binary %1$s is not executable"
@ -14870,13 +14857,13 @@ msgstr ""
"розширених можливостей і створення смуг"
msgid "RDP doesn't support 'multiUser'"
msgstr "У RDP не передбачено підтримки «multiUser»"
msgstr ""
msgid "RDP doesn't support 'replaceUser'"
msgstr "У RDP не передбачено підтримки «replaceUser»"
msgstr ""
msgid "RDP password expiration isn't supported"
msgstr "Підтримки завершення строку дії пароля RDP не передбачено"
msgstr ""
msgid "RDT Memory Bandwidth allocation unsupported"
msgstr "Підтримки розподілу ширини каналу пам'яті RDT не передбачено"
@ -17791,8 +17778,6 @@ msgid ""
"The 'dev' attribute of the <source> element can only be used with "
"<interface> type='user' or type='vhostuser' if the <backend> type='passt'"
msgstr ""
"Атрибут «dev» елемента <source> можна використовувати лише з <interface> "
"type='user' або type='vhostuser', якщо для <backend> type='passt'"
#, c-format
msgid ""
@ -18370,10 +18355,10 @@ msgid "Thread(s) per core:"
msgstr "Потоків на ядро:"
msgid "Throttle group deleted successfully\n"
msgstr "Групу регулювання успішно вилучено\n"
msgstr ""
msgid "Throttle group set successfully\n"
msgstr "Групу регулювання успішно встановлено\n"
msgstr ""
#, c-format
msgid "Time '%1$lld' is too big for guest agent"
@ -20251,7 +20236,7 @@ msgstr "Не вдалося прочитати файл pid «%1$s»"
#, c-format
msgid "Unable to read qemu-rdp pidfile '%1$s'"
msgstr "Не вдалося прочитати файл PID qemu-rdp «%1$s»"
msgstr ""
#, c-format
msgid "Unable to read slirp pidfile '%1$s'"
@ -20665,7 +20650,7 @@ msgid "Unable to set thread local variable"
msgstr "Не вдалося встановити локальний змінну потоку виконання"
msgid "Unable to set throttle group"
msgstr "Не вдалося встановити групу регулювання"
msgstr ""
#, c-format
msgid "Unable to set vlan configuration on port %1$s: %2$s"
@ -21755,7 +21740,7 @@ msgid "Unsupported object type %1$d"
msgstr "Підтримки типів об'єктів %1$d не передбачено"
msgid "Unsupported qemu-rdp listen type"
msgstr "Непідтримуваний тип очікування qemu-rdp"
msgstr ""
msgid "Unsupported resctrl monitor type"
msgstr "Непідтримуваний тип монітора resctrl"
@ -23192,15 +23177,11 @@ msgstr "блок"
msgid ""
"block 'iotune' can't be used together with 'throttlefilters' for disk '%1$s'"
msgstr ""
"блок «iotune» не можна використовувати разом із «throttlefilters» для диска "
"«%1$s»"
#, c-format
msgid ""
"block 'throttlefilters' can't be used together with 'iotune' for disk '%1$s'"
msgstr ""
"блок «throttlefilters» не можна використовувати разом із «iotune» для диска "
"«%1$s»"
#, c-format
msgid "block I/O throttle limit must be no more than %1$llu using QEMU"
@ -23586,7 +23567,7 @@ msgid "can't manipulate inactive snapshots of disk '%1$s'"
msgstr "неможлива робота із неактивними знімками диска «%1$s»"
msgid "can't open log context"
msgstr "не вдалося відкрити контекст журналу"
msgstr ""
#, c-format
msgid "can't open session to the domain with id %1$d"
@ -23831,7 +23812,7 @@ msgid "cannot change persistent config of a transient network"
msgstr "не можна змінювати сталі налаштування тимчасової мережі"
msgid "cannot change port settings on rdp graphics"
msgstr "не вдалося змінити параметри порту для графіки rdp"
msgstr ""
msgid "cannot change port settings on spice graphics"
msgstr "не вдалося змінити параметри порту графічної системи SPICE"
@ -25191,7 +25172,7 @@ msgid "cd: %1$s: %2$s"
msgstr "cd: %1$s: %2$s"
msgid "cdrom device with throttle filters isn't supported"
msgstr "підтримки пристрою cdrom з фільтрами регулювання не передбачено"
msgstr ""
msgid "cdrom device with virtio bus isn't supported"
msgstr "підтримки пристроїв cdrom з каналом virtio не передбачено"
@ -25485,7 +25466,7 @@ msgstr ""
"нульовим виявленням"
msgid "comma separated list of throttle groups to be applied"
msgstr "список відокремлених комами груп регулювання, які буде застосовано"
msgstr ""
msgid "command"
msgstr "команда"
@ -25702,7 +25683,7 @@ msgid "control domain's outgoing traffics"
msgstr "керування вихідними даними домену"
msgid "control next boot state"
msgstr "керувати станом наступного завантаження"
msgstr ""
msgid "control or query domain emulator affinity"
msgstr "вказати або визначити прив'язку у емуляторі домену"
@ -25718,8 +25699,6 @@ msgid ""
"controller driver 'iothread' attribute can't be used together with "
"'iothreads' subelement"
msgstr ""
"атрибут «iothread» драйвера контролера не можна використовувати з разом із "
"піделементом «iothreads»"
#, c-format
msgid "controller index='%1$d' already exists"
@ -26432,8 +26411,6 @@ msgid ""
"dbus-daemon died and reported:\n"
"%1$s"
msgstr ""
"dbus-daemon завершив роботу і повідомив:\n"
"%1$s"
msgid "default"
msgstr "типовий"
@ -27533,11 +27510,11 @@ msgstr "дублювання домену «%1$s»"
#, c-format
msgid "duplicate filter name '%1$s' found"
msgstr "виявлено дублювання назви фільтра «%1$s»"
msgstr ""
#, c-format
msgid "duplicate group name '%1$s' found"
msgstr "виявлено дублювання назви групи «%1$s»"
msgstr ""
#, c-format
msgid "duplicate iothread id '%1$u' found"
@ -28054,10 +28031,6 @@ msgid ""
"oldMAC: %3$s\n"
"newMAC: %4$s\n"
msgstr ""
"подія «nic-mac-change» для домену «%1$s»:\n"
"альтернатива: %2$s\n"
"стара-MAC: %3$s\n"
"нова-MAC: %4$s\n"
#, c-format
msgid "event 'rtc-change' for domain '%1$s': %2$lld\n"
@ -28763,7 +28736,7 @@ msgid "failed to get hostname"
msgstr "помилка отримання назви вузла гіпервізора"
msgid "failed to get hypervisor CPU model names"
msgstr "не вдалося отримати назви моделей процесорів гіпервізора"
msgstr ""
msgid "failed to get hypervisor type"
msgstr "помилка отримання типа гіпервізора"
@ -29334,7 +29307,7 @@ msgid "failed to seek in log file %1$s"
msgstr "не вдалося виконати позиціювання у файлі журналу %1$s"
msgid "failed to seek on file descriptor"
msgstr "не вдалося виконати позиціювання на дескрипторі файла"
msgstr ""
#, c-format
msgid "failed to seek to end of %1$s"
@ -29911,7 +29884,7 @@ msgid "format of the destination file"
msgstr "формат файла призначення"
msgid "format of the save image file"
msgstr "формат збереження файла образу"
msgstr ""
#, c-format
msgid "formatter for %1$s %2$s reported error"
@ -30169,28 +30142,26 @@ msgstr ""
"вистачає: %1$s"
msgid "guest agent command failed"
msgstr "помилка команди агента гостьової системи"
msgstr ""
#, c-format
msgid "guest agent command failed: %1$s"
msgstr "помилка команди агента гостьової системи: %1$s"
msgstr ""
msgid "guest agent command timed out"
msgstr "перевищено час очікування на виконання команди агента гостьової системи"
msgstr ""
#, c-format
msgid "guest agent command timed out: %1$s"
msgstr ""
"перевищено час очікування на виконання команди агента гостьової системи: %1$s"
#, c-format
msgid "guest agent didn't respond to command within '%1$d' seconds"
msgstr "агент гостьової системи не відповів на команду за «%1$d» секунд"
msgstr ""
#, c-format
msgid "guest agent didn't respond to synchronization within '%1$d' seconds"
msgstr ""
"агент гостьової системи не відповів на синхронізацію протягом %1$d секунд"
msgid "guest agent replied with wrong id to guest-sync command"
msgstr ""
@ -30661,7 +30632,7 @@ msgid "inbound rate larger than maximum %1$u"
msgstr "вхідна швидкість перевищує максимальну, %1$u"
msgid "include all CPU models known to the hypervisor for the architecture"
msgstr "включити усі моделі процесорів, відомі гіпервізору для архітектури"
msgstr ""
msgid "include backup size estimate in XML dump"
msgstr "включити оцінку розміру резервної копії до дампу XML"
@ -32095,7 +32066,7 @@ msgid "list all domain blocks"
msgstr "показати список всіх блоків"
msgid "list all domain throttlegroups."
msgstr "вивести усі групи регулювання домену."
msgstr ""
msgid "list all domain virtual interfaces"
msgstr "список всіх віртуальних інтерфейсів домену"
@ -32723,7 +32694,6 @@ msgstr "помилкове форматування слоту у даних щ
msgid "managed save cannot be requested for transient domains"
msgstr ""
"запит щодо керованого збереження не можна надсилати для тимчасових доменів"
msgid "managed save of a domain state"
msgstr "кероване збереження стану домену"
@ -33647,7 +33617,7 @@ msgid "missing gluster volume name for path '%1$s'"
msgstr "не вказано назви тому gluster для шляху «%1$s»"
msgid "missing group name"
msgstr "не вистачає назви групи"
msgstr ""
#, c-format
msgid "missing group_device value for '%1$s'"
@ -33742,7 +33712,7 @@ msgid "missing listen element"
msgstr "пропущено елемент listen"
msgid "missing listen element for VNC graphics"
msgstr "пропущено елемент listen для графіки VNC"
msgstr ""
msgid "missing listen element for spice graphics"
msgstr "пропущено елемент очікування (listen) для графіки spice"
@ -34820,7 +34790,7 @@ msgid "no CPUs given"
msgstr "не вказано процесори"
msgid "no D-Bus address"
msgstr "немає адреси D-Bus"
msgstr ""
msgid "no FLR, PM reset or bus reset available"
msgstr "немає FLR, доступне скидання PM чи шини"
@ -35495,13 +35465,9 @@ msgstr "numad є недоступним для цього вузла"
msgid "number of IO channels to use for parallel restore"
msgstr ""
"кількість каналів введення-виведення для використання при паралельному "
"відновленні"
msgid "number of IO channels to use for parallel save"
msgstr ""
"кількість каналів введення-виведення для використання при паралельному "
"збереженні"
msgid "number of bytes read:"
msgstr "кількість прочитаних байтів:"
@ -35532,7 +35498,7 @@ msgstr ""
"переходу до стану бездіяльності"
msgid "number of parallel save channels cannot be less than 1"
msgstr "кількість каналів паралельного збереження не може бути меншою за 1"
msgstr ""
msgid "number of read operations:"
msgstr "кількість дій з читання:"
@ -35687,8 +35653,6 @@ msgid ""
"only 1 graphics device of each type (sdl, vnc, spice, headless, dbus, rdp) "
"is supported"
msgstr ""
"передбачено підтримку лише 1 графічного пристрою кожного типу (sdl, vnc, "
"spice, headless, dbus, rdp)"
msgid "only JSON objects can be top level"
msgstr "на верхньому рівні можуть бути лише об'єкти JSON"
@ -36096,7 +36060,7 @@ msgstr "значення параметра %1$s є занадто велики
#, c-format
msgid "parameter '%1$s' is missing in reply of guest-get-load"
msgstr "у відповіді guest-get-load не визначає параметра «%1$s»"
msgstr ""
#, c-format
msgid "parameter '%1$s' not supported"
@ -36586,7 +36550,7 @@ msgid "preserve sparseness of volume"
msgstr "зберегти розрідженість тому"
msgid "preserve state before shutting down"
msgstr "зберегти стан до вимикання"
msgstr ""
msgid "pretty-print any JSON output"
msgstr "форматоване виведення для усіх виведених даних JSON"
@ -36775,7 +36739,7 @@ msgid "qemu agent didn't return an array of keys"
msgstr "Агентом qemu не повернуто масиву ключів"
msgid "qemu agent didn't return an array of loads"
msgstr "агент qemu не повернув масиву навантажень"
msgstr ""
#, c-format
msgid "qemu didn't report thread id for vcpu '%1$zu'"
@ -36851,23 +36815,18 @@ msgid ""
"qemu-rdp died and reported:\n"
"%1$s"
msgstr ""
"qemu-rdp завершив роботу і повернув:\n"
"%1$s"
msgid "qemu-rdp does not support multiple listens for one graphics device."
msgstr ""
"у qemu-rdp не передбачено підтримки декількох каналів очікування для одного "
"графічного пристрою."
msgid "qemu-rdp doesn't support the 'multiUser' attribute."
msgstr "у qemu-rdp не передбачено підтримки атрибута «multiUser»."
msgstr ""
msgid "qemu-rdp doesn't support the 'replaceUser' attribute."
msgstr "у qemu-rdp не передбачено підтримки атрибута «replaceUser»."
msgstr ""
msgid "qemu-rdp support requires a D-Bus bus graphics device."
msgstr ""
"для підтримки qemu-rdp потрібен графічний пристрій із підтримкою шини D-Bus."
#, c-format
msgid "qom-get invalid object property type %1$d"
@ -37127,11 +37086,11 @@ msgid "rawio is only supported for scsi host device"
msgstr "підтримку rawio передбачено лише для пристроїв scsi основної системи"
msgid "rdp"
msgstr "rdp"
msgstr ""
#, c-format
msgid "rdp_tls_x509_cert_dir directory '%1$s' does not exist"
msgstr "каталогу rdp_tls_x509_cert_dir «%1$s» не існує"
msgstr ""
msgid "re-initialize NVRAM from its pristine template"
msgstr "повторно ініціалізувати NVRAM з її початкового шаблона"
@ -37427,7 +37386,7 @@ msgid "report interface information"
msgstr "вивести звіт щодо інтерфейсу"
msgid "report load averages information"
msgstr "повідомити дані щодо середнього навантаження"
msgstr ""
msgid "report only stats that are accessible instantly"
msgstr "звітувати лише про статистичні дані, які негайно доступні"
@ -37754,8 +37713,6 @@ msgstr "збереження скасовано"
#, c-format
msgid "save image format %1$s is not supported by this QEMU binary"
msgstr ""
"підтримки формату образу збереження «%1$s» у цьому виконуваному файлі QEMU "
"не передбачено"
msgid "save image is incomplete"
msgstr "збережений образ є неповним"
@ -38162,10 +38119,10 @@ msgid "shares '%1$llu' must be in range [%2$llu, %3$llu]"
msgstr "shares «%1$llu» має перебувати у діапазоні [%2$llu, %3$llu]"
msgid "shim is not supported by this QEMU binary"
msgstr "підтримки shim у цьому виконуваному файлі QEMU не передбачено"
msgstr ""
msgid "shim only allowed with kernel option"
msgstr "shim можна використовувати лише з параметром ядра"
msgstr ""
#, c-format
msgid ""
@ -38394,8 +38351,6 @@ msgid ""
"source disk for '%1$s' is not a regular file, reverting to snapshot is not "
"supported"
msgstr ""
"початковий диск для «%1$s» не є звичайним файлом, повернення до знімка не "
"передбачено"
#, c-format
msgid ""
@ -38558,7 +38513,7 @@ msgid "status mismatch in event (actual 0x%1$x, expected 0x%2$x)"
msgstr "невідповідність станів у події (маємо 0x%1$x, мало бути 0x%2$x)"
msgid "stop the daemon"
msgstr "зупинити фонову службу"
msgstr ""
msgid "stopped, with no saved guests"
msgstr "зупинено без збережених гостьових систем"
@ -39287,18 +39242,18 @@ msgstr "порогове значення як масштабоване числ
#, c-format
msgid "throttle group '%1$s' is still being used by disk %2$s"
msgstr "група регулювання «%1$s» усе ще використовує диск %2$s"
msgstr ""
#, c-format
msgid "throttle group '%1$s' not found"
msgstr "групи регулювання «%1$s» не знайдено"
msgstr ""
#, c-format
msgid "throttle group field '%1$s' must be an integer"
msgstr "поле групи регулювання «%1$s» має бути цілим"
msgstr ""
msgid "throttle group name"
msgstr "назва групи регулювання"
msgstr ""
msgid "time to set"
msgstr "час, який слід встановити"
@ -40603,7 +40558,7 @@ msgstr "неочікуваний тип файлової системи %1$d"
#, c-format
msgid "unexpected graphics type '%1$d'"
msgstr "неочікуваний тип графіки «%1$d»"
msgstr ""
#, c-format
msgid "unexpected host-model CPU for %1$s architecture"
@ -40896,15 +40851,15 @@ msgstr "невідомий тип розпізнавання %1$s"
#, c-format
msgid "unknown auto_shutdown_poweroff '%1$s'"
msgstr "невідоме значення auto_shutdown_poweroff «%1$s»"
msgstr ""
#, c-format
msgid "unknown auto_shutdown_try_save '%1$s'"
msgstr "невідоме значення auto_shutdown_try_save «%1$s»"
msgstr ""
#, c-format
msgid "unknown auto_shutdown_try_shutdown '%1$s'"
msgstr "невідоме значення auto_shutdown_try_shutdown «%1$s»"
msgstr ""
#, c-format
msgid "unknown backend source type '%1$s' for external TPM"
@ -41484,7 +41439,7 @@ msgid "unsupported disk driver %1$s"
msgstr "непідтримуваний драйвер диска, %1$s"
msgid "unsupported disk protocol"
msgstr "непідтримуваний протокол роботи з диском"
msgstr ""
#, c-format
msgid "unsupported disk snapshot type '%1$s'"

View File

@ -818,6 +818,8 @@ class CParser:
# Parse a comment block associate to a macro
#
def parseMacroComment(self, name, quiet=0):
global ignored_macros
if name[0:2] == '__':
quiet = 1
if name in ignored_macros:
@ -893,6 +895,8 @@ class CParser:
# as possible
#
def mergeFunctionComment(self, name, description, quiet=0):
global ignored_functions
if name == 'main':
quiet = 1
if name[0:2] == '__':
@ -1131,6 +1135,8 @@ class CParser:
self.lexer.push(tok)
def token(self):
global ignored_words
token = self.lexer.token()
while token is not None:
if token[0] == 'comment':

View File

@ -4,7 +4,6 @@
* Copyright (C) 2014 Roman Bogorodskiy
* Copyright (C) 2014 Semihalf
* Copyright (C) 2020 Fabian Freyer
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -109,16 +108,6 @@ virBhyveDomainCapsFill(virDomainCaps *caps,
VIR_DOMAIN_CAPS_ENUM_SET(caps->video.modelType, VIR_DOMAIN_VIDEO_TYPE_GOP);
}
if (bhyvecaps & BHYVE_CAP_VIRTIO_RND) {
caps->rng.supported = VIR_TRISTATE_BOOL_YES;
caps->rng.model.report = true;
caps->rng.backendModel.report = true;
VIR_DOMAIN_CAPS_ENUM_SET(caps->rng.model, VIR_DOMAIN_RNG_MODEL_VIRTIO);
VIR_DOMAIN_CAPS_ENUM_SET(caps->rng.backendModel,
VIR_DOMAIN_RNG_BACKEND_RANDOM);
}
caps->hostdev.supported = VIR_TRISTATE_BOOL_NO;
caps->features[VIR_DOMAIN_CAPS_FEATURE_IOTHREADS] = VIR_TRISTATE_BOOL_NO;
caps->features[VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO] = VIR_TRISTATE_BOOL_NO;
@ -338,17 +327,6 @@ bhyveProbeCapsVirtio9p(unsigned int *caps, char *binary)
}
static int
bhyveProbeCapsVirtioRnd(unsigned int *caps, char *binary)
{
return bhyveProbeCapsDeviceHelper(caps, binary,
"-s",
"0,virtio-rnd",
"pci slot 0:0: unknown device \"virtio-rnd\"",
BHYVE_CAP_VIRTIO_RND);
}
int
virBhyveProbeCaps(unsigned int *caps)
{
@ -386,9 +364,6 @@ virBhyveProbeCaps(unsigned int *caps)
if ((ret = bhyveProbeCapsVirtio9p(caps, binary)))
goto out;
if ((ret = bhyveProbeCapsVirtioRnd(caps, binary)))
goto out;
out:
VIR_FREE(binary);
return ret;

View File

@ -2,7 +2,6 @@
* bhyve_capabilities.h: bhyve capabilities module
*
* Copyright (C) 2014 Semihalf
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -53,7 +52,6 @@ typedef enum {
BHYVE_CAP_SOUND_HDA = 1 << 7,
BHYVE_CAP_VNC_PASSWORD = 1 << 8,
BHYVE_CAP_VIRTIO_9P = 1 << 9,
BHYVE_CAP_VIRTIO_RND = 1 << 10,
} virBhyveCapsFlags;
int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);

View File

@ -2,7 +2,6 @@
* bhyve_command.c: bhyve command generation
*
* Copyright (C) 2014 Roman Bogorodskiy
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -27,7 +26,6 @@
#include "bhyve_domain.h"
#include "bhyve_conf.h"
#include "bhyve_driver.h"
#include "domain_validate.h"
#include "datatypes.h"
#include "viralloc.h"
#include "virfile.h"
@ -54,7 +52,6 @@ bhyveBuildNetArgStr(const virDomainDef *def,
char *nic_model = NULL;
int ret = -1;
virDomainNetType actualType = virDomainNetGetActualType(net);
g_autoptr(virConnect) netconn = NULL;
if (net->model == VIR_DOMAIN_NET_MODEL_VIRTIO) {
nic_model = g_strdup("virtio-net");
@ -72,43 +69,12 @@ bhyveBuildNetArgStr(const virDomainDef *def,
return -1;
}
if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
if (!netconn && !(netconn = virGetConnectNetwork()))
goto cleanup;
if (virDomainNetAllocateActualDevice(netconn, def, net) < 0)
goto cleanup;
}
/* final validation now that actual type is known */
if (virDomainActualNetDefValidate(net) < 0)
return -1;
switch (actualType) {
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_BRIDGE:
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
brname = g_strdup(virDomainNetGetActualBridgeName(net));
if (!brname) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No bridge name specified"));
goto cleanup;
}
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_VDPA:
case VIR_DOMAIN_NET_TYPE_NULL:
case VIR_DOMAIN_NET_TYPE_VDS:
case VIR_DOMAIN_NET_TYPE_LAST:
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported network type %1$s"),
virDomainNetTypeToString(actualType));
_("Network type %1$d is not supported"),
virDomainNetGetActualType(net));
goto cleanup;
}
@ -186,24 +152,6 @@ bhyveBuildConsoleArgStr(const virDomainDef *def, virCommand *cmd)
return 0;
}
static int
bhyveBuildRNGArgStr(const virDomainDef *def G_GNUC_UNUSED,
virDomainRNGDef *rng,
virCommand *cmd)
{
if (rng->backend != VIR_DOMAIN_RNG_BACKEND_RANDOM) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("RNG backend is not supported"));
return -1;
}
virCommandAddArg(cmd, "-s");
virCommandAddArgFormat(cmd, "%d:%d,virtio-rnd",
rng->info.addr.pci.slot,
rng->info.addr.pci.function);
return 0;
}
static int
bhyveBuildAHCIControllerArgStr(const virDomainDef *def,
virDomainControllerDef *controller,
@ -859,10 +807,6 @@ virBhyveProcessBuildBhyveCmd(struct _bhyveConn *driver, virDomainDef *def,
if (bhyveBuildConsoleArgStr(def, cmd) < 0)
return NULL;
for (i = 0; i < def->nrngs; i++)
if (bhyveBuildRNGArgStr(def, def->rngs[i], cmd) < 0)
return NULL;
if (def->namespaceData) {
bhyveDomainCmdlineDef *bhyvecmd;

View File

@ -2,7 +2,6 @@
* bhyve_device.c: bhyve device management
*
* Copyright (C) 2014 Roman Bogorodskiy
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -185,16 +184,6 @@ bhyveAssignDevicePCISlots(virDomainDef *def,
return -1;
}
for (i = 0; i < def->nrngs; i++) {
if (!virDeviceInfoPCIAddressIsWanted(&def->rngs[i]->info))
continue;
if (virDomainPCIAddressReserveNextAddr(addrs,
&def->rngs[i]->info,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
-1) < 0)
return -1;
}
return 0;
}

View File

@ -2,7 +2,6 @@
* bhyve_domain.c: bhyve domain private state
*
* Copyright (C) 2014 Roman Bogorodskiy
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -244,26 +243,6 @@ bhyveDomainDeviceDefValidate(const virDomainDeviceDef *dev,
return -1;
}
if (dev->type == VIR_DOMAIN_DEVICE_RNG) {
if (dev->data.rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO) {
if (dev->data.rng->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM) {
if (STRNEQ(dev->data.rng->source.file, "/dev/random")) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Only /dev/random source is supported"));
return -1;
}
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Only 'random' backend model is supported"));
return -1;
}
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Only 'virio' RNG device model is supported"));
return -1;
}
}
return 0;
}

View File

@ -5,7 +5,6 @@
* Copyright (C) 2006 Daniel P. Berrange
* Copyright (c) 2011 NetApp, Inc.
* Copyright (C) 2020 Fabian Freyer
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -640,32 +639,6 @@ bhyveParsePCIFbuf(virDomainDef *def,
return -1;
}
static int
bhyveParsePCIRND(virDomainDef *def,
virDomainXMLOption *xmlopt G_GNUC_UNUSED,
unsigned caps G_GNUC_UNUSED,
unsigned bus,
unsigned slot,
unsigned function,
const char *config G_GNUC_UNUSED)
{
/* -s slot,virtio-rnd */
virDomainRNGDef *rng = g_new0(virDomainRNGDef, 1);
rng->model = VIR_DOMAIN_RNG_MODEL_VIRTIO;
rng->backend = VIR_DOMAIN_RNG_BACKEND_RANDOM;
rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
rng->info.addr.pci.bus = bus;
rng->info.addr.pci.slot = slot;
rng->info.addr.pci.function = function;
rng->source.file = g_strdup("/dev/random");
VIR_APPEND_ELEMENT(def->rngs, def->nrngs, rng);
return 0;
}
static int
bhyveParseBhyvePCIArg(virDomainDef *def,
virDomainXMLOption *xmlopt,
@ -730,8 +703,6 @@ bhyveParseBhyvePCIArg(virDomainDef *def,
VIR_DOMAIN_NET_MODEL_E1000, conf);
else if (STREQ(emulation, "fbuf"))
bhyveParsePCIFbuf(def, xmlopt, caps, bus, slot, function, conf);
else if (STREQ(emulation, "virtio-rnd"))
bhyveParsePCIRND(def, xmlopt, caps, bus, slot, function, conf);
VIR_FREE(emulation);
VIR_FREE(slotdef);

View File

@ -2,7 +2,6 @@
* bhyve_process.c: bhyve process management
*
* Copyright (C) 2014 Roman Bogorodskiy
* Copyright (C) 2025 The FreeBSD Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -72,23 +71,18 @@ static void
bhyveNetCleanup(virDomainObj *vm)
{
size_t i;
g_autoptr(virConnect) conn = NULL;
for (i = 0; i < vm->def->nnets; i++) {
virDomainNetDef *net = vm->def->nets[i];
virDomainNetType actualType = virDomainNetGetActualType(net);
if (net->ifname) {
ignore_value(virNetDevBridgeRemovePort(
virDomainNetGetActualBridgeName(net),
net->ifname));
ignore_value(virNetDevTapDelete(net->ifname, NULL));
}
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
if (conn || (conn = virGetConnectNetwork()))
virDomainNetReleaseActualDevice(conn, net);
else
VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname));
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
if (net->ifname) {
ignore_value(virNetDevBridgeRemovePort(
virDomainNetGetActualBridgeName(net),
net->ifname));
ignore_value(virNetDevTapDelete(net->ifname, NULL));
}
}
}
}
@ -443,8 +437,6 @@ virBhyveProcessReconnect(virDomainObj *vm,
char **proc_argv;
char *expected_proctitle = NULL;
bhyveDomainObjPrivate *priv = vm->privateData;
g_autoptr(virConnect) conn = NULL;
size_t i;
int ret = -1;
if (!virDomainObjIsActive(vm))
@ -477,14 +469,6 @@ virBhyveProcessReconnect(virDomainObj *vm,
}
}
for (i = 0; i < vm->def->nnets; i++) {
virDomainNetDef *net = vm->def->nets[i];
if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK && !conn)
conn = virGetConnectNetwork();
virDomainNetNotifyActualDevice(conn, vm->def, net);
}
cleanup:
if (ret < 0) {
/* If VM is reported to be in active state, but we cannot find

View File

@ -68,7 +68,6 @@ virCHDomainObjPrivateFree(void *data)
virBitmapFree(priv->autoCpuset);
virBitmapFree(priv->autoNodeset);
virCgroupFree(priv->cgroup);
g_free(priv->pidfile);
g_free(priv);
}

View File

@ -36,7 +36,6 @@ struct _virCHDomainObjPrivate {
virBitmap *autoCpuset;
virBitmap *autoNodeset;
virCgroup *cgroup;
char *pidfile;
};
#define CH_DOMAIN_PRIVATE(vm) \

View File

@ -54,10 +54,10 @@ static int
virCHEventStopProcess(virDomainObj *vm,
virDomainShutoffReason reason)
{
virCHDriver *driver = CH_DOMAIN_PRIVATE(vm)->driver;
virCHDriver *driver = ((virCHDomainObjPrivate *)vm->privateData)->driver;
virObjectLock(vm);
if (virDomainObjBeginJob(vm, VIR_JOB_DESTROY))
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY))
return -1;
virCHProcessStop(driver, vm, reason);
virDomainObjEndJob(vm);
@ -97,6 +97,7 @@ virCHProcessEvent(virCHMonitor *mon,
case VIR_CH_EVENT_VM_BOOTING:
case VIR_CH_EVENT_VM_BOOTED:
case VIR_CH_EVENT_VM_REBOOTING:
case VIR_CH_EVENT_VM_REBOOTED:
case VIR_CH_EVENT_VM_PAUSING:
case VIR_CH_EVENT_VM_PAUSED:
case VIR_CH_EVENT_VM_RESUMING:
@ -108,16 +109,15 @@ virCHProcessEvent(virCHMonitor *mon,
case VIR_CH_EVENT_VM_DELETED:
break;
case VIR_CH_EVENT_VMM_SHUTDOWN:
case VIR_CH_EVENT_VM_SHUTDOWN:
if (virCHEventStopProcess(vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN)) {
VIR_WARN("Failed to mark the VM(%s) as SHUTDOWN!",
vm->def->name);
ret = -1;
}
break;
case VIR_CH_EVENT_VM_REBOOTED:
case VIR_CH_EVENT_VM_SHUTDOWN:
virObjectLock(vm);
virCHProcessUpdateInfo(vm);
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
virObjectUnlock(vm);
break;
case VIR_CH_EVENT_LAST:
@ -297,7 +297,7 @@ int
virCHStartEventHandler(virCHMonitor *mon)
{
g_autofree char *name = NULL;
name = g_strdup_printf("ch-evt-%d", mon->vm->pid);
name = g_strdup_printf("ch-evt-%d", mon->pid);
virObjectRef(mon);
if (virThreadCreateFull(&mon->event_handler_thread,

View File

@ -27,7 +27,6 @@
#include "datatypes.h"
#include "ch_conf.h"
#include "ch_domain.h"
#include "ch_events.h"
#include "ch_interface.h"
#include "ch_monitor.h"
@ -38,7 +37,6 @@
#include "virfile.h"
#include "virjson.h"
#include "virlog.h"
#include "virpidfile.h"
#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_CH
@ -156,7 +154,7 @@ virCHMonitorBuildPayloadJson(virJSONValue *content, virDomainDef *vmdef)
buf = g_base64_decode(vmdef->sec->data.sev_snp.host_data, &len);
if (len != host_data_len) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Invalid host_data provided. Expected '%1$zu' bytes"),
_("Invalid host_data provided. Expected '%1$ld' bytes"),
host_data_len);
return -1;
}
@ -584,12 +582,10 @@ chMonitorCreateSocket(const char *socket_path)
virCHMonitor *
virCHMonitorNew(virDomainObj *vm, virCHDriverConfig *cfg, int logfile)
{
virCHDomainObjPrivate *priv = vm->privateData;
g_autoptr(virCHMonitor) mon = NULL;
g_autoptr(virCommand) cmd = NULL;
int socket_fd = 0;
int event_monitor_fd;
int rv;
if (virCHMonitorInitialize() < 0)
return NULL;
@ -648,7 +644,6 @@ virCHMonitorNew(virDomainObj *vm, virCHDriverConfig *cfg, int logfile)
virCommandSetErrorFD(cmd, &logfile);
virCommandNonblockingFDs(cmd);
virCommandSetUmask(cmd, 0x002);
socket_fd = chMonitorCreateSocket(mon->socketpath);
if (socket_fd < 0) {
virReportSystemError(errno,
@ -660,26 +655,13 @@ virCHMonitorNew(virDomainObj *vm, virCHDriverConfig *cfg, int logfile)
virCommandAddArg(cmd, "--api-socket");
virCommandAddArgFormat(cmd, "fd=%d", socket_fd);
virCommandPassFD(cmd, socket_fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
virCommandAddArg(cmd, "--event-monitor");
virCommandAddArgFormat(cmd, "path=%s", mon->eventmonitorpath);
virCommandSetPidFile(cmd, priv->pidfile);
virCommandDaemonize(cmd);
/* launch Cloud-Hypervisor socket */
if (virCommandRun(cmd, NULL) < 0) {
VIR_DEBUG("CH vm=%p name=%s failed to spawn",
vm, vm->def->name);
if (virCommandRunAsync(cmd, &mon->pid) < 0)
return NULL;
}
if ((rv = virPidFileReadPath(priv->pidfile, &vm->pid)) < 0) {
virReportSystemError(-rv,
_("Domain %1$s didn't show up"),
vm->def->name);
return NULL;
}
VIR_DEBUG("CH vm=%p name=%s running with pid=%lld",
vm, vm->def->name, (long long)vm->pid);
/* open the reader end of fifo before start Event Handler */
while ((event_monitor_fd = open(mon->eventmonitorpath, O_RDONLY)) < 0) {
@ -727,6 +709,12 @@ void virCHMonitorClose(virCHMonitor *mon)
if (!mon)
return;
if (mon->pid > 0) {
/* try cleaning up the Cloud-Hypervisor process */
virProcessAbort(mon->pid);
mon->pid = 0;
}
if (mon->handle)
curl_easy_cleanup(mon->handle);
@ -1139,7 +1127,7 @@ virCHMonitorBuildRestoreJson(virDomainDef *vmdef,
g_autoptr(virJSONValue) nets = virJSONValueNewArray();
for (i = 0; i < vmdef->nnets; i++) {
g_autoptr(virJSONValue) net_json = virJSONValueNewObject();
g_autofree char *id = g_strdup_printf("%s_%zu", CH_NET_ID_PREFIX, i);
g_autofree char *id = g_strdup_printf("%s_%ld", CH_NET_ID_PREFIX, i);
if (virJSONValueObjectAppendString(net_json, "id", id) < 0)
return -1;
if (virJSONValueObjectAppendNumberInt(net_json, "num_fds", vmdef->nets[i]->driver.virtio.queues))
@ -1208,7 +1196,10 @@ virCHMonitorGetIOThreads(virCHMonitor *mon,
if (!(map = virProcessGetAffinity(iothreadinfo->iothread_id)))
goto error;
virBitmapToData(map, &(iothreadinfo->cpumap), &(iothreadinfo->cpumaplen));
if (virBitmapToData(map, &(iothreadinfo->cpumap),
&(iothreadinfo->cpumaplen)) < 0) {
goto error;
}
/* Append to iothreadinfolist */
iothreadinfolist[niothreads] = g_steal_pointer(&iothreadinfo);

View File

@ -108,6 +108,8 @@ struct _virCHMonitor {
size_t buf_fill_sz;
} event_buffer;
pid_t pid;
virDomainObj *vm;
size_t nthreads;

View File

@ -36,7 +36,6 @@
#include "virjson.h"
#include "virlog.h"
#include "virnuma.h"
#include "virpidfile.h"
#include "virstring.h"
#include "ch_interface.h"
#include "ch_hostdev.h"
@ -131,7 +130,7 @@ virCHProcessUpdateConsole(virDomainObj *vm,
virCHProcessUpdateConsoleDevice(vm, config, "serial");
}
int
static int
virCHProcessUpdateInfo(virDomainObj *vm)
{
g_autoptr(virJSONValue) info = NULL;
@ -430,8 +429,8 @@ virCHProcessSetupVcpus(virDomainObj *vm)
size_t i;
if ((vm->def->cputune.period || vm->def->cputune.quota) &&
!virCgroupHasController(CH_DOMAIN_PRIVATE(vm)->cgroup,
VIR_CGROUP_CONTROLLER_CPU)) {
!virCgroupHasController(((virCHDomainObjPrivate *) vm->privateData)->
cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("cgroup cpu is required for scheduler tuning"));
return -1;
@ -701,7 +700,7 @@ chProcessAddNetworkDevices(virCHDriver *driver,
VIR_DEBUG("payload sent with net-add request to CH = %s", payload);
virBufferAsprintf(&buf, "%s", virBufferCurrentContent(&http_headers));
virBufferAsprintf(&buf, "Content-Length: %zu\r\n\r\n", strlen(payload));
virBufferAsprintf(&buf, "Content-Length: %ld\r\n\r\n", strlen(payload));
virBufferAsprintf(&buf, "%s", payload);
payload_len = virBufferUse(&buf);
payload = virBufferContentAndReset(&buf);
@ -851,21 +850,6 @@ virCHProcessPrepareHost(virCHDriver *driver, virDomainObj *vm)
if (virCHHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0)
return -1;
VIR_FREE(priv->pidfile);
if (!(priv->pidfile = virPidFileBuildPath(cfg->stateDir, vm->def->name))) {
virReportSystemError(errno, "%s",
_("Failed to build pidfile path."));
return -1;
}
if (unlink(priv->pidfile) < 0 &&
errno != ENOENT) {
virReportSystemError(errno,
_("Cannot remove stale PID file %1$s"),
priv->pidfile);
return -1;
}
/* Ensure no historical cgroup for this VM is lying around */
VIR_DEBUG("Ensuring no historical cgroup is lying around");
virDomainCgroupRemoveCgroup(vm, priv->cgroup, priv->machineName);
@ -957,6 +941,7 @@ virCHProcessStart(virCHDriver *driver,
}
}
vm->pid = priv->monitor->pid;
vm->def->id = vm->pid;
priv->machineName = virCHDomainGetMachineName(vm);
@ -1023,7 +1008,6 @@ virCHProcessStop(virCHDriver *driver,
virErrorPreserveLast(&orig_err);
if (priv->monitor) {
virProcessAbort(vm->pid);
g_clear_pointer(&priv->monitor, virCHMonitorClose);
}
@ -1051,15 +1035,6 @@ virCHProcessStop(virCHDriver *driver,
vm->def->id = -1;
g_clear_pointer(&priv->machineName, g_free);
if (priv->pidfile) {
if (unlink(priv->pidfile) < 0 &&
errno != ENOENT)
VIR_WARN("Failed to remove PID file for %s: %s",
vm->def->name, g_strerror(errno));
g_clear_pointer(&priv->pidfile, g_free);
}
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
virHostdevReAttachDomainDevices(driver->hostdevMgr, CH_DRIVER_NAME, def,
@ -1117,6 +1092,7 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from
}
}
vm->pid = priv->monitor->pid;
vm->def->id = vm->pid;
priv->machineName = virCHDomainGetMachineName(vm);
@ -1130,7 +1106,7 @@ virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from
virBufferAddLit(&http_headers, "Host: localhost\r\n");
virBufferAddLit(&http_headers, "Content-Type: application/json\r\n");
virBufferAsprintf(&buf, "%s", virBufferCurrentContent(&http_headers));
virBufferAsprintf(&buf, "Content-Length: %zu\r\n\r\n", strlen(payload));
virBufferAsprintf(&buf, "Content-Length: %ld\r\n\r\n", strlen(payload));
virBufferAsprintf(&buf, "%s", payload);
payload_len = virBufferUse(&buf);
payload = virBufferContentAndReset(&buf);

View File

@ -36,5 +36,3 @@ int virCHProcessSetupVcpu(virDomainObj *vm,
int virCHProcessStartRestore(virCHDriver *driver,
virDomainObj *vm,
const char *from);
int virCHProcessUpdateInfo(virDomainObj *vm);

View File

@ -228,7 +228,7 @@ virDomainBackupDefParseXML(xmlXPathContextPtr ctxt,
def->server = g_new0(virStorageNetHostDef, 1);
if (virDomainStorageNetworkParseHost(node, def->server, true) < 0)
if (virDomainStorageNetworkParseHost(node, def->server) < 0)
return NULL;
if (def->server->transport == VIR_STORAGE_NET_HOST_TRANS_RDMA) {
@ -388,7 +388,6 @@ virDomainBackupDefFormat(virBuffer *buf,
if (def->server->port)
virBufferAsprintf(&serverAttrBuf, " port='%u'", def->server->port);
virBufferEscapeString(&serverAttrBuf, " socket='%s'", def->server->socket);
virBufferEscapeString(&serverAttrBuf, " fdgroup='%s'", def->server->fdgroup);
}
virXMLFormatElement(&childBuf, "server", &serverAttrBuf, NULL);

View File

@ -6014,81 +6014,58 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
int
virDomainStorageNetworkParseHost(xmlNodePtr hostnode,
virStorageNetHostDef *host,
bool allow_fd)
virStorageNetHostDef *host)
{
g_autofree char *socket = NULL;
int ret = -1;
g_autofree char *transport = NULL;
g_autofree char *port = NULL;
memset(host, 0, sizeof(*host));
if (virXMLPropEnumDefault(hostnode, "transport",
virStorageNetHostTransportTypeFromString,
VIR_XML_PROP_NONE,
&host->transport,
VIR_STORAGE_NET_HOST_TRANS_TCP) < 0)
return -1;
VIR_STORAGE_NET_HOST_TRANS_TCP) < 0) {
goto cleanup;
}
socket = virXMLPropString(hostnode, "socket");
host->socket = virXMLPropString(hostnode, "socket");
switch (host->transport) {
case VIR_STORAGE_NET_HOST_TRANS_UNIX:
if (!socket) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing socket for unix transport"));
return -1;
}
if (host->transport == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
host->socket == NULL) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing socket for unix transport"));
goto cleanup;
}
host->socket = g_steal_pointer(&socket);
break;
case VIR_STORAGE_NET_HOST_TRANS_TCP:
case VIR_STORAGE_NET_HOST_TRANS_RDMA: {
g_autofree char *portstr = NULL;
unsigned int port = 0;
if (socket) {
virReportError(VIR_ERR_XML_ERROR,
_("transport '%1$s' does not support socket attribute"),
virStorageNetHostTransportTypeToString(host->transport));
return -1;
}
if ((portstr = virXMLPropString(hostnode, "port")) &&
virStringParsePort(portstr, &port) < 0)
return -1;
if (host->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX &&
host->socket != NULL) {
virReportError(VIR_ERR_XML_ERROR,
_("transport '%1$s' does not support socket attribute"),
transport);
goto cleanup;
}
if (host->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
if (!(host->name = virXMLPropString(hostnode, "name"))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing name for host"));
return -1;
goto cleanup;
}
host->port = port;
}
break;
case VIR_STORAGE_NET_HOST_TRANS_FD:
if (!allow_fd) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("transport 'fd' is now allowed"));
return -1;
if ((port = virXMLPropString(hostnode, "port"))) {
if (virStringParsePort(port, &host->port) < 0)
goto cleanup;
}
if (socket) {
virReportError(VIR_ERR_XML_ERROR,
_("transport '%1$s' does not support socket attribute"),
virStorageNetHostTransportTypeToString(host->transport));
return -1;
}
if (!(host->fdgroup = virXMLPropStringRequired(hostnode, "fdgroup")))
return -1;
break;
case VIR_STORAGE_NET_HOST_TRANS_LAST:
break;
}
return 0;
ret = 0;
cleanup:
if (ret < 0)
virStorageNetHostDefClear(host);
return ret;
}
@ -6112,7 +6089,7 @@ virDomainStorageNetworkParseHosts(xmlNodePtr node,
*nhosts = nhostnodes;
for (i = 0; i < nhostnodes; i++) {
if (virDomainStorageNetworkParseHost(hostnodes[i], *hosts + i, false) < 0)
if (virDomainStorageNetworkParseHost(hostnodes[i], *hosts + i) < 0)
return -1;
}
@ -31002,7 +30979,7 @@ virDomainNetTypeSharesHostView(const virDomainNetDef *net)
}
virNetworkPortDef *
virDomainNetDefToNetworkPort(const virDomainDef *dom,
virDomainNetDefToNetworkPort(virDomainDef *dom,
virDomainNetDef *iface)
{
g_autoptr(virNetworkPortDef) port = NULL;
@ -31128,7 +31105,7 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDef *iface,
}
virNetworkPortDef *
virDomainNetDefActualToNetworkPort(const virDomainDef *dom,
virDomainNetDefActualToNetworkPort(virDomainDef *dom,
virDomainNetDef *iface)
{
virDomainActualNetDef *actual;
@ -31240,7 +31217,7 @@ virDomainNetDefActualToNetworkPort(const virDomainDef *dom,
static int
virDomainNetCreatePort(virConnectPtr conn,
const virDomainDef *dom,
virDomainDef *dom,
virDomainNetDef *iface,
unsigned int flags)
{
@ -31305,7 +31282,7 @@ virDomainNetCreatePort(virConnectPtr conn,
int
virDomainNetAllocateActualDevice(virConnectPtr conn,
const virDomainDef *dom,
virDomainDef *dom,
virDomainNetDef *iface)
{
return virDomainNetCreatePort(conn, dom, iface, 0);
@ -31313,7 +31290,7 @@ virDomainNetAllocateActualDevice(virConnectPtr conn,
void
virDomainNetNotifyActualDevice(virConnectPtr conn,
const virDomainDef *dom,
virDomainDef *dom,
virDomainNetDef *iface)
{
virDomainNetType actualType = virDomainNetGetActualType(iface);

View File

@ -4024,8 +4024,7 @@ virDomainDiskByTarget(virDomainDef *def,
void virDomainDiskInsert(virDomainDef *def, virDomainDiskDef *disk);
int virDomainStorageNetworkParseHost(xmlNodePtr hostnode,
virStorageNetHostDef *host,
bool allow_fd);
virStorageNetHostDef *host);
int virDomainDiskDefAssignAddress(virDomainXMLOption *xmlopt,
virDomainDiskDef *def,
const virDomainDef *vmdef);
@ -4531,7 +4530,7 @@ virDomainDefLifecycleActionAllowed(virDomainLifecycle type,
virDomainLifecycleAction action);
virNetworkPortDef *
virDomainNetDefToNetworkPort(const virDomainDef *dom,
virDomainNetDefToNetworkPort(virDomainDef *dom,
virDomainNetDef *iface);
int
@ -4539,18 +4538,18 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDef *iface,
virNetworkPortDef *port);
virNetworkPortDef *
virDomainNetDefActualToNetworkPort(const virDomainDef *dom,
virDomainNetDefActualToNetworkPort(virDomainDef *dom,
virDomainNetDef *iface);
int
virDomainNetAllocateActualDevice(virConnectPtr conn,
const virDomainDef *dom,
virDomainDef *dom,
virDomainNetDef *iface)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void
virDomainNetNotifyActualDevice(virConnectPtr conn,
const virDomainDef *dom,
virDomainDef *dom,
virDomainNetDef *iface)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);

View File

@ -562,7 +562,7 @@ virDomainDiskDefValidateSourceChainOne(const virStorageSource *src)
return -1;
}
if (src->dataFileStore->dataFileStore || src->dataFileStore->backingStore) {
if (src->dataFileStore->dataFileStore || src->backingStore) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("The <source> of <dataStore> can't have another nested <dataStore> or <backingStore> element"));
return -1;

View File

@ -90,12 +90,6 @@
<ref name="absFilePath"/>
</attribute>
</group>
<group>
<attribute name="transport">
<value>fd</value>
</attribute>
<attribute name="fdgroup"/>
</group>
</choice>
</element>
<ref name="backupDisksPull"/>

View File

@ -1409,8 +1409,6 @@ virStorageVolDefParse(virStoragePoolDef *pool,
"volume", &ctxt, "storagevol.rng", validate)))
return NULL;
flags &= ~VIR_VOL_XML_PARSE_VALIDATE;
return virStorageVolDefParseXML(pool, ctxt, flags);
}

View File

@ -97,7 +97,6 @@ VIR_ENUM_IMPL(virStorageNetHostTransport,
"tcp",
"unix",
"rdma",
"fd",
);
@ -142,6 +141,17 @@ virStorageSourceHasBacking(const virStorageSource *src)
}
void
virStorageNetHostDefClear(virStorageNetHostDef *def)
{
if (!def)
return;
VIR_FREE(def->name);
VIR_FREE(def->socket);
}
void
virStorageNetHostDefFree(size_t nhosts,
virStorageNetHostDef *hosts)
@ -151,12 +161,8 @@ virStorageNetHostDefFree(size_t nhosts,
if (!hosts)
return;
for (i = 0; i < nhosts; i++) {
g_free(hosts[i].name);
g_free(hosts[i].socket);
g_free(hosts[i].fdgroup);
g_free(hosts[i].qemu_fdname);
}
for (i = 0; i < nhosts; i++)
virStorageNetHostDefClear(&hosts[i]);
g_free(hosts);
}

View File

@ -141,7 +141,6 @@ typedef enum {
VIR_STORAGE_NET_HOST_TRANS_TCP,
VIR_STORAGE_NET_HOST_TRANS_UNIX,
VIR_STORAGE_NET_HOST_TRANS_RDMA,
VIR_STORAGE_NET_HOST_TRANS_FD,
VIR_STORAGE_NET_HOST_TRANS_LAST
} virStorageNetHostTransport;
@ -155,9 +154,6 @@ struct _virStorageNetHostDef {
unsigned int port;
virStorageNetHostTransport transport;
char *socket; /* path to unix socket */
char *fdgroup;
char *qemu_fdname; /* name used with 'getfd' to pass to qemu - internal */
};
@ -506,6 +502,9 @@ virSecurityDeviceLabelDef *
virStorageSourceGetSecurityLabelDef(virStorageSource *src,
const char *model);
void
virStorageNetHostDefClear(virStorageNetHostDef *def);
void
virStorageNetHostDefFree(size_t nhosts,
virStorageNetHostDef *hosts);

View File

@ -1,7 +1,5 @@
cpumap_data = [
'arm_a64fx.xml',
'arm_Ampere-1a.xml',
'arm_Ampere-1.xml',
'arm_cortex-a53.xml',
'arm_cortex-a57.xml',
'arm_cortex-a72.xml',

View File

@ -687,9 +687,7 @@ esxConnectToVCenter(esxPrivate *priv,
g_autofree char *url = NULL;
if (!hostSystemIPAddress &&
(!priv->parsedUri->path ||
STREQ(priv->parsedUri->path, "") ||
STREQ(priv->parsedUri->path, "/"))) {
(!priv->parsedUri->path || STREQ(priv->parsedUri->path, "/"))) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("Path has to specify the datacenter and compute resource"));
return -1;
@ -801,7 +799,6 @@ esxConnectOpen(virConnectPtr conn, virConnectAuthPtr auth,
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
if (STRCASENEQ(conn->uri->scheme, "vpx") &&
STRNEQ(conn->uri->path, "") &&
STRNEQ(conn->uri->path, "/")) {
VIR_WARN("Ignoring unexpected path '%s' for non-vpx scheme '%s'",
conn->uri->path, conn->uri->scheme);
@ -4795,20 +4792,18 @@ esxConnectListAllDomains(virConnectPtr conn,
virtualMachine = virtualMachine->_next) {
g_autofree char *name = NULL;
/* If the lookup of the required properties fails for some of the machines
* in the list it's preferrable to return the valid objects instead of
* failing outright */
if ((needIdentity && esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, uuid) < 0) ||
(needPowerState && esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0)) {
/* Raise error only if we didn't successfuly fill any domain */
if (count == 0 && !virtualMachine->_next)
if (needIdentity) {
if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id,
&name, uuid) < 0) {
goto cleanup;
}
}
/* failure to fetch information of a single VM must not interrupt
* the lookup of the rest */
virResetLastError();
continue;
if (needPowerState) {
if (esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
goto cleanup;
}
}
/* filter by active state */

View File

@ -652,7 +652,9 @@ virDomainDriverGetIOThreadsConfig(virDomainDef *targetDef,
cpumask = bitmap;
}
}
virBitmapToData(cpumask, &info_ret[i]->cpumap, &info_ret[i]->cpumaplen);
if (virBitmapToData(cpumask, &info_ret[i]->cpumap,
&info_ret[i]->cpumaplen) < 0)
goto cleanup;
}
*info = g_steal_pointer(&info_ret);

View File

@ -410,20 +410,17 @@ virConnectGetMaxVcpus(virConnectPtr conn,
* Use of this API is strongly discouraged as the information provided
* is not guaranteed to be accurate on all hardware platforms.
*
* The CPU frequency value (field 'mhz' in virNodeInfo) merely reflects the
* speed that the first CPU in the machine is currently running at. This speed
* may vary across CPUs and changes continually as the host OS throttles.
* The mHZ value merely reflects the speed that the first CPU in the
* machine is currently running at. This speed may vary across CPUs
* and changes continually as the host OS throttles.
*
* The virNodeInfo structure is not extensible thus only supports global
* nodes/sockets/cores/threads (sockets/cores/threads is per NUMA node)
* topology information. If the host CPU has any further groupings (e.g.
* dies, clusters, etc) or the NUMA topology is non-symmetrical the structure
* can't faithfully represent the system. In such cases a fake topology
* (nodes = 1, sockets = 1, cores = number of host cpus, threads = 1) which
* only correctly represents the total host CPU count is reported.
* The nodes/sockets/cores/threads data is potentially inaccurate as
* it assumes a symmetric installation. If one NUMA node has more
* sockets populated that another NUMA node this information will be
* wrong. It is also not able to report about CPU dies.
*
* Applications are recommended to use the virConnectGetCapabilities()
* call instead, which provides all the information except CPU frequency,
* call instead, which provides all the information except CPU mHZ,
* in a more accurate representation.
*
* Returns 0 in case of success and -1 in case of failure.

View File

@ -1153,6 +1153,7 @@ virStorageFileFeatureTypeFromString;
virStorageFileFeatureTypeToString;
virStorageFileFormatTypeFromString;
virStorageFileFormatTypeToString;
virStorageNetHostDefClear;
virStorageNetHostDefCopy;
virStorageNetHostDefFree;
virStorageNetHostTransportTypeFromString;

View File

@ -582,107 +582,6 @@ libxlMakeDomBuildInfo(virDomainDef *def,
VIR_TRISTATE_SWITCH_ON);
#endif
#ifdef LIBXL_HAVE_BUILDINFO_HVM_VIRIDIAN_ENABLE_DISABLE
if (def->features[VIR_DOMAIN_FEATURE_HYPERV] != VIR_DOMAIN_HYPERV_MODE_NONE) {
libxl_bitmap_alloc(ctx, &b_info->u.hvm.viridian_enable,
LIBXL_BUILDINFO_HVM_VIRIDIAN_ENABLE_DISABLE_WIDTH);
switch ((virDomainHyperVMode) def->features[VIR_DOMAIN_FEATURE_HYPERV]) {
case VIR_DOMAIN_HYPERV_MODE_CUSTOM:
/* Base is required by Xen to enable any other flag */
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_BASE);
/* Enable crash ctl register by default to allow guest logs to reach Xen */
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_CRASH_CTL);
break;
case VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH:
libxl_bitmap_set_any(&b_info->u.hvm.viridian_enable);
break;
case VIR_DOMAIN_HYPERV_MODE_NONE:
case VIR_DOMAIN_HYPERV_MODE_LAST:
default:
virReportEnumRangeError(virDomainHyperVMode,
def->features[VIR_DOMAIN_FEATURE_HYPERV]);
return -1;
}
for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_VPINDEX:
case VIR_DOMAIN_HYPERV_RELAXED:
/* Already set by base flag */
break;
case VIR_DOMAIN_HYPERV_SYNIC:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_SYNIC);
}
break;
case VIR_DOMAIN_HYPERV_STIMER:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
/* STIMER implies synic and clock features */
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_STIMER);
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_SYNIC);
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_TIME_REF_COUNT);
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_REFERENCE_TSC);
}
break;
case VIR_DOMAIN_HYPERV_VAPIC:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_APIC_ASSIST);
}
break;
case VIR_DOMAIN_HYPERV_FREQUENCIES:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_FREQ);
}
break;
case VIR_DOMAIN_HYPERV_TLBFLUSH:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_HCALL_REMOTE_TLB_FLUSH);
}
break;
case VIR_DOMAIN_HYPERV_IPI:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
libxl_bitmap_set(&b_info->u.hvm.viridian_enable,
LIBXL_VIRIDIAN_ENLIGHTENMENT_HCALL_IPI);
}
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
case VIR_DOMAIN_HYPERV_VENDOR_ID:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
const char *name = virDomainHypervTypeToString(i);
VIR_WARN("Hyper-v flag '%s' specified per-domain but is a global Xen setting and will be ignored.", name);
}
break;
case VIR_DOMAIN_HYPERV_RUNTIME:
case VIR_DOMAIN_HYPERV_RESET:
case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
case VIR_DOMAIN_HYPERV_EVMCS:
case VIR_DOMAIN_HYPERV_AVIC:
case VIR_DOMAIN_HYPERV_EMSR_BITMAP:
case VIR_DOMAIN_HYPERV_XMM_INPUT:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) {
const char *name = virDomainHypervTypeToString(i);
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Hyper-v enlightenment feature '%1$s' is not supported for Xen domains."), name);
}
break;
case VIR_DOMAIN_HYPERV_LAST:
break;
}
}
}
#endif
/* copy the table path to acpi_firmware */
if (def->os.nacpiTables)
b_info->u.hvm.acpi_firmware = g_strdup(def->os.acpiTables[0]->path);

View File

@ -710,8 +710,7 @@ networkStateInitialize(bool privileged,
network_driver->networkEventState = virObjectEventStateNew();
#ifdef WITH_FIREWALLD
if (!virGDBusHasSystemBus() ||
!(sysbus = virGDBusGetSystemBus())) {
if (!(sysbus = virGDBusGetSystemBus())) {
VIR_WARN("DBus not available, disabling firewalld support "
"in bridge_network_driver: %s", virGetLastErrorMessage());
} else {

View File

@ -203,12 +203,12 @@ virNWFilterInstReset(virNWFilterInst *inst)
for (i = 0; i < inst->nfilters; i++)
virNWFilterObjUnlock(inst->filters[i]);
g_clear_pointer(&inst->filters, g_free);
g_free(inst->filters);
inst->nfilters = 0;
for (i = 0; i < inst->nrules; i++)
virNWFilterRuleInstFree(inst->rules[i]);
g_clear_pointer(&inst->rules, g_free);
g_free(inst->rules);
inst->nrules = 0;
}

View File

@ -27,6 +27,7 @@ qemu_driver_sources = [
'qemu_migration_params.c',
'qemu_monitor.c',
'qemu_monitor_json.c',
'qemu_monitor_text.c',
'qemu_namespace.c',
'qemu_nbdkit.c',
'qemu_passt.c',

View File

@ -87,7 +87,6 @@ qemuBackupPrepare(virDomainBackupDef *def)
break;
case VIR_STORAGE_NET_HOST_TRANS_RDMA:
case VIR_STORAGE_NET_HOST_TRANS_FD:
case VIR_STORAGE_NET_HOST_TRANS_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unexpected transport in <domainbackup>"));
@ -761,7 +760,6 @@ qemuBackupBegin(virDomainObj *vm,
bool reuse = (flags & VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL);
int rc = 0;
int ret = -1;
g_autoptr(qemuFDPassDirect) fdpass = NULL;
virCheckFlags(VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL, -1);
@ -848,29 +846,6 @@ qemuBackupBegin(virDomainObj *vm,
priv->backup = g_steal_pointer(&def);
if (pull && priv->backup->server->fdgroup) {
virStorageSourceFDTuple *fdt = NULL;
VIR_AUTOCLOSE fdcopy = -1;
if (!(fdt = virHashLookup(priv->fds, priv->backup->server->fdgroup))) {
virReportError(VIR_ERR_INVALID_ARG,
_("file descriptor group '%1$s' was not associated with the domain"),
priv->backup->server->fdgroup);
goto endjob;
}
if (fdt->nfds != 1) {
virReportError(VIR_ERR_INVALID_ARG,
_("file descriptor group '%1$s' must contain only 1 file descriptor for NBD server"),
priv->backup->server->fdgroup);
goto endjob;
}
priv->backup->server->qemu_fdname = g_strdup("libvirt-backup-nbd");
fdcopy = dup(fdt->fds[0]);
fdpass = qemuFDPassDirectNew(priv->backup->server->qemu_fdname, &fdcopy);
}
if (qemuDomainObjEnterMonitorAsync(vm, VIR_ASYNC_JOB_BACKUP) < 0)
goto endjob;
@ -881,9 +856,6 @@ qemuBackupBegin(virDomainObj *vm,
if (rc == 0 && tlsProps)
rc = qemuMonitorAddObject(priv->mon, &tlsProps, &tlsAlias);
if (rc == 0 && fdpass)
rc = qemuFDPassDirectTransferMonitor(fdpass, priv->mon);
if (rc == 0) {
if ((rc = qemuMonitorNBDServerStart(priv->mon, priv->backup->server, tlsAlias)) == 0)
nbd_running = true;

View File

@ -266,7 +266,6 @@ qemuBlockStorageSourceBuildJSONSocketAddress(virStorageNetHostDef *host)
break;
case VIR_STORAGE_NET_HOST_TRANS_RDMA:
case VIR_STORAGE_NET_HOST_TRANS_FD:
case VIR_STORAGE_NET_HOST_TRANS_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("transport protocol '%1$s' is not yet supported"),
@ -2875,9 +2874,6 @@ qemuBlockThrottleFiltersDetach(qemuMonitor *mon,
{
size_t i;
if (!data)
return;
for (i = data->nfilterdata; i > 0; i--)
qemuBlockThrottleFilterAttachRollback(mon, data->filterdata[i-1]);
}
@ -3645,6 +3641,9 @@ qemuBlockExportGetNBDProps(const char *nodename,
* @writable: whether the NBD export allows writes
* @bitmap: (optional) block dirty bitmap to export along
*
* This function automatically selects the proper invocation of exporting a
* block backend via NBD in qemu.
*
* This function must be called while in the monitor context.
*/
int
@ -3658,6 +3657,10 @@ qemuBlockExportAddNBD(virDomainObj *vm,
g_autoptr(virJSONValue) nbdprops = NULL;
const char *bitmaps[2] = { bitmap, NULL };
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCK_EXPORT_ADD))
return qemuMonitorNBDServerAdd(priv->mon, qemuBlockStorageSourceGetEffectiveNodename(src),
exportname, writable, bitmap);
if (!(nbdprops = qemuBlockExportGetNBDProps(qemuBlockStorageSourceGetEffectiveNodename(src),
exportname, writable, bitmaps)))
return -1;

View File

@ -529,7 +529,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 330 */
"bitmap-merge", /* X_QEMU_CAPS_BITMAP_MERGE */
"nbd-bitmap", /* X_QEMU_CAPS_NBD_BITMAP */
"nbd-bitmap", /* QEMU_CAPS_NBD_BITMAP */
"x86-max-cpu", /* QEMU_CAPS_X86_MAX_CPU */
"cpu-unavailable-features", /* QEMU_CAPS_CPU_UNAVAILABLE_FEATURES */
"canonical-cpu-features", /* QEMU_CAPS_CANONICAL_CPU_FEATURES */
@ -600,7 +600,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 380 */
"usb-host.hostdevice", /* QEMU_CAPS_USB_HOST_HOSTDEVICE */
"virtio-balloon.free-page-reporting", /* QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING */
"block-export-add", /* X_QEMU_CAPS_BLOCK_EXPORT_ADD */
"block-export-add", /* QEMU_CAPS_BLOCK_EXPORT_ADD */
"netdev.vhost-vdpa", /* QEMU_CAPS_NETDEV_VHOST_VDPA */
"fsdev.createmode", /* X_QEMU_CAPS_FSDEV_CREATEMODE */
@ -717,7 +717,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"machine-i8042-opt", /* QEMU_CAPS_MACHINE_I8042_OPT */
/* 465 */
"snapshot-internal-qmp", /* X_QEMU_CAPS_SNAPSHOT_INTERNAL_QMP */
"snapshot-internal-qmp", /* QEMU_CAPS_SNAPSHOT_INTERNAL_QMP */
"chardev-reconnect-miliseconds", /* QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS */
"virtio-ccw.loadparm", /* QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM */
"netdev-stream-reconnect-miliseconds", /* QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS */
@ -1243,6 +1243,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
{ "query-cpu-definitions", QEMU_CAPS_QUERY_CPU_DEFINITIONS },
{ "query-cpu-model-baseline", QEMU_CAPS_QUERY_CPU_MODEL_BASELINE },
{ "query-cpu-model-comparison", QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON },
{ "block-export-add", QEMU_CAPS_BLOCK_EXPORT_ADD },
{ "set-action", QEMU_CAPS_SET_ACTION },
{ "query-dirty-rate", QEMU_CAPS_QUERY_DIRTY_RATE },
{ "sev-inject-launch-secret", QEMU_CAPS_SEV_INJECT_LAUNCH_SECRET },
@ -1250,6 +1251,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
{ "query-stats", QEMU_CAPS_QUERY_STATS },
{ "query-stats-schemas", QEMU_CAPS_QUERY_STATS_SCHEMAS },
{ "display-reload", QEMU_CAPS_DISPLAY_RELOAD },
{ "snapshot-save", QEMU_CAPS_SNAPSHOT_INTERNAL_QMP },
{ "blockdev-set-active", QEMU_CAPS_BLOCKDEV_SET_ACTIVE },
};
@ -1581,6 +1583,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
{ "chardev-add/arg-type/backend/+qemu-vdagent", QEMU_CAPS_CHARDEV_QEMU_VDAGENT },
{ "device_add/$json-cli-hotplug", QEMU_CAPS_DEVICE_JSON },
{ "nbd-server-start/arg-type/tls-creds", QEMU_CAPS_NBD_TLS },
{ "nbd-server-add/arg-type/bitmap", QEMU_CAPS_NBD_BITMAP },
{ "netdev_add/arg-type/+stream", QEMU_CAPS_NETDEV_STREAM },
{ "netdev_add/arg-type/+stream/reconnect", QEMU_CAPS_NETDEV_STREAM_RECONNECT },
{ "netdev_add/arg-type/+vhost-vdpa", QEMU_CAPS_NETDEV_VHOST_VDPA },

View File

@ -510,7 +510,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
/* 330 */
X_QEMU_CAPS_BITMAP_MERGE, /* block-dirty-bitmap-merge */
X_QEMU_CAPS_NBD_BITMAP, /* nbd-server-add supports bitmap */
QEMU_CAPS_NBD_BITMAP, /* nbd-server-add supports bitmap */
QEMU_CAPS_X86_MAX_CPU, /* max-x86_64-cpu type exists */
QEMU_CAPS_CPU_UNAVAILABLE_FEATURES, /* "unavailable-features" CPU property */
QEMU_CAPS_CANONICAL_CPU_FEATURES, /* avoid CPU feature aliases */
@ -581,7 +581,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
/* 380 */
QEMU_CAPS_USB_HOST_HOSTDEVICE, /* -device usb-host.hostdevice */
QEMU_CAPS_VIRTIO_BALLOON_FREE_PAGE_REPORTING, /*virtio balloon free-page-reporting */
X_QEMU_CAPS_BLOCK_EXPORT_ADD, /* 'block-export-add' command is supported */
QEMU_CAPS_BLOCK_EXPORT_ADD, /* 'block-export-add' command is supported */
QEMU_CAPS_NETDEV_VHOST_VDPA, /* -netdev vhost-vdpa*/
X_QEMU_CAPS_FSDEV_CREATEMODE, /* fsdev.createmode */
@ -698,7 +698,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_MACHINE_I8042_OPT, /* -machine xxx,i8042=on/off; use virQEMUCapsSupportsI8042Toggle() to query this capability */
/* 465 */
X_QEMU_CAPS_SNAPSHOT_INTERNAL_QMP, /* internal snapshot support via QMP commands 'snapshot-save'/'snapshot-delete' */
QEMU_CAPS_SNAPSHOT_INTERNAL_QMP, /* internal snapshot support via QMP commands 'snapshot-save'/'snapshot-delete' */
QEMU_CAPS_CHARDEV_RECONNECT_MILISECONDS, /* 'reconnect-ms' option for chardevs supported */
QEMU_CAPS_VIRTIO_CCW_DEVICE_LOADPARM, /* loadparm available on CCW device for multi device boot */
QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS, /* 'reconnect-ms' option for netdev stream supported */

View File

@ -10685,6 +10685,12 @@ qemuBuildCommandLine(virDomainObj *vm,
if (qemuBuildSecCommandLine(vm, cmd, def->sec) < 0)
return NULL;
/* Internal snapshot reversion happens via QMP command after startup if
* supported */
if (snapshot &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SNAPSHOT_INTERNAL_QMP))
virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
if (def->namespaceData) {
qemuDomainXmlNsDef *qemuxmlns;
GStrv n;

View File

@ -5321,7 +5321,8 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver,
*/
if (origCPU) {
virCPUDefFree(def->cpu);
def->cpu = virCPUDefCopy(origCPU);
if (!(def->cpu = virCPUDefCopy(origCPU)))
return -1;
}
if (def->cpu &&
@ -5790,7 +5791,7 @@ static void
qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
virDomainObj *vm,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autofree char *snapDir = NULL;
@ -5816,7 +5817,7 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
if (rmdir(chkDir) < 0 && errno != ENOENT)
VIR_WARN("unable to remove checkpoint directory %s", chkDir);
}
qemuExtDevicesCleanupHost(driver, vm->def, flags, migration);
qemuExtDevicesCleanupHost(driver, vm->def, flags, outgoingMigration);
}
@ -5829,14 +5830,14 @@ void
qemuDomainRemoveInactive(virQEMUDriver *driver,
virDomainObj *vm,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
{
if (vm->persistent) {
/* Short-circuit, we don't want to remove a persistent domain */
return;
}
qemuDomainRemoveInactiveCommon(driver, vm, flags, migration);
qemuDomainRemoveInactiveCommon(driver, vm, flags, outgoingMigration);
virDomainObjListRemove(driver->domains, vm);
}
@ -9353,8 +9354,8 @@ qemuDomainSaveCookieNew(virDomainObj *vm)
if (!(cookie = virObjectNew(qemuDomainSaveCookieClass)))
return NULL;
if (priv->origCPU)
cookie->cpu = virCPUDefCopy(vm->def->cpu);
if (priv->origCPU && !(cookie->cpu = virCPUDefCopy(vm->def->cpu)))
return NULL;
cookie->slirpHelper = qemuDomainGetSlirpHelperOk(vm);
@ -9694,7 +9695,7 @@ qemuDomainPrepareStorageSourceFDs(virStorageSource *src,
}
static int
int
qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk,
virStorageSource *src,
const char *nodenameprefix,
@ -10087,7 +10088,6 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
case QEMU_PROCESS_EVENT_WATCHDOG:
case QEMU_PROCESS_EVENT_DEVICE_DELETED:
case QEMU_PROCESS_EVENT_NETDEV_STREAM_DISCONNECTED:
case QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED:
case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED:
case QEMU_PROCESS_EVENT_SERIAL_CHANGED:
case QEMU_PROCESS_EVENT_GUEST_CRASHLOADED:

View File

@ -469,7 +469,6 @@ typedef enum {
QEMU_PROCESS_EVENT_GUESTPANIC,
QEMU_PROCESS_EVENT_DEVICE_DELETED,
QEMU_PROCESS_EVENT_NETDEV_STREAM_DISCONNECTED,
QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED,
QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED,
QEMU_PROCESS_EVENT_SERIAL_CHANGED,
QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE,
@ -694,7 +693,7 @@ int qemuDomainMomentDiscardAll(void *payload,
void qemuDomainRemoveInactive(virQEMUDriver *driver,
virDomainObj *vm,
virDomainUndefineFlagsValues flags,
bool migration);
bool outgoingMigration);
void
qemuDomainRemoveInactiveLocked(virQEMUDriver *driver,
@ -758,6 +757,11 @@ int qemuDomainStorageSourceAccessAllow(virQEMUDriver *driver,
bool newSource,
bool chainTop);
int qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk,
virStorageSource *src,
const char *nodenameprefix,
qemuDomainObjPrivate *priv,
virQEMUDriverConfig *cfg);
int qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDef *disk,
virStorageSource *src,
qemuDomainObjPrivate *priv,

View File

@ -3607,12 +3607,12 @@ processDeviceDeletedEvent(virQEMUDriver *driver,
static void
processNetdevDisconnectedEvent(virDomainObj *vm,
const char *netdevId,
const char *eventName)
processNetdevStreamDisconnectedEvent(virDomainObj *vm,
const char *netdevId)
{
virDomainDeviceDef dev;
virDomainNetDef *def;
virQEMUCaps *qemuCaps = QEMU_DOMAIN_PRIVATE(vm)->qemuCaps;
const char *devAlias = STRSKIP(netdevId, "host");
/* The event sends us the "netdev-id", but we don't store the
@ -3624,13 +3624,13 @@ processNetdevDisconnectedEvent(virDomainObj *vm,
*/
if (!devAlias) {
VIR_WARN("Received %s event for unrecognized netdev %s from domain %p %s",
eventName, netdevId, vm, vm->def->name);
VIR_WARN("Received NETDEV_STREAM_DISCONNECTED event for unrecognized netdev %s from domain %p %s",
netdevId, vm, vm->def->name);
return;
}
VIR_DEBUG("Received %s event for device %s from domain %p %s",
eventName, devAlias, vm, vm->def->name);
VIR_DEBUG("Received NETDEV_STREAM_DISCONNECTED event for device %s from domain %p %s",
devAlias, vm, vm->def->name);
if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
return;
@ -3641,28 +3641,34 @@ processNetdevDisconnectedEvent(virDomainObj *vm,
}
if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0) {
VIR_WARN("%s event received for non-existent device %s in domain %s",
eventName, devAlias, vm->def->name);
VIR_WARN("NETDEV_STREAM_DISCONNECTED event received for non-existent device %s in domain %s",
devAlias, vm->def->name);
goto endjob;
}
if (dev.type != VIR_DOMAIN_DEVICE_NET) {
VIR_WARN("%s event received for non-network device %s in domain %s",
eventName, devAlias, vm->def->name);
VIR_WARN("NETDEV_STREAM_DISCONNECTED event received for non-network device %s in domain %s",
devAlias, vm->def->name);
goto endjob;
}
def = dev.data.net;
if (def->backend.type != VIR_DOMAIN_NET_BACKEND_PASST) {
VIR_DEBUG("ignore %s event for non-passt network device %s in domain %s",
eventName, def->info.alias, vm->def->name);
VIR_DEBUG("ignore NETDEV_STREAM_DISCONNECTED event for non-passt network device %s in domain %s",
def->info.alias, vm->def->name);
goto endjob;
}
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_STREAM_RECONNECT)) {
VIR_WARN("ignore NETDEV_STREAM_DISCONNECTED event for passt network device %s in domain %s - QEMU binary does not support reconnect",
def->info.alias, vm->def->name);
goto endjob;
}
/* handle the event - restart the passt process with its original
* parameters
*/
VIR_DEBUG("process %s event for network device %s in domain %s",
eventName, def->info.alias, vm->def->name);
VIR_DEBUG("process NETDEV_STREAM_DISCONNECTED event for network device %s in domain %s",
def->info.alias, vm->def->name);
if (qemuPasstStart(vm, def) < 0)
goto endjob;
@ -3672,22 +3678,6 @@ processNetdevDisconnectedEvent(virDomainObj *vm,
}
static void
processNetdevStreamDisconnectedEvent(virDomainObj *vm,
const char *netdevId)
{
processNetdevDisconnectedEvent(vm, netdevId, "NETDEV_STREAM_DISCONNECTED");
}
static void
processNetdevVhostUserDisconnectedEvent(virDomainObj *vm,
const char *netdevId)
{
processNetdevDisconnectedEvent(vm, netdevId, "NETDEV_VHOST_USER_DISCONNECTED");
}
static void
processNicRxFilterChangedEvent(virQEMUDriver *driver,
virDomainObj *vm,
@ -3855,7 +3845,6 @@ processMonitorEOFEvent(virQEMUDriver *driver,
const char *auditReason = "shutdown";
unsigned int stopFlags = 0;
virObjectEvent *event = NULL;
bool migration;
if (vm->def->id != domid) {
VIR_DEBUG("Domain %s was restarted, ignoring EOF",
@ -3866,8 +3855,6 @@ processMonitorEOFEvent(virQEMUDriver *driver,
if (qemuProcessBeginStopJob(vm, VIR_JOB_DESTROY, true) < 0)
return;
migration = vm->job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN;
if (!virDomainObjIsActive(vm)) {
VIR_DEBUG("Domain %p '%s' is not active, ignoring EOF",
vm, vm->def->name);
@ -3882,7 +3869,7 @@ processMonitorEOFEvent(virQEMUDriver *driver,
auditReason = "failed";
}
if (migration) {
if (vm->job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN) {
stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
qemuMigrationDstErrorSave(driver, vm->def->name,
qemuMonitorLastError(priv->mon));
@ -3895,7 +3882,7 @@ processMonitorEOFEvent(virQEMUDriver *driver,
virObjectEventStateQueue(driver->domainEventState, event);
endjob:
qemuDomainRemoveInactive(driver, vm, 0, migration);
qemuDomainRemoveInactive(driver, vm, 0, false);
qemuProcessEndStopJob(vm);
}
@ -4089,9 +4076,6 @@ static void qemuProcessEventHandler(void *data, void *opaque)
case QEMU_PROCESS_EVENT_NETDEV_STREAM_DISCONNECTED:
processNetdevStreamDisconnectedEvent(vm, processEvent->data);
break;
case QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED:
processNetdevVhostUserDisconnectedEvent(vm, processEvent->data);
break;
case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED:
processNicRxFilterChangedEvent(driver, vm, processEvent->data);
break;
@ -4803,7 +4787,8 @@ qemuDomainGetIOThreadsLive(virDomainObj *vm,
if (!(map = virProcessGetAffinity(iothreads[i]->thread_id)))
goto endjob;
virBitmapToData(map, &info_ret[i]->cpumap, &info_ret[i]->cpumaplen);
if (virBitmapToData(map, &info_ret[i]->cpumap, &info_ret[i]->cpumaplen) < 0)
goto endjob;
}
*info = g_steal_pointer(&info_ret);
@ -14399,6 +14384,13 @@ qemuDomainBlockCopyCommon(virDomainObj *vm,
* as read-write for the duration of the copy job */
mirror->readonly = false;
/* we must initialize XML-provided chain prior to detecting to keep semantics
* with VM startup */
for (n = mirror; virStorageSourceIsBacking(n); n = n->backingStore) {
if (qemuDomainPrepareStorageSourceBlockdev(disk, n, priv, cfg) < 0)
goto endjob;
}
/* 'qemuDomainPrepareStorageSourceBlockdev' calls
* 'qemuDomainPrepareDiskSourceData' which propagates 'detect_zeroes'
* into the topmost virStorage source of the disk chain.
@ -14409,13 +14401,6 @@ qemuDomainBlockCopyCommon(virDomainObj *vm,
mirror->detect_zeroes = disk->detect_zeroes;
mirror->discard_no_unref = disk->discard_no_unref;
/* we must initialize XML-provided chain prior to detecting to keep semantics
* with VM startup */
for (n = mirror; virStorageSourceIsBacking(n); n = n->backingStore) {
if (qemuDomainPrepareStorageSourceBlockdev(disk, n, priv, cfg) < 0)
goto endjob;
}
/* If reusing an external image that includes a backing file but the user
* did not enumerate the chain in the XML we need to detect the chain */
if (mirror_reuse &&
@ -14512,8 +14497,10 @@ qemuDomainBlockCopyCommon(virDomainObj *vm,
virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0);
qemuDomainObjExitMonitor(vm);
if (ret < 0)
if (ret < 0) {
qemuDomainStorageSourceChainAccessRevoke(driver, vm, mirror);
goto endjob;
}
/* Update vm in place to match changes. */
need_unlink = false;

View File

@ -154,7 +154,7 @@ void
qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainDef *def,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
{
size_t i;
@ -165,7 +165,7 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainTPMDef *tpm = def->tpms[i];
if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
qemuExtTPMCleanupHost(driver, tpm, flags, migration);
qemuExtTPMCleanupHost(driver, tpm, flags, outgoingMigration);
}
}
@ -280,7 +280,7 @@ qemuExtDevicesStart(virQEMUDriver *driver,
void
qemuExtDevicesStop(virQEMUDriver *driver,
virDomainObj *vm,
bool migration)
bool outgoingMigration)
{
virDomainDef *def = vm->def;
size_t i;
@ -297,7 +297,7 @@ qemuExtDevicesStop(virQEMUDriver *driver,
for (i = 0; i < def->ntpms; i++) {
if (def->tpms[i]->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
qemuExtTPMStop(driver, vm, migration);
qemuExtTPMStop(driver, vm, outgoingMigration);
}
for (i = 0; i < def->nnets; i++) {

View File

@ -48,7 +48,7 @@ int qemuExtDevicesPrepareHost(virQEMUDriver *driver,
void qemuExtDevicesCleanupHost(virQEMUDriver *driver,
virDomainDef *def,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuExtDevicesStart(virQEMUDriver *driver,
@ -59,7 +59,7 @@ int qemuExtDevicesStart(virQEMUDriver *driver,
void qemuExtDevicesStop(virQEMUDriver *driver,
virDomainObj *vm,
bool migration)
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
bool qemuExtDevicesHasDevice(virDomainDef *def);

View File

@ -740,15 +740,10 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
if (rc < 0)
goto rollback;
if (!(filterData = qemuBuildThrottleFiltersAttachPrepareBlockdev(disk)))
return -1;
if (filterData->nfilterdata > 0) {
if ((filterData = qemuBuildThrottleFiltersAttachPrepareBlockdev(disk))) {
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
return -1;
rc = qemuBlockThrottleFiltersAttach(priv->mon, filterData);
qemuDomainObjExitMonitor(vm);
if (rc < 0)
goto rollback;
@ -1273,7 +1268,12 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
qemuPasstPrepareVhostUser(vm, net);
/* vhostuser needs socket path in this location, and when
* backend is passt, the path is derived from other info,
* not taken from config.
*/
g_free(net->data.vhostuser->data.nix.path);
net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net);
if (qemuPasstStart(vm, net) < 0)
goto cleanup;

View File

@ -3609,7 +3609,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver,
* and there is no 'goto cleanup;' in the middle of those */
VIR_FREE(priv->origname);
virDomainObjRemoveTransientDef(vm);
qemuDomainRemoveInactive(driver, vm, 0, true);
qemuDomainRemoveInactive(driver, vm, 0, false);
}
virDomainObjEndAPI(&vm);
virErrorRestore(&origErr);
@ -6977,7 +6977,7 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver,
}
if (!qemuDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, true);
qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, false);
virErrorRestore(&orig_err);
return NULL;
@ -7113,7 +7113,7 @@ qemuMigrationProcessUnattended(virQEMUDriver *driver,
qemuMigrationJobFinish(vm);
if (!virDomainObjIsActive(vm))
qemuDomainRemoveInactive(driver, vm, 0, true);
qemuDomainRemoveInactive(driver, vm, 0, false);
}

View File

@ -28,6 +28,7 @@
#include "qemu_alias.h"
#include "qemu_monitor.h"
#include "qemu_monitor_text.h"
#include "qemu_monitor_json.h"
#include "qemu_domain.h"
#include "qemu_capabilities.h"
@ -79,7 +80,7 @@ VIR_LOG_INIT("qemu.qemu_monitor");
_("monitor must not be NULL")); \
exit; \
} \
VIR_DEBUG("mon:%p vm:%p monfd:%d", mon, mon->vm, mon->fd); \
VIR_DEBUG("mon:%p vm:%p fd:%d", mon, mon->vm, mon->fd); \
} while (0)
/* Check monitor and return NULL on error */
@ -1264,17 +1265,6 @@ qemuMonitorEmitNetdevStreamDisconnected(qemuMonitor *mon,
}
void
qemuMonitorEmitNetdevVhostUserDisconnected(qemuMonitor *mon,
const char *devAlias)
{
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, domainNetdevVhostUserDisconnected,
mon->vm, devAlias);
}
void
qemuMonitorEmitSerialChange(qemuMonitor *mon,
const char *devAlias,
@ -2755,6 +2745,30 @@ qemuMonitorDelObject(qemuMonitor *mon,
}
int
qemuMonitorCreateSnapshot(qemuMonitor *mon, const char *name)
{
VIR_DEBUG("name=%s", name);
QEMU_CHECK_MONITOR(mon);
/* there won't ever be a direct QMP replacement for this function */
return qemuMonitorTextCreateSnapshot(mon, name);
}
int
qemuMonitorDeleteSnapshot(qemuMonitor *mon, const char *name)
{
VIR_DEBUG("name=%s", name);
QEMU_CHECK_MONITOR(mon);
/* there won't ever be a direct QMP replacement for this function */
return qemuMonitorTextDeleteSnapshot(mon, name);
}
int
qemuMonitorSnapshotSave(qemuMonitor *mon,
const char *jobname,
@ -3523,6 +3537,23 @@ qemuMonitorNBDServerStart(qemuMonitor *mon,
}
int
qemuMonitorNBDServerAdd(qemuMonitor *mon,
const char *deviceID,
const char *export,
bool writable,
const char *bitmap)
{
VIR_DEBUG("deviceID=%s, export=%s, bitmap=%s", deviceID, NULLSTR(export),
NULLSTR(bitmap));
QEMU_CHECK_MONITOR(mon);
return qemuMonitorJSONNBDServerAdd(mon, deviceID, export, writable,
bitmap);
}
int
qemuMonitorNBDServerStop(qemuMonitor *mon)
{

View File

@ -255,9 +255,6 @@ typedef void (*qemuMonitorDomainDeviceUnplugErrCallback)(qemuMonitor *mon,
typedef void (*qemuMonitorDomainNetdevStreamDisconnectedCallback)(qemuMonitor *mon,
virDomainObj *vm,
const char *devAlias);
typedef void (*qemuMonitorDomainNetdevVhostUserDisconnectedCallback)(qemuMonitor *mon,
virDomainObj *vm,
const char *devAlias);
typedef void (*qemuMonitorDomainNicRxFilterChangedCallback)(qemuMonitor *mon,
virDomainObj *vm,
const char *devAlias);
@ -406,7 +403,6 @@ struct _qemuMonitorCallbacks {
qemuMonitorDomainMemoryDeviceSizeChange domainMemoryDeviceSizeChange;
qemuMonitorDomainDeviceUnplugErrCallback domainDeviceUnplugError;
qemuMonitorDomainNetdevStreamDisconnectedCallback domainNetdevStreamDisconnected;
qemuMonitorDomainNetdevVhostUserDisconnectedCallback domainNetdevVhostUserDisconnected;
};
qemuMonitor *qemuMonitorOpen(virDomainObj *vm,
@ -494,8 +490,6 @@ void qemuMonitorEmitDeviceUnplugErr(qemuMonitor *mon,
const char *devAlias);
void qemuMonitorEmitNetdevStreamDisconnected(qemuMonitor *mon,
const char *devAlias);
void qemuMonitorEmitNetdevVhostUserDisconnected(qemuMonitor *mon,
const char *devAlias);
void qemuMonitorEmitNicRxFilterChanged(qemuMonitor *mon,
const char *devAlias);
void qemuMonitorEmitSerialChange(qemuMonitor *mon,
@ -982,6 +976,9 @@ int qemuMonitorDelObject(qemuMonitor *mon,
const char *objalias,
bool report_error);
int qemuMonitorCreateSnapshot(qemuMonitor *mon, const char *name);
int qemuMonitorDeleteSnapshot(qemuMonitor *mon, const char *name);
int qemuMonitorTransaction(qemuMonitor *mon, virJSONValue **actions)
ATTRIBUTE_NONNULL(2);
int qemuMonitorBlockdevMirror(qemuMonitor *mon,
@ -1224,6 +1221,11 @@ int qemuMonitorNBDServerStart(qemuMonitor *mon,
const virStorageNetHostDef *server,
const char *tls_alias)
ATTRIBUTE_NONNULL(2);
int qemuMonitorNBDServerAdd(qemuMonitor *mon,
const char *deviceID,
const char *export,
bool writable,
const char *bitmap);
int qemuMonitorNBDServerStop(qemuMonitor *mon);
int qemuMonitorBlockExportAdd(qemuMonitor *mon,

View File

@ -85,7 +85,6 @@ static void qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon, virJSONValue *d
static void qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon, virJSONValue *data);
static void qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data);
static void qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *data);
static void qemuMonitorJSONHandleNetdevVhostUserDisconnected(qemuMonitor *mon, virJSONValue *data);
typedef struct {
const char *type;
@ -109,7 +108,6 @@ static qemuEventHandler eventHandlers[] = {
{ "MIGRATION", qemuMonitorJSONHandleMigrationStatus, },
{ "MIGRATION_PASS", qemuMonitorJSONHandleMigrationPass, },
{ "NETDEV_STREAM_DISCONNECTED", qemuMonitorJSONHandleNetdevStreamDisconnected, },
{ "NETDEV_VHOST_USER_DISCONNECTED", qemuMonitorJSONHandleNetdevVhostUserDisconnected, },
{ "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, },
{ "PR_MANAGER_STATUS_CHANGED", qemuMonitorJSONHandlePRManagerStatusChanged, },
{ "RDMA_GID_STATUS_CHANGED", qemuMonitorJSONHandleRdmaGidStatusChanged, },
@ -1046,20 +1044,6 @@ qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *da
}
static void
qemuMonitorJSONHandleNetdevVhostUserDisconnected(qemuMonitor *mon, virJSONValue *data)
{
const char *name;
if (!(name = virJSONValueObjectGetString(data, "netdev-id"))) {
VIR_WARN("missing device in NETDEV_VHOST_USER_DISCONNECTED event");
return;
}
qemuMonitorEmitNetdevVhostUserDisconnected(mon, name);
}
static void
qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor *mon, virJSONValue *data)
{
@ -6339,24 +6323,6 @@ qemuMonitorJSONBuildUnixSocketAddress(const char *path)
}
static virJSONValue *
qemuMonitorJSONBuildFDSocketAddress(const char *name)
{
g_autoptr(virJSONValue) addr = NULL;
g_autoptr(virJSONValue) data = NULL;
if (virJSONValueObjectAdd(&data, "s:str", name, NULL) < 0)
return NULL;
if (virJSONValueObjectAdd(&addr,
"s:type", "fd",
"a:data", &data, NULL) < 0)
return NULL;
return g_steal_pointer(&addr);
}
int
qemuMonitorJSONNBDServerStart(qemuMonitor *mon,
const virStorageNetHostDef *server,
@ -6375,9 +6341,6 @@ qemuMonitorJSONNBDServerStart(qemuMonitor *mon,
case VIR_STORAGE_NET_HOST_TRANS_UNIX:
addr = qemuMonitorJSONBuildUnixSocketAddress(server->socket);
break;
case VIR_STORAGE_NET_HOST_TRANS_FD:
addr = qemuMonitorJSONBuildFDSocketAddress(server->qemu_fdname);
break;
case VIR_STORAGE_NET_HOST_TRANS_RDMA:
case VIR_STORAGE_NET_HOST_TRANS_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -6402,6 +6365,34 @@ qemuMonitorJSONNBDServerStart(qemuMonitor *mon,
return 0;
}
int
qemuMonitorJSONNBDServerAdd(qemuMonitor *mon,
const char *deviceID,
const char *export,
bool writable,
const char *bitmap)
{
g_autoptr(virJSONValue) cmd = NULL;
g_autoptr(virJSONValue) reply = NULL;
/* Note: bitmap must be NULL if QEMU_CAPS_NBD_BITMAP is lacking */
if (!(cmd = qemuMonitorJSONMakeCommand("nbd-server-add",
"s:device", deviceID,
"S:name", export,
"b:writable", writable,
"S:bitmap", bitmap,
NULL)))
return -1;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
return -1;
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
return -1;
return 0;
}
int
qemuMonitorJSONNBDServerStop(qemuMonitor *mon)
{

View File

@ -541,6 +541,12 @@ qemuMonitorJSONNBDServerStart(qemuMonitor *mon,
const virStorageNetHostDef *server,
const char *tls_alias);
int
qemuMonitorJSONNBDServerAdd(qemuMonitor *mon,
const char *deviceID,
const char *export,
bool writable,
const char *bitmap);
int
qemuMonitorJSONNBDServerStop(qemuMonitor *mon);
int

View File

@ -0,0 +1,88 @@
/*
* qemu_monitor_text.c: interaction with QEMU monitor console
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "qemu_monitor_text.h"
#include "qemu_monitor_json.h"
#include "virlog.h"
#include "virerror.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
VIR_LOG_INIT("qemu.qemu_monitor_text");
int
qemuMonitorTextCreateSnapshot(qemuMonitor *mon,
const char *name)
{
g_autofree char *cmd = NULL;
g_autofree char *reply = NULL;
cmd = g_strdup_printf("savevm \"%s\"", name);
if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply))
return -1;
if (strstr(reply, "Error while creating snapshot") ||
strstr(reply, "Could not open VM state file") ||
strstr(reply, "State blocked by non-migratable device") ||
strstr(reply, "Error: ") ||
(strstr(reply, "Error") && strstr(reply, "while writing VM"))) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("Failed to take snapshot: %1$s"), reply);
return -1;
} else if (strstr(reply, "No block device can accept snapshots")) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("this domain does not have a device to take snapshots"));
return -1;
}
return 0;
}
int qemuMonitorTextDeleteSnapshot(qemuMonitor *mon, const char *name)
{
g_autofree char *cmd = NULL;
g_autofree char *reply = NULL;
cmd = g_strdup_printf("delvm \"%s\"", name);
if (qemuMonitorJSONHumanCommand(mon, cmd, -1, &reply))
return -1;
if (strstr(reply, "No block device supports snapshots")) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("this domain does not have a device to delete snapshots"));
return -1;
} else if (strstr(reply, "Snapshots not supported on device")) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s", reply);
return -1;
} else if (strstr(reply, "Error: ") ||
(strstr(reply, "Error") &&
strstr(reply, "while deleting snapshot"))) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("Failed to delete snapshot: %1$s"), reply);
return -1;
}
return 0;
}

View File

@ -0,0 +1,29 @@
/*
* qemu_monitor_text.h: interaction with QEMU monitor console
*
* Copyright (C) 2006-2009, 2011-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "internal.h"
#include "qemu_monitor.h"
int qemuMonitorTextCreateSnapshot(qemuMonitor *mon, const char *name);
int qemuMonitorTextDeleteSnapshot(qemuMonitor *mon, const char *name);

View File

@ -36,7 +36,7 @@ VIR_LOG_INIT("qemu.passt");
#define PASST "passt"
#define QEMU_PASST_RECONNECT_TIMEOUT 5
static char *
qemuPasstCreatePidFilename(virDomainObj *vm,
@ -106,15 +106,11 @@ qemuPasstAddNetProps(virDomainObj *vm,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_STREAM_RECONNECT)) {
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_STREAM_RECONNECT_MILISECONDS)) {
if (virJSONValueObjectAdd(netprops, "u:reconnect-ms",
QEMU_PASST_RECONNECT_TIMEOUT * 1000, NULL) < 0) {
if (virJSONValueObjectAdd(netprops, "u:reconnect-ms", 5000, NULL) < 0)
return -1;
}
} else {
if (virJSONValueObjectAdd(netprops, "u:reconnect",
QEMU_PASST_RECONNECT_TIMEOUT, NULL) < 0) {
if (virJSONValueObjectAdd(netprops, "u:reconnect", 5, NULL) < 0)
return -1;
}
}
}
@ -169,31 +165,6 @@ qemuPasstSetupCgroup(virDomainObj *vm,
}
void
qemuPasstPrepareVhostUser(virDomainObj *vm,
virDomainNetDef *net)
{
/* There are some options on the QEMU commandline for a vhost-user
* chr device that are normally configurable, but when it is passt
* speaking to the vhost-user device those things are
* derived/fixed. This function, which is called prior to
* generating the QEMU commandline, sets thos derived/fixed things
* in the chr device object.
*/
/* The socket path is not user-configurable for passt - it is
* derived from other info
*/
g_free(net->data.vhostuser->data.nix.path);
net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net);
/* reconnect is always enabled, with timeout always at 5 seconds, when
* using passt
*/
net->data.vhostuser->data.nix.reconnect.enabled = VIR_TRISTATE_BOOL_YES;
net->data.vhostuser->data.nix.reconnect.timeout = QEMU_PASST_RECONNECT_TIMEOUT;
}
int
qemuPasstStart(virDomainObj *vm,
virDomainNetDef *net)

View File

@ -37,8 +37,5 @@ int qemuPasstSetupCgroup(virDomainObj *vm,
virDomainNetDef *net,
virCgroup *cgroup);
void qemuPasstPrepareVhostUser(virDomainObj *vm,
virDomainNetDef *net);
char *qemuPasstCreateSocketPath(virDomainObj *vm,
virDomainNetDef *net);

View File

@ -1402,23 +1402,6 @@ qemuProcessHandleNetdevStreamDisconnected(qemuMonitor *mon G_GNUC_UNUSED,
}
static void
qemuProcessHandleNetdevVhostUserDisconnected(qemuMonitor *mon G_GNUC_UNUSED,
virDomainObj *vm,
const char *devAlias)
{
virObjectLock(vm);
VIR_DEBUG("Device %s Netdev vhost-user Disconnected in domain %p %s",
devAlias, vm, vm->def->name);
qemuProcessEventSubmit(vm, QEMU_PROCESS_EVENT_NETDEV_VHOST_USER_DISCONNECTED,
0, 0, g_strdup(devAlias));
virObjectUnlock(vm);
}
static void
qemuProcessHandleNicRxFilterChanged(qemuMonitor *mon G_GNUC_UNUSED,
virDomainObj *vm,
@ -1865,7 +1848,6 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainMemoryDeviceSizeChange = qemuProcessHandleMemoryDeviceSizeChange,
.domainDeviceUnplugError = qemuProcessHandleDeviceUnplugErr,
.domainNetdevStreamDisconnected = qemuProcessHandleNetdevStreamDisconnected,
.domainNetdevVhostUserDisconnected = qemuProcessHandleNetdevVhostUserDisconnected,
};
static void
@ -6022,8 +6004,13 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
if (net->backend.type == VIR_DOMAIN_NET_BACKEND_PASST) {
/* some extra setup of internal data for passt vhostuser mode */
qemuPasstPrepareVhostUser(vm, net);
/* when using the passt backend, the path of the
* unix socket is always derived from other info
* *not* manually given in the config, but all the
* vhostuser code looks for it there.
*/
g_free(net->data.vhostuser->data.nix.path);
net->data.vhostuser->data.nix.path = qemuPasstCreateSocketPath(vm, net);
}
break;
@ -8252,7 +8239,8 @@ qemuProcessLaunch(virConnectPtr conn,
qemuDomainVcpuPersistOrder(vm->def);
if (snapshot) {
if (snapshot &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SNAPSHOT_INTERNAL_QMP)) {
VIR_DEBUG("reverting internal snapshot via QMP");
if (qemuSnapshotInternalRevert(vm, snapshot, asyncJob) < 0)
goto cleanup;
@ -8926,6 +8914,7 @@ void qemuProcessStop(virQEMUDriver *driver,
size_t i;
g_autofree char *timestamp = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
bool outgoingMigration;
VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%lld, "
"reason=%s, asyncJob=%s, flags=0x%x",
@ -9001,7 +8990,10 @@ void qemuProcessStop(virQEMUDriver *driver,
qemuDomainCleanupRun(driver, vm);
qemuExtDevicesStop(driver, vm, !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED));
outgoingMigration = (flags & VIR_QEMU_PROCESS_STOP_MIGRATED) &&
(asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT);
qemuExtDevicesStop(driver, vm, outgoingMigration);
qemuDBusStop(driver, vm);
@ -9267,7 +9259,7 @@ qemuProcessAutoDestroy(virDomainObj *dom,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
qemuDomainRemoveInactive(driver, dom, 0, !!(stopFlags & VIR_QEMU_PROCESS_STOP_MIGRATED));
qemuDomainRemoveInactive(driver, dom, 0, false);
qemuProcessEndStopJob(dom);

View File

@ -413,25 +413,12 @@ qemuRdpSetCredentials(virDomainObj *vm,
}
/**
* qemuRdpAvailable:
* @helper: name (or path to) 'qemu-rdp' binary
*
* Returns whether 'qemu-rdp' is available.
*
* Important:
* This function is called from 'virQEMUDriverGetDomainCapabilities'. It must
* not report any errors and must not add any additional checks.
*
* This function is mocked from 'tests/testutilsqemu.c'
*
*/
bool
qemuRdpAvailable(const char *helper)
{
g_autofree char *helperPath = NULL;
g_autoptr(qemuRdp) rdp = NULL;
/* This function was added corresponding to the first release of 'qemu-rdp'
* thus checking existence of the helper binary is sufficient. */
return !!(helperPath = virFindFileInPath(helper));
rdp = qemuRdpNewForHelper(helper);
return rdp && qemuRdpHasFeature(rdp, QEMU_RDP_FEATURE_DBUS_ADDRESS);
}

View File

@ -554,12 +554,12 @@ qemuSnapshotCreateActiveInternal(virQEMUDriver *driver,
virDomainMomentObj *snap,
unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
virObjectEvent *event = NULL;
bool resume = false;
virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap);
int ret = -1;
int rv = 0;
g_autoptr(qemuBlockJobData) job = NULL;
if (!qemuMigrationSrcIsAllowed(vm, false, VIR_ASYNC_JOB_SNAPSHOT, 0))
goto cleanup;
@ -581,11 +581,27 @@ qemuSnapshotCreateActiveInternal(virQEMUDriver *driver,
}
}
if (!(job = qemuSnapshotCreateActiveInternalStart(vm, snapdef)))
goto cleanup;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SNAPSHOT_INTERNAL_QMP)) {
g_autoptr(qemuBlockJobData) job = NULL;
while ((rv = qemuSnapshotCreateActiveInternalDone(vm, job)) != 1) {
if (rv < 0 || qemuDomainObjWait(vm) < 0)
if (!(job = qemuSnapshotCreateActiveInternalStart(vm, snapdef)))
goto cleanup;
while ((rv = qemuSnapshotCreateActiveInternalDone(vm, job)) != 1) {
if (rv < 0 || qemuDomainObjWait(vm) < 0)
goto cleanup;
}
ret = 0;
} else {
if (qemuDomainObjEnterMonitorAsync(vm, VIR_ASYNC_JOB_SNAPSHOT) < 0) {
resume = false;
goto cleanup;
}
ret = qemuMonitorCreateSnapshot(priv->mon, snap->def->name);
qemuDomainObjExitMonitor(vm);
if (ret < 0)
goto cleanup;
}
@ -601,8 +617,6 @@ qemuSnapshotCreateActiveInternal(virQEMUDriver *driver,
resume = false;
}
ret = 0;
cleanup:
if (resume && virDomainObjIsActive(vm) &&
qemuProcessStartCPUs(driver, vm,
@ -929,6 +943,7 @@ qemuSnapshotPrepare(virDomainObj *vm,
bool *has_manual,
unsigned int *flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
size_t i;
bool active = virDomainObjIsActive(vm);
bool reuse = (*flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0;
@ -1049,6 +1064,13 @@ qemuSnapshotPrepare(virDomainObj *vm,
* varstore is in qcow2 format.
*/
if (active && found_internal) {
if (virDomainDefHasOldStyleUEFI(vm->def) &&
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SNAPSHOT_INTERNAL_QMP)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("internal snapshots of a VM with pflash based firmware are not supported with this qemu"));
return -1;
}
if (vm->def->os.loader &&
vm->def->os.loader->nvram &&
vm->def->os.loader->nvram->format != VIR_STORAGE_FILE_QCOW2) {
@ -4097,13 +4119,22 @@ qemuSnapshotDiscardImpl(virDomainObj *vm,
return -1;
} else {
virDomainSnapshotDef *snapdef = virDomainSnapshotObjGetDef(snap);
qemuDomainObjPrivate *priv = vm->privateData;
/* Similarly as internal snapshot creation we would use a regular job
* here so set a mask to forbid any other job. */
qemuDomainObjSetAsyncJobMask(vm, VIR_JOB_NONE);
if (qemuSnapshotDiscardActiveInternal(vm, snapdef) < 0)
return -1;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SNAPSHOT_INTERNAL_QMP)) {
if (qemuSnapshotDiscardActiveInternal(vm, snapdef) < 0)
return -1;
} else {
if (qemuDomainObjEnterMonitorAsync(vm, VIR_ASYNC_JOB_SNAPSHOT) < 0)
return -1;
/* we continue on even in the face of error */
qemuMonitorDeleteSnapshot(qemuDomainGetMonitor(vm), snap->def->name);
qemuDomainObjExitMonitor(vm);
}
qemuDomainObjSetAsyncJobMask(vm, VIR_JOB_DEFAULT_MASK);
}

View File

@ -929,8 +929,7 @@ qemuTPMEmulatorInitPaths(virDomainTPMDef *tpm,
* @driver: QEMU driver
* @tpm: TPM definition
* @flags: flags indicating whether to keep or remove TPM persistent state
* @migration: whether cleanup is due to a successful outgoing or failed
* incoming migration
* @outgoingMigration: whether cleanup is due to an outgoing migration
*
* Clean up persistent storage for the swtpm.
*/
@ -938,12 +937,14 @@ static void
qemuTPMEmulatorCleanupHost(virQEMUDriver *driver,
virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
/* Never remove the state in case of migration with shared storage. */
if (migration &&
/* Never remove the state in case of outgoing migration with shared
* storage.
*/
if (outgoingMigration &&
virFileIsSharedFS(tpm->data.emulator.source_path, cfg->sharedFilesystems) == 1)
return;
@ -1314,9 +1315,9 @@ void
qemuExtTPMCleanupHost(virQEMUDriver *driver,
virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
{
qemuTPMEmulatorCleanupHost(driver, tpm, flags, migration);
qemuTPMEmulatorCleanupHost(driver, tpm, flags, outgoingMigration);
}
@ -1340,7 +1341,7 @@ qemuExtTPMStart(virQEMUDriver *driver,
void
qemuExtTPMStop(virQEMUDriver *driver,
virDomainObj *vm,
bool migration)
bool outgoingMigration)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autofree char *shortName = virDomainDefGetShortName(vm->def);
@ -1350,7 +1351,7 @@ qemuExtTPMStop(virQEMUDriver *driver,
return;
qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName);
if (migration && qemuTPMHasSharedStorage(driver, vm->def))
if (outgoingMigration && qemuTPMHasSharedStorage(driver, vm->def))
restoreTPMStateLabel = false;
if (qemuSecurityRestoreTPMLabels(driver, vm, restoreTPMStateLabel, false) < 0)

View File

@ -38,7 +38,7 @@ int qemuExtTPMPrepareHost(virQEMUDriver *driver,
void qemuExtTPMCleanupHost(virQEMUDriver *driver,
virDomainTPMDef *tpm,
virDomainUndefineFlagsValues flags,
bool migration)
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuExtTPMStart(virQEMUDriver *driver,
@ -52,7 +52,7 @@ int qemuExtTPMStart(virQEMUDriver *driver,
void qemuExtTPMStop(virQEMUDriver *driver,
virDomainObj *vm,
bool migration)
bool outgoingMigration)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int qemuExtTPMSetupCgroup(virQEMUDriver *driver,

View File

@ -742,42 +742,6 @@ remoteConnectFormatURI(virURI *uri,
}
static int
remoteCallOpen(virConnectPtr conn,
struct private_data *priv,
const char *name,
unsigned int flags)
{
remote_connect_open_args args = { (char**) &name, flags };
VIR_DEBUG("Trying to open URI '%s'", name);
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_OPEN,
(xdrproc_t) xdr_remote_connect_open_args, (char *) &args,
(xdrproc_t) xdr_void, (char *) NULL) == -1)
return -1;
/* Now try and find out what URI the daemon used */
if (conn->uri == NULL) {
remote_connect_get_uri_ret uriret = { 0 };
VIR_DEBUG("Trying to query remote URI");
if (call(conn, priv, 0,
REMOTE_PROC_CONNECT_GET_URI,
(xdrproc_t) xdr_void, (char *) NULL,
(xdrproc_t) xdr_remote_connect_get_uri_ret, (char *) &uriret) < 0)
return -1;
VIR_DEBUG("Auto-probed URI is %s", uriret.uri);
conn->uri = virURIParse(uriret.uri);
VIR_FREE(uriret.uri);
if (!conn->uri)
return -1;
}
return 0;
}
/* helper macro to ease extraction of arguments from the URI */
#define EXTRACT_URI_ARG_STR(ARG_NAME, ARG_VAR) \
if (STRCASEEQ(var->name, ARG_NAME)) { \
@ -794,74 +758,13 @@ remoteCallOpen(virConnectPtr conn,
virReportError(VIR_ERR_INVALID_ARG, \
_("Failed to parse value of URI component %1$s"), \
var->name); \
return -1; \
goto error; \
} \
ARG_VAR = tmp == 0; \
var->ignore = 1; \
continue; \
}
static int
doRemoteOpenExtractURIArgs(virConnectPtr conn,
char **name,
char **command,
char **sockname,
char **authtype,
char **sshauth,
char **netcat,
char **keyfile,
char **pkipath,
char **knownHosts,
char **knownHostsVerify,
char **tls_priority,
char **mode_str,
char **proxy_str,
#ifndef WIN32
bool *tty,
#endif
bool *sanity,
bool *verify)
{
size_t i;
for (i = 0; i < conn->uri->paramsCount; i++) {
virURIParam *var = &conn->uri->params[i];
EXTRACT_URI_ARG_STR("name", *name);
EXTRACT_URI_ARG_STR("command", *command);
EXTRACT_URI_ARG_STR("socket", *sockname);
EXTRACT_URI_ARG_STR("auth", *authtype);
EXTRACT_URI_ARG_STR("sshauth", *sshauth);
EXTRACT_URI_ARG_STR("netcat", *netcat);
EXTRACT_URI_ARG_STR("keyfile", *keyfile);
EXTRACT_URI_ARG_STR("pkipath", *pkipath);
EXTRACT_URI_ARG_STR("known_hosts", *knownHosts);
EXTRACT_URI_ARG_STR("known_hosts_verify", *knownHostsVerify);
EXTRACT_URI_ARG_STR("tls_priority", *tls_priority);
EXTRACT_URI_ARG_STR("mode", *mode_str);
EXTRACT_URI_ARG_STR("proxy", *proxy_str);
EXTRACT_URI_ARG_BOOL("no_sanity", *sanity);
EXTRACT_URI_ARG_BOOL("no_verify", *verify);
#ifndef WIN32
EXTRACT_URI_ARG_BOOL("no_tty", *tty);
#endif
if (STRCASEEQ(var->name, "authfile")) {
/* Strip this param, used by virauth.c */
var->ignore = 1;
continue;
}
VIR_DEBUG("passing through variable '%s' ('%s') to remote end",
var->name, var->value);
}
return 0;
}
#undef EXTRACT_URI_ARG_STR
#undef EXTRACT_URI_ARG_BOOL
/*
* URIs that this driver needs to handle:
@ -915,6 +818,7 @@ doRemoteOpen(virConnectPtr conn,
bool tty = true;
#endif
int mode;
size_t i;
int proxy;
/* We handle *ALL* URIs here. The caller has rejected any
@ -940,28 +844,35 @@ doRemoteOpen(virConnectPtr conn,
* although that won't be the case for now).
*/
if (conn->uri) {
/* This really needs to be a separate function to keep
* the stack size at sane levels. */
if (doRemoteOpenExtractURIArgs(conn,
&name,
&command,
&sockname,
&authtype,
&sshauth,
&netcat,
&keyfile,
&pkipath,
&knownHosts,
&knownHostsVerify,
&tls_priority,
&mode_str,
&proxy_str,
for (i = 0; i < conn->uri->paramsCount; i++) {
virURIParam *var = &conn->uri->params[i];
EXTRACT_URI_ARG_STR("name", name);
EXTRACT_URI_ARG_STR("command", command);
EXTRACT_URI_ARG_STR("socket", sockname);
EXTRACT_URI_ARG_STR("auth", authtype);
EXTRACT_URI_ARG_STR("sshauth", sshauth);
EXTRACT_URI_ARG_STR("netcat", netcat);
EXTRACT_URI_ARG_STR("keyfile", keyfile);
EXTRACT_URI_ARG_STR("pkipath", pkipath);
EXTRACT_URI_ARG_STR("known_hosts", knownHosts);
EXTRACT_URI_ARG_STR("known_hosts_verify", knownHostsVerify);
EXTRACT_URI_ARG_STR("tls_priority", tls_priority);
EXTRACT_URI_ARG_STR("mode", mode_str);
EXTRACT_URI_ARG_STR("proxy", proxy_str);
EXTRACT_URI_ARG_BOOL("no_sanity", sanity);
EXTRACT_URI_ARG_BOOL("no_verify", verify);
#ifndef WIN32
&tty,
EXTRACT_URI_ARG_BOOL("no_tty", tty);
#endif
&sanity,
&verify) < 0) {
goto error;
if (STRCASEEQ(var->name, "authfile")) {
/* Strip this param, used by virauth.c */
var->ignore = 1;
continue;
}
VIR_DEBUG("passing through variable '%s' ('%s') to remote end",
var->name, var->value);
}
/* Construct the original name. */
@ -1063,7 +974,7 @@ doRemoteOpen(virConnectPtr conn,
VIR_DEBUG("Connecting with transport %d", transport);
switch (transport) {
switch ((remoteDriverTransport)transport) {
case REMOTE_DRIVER_TRANSPORT_UNIX:
case REMOTE_DRIVER_TRANSPORT_SSH:
case REMOTE_DRIVER_TRANSPORT_LIBSSH:
@ -1088,7 +999,7 @@ doRemoteOpen(virConnectPtr conn,
VIR_DEBUG("Chosen UNIX socket %s", NULLSTR(sockname));
/* Connect to the remote service. */
switch (transport) {
switch ((remoteDriverTransport)transport) {
case REMOTE_DRIVER_TRANSPORT_TLS:
if (conf && !tls_priority &&
virConfGetValueString(conf, "tls_priority", &tls_priority) < 0)
@ -1277,8 +1188,33 @@ doRemoteOpen(virConnectPtr conn,
}
/* Finally we can call the remote side's open function. */
if (remoteCallOpen(conn, priv, name, flags) < 0)
goto error;
{
remote_connect_open_args args = { &name, flags };
VIR_DEBUG("Trying to open URI '%s'", name);
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_OPEN,
(xdrproc_t) xdr_remote_connect_open_args, (char *) &args,
(xdrproc_t) xdr_void, (char *) NULL) == -1)
goto error;
}
/* Now try and find out what URI the daemon used */
if (conn->uri == NULL) {
remote_connect_get_uri_ret uriret = { 0 };
VIR_DEBUG("Trying to query remote URI");
if (call(conn, priv, 0,
REMOTE_PROC_CONNECT_GET_URI,
(xdrproc_t) xdr_void, (char *) NULL,
(xdrproc_t) xdr_remote_connect_get_uri_ret, (char *) &uriret) < 0)
goto error;
VIR_DEBUG("Auto-probed URI is %s", uriret.uri);
conn->uri = virURIParse(uriret.uri);
VIR_FREE(uriret.uri);
if (!conn->uri)
goto error;
}
/* Set up events */
if (!(priv->eventState = virObjectEventStateNew()))
@ -1312,6 +1248,8 @@ doRemoteOpen(virConnectPtr conn,
VIR_FREE(priv->hostname);
return VIR_DRV_OPEN_ERROR;
}
#undef EXTRACT_URI_ARG_STR
#undef EXTRACT_URI_ARG_BOOL
static struct private_data *
remoteAllocPrivateData(void)

View File

@ -117,4 +117,6 @@
deny /sys/fs/cgroup?*{,/**} wklx,
deny /sys/fs?*{,/**} wklx,
@BEGIN_APPARMOR_3@
include if exists <abstractions/libvirt-lxc.d>
@END_APPARMOR_3@

View File

@ -190,6 +190,7 @@
/usr/{lib,lib64}/libswtpm_libtpms.so mr,
/usr/lib/@{multiarch}/libswtpm_libtpms.so mr,
@BEGIN_APPARMOR_3@
# support for passt network back-end
/usr/bin/passt Cx -> passt,
@ -205,6 +206,7 @@
include if exists <abstractions/passt>
}
@END_APPARMOR_3@
# for save and resume
/{usr/,}bin/dash rmix,
@ -279,4 +281,6 @@
owner /var/lib/libvirt/qemu/nvram/*_VARS.fd rwk,
owner /var/lib/libvirt/qemu/nvram/*_VARS.ms.fd rwk,
@BEGIN_APPARMOR_3@
include if exists <abstractions/libvirt-qemu.d>
@END_APPARMOR_3@

View File

@ -5,6 +5,11 @@ apparmor_gen_profiles = [
'usr.sbin.virtxend',
]
apparmor_gen_abstractions = [
'libvirt-qemu',
'libvirt-lxc',
]
apparmor_gen_profiles_conf = configuration_data({
'sysconfdir': sysconfdir,
'sbindir': sbindir,
@ -14,9 +19,41 @@ apparmor_gen_profiles_conf = configuration_data({
apparmor_dir = sysconfdir / 'apparmor.d'
# Our profiles use some features that only work well on AppArmor 3.x,
# specifically the 'include if exists' directive. In order to keep
# supporting AppArmor 2.x, the bits that are version-specific are
# enclosed in special markers and we decide which ones to include
# based on the AppArmor version detected on the host.
#
# TODO: drop the additional complexity once we no longer target
# distros that ship AppArmor 2.x (Debian 11, Ubuntu 20.04)
if conf.has('WITH_APPARMOR_3')
apparmor_gen_cmd = [
'sed',
'-e', '/[@]BEGIN_APPARMOR_3[@]/d',
'-e', '/[@]END_APPARMOR_3[@]/d',
'-e', '/[@]BEGIN_APPARMOR_2[@]/,/[@]END_APPARMOR_2[@]/d',
'@INPUT@'
]
else
apparmor_gen_cmd = [
'sed',
'-e', '/[@]BEGIN_APPARMOR_3[@]/,/[@]END_APPARMOR_3[@]/d',
'-e', '/[@]BEGIN_APPARMOR_2[@]/d',
'-e', '/[@]END_APPARMOR_2[@]/d',
'@INPUT@'
]
endif
foreach name : apparmor_gen_profiles
configure_file(
tmp = configure_file(
input: '@0@.in'.format(name),
output: '@0@.tmp'.format(name),
command: apparmor_gen_cmd,
capture: true,
)
configure_file(
input: tmp,
output: name,
configuration: apparmor_gen_profiles_conf,
install: true,
@ -24,12 +61,29 @@ foreach name : apparmor_gen_profiles
)
endforeach
install_data(
[ 'libvirt-qemu', 'libvirt-lxc' ],
install_dir: apparmor_dir / 'abstractions',
)
foreach name : apparmor_gen_abstractions
configure_file(
input: '@0@.in'.format(name),
output: name,
command: apparmor_gen_cmd,
capture: true,
install: true,
install_dir: apparmor_dir / 'abstractions',
)
endforeach
install_data(
[ 'TEMPLATE.qemu', 'TEMPLATE.lxc' ],
install_dir: apparmor_dir / 'libvirt',
)
if not conf.has('WITH_APPARMOR_3')
# We only install the empty local override for AppArmor 2.x. For
# AppArmor 3.x, upstream's preference is to avoid creating these
# files in order to limit the amount of filesystem clutter.
install_data(
'usr.lib.libvirt.virt-aa-helper.local',
install_dir: apparmor_dir / 'local',
rename: 'usr.lib.libvirt.virt-aa-helper',
)
endif

View File

@ -74,5 +74,10 @@ profile virt-aa-helper @libexecdir@/virt-aa-helper {
/**.[iI][sS][oO] r,
/**/disk{,.*} r,
@BEGIN_APPARMOR_3@
include if exists <local/usr.lib.libvirt.virt-aa-helper>
@END_APPARMOR_3@
@BEGIN_APPARMOR_2@
#include <local/usr.lib.libvirt.virt-aa-helper>
@END_APPARMOR_2@
}

View File

@ -144,5 +144,7 @@ profile libvirtd @sbindir@/libvirtd flags=(attach_disconnected) {
/usr/{lib,lib64,lib/qemu,libexec,libexec/qemu}/qemu-bridge-helper rmix,
}
@BEGIN_APPARMOR_3@
include if exists <local/usr.sbin.libvirtd>
@END_APPARMOR_3@
}

View File

@ -136,5 +136,7 @@ profile virtqemud @sbindir@/virtqemud flags=(attach_disconnected) {
/usr/{lib,lib64,lib/qemu,libexec,libexec/qemu}/qemu-bridge-helper rmix,
}
@BEGIN_APPARMOR_3@
include if exists <local/usr.sbin.virtqemud>
@END_APPARMOR_3@
}

View File

@ -55,5 +55,7 @@ profile virtxend @sbindir@/virtxend flags=(attach_disconnected) {
/etc/libvirt/hooks/** rmix,
/etc/xen/scripts/** rmix,
@BEGIN_APPARMOR_3@
include if exists <local/usr.sbin.virtxend>
@END_APPARMOR_3@
}

View File

@ -1560,8 +1560,13 @@ main(int argc, char **argv)
/* create the profile from TEMPLATE */
if (ctl->cmd == 'c' || purged) {
g_autofree char *tmp = g_strdup_printf(
" #include if exists <libvirt/%s.files>\n", ctl->uuid);
g_autofree char *tmp = NULL;
#if defined(WITH_APPARMOR_3)
const char *ifexists = "if exists ";
#else
const char *ifexists = "";
#endif
tmp = g_strdup_printf(" #include %s<libvirt/%s.files>\n", ifexists, ctl->uuid);
if (ctl->dryrun) {
vah_info(profile);

View File

@ -1939,7 +1939,6 @@ storageVolCreateXML(virStoragePoolPtr pool,
if (backend->buildVol) {
int buildret;
virStorageVolDef *buildvoldef = NULL;
unsigned int buildFlags = flags;
buildvoldef = g_new0(virStorageVolDef, 1);
@ -1954,8 +1953,7 @@ storageVolCreateXML(virStoragePoolPtr pool,
voldef->building = true;
virObjectUnlock(obj);
buildFlags &= ~VIR_STORAGE_VOL_CREATE_VALIDATE;
buildret = backend->buildVol(obj, buildvoldef, buildFlags);
buildret = backend->buildVol(obj, buildvoldef, flags);
VIR_FREE(buildvoldef);

View File

@ -74,7 +74,6 @@ virStorageFileBackendGlusterInitServer(virStorageFileBackendGlusterPriv *priv,
hoststr = host->socket;
break;
case VIR_STORAGE_NET_HOST_TRANS_FD:
case VIR_STORAGE_NET_HOST_TRANS_LAST:
break;
}

View File

@ -637,8 +637,10 @@ virBitmapNewData(const void *data,
* Convert a bitmap to a chunk of data containing bits information.
* Data consists of sequential bytes, with lower bytes containing
* lower bits. This function allocates @data.
*
* Returns 0 on success, -1 otherwise.
*/
void
int
virBitmapToData(virBitmap *bitmap,
unsigned char **data,
int *dataLen)
@ -654,6 +656,8 @@ virBitmapToData(virBitmap *bitmap,
*dataLen = len;
virBitmapToDataBuf(bitmap, *data, *dataLen);
return 0;
}

View File

@ -91,7 +91,7 @@ virBitmap *virBitmapNewCopy(virBitmap *src) ATTRIBUTE_NONNULL(1);
virBitmap *virBitmapNewData(const void *data, int len) ATTRIBUTE_NONNULL(1);
void virBitmapToData(virBitmap *bitmap, unsigned char **data, int *dataLen)
int virBitmapToData(virBitmap *bitmap, unsigned char **data, int *dataLen)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
void virBitmapToDataBuf(virBitmap *bitmap, unsigned char *data, size_t len)

View File

@ -643,8 +643,9 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
int nodecpus, nodecores, nodesockets, nodethreads, offline = 0;
int threads_per_subcore = 0;
unsigned int node;
g_autofree char *sysfs_nodedir = NULL;
g_autofree char *sysfs_cpudir_fallback = NULL;
int ret = -1;
char *sysfs_nodedir = NULL;
char *sysfs_cpudir = NULL;
int direrr;
*mhz = 0;
@ -658,11 +659,12 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
/* Get information about what CPUs are present in the host and what
* CPUs are online, so that we don't have to so for each node */
if (!(present_cpus_map = virHostCPUGetPresentBitmap()))
return -1;
if (!(online_cpus_map = virHostCPUGetOnlineBitmap()))
return -1;
present_cpus_map = virHostCPUGetPresentBitmap();
if (!present_cpus_map)
goto cleanup;
online_cpus_map = virHostCPUGetOnlineBitmap();
if (!online_cpus_map)
goto cleanup;
/* OK, we've parsed clock speed out of /proc/cpuinfo. Get the
* core, node, socket, thread and topology information from /sys
@ -697,7 +699,7 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
* On hosts other than POWER this will be 0, in which case a simpler
* thread-counting logic will be used */
if ((threads_per_subcore = virHostCPUGetThreadsPerSubcore(arch)) < 0)
return -1;
goto cleanup;
/* If the subcore configuration is not valid, just pretend subcores
* are not in use and count threads one by one */
@ -705,8 +707,6 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
threads_per_subcore = 0;
while ((direrr = virDirRead(nodedir, &nodedirent, sysfs_nodedir)) > 0) {
g_autofree char *sysfs_cpudir = NULL;
if (sscanf(nodedirent->d_name, "node%u", &node) != 1)
continue;
@ -721,7 +721,9 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
threads_per_subcore,
&nodesockets, &nodecores,
&nodethreads, &offline)) < 0)
return -1;
goto cleanup;
VIR_FREE(sysfs_cpudir);
*cpus += nodecpus;
@ -736,21 +738,23 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
}
if (direrr < 0)
return -1;
goto cleanup;
if (*cpus && *nodes)
goto done;
fallback:
sysfs_cpudir_fallback = g_strdup_printf("%s/cpu", SYSFS_SYSTEM_PATH);
VIR_FREE(sysfs_cpudir);
if ((nodecpus = virHostCPUParseNode(sysfs_cpudir_fallback, arch,
sysfs_cpudir = g_strdup_printf("%s/cpu", SYSFS_SYSTEM_PATH);
if ((nodecpus = virHostCPUParseNode(sysfs_cpudir, arch,
present_cpus_map,
online_cpus_map,
threads_per_subcore,
&nodesockets, &nodecores,
&nodethreads, &offline)) < 0)
return -1;
goto cleanup;
*nodes = 1;
*cpus = nodecpus;
@ -762,17 +766,17 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
/* There should always be at least one cpu, socket, node, and thread. */
if (*cpus == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no CPUs found"));
return -1;
goto cleanup;
}
if (*sockets == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no sockets found"));
return -1;
goto cleanup;
}
if (*threads == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no threads found"));
return -1;
goto cleanup;
}
/* Now check if the topology makes sense. There are machines that don't
@ -792,7 +796,12 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
*threads = 1;
}
return 0;
ret = 0;
cleanup:
VIR_FREE(sysfs_nodedir);
VIR_FREE(sysfs_cpudir);
return ret;
}
# define TICK_TO_NSEC (1000ull * 1000ull * 1000ull / sysconf(_SC_CLK_TCK))
@ -1101,8 +1110,8 @@ virHostCPUGetMap(unsigned char **cpumap,
if (!(cpus = virHostCPUGetOnlineBitmap()))
goto cleanup;
if (cpumap)
virBitmapToData(cpus, cpumap, &dummy);
if (cpumap && virBitmapToData(cpus, cpumap, &dummy) < 0)
goto cleanup;
if (online)
*online = virBitmapCountBits(cpus);

View File

@ -70,14 +70,11 @@ virInhibitorAcquire(const char *what,
VIR_DEBUG("what=%s who=%s why=%s mode=%s",
NULLSTR(what), NULLSTR(who), NULLSTR(why), NULLSTR(mode));
if (!virGDBusHasSystemBus()) {
if (!(systemBus = virGDBusGetSystemBus())) {
VIR_DEBUG("system dbus not available, skipping system inhibitor");
return 0;
}
if (!(systemBus = virGDBusGetSystemBus()))
return 0;
if (virSystemdHasLogind() < 0) {
VIR_DEBUG("logind not available, skipping system inhibitor");
return 0;

View File

@ -4553,507 +4553,6 @@ static int vboxCloseDisksRecursively(virDomainPtr dom, char *location)
return ret;
}
static int
vboxSnapshotReplaceRWDisks(struct _vboxDriver *data,
virVBoxSnapshotConfMachine *snapshotMachineDesc,
char *currentSnapshotXmlFilePath)
{
g_auto(GStrv) realReadWriteDisksPath = NULL;
g_auto(GStrv) realReadOnlyDisksPath = NULL;
int realReadWriteDisksPathSize = 0;
int realReadOnlyDisksPathSize = 0;
int it = 0;
/*
* We have created fake disks, so we have to remove them and replace them with
* the read-write disks if there are any. The fake disks will be closed during
* the machine unregistration.
*/
if (virVBoxSnapshotConfRemoveFakeDisks(snapshotMachineDesc) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to remove Fake Disks"));
return -1;
}
realReadWriteDisksPathSize = virVBoxSnapshotConfGetRWDisksPathsFromLibvirtXML(currentSnapshotXmlFilePath,
&realReadWriteDisksPath);
realReadOnlyDisksPathSize = virVBoxSnapshotConfGetRODisksPathsFromLibvirtXML(currentSnapshotXmlFilePath,
&realReadOnlyDisksPath);
/* The read-only disk number is necessarily greater or equal to the
* read-write disk number */
if (realReadOnlyDisksPathSize < realReadWriteDisksPathSize) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("The read only disk number must be greater or equal to the read write disk number"));
return -1;
}
for (it = 0; it < realReadWriteDisksPathSize; it++) {
virVBoxSnapshotConfHardDisk *readWriteDisk = NULL;
PRUnichar *locationUtf = NULL;
IMedium *readWriteMedium = NULL;
char *uuid = NULL;
PRUnichar *formatUtf = NULL;
char *format = NULL;
const char *parentUuid = NULL;
vboxIID iid;
nsresult rc;
VBOX_IID_INITIALIZE(&iid);
VBOX_UTF8_TO_UTF16(realReadWriteDisksPath[it], &locationUtf);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&readWriteMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
VBOX_UTF16_FREE(locationUtf);
return -1;
}
VBOX_UTF16_FREE(locationUtf);
rc = gVBoxAPI.UIMedium.GetId(readWriteMedium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get the read write medium id"));
return -1;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
vboxIIDUnalloc(&iid);
rc = gVBoxAPI.UIMedium.GetFormat(readWriteMedium, &formatUtf);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get the read write medium format"));
return -1;
}
VBOX_UTF16_TO_UTF8(formatUtf, &format);
VBOX_UTF16_FREE(formatUtf);
readWriteDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
readWriteDisk->format = format;
readWriteDisk->uuid = uuid;
readWriteDisk->location = realReadWriteDisksPath[it];
/*
* We get the current snapshot's read-only disk uuid in order to add the
* read-write disk to the media registry as its child. The read-only disk
* is already in the media registry because it is the fake disk's parent.
*/
parentUuid = virVBoxSnapshotConfHardDiskUuidByLocation(snapshotMachineDesc,
realReadOnlyDisksPath[it]);
if (parentUuid == NULL) {
VIR_FREE(readWriteDisk);
return -1;
}
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(readWriteDisk,
snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to media Registry"));
VIR_FREE(readWriteDisk);
return -1;
}
rc = gVBoxAPI.UIMedium.Close(readWriteMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close HardDisk"));
return -1;
}
}
return 0;
}
static int
vboxSnapshotAddDisksToMediaRegistry(struct _vboxDriver *data,
virDomainSnapshotDef *def,
virVBoxSnapshotConfMachine *snapshotMachineDesc)
{
int it = 0;
for (it = 0; it < def->parent.dom->ndisks; it++) {
int diskInMediaRegistry = 0;
IMedium *readOnlyMedium = NULL;
PRUnichar *locationUtf = NULL;
char *uuid = NULL;
PRUnichar *formatUtf = NULL;
char *format = NULL;
char *parentUuid = NULL;
virVBoxSnapshotConfHardDisk *readOnlyDisk = NULL;
vboxIID iid, parentiid;
IMedium *parentReadOnlyMedium = NULL;
nsresult rc;
VBOX_IID_INITIALIZE(&iid);
VBOX_IID_INITIALIZE(&parentiid);
diskInMediaRegistry = virVBoxSnapshotConfDiskIsInMediaRegistry(snapshotMachineDesc,
def->parent.dom->disks[it]->src->path);
if (diskInMediaRegistry == -1) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to know if disk is in media registry"));
return -1;
}
if (diskInMediaRegistry == 1) /* Nothing to do. */
continue;
/* The read only disk is not in the media registry */
VBOX_UTF8_TO_UTF16(def->parent.dom->disks[it]->src->path, &locationUtf);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&readOnlyMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
VBOX_UTF16_FREE(locationUtf);
return -1;
}
VBOX_UTF16_FREE(locationUtf);
rc = gVBoxAPI.UIMedium.GetId(readOnlyMedium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk id"));
return -1;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
vboxIIDUnalloc(&iid);
rc = gVBoxAPI.UIMedium.GetFormat(readOnlyMedium, &formatUtf);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk format"));
VIR_FREE(uuid);
return -1;
}
VBOX_UTF16_TO_UTF8(formatUtf, &format);
VBOX_UTF16_FREE(formatUtf);
/* This disk is already in the media registry */
rc = gVBoxAPI.UIMedium.GetParent(readOnlyMedium, &parentReadOnlyMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get parent hard disk"));
VIR_FREE(uuid);
return -1;
}
rc = gVBoxAPI.UIMedium.GetId(parentReadOnlyMedium, &parentiid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk id"));
VIR_FREE(uuid);
return -1;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
vboxIIDUnalloc(&parentiid);
rc = gVBoxAPI.UIMedium.Close(readOnlyMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close HardDisk"));
VIR_FREE(uuid);
VIR_FREE(parentUuid);
return -1;
}
readOnlyDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
readOnlyDisk->format = format;
readOnlyDisk->uuid = uuid;
readOnlyDisk->location = g_strdup(def->parent.dom->disks[it]->src->path);
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(readOnlyDisk, snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to media registry"));
VIR_FREE(readOnlyDisk);
return -1;
}
}
return 0;
}
static int
vboxSnapshotAddRWDisks(struct _vboxDriver *data,
virDomainSnapshotDef *def,
virVBoxSnapshotConfMachine *snapshotMachineDesc,
bool needToChangeStorageController)
{
int it = 0;
for (it = 0; it < def->ndisks; it++) {
IMedium *medium = NULL;
PRUnichar *locationUtf16 = NULL;
virVBoxSnapshotConfHardDisk *disk = NULL;
PRUnichar *formatUtf16 = NULL;
char *format = NULL;
char *uuid = NULL;
IMedium *parentDisk = NULL;
char *parentUuid = NULL;
vboxIID iid, parentiid;
nsresult rc;
VBOX_IID_INITIALIZE(&iid);
VBOX_IID_INITIALIZE(&parentiid);
VBOX_UTF8_TO_UTF16(def->disks[it].src->path, &locationUtf16);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf16,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&medium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
return -1;
}
VBOX_UTF16_FREE(locationUtf16);
disk = g_new0(virVBoxSnapshotConfHardDisk, 1);
rc = gVBoxAPI.UIMedium.GetFormat(medium, &formatUtf16);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get disk format"));
VIR_FREE(disk);
return -1;
}
VBOX_UTF16_TO_UTF8(formatUtf16, &format);
disk->format = format;
VBOX_UTF16_FREE(formatUtf16);
disk->location = g_strdup(def->disks[it].src->path);
rc = gVBoxAPI.UIMedium.GetId(medium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get disk uuid"));
VIR_FREE(disk);
return -1;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
disk->uuid = uuid;
vboxIIDUnalloc(&iid);
rc = gVBoxAPI.UIMedium.GetParent(medium, &parentDisk);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get disk parent"));
VIR_FREE(disk);
return -1;
}
gVBoxAPI.UIMedium.GetId(parentDisk, &parentiid);
gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
vboxIIDUnalloc(&parentiid);
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(disk,
snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to the media registry"));
VIR_FREE(disk);
return -1;
}
if (needToChangeStorageController) {
/* We need to append this disk in the storage controller */
g_auto(GStrv) searchResultTab = NULL;
char *tmp = NULL;
ssize_t resultSize = 0;
resultSize = virStringSearch(snapshotMachineDesc->storageController,
VBOX_UUID_REGEX,
it + 1,
&searchResultTab);
if (resultSize != it + 1) {
vboxReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find UUID %1$s"), searchResultTab[it]);
return -1;
}
tmp = virStringReplace(snapshotMachineDesc->storageController,
searchResultTab[it],
disk->uuid);
VIR_FREE(snapshotMachineDesc->storageController);
if (!tmp)
return -1;
snapshotMachineDesc->storageController = g_strdup(tmp);
VIR_FREE(tmp);
}
/* Close disk */
rc = gVBoxAPI.UIMedium.Close(medium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close HardDisk"));
return -1;
}
}
return 0;
}
static int
vboxSnapshotCreateFakeDiffStorage(struct _vboxDriver *data,
virDomainSnapshotDef *def,
char *machineLocationPath,
virVBoxSnapshotConfMachine *snapshotMachineDesc)
{
virVBoxSnapshotConfHardDisk *newHardDisk = NULL;
int it;
int ret = -1;
for (it = 0; it < def->parent.dom->ndisks; it++) {
IMedium *medium = NULL;
PRUnichar *locationUtf16 = NULL;
char *parentUuid = NULL;
IMedium *newMedium = NULL;
PRUnichar *formatUtf16 = NULL;
PRUnichar *newLocation = NULL;
char *newLocationUtf8 = NULL;
resultCodeUnion resultCode;
char *uuid = NULL;
char *format = NULL;
char *tmp = NULL;
vboxIID iid, parentiid;
IProgress *progress = NULL;
PRUint32 tab[1];
nsresult rc;
g_auto(GStrv) searchResultTab = NULL;
ssize_t resultSize = 0;
VBOX_IID_INITIALIZE(&iid);
VBOX_IID_INITIALIZE(&parentiid);
VBOX_UTF8_TO_UTF16(def->parent.dom->disks[it]->src->path, &locationUtf16);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf16,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&medium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
VBOX_UTF16_FREE(locationUtf16);
goto cleanup;
}
VBOX_UTF16_FREE(locationUtf16);
rc = gVBoxAPI.UIMedium.GetId(medium, &parentiid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk id"));
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
vboxIIDUnalloc(&parentiid);
VBOX_UTF8_TO_UTF16("VDI", &formatUtf16);
newLocationUtf8 = g_strdup_printf("%sfakedisk-%d.vdi",
machineLocationPath, it);
VBOX_UTF8_TO_UTF16(newLocationUtf8, &newLocation);
rc = gVBoxAPI.UIVirtualBox.CreateHardDisk(data->vboxObj,
formatUtf16,
newLocation,
&newMedium);
VBOX_UTF16_FREE(newLocation);
VBOX_UTF16_FREE(formatUtf16);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to create HardDisk"));
goto cleanup;
}
tab[0] = MediumVariant_Diff;
gVBoxAPI.UIMedium.CreateDiffStorage(medium, newMedium, 1, tab, &progress);
gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
if (RC_FAILED(resultCode)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR,
_("Error while creating diff storage, rc=%1$08x"),
resultCode.uResultCode);
goto cleanup;
}
VBOX_RELEASE(progress);
/*
* The differential newHardDisk is created, we add it to the
* media registry and the machine storage controllers.
*/
newHardDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
rc = gVBoxAPI.UIMedium.GetId(newMedium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get medium uuid"));
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
newHardDisk->uuid = uuid;
vboxIIDUnalloc(&iid);
newHardDisk->location = g_strdup(newLocationUtf8);
rc = gVBoxAPI.UIMedium.GetFormat(newMedium, &formatUtf16);
VBOX_UTF16_TO_UTF8(formatUtf16, &format);
newHardDisk->format = format;
VBOX_UTF16_FREE(formatUtf16);
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(newHardDisk,
snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to the media registry"));
goto cleanup;
}
newHardDisk = NULL; /* Consumed by above */
/* Adding the fake disk to the machine storage controllers */
resultSize = virStringSearch(snapshotMachineDesc->storageController,
VBOX_UUID_REGEX,
it + 1,
&searchResultTab);
if (resultSize != it + 1) {
vboxReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find UUID %1$s"), searchResultTab[it]);
goto cleanup;
}
tmp = virStringReplace(snapshotMachineDesc->storageController,
searchResultTab[it],
uuid);
VIR_FREE(snapshotMachineDesc->storageController);
if (!tmp)
goto cleanup;
snapshotMachineDesc->storageController = g_strdup(tmp);
VIR_FREE(tmp);
/* Closing the "fake" disk */
rc = gVBoxAPI.UIMedium.Close(newMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close the new medium"));
goto cleanup;
}
}
ret = 0;
cleanup:
virVboxSnapshotConfHardDiskFree(newHardDisk);
return ret;
}
static int
vboxSnapshotRedefine(virDomainPtr dom,
virDomainSnapshotDef *def,
@ -5097,10 +4596,15 @@ vboxSnapshotRedefine(virDomainPtr dom,
char *currentSnapshotXmlFilePath = NULL;
PRUnichar *machineNameUtf16 = NULL;
char *machineName = NULL;
g_auto(GStrv) realReadWriteDisksPath = NULL;
int realReadWriteDisksPathSize = 0;
g_auto(GStrv) realReadOnlyDisksPath = NULL;
int realReadOnlyDisksPathSize = 0;
virVBoxSnapshotConfSnapshot *newSnapshotPtr = NULL;
unsigned char snapshotUuid[VIR_UUID_BUFLEN];
virVBoxSnapshotConfHardDisk **hardDiskToOpen = NULL;
size_t hardDiskToOpenSize = 0;
virVBoxSnapshotConfHardDisk *newHardDisk = NULL;
g_auto(GStrv) searchResultTab = NULL;
ssize_t resultSize = 0;
int it = 0;
@ -5164,10 +4668,102 @@ vboxSnapshotRedefine(virDomainPtr dom,
}
if (snapshotFileExists) {
if (vboxSnapshotReplaceRWDisks(data, snapshotMachineDesc,
currentSnapshotXmlFilePath) < 0)
/*
* We have created fake disks, so we have to remove them and replace them with
* the read-write disks if there are any. The fake disks will be closed during
* the machine unregistration.
*/
if (virVBoxSnapshotConfRemoveFakeDisks(snapshotMachineDesc) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to remove Fake Disks"));
goto cleanup;
}
realReadWriteDisksPathSize = virVBoxSnapshotConfGetRWDisksPathsFromLibvirtXML(currentSnapshotXmlFilePath,
&realReadWriteDisksPath);
realReadOnlyDisksPathSize = virVBoxSnapshotConfGetRODisksPathsFromLibvirtXML(currentSnapshotXmlFilePath,
&realReadOnlyDisksPath);
/* The read-only disk number is necessarily greater or equal to the
* read-write disk number */
if (realReadOnlyDisksPathSize < realReadWriteDisksPathSize) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("The read only disk number must be greater or equal to the read write disk number"));
goto cleanup;
}
for (it = 0; it < realReadWriteDisksPathSize; it++) {
virVBoxSnapshotConfHardDisk *readWriteDisk = NULL;
PRUnichar *locationUtf = NULL;
IMedium *readWriteMedium = NULL;
char *uuid = NULL;
PRUnichar *formatUtf = NULL;
char *format = NULL;
const char *parentUuid = NULL;
vboxIID iid;
VBOX_IID_INITIALIZE(&iid);
VBOX_UTF8_TO_UTF16(realReadWriteDisksPath[it], &locationUtf);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&readWriteMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
VBOX_UTF16_FREE(locationUtf);
goto cleanup;
}
VBOX_UTF16_FREE(locationUtf);
rc = gVBoxAPI.UIMedium.GetId(readWriteMedium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get the read write medium id"));
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
vboxIIDUnalloc(&iid);
rc = gVBoxAPI.UIMedium.GetFormat(readWriteMedium, &formatUtf);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get the read write medium format"));
goto cleanup;
}
VBOX_UTF16_TO_UTF8(formatUtf, &format);
VBOX_UTF16_FREE(formatUtf);
readWriteDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
readWriteDisk->format = format;
readWriteDisk->uuid = uuid;
readWriteDisk->location = realReadWriteDisksPath[it];
/*
* We get the current snapshot's read-only disk uuid in order to add the
* read-write disk to the media registry as its child. The read-only disk
* is already in the media registry because it is the fake disk's parent.
*/
parentUuid = virVBoxSnapshotConfHardDiskUuidByLocation(snapshotMachineDesc,
realReadOnlyDisksPath[it]);
if (parentUuid == NULL) {
VIR_FREE(readWriteDisk);
goto cleanup;
}
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(readWriteDisk,
snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to media Registry"));
VIR_FREE(readWriteDisk);
goto cleanup;
}
rc = gVBoxAPI.UIMedium.Close(readWriteMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close HardDisk"));
goto cleanup;
}
}
/*
* Now we have done this swap, we remove the snapshot xml file from the
* current machine location.
@ -5183,8 +4779,106 @@ vboxSnapshotRedefine(virDomainPtr dom,
* read-only disks are in the redefined snapshot's media registry (the disks need to
* be open to query their uuid).
*/
if (vboxSnapshotAddDisksToMediaRegistry(data, def, snapshotMachineDesc) < 0)
goto cleanup;
for (it = 0; it < def->parent.dom->ndisks; it++) {
int diskInMediaRegistry = 0;
IMedium *readOnlyMedium = NULL;
PRUnichar *locationUtf = NULL;
char *uuid = NULL;
PRUnichar *formatUtf = NULL;
char *format = NULL;
char *parentUuid = NULL;
virVBoxSnapshotConfHardDisk *readOnlyDisk = NULL;
vboxIID iid, parentiid;
IMedium *parentReadOnlyMedium = NULL;
VBOX_IID_INITIALIZE(&iid);
VBOX_IID_INITIALIZE(&parentiid);
diskInMediaRegistry = virVBoxSnapshotConfDiskIsInMediaRegistry(snapshotMachineDesc,
def->parent.dom->disks[it]->src->path);
if (diskInMediaRegistry == -1) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to know if disk is in media registry"));
goto cleanup;
}
if (diskInMediaRegistry == 1) /* Nothing to do. */
continue;
/* The read only disk is not in the media registry */
VBOX_UTF8_TO_UTF16(def->parent.dom->disks[it]->src->path, &locationUtf);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&readOnlyMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
VBOX_UTF16_FREE(locationUtf);
goto cleanup;
}
VBOX_UTF16_FREE(locationUtf);
rc = gVBoxAPI.UIMedium.GetId(readOnlyMedium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk id"));
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
vboxIIDUnalloc(&iid);
rc = gVBoxAPI.UIMedium.GetFormat(readOnlyMedium, &formatUtf);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk format"));
VIR_FREE(uuid);
goto cleanup;
}
VBOX_UTF16_TO_UTF8(formatUtf, &format);
VBOX_UTF16_FREE(formatUtf);
/* This disk is already in the media registry */
rc = gVBoxAPI.UIMedium.GetParent(readOnlyMedium, &parentReadOnlyMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get parent hard disk"));
VIR_FREE(uuid);
goto cleanup;
}
rc = gVBoxAPI.UIMedium.GetId(parentReadOnlyMedium, &parentiid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk id"));
VIR_FREE(uuid);
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
vboxIIDUnalloc(&parentiid);
rc = gVBoxAPI.UIMedium.Close(readOnlyMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close HardDisk"));
VIR_FREE(uuid);
VIR_FREE(parentUuid);
goto cleanup;
}
readOnlyDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
readOnlyDisk->format = format;
readOnlyDisk->uuid = uuid;
readOnlyDisk->location = g_strdup(def->parent.dom->disks[it]->src->path);
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(readOnlyDisk, snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to media registry"));
VIR_FREE(readOnlyDisk);
goto cleanup;
}
}
/* Now, we can unregister the machine */
rc = gVBoxAPI.UIMachine.Unregister(machine,
@ -5368,20 +5062,243 @@ vboxSnapshotRedefine(virDomainPtr dom,
* If the snapshot to redefine is the current snapshot, we add read-write disks in
* the machine storage controllers.
*/
if (vboxSnapshotAddRWDisks(data, def, snapshotMachineDesc,
needToChangeStorageController) < 0) {
goto cleanup;
for (it = 0; it < def->ndisks; it++) {
IMedium *medium = NULL;
PRUnichar *locationUtf16 = NULL;
virVBoxSnapshotConfHardDisk *disk = NULL;
PRUnichar *formatUtf16 = NULL;
char *format = NULL;
char *uuid = NULL;
IMedium *parentDisk = NULL;
char *parentUuid = NULL;
vboxIID iid, parentiid;
VBOX_IID_INITIALIZE(&iid);
VBOX_IID_INITIALIZE(&parentiid);
VBOX_UTF8_TO_UTF16(def->disks[it].src->path, &locationUtf16);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf16,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&medium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
goto cleanup;
}
VBOX_UTF16_FREE(locationUtf16);
disk = g_new0(virVBoxSnapshotConfHardDisk, 1);
rc = gVBoxAPI.UIMedium.GetFormat(medium, &formatUtf16);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get disk format"));
VIR_FREE(disk);
goto cleanup;
}
VBOX_UTF16_TO_UTF8(formatUtf16, &format);
disk->format = format;
VBOX_UTF16_FREE(formatUtf16);
disk->location = g_strdup(def->disks[it].src->path);
rc = gVBoxAPI.UIMedium.GetId(medium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get disk uuid"));
VIR_FREE(disk);
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
disk->uuid = uuid;
vboxIIDUnalloc(&iid);
rc = gVBoxAPI.UIMedium.GetParent(medium, &parentDisk);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get disk parent"));
VIR_FREE(disk);
goto cleanup;
}
gVBoxAPI.UIMedium.GetId(parentDisk, &parentiid);
gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
vboxIIDUnalloc(&parentiid);
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(disk,
snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to the media registry"));
VIR_FREE(disk);
goto cleanup;
}
if (needToChangeStorageController) {
/* We need to append this disk in the storage controller */
char *tmp = NULL;
resultSize = virStringSearch(snapshotMachineDesc->storageController,
VBOX_UUID_REGEX,
it + 1,
&searchResultTab);
if (resultSize != it + 1) {
vboxReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find UUID %1$s"), searchResultTab[it]);
goto cleanup;
}
tmp = virStringReplace(snapshotMachineDesc->storageController,
searchResultTab[it],
disk->uuid);
VIR_FREE(snapshotMachineDesc->storageController);
if (!tmp)
goto cleanup;
snapshotMachineDesc->storageController = g_strdup(tmp);
VIR_FREE(tmp);
}
/* Close disk */
rc = gVBoxAPI.UIMedium.Close(medium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close HardDisk"));
goto cleanup;
}
}
} else {
char *snapshotContent;
/* Create a "fake" disk to avoid corrupting children snapshot disks. */
if (vboxSnapshotCreateFakeDiffStorage(data, def,
machineLocationPath,
snapshotMachineDesc) < 0) {
goto cleanup;
}
for (it = 0; it < def->parent.dom->ndisks; it++) {
IMedium *medium = NULL;
PRUnichar *locationUtf16 = NULL;
char *parentUuid = NULL;
IMedium *newMedium = NULL;
PRUnichar *formatUtf16 = NULL;
PRUnichar *newLocation = NULL;
char *newLocationUtf8 = NULL;
resultCodeUnion resultCode;
char *uuid = NULL;
char *format = NULL;
char *tmp = NULL;
vboxIID iid, parentiid;
IProgress *progress = NULL;
PRUint32 tab[1];
VBOX_IID_INITIALIZE(&iid);
VBOX_IID_INITIALIZE(&parentiid);
VBOX_UTF8_TO_UTF16(def->parent.dom->disks[it]->src->path, &locationUtf16);
rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
locationUtf16,
DeviceType_HardDisk,
AccessMode_ReadWrite,
&medium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to open HardDisk"));
VBOX_UTF16_FREE(locationUtf16);
goto cleanup;
}
VBOX_UTF16_FREE(locationUtf16);
rc = gVBoxAPI.UIMedium.GetId(medium, &parentiid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get hard disk id"));
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
vboxIIDUnalloc(&parentiid);
VBOX_UTF8_TO_UTF16("VDI", &formatUtf16);
newLocationUtf8 = g_strdup_printf("%sfakedisk-%d.vdi",
machineLocationPath, it);
VBOX_UTF8_TO_UTF16(newLocationUtf8, &newLocation);
rc = gVBoxAPI.UIVirtualBox.CreateHardDisk(data->vboxObj,
formatUtf16,
newLocation,
&newMedium);
VBOX_UTF16_FREE(newLocation);
VBOX_UTF16_FREE(formatUtf16);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to create HardDisk"));
goto cleanup;
}
tab[0] = MediumVariant_Diff;
gVBoxAPI.UIMedium.CreateDiffStorage(medium, newMedium, 1, tab, &progress);
gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
if (RC_FAILED(resultCode)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR,
_("Error while creating diff storage, rc=%1$08x"),
resultCode.uResultCode);
goto cleanup;
}
VBOX_RELEASE(progress);
/*
* The differential newHardDisk is created, we add it to the
* media registry and the machine storage controllers.
*/
newHardDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
rc = gVBoxAPI.UIMedium.GetId(newMedium, &iid);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get medium uuid"));
goto cleanup;
}
gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
newHardDisk->uuid = uuid;
vboxIIDUnalloc(&iid);
newHardDisk->location = g_strdup(newLocationUtf8);
rc = gVBoxAPI.UIMedium.GetFormat(newMedium, &formatUtf16);
VBOX_UTF16_TO_UTF8(formatUtf16, &format);
newHardDisk->format = format;
VBOX_UTF16_FREE(formatUtf16);
if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(newHardDisk,
snapshotMachineDesc->mediaRegistry,
parentUuid) < 0) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to add hard disk to the media registry"));
goto cleanup;
}
newHardDisk = NULL; /* Consumed by above */
/* Adding the fake disk to the machine storage controllers */
resultSize = virStringSearch(snapshotMachineDesc->storageController,
VBOX_UUID_REGEX,
it + 1,
&searchResultTab);
if (resultSize != it + 1) {
vboxReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find UUID %1$s"), searchResultTab[it]);
goto cleanup;
}
tmp = virStringReplace(snapshotMachineDesc->storageController,
searchResultTab[it],
uuid);
VIR_FREE(snapshotMachineDesc->storageController);
if (!tmp)
goto cleanup;
snapshotMachineDesc->storageController = g_strdup(tmp);
VIR_FREE(tmp);
/* Closing the "fake" disk */
rc = gVBoxAPI.UIMedium.Close(newMedium);
if (NS_FAILED(rc)) {
vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to close the new medium"));
goto cleanup;
}
}
/*
* We save the snapshot xml file to retrieve the real read-write disk during the
* next define. This file is saved as "'machineLocation'/snapshot-'uuid'.xml"
@ -5470,6 +5387,7 @@ vboxSnapshotRedefine(virDomainPtr dom,
VIR_FREE(currentSnapshotXmlFilePath);
VBOX_UTF16_FREE(machineNameUtf16);
VBOX_UTF8_FREE(machineName);
virVboxSnapshotConfHardDiskFree(newHardDisk);
VIR_FREE(hardDiskToOpen);
VIR_FREE(newSnapshotPtr);
VIR_FREE(machineLocationPath);

View File

@ -1,8 +0,0 @@
/usr/sbin/bhyve \
-c 1 \
-m 214 \
-H \
-P \
-s 0:0,hostbridge \
-s 1:0,virtio-rnd \
bhyve

View File

@ -1,20 +0,0 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type>hvm</type>
</os>
<clock offset='localtime'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>destroy</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<rng model='virtio'>
<backend model='random'>/dev/random</backend>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</rng>
</devices>
</domain>

View File

@ -188,7 +188,6 @@ mymain(void)
DO_TEST("vnc-vga-io");
DO_TEST("vnc-resolution");
DO_TEST("vnc-password");
DO_TEST("virtio-rnd");
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);

View File

@ -1,26 +0,0 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<mac address='52:54:00:b9:94:02'/>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<rng model='virtio'>
<backend model='builtin'/>
</rng>
</devices>
</domain>

View File

@ -1,26 +0,0 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<mac address='52:54:00:b9:94:02'/>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<rng model='virtio'>
<backend model='random'>/random/dev</backend>
</rng>
</devices>
</domain>

View File

@ -1,26 +0,0 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<mac address='52:54:00:b9:94:02'/>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<rng model='virtio-transitional'>
<backend model='random'/>
</rng>
</devices>
</domain>

View File

@ -1,11 +0,0 @@
bhyve \
-c 1 \
-m 214 \
-u \
-H \
-P \
-s 0:0,hostbridge \
-s 2:0,ahci,hd:/tmp/freebsd.img \
-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \
-s 4:0,virtio-rnd \
bhyve

View File

@ -1,4 +0,0 @@
bhyveload \
-m 214 \
-d /tmp/freebsd.img \
bhyve

View File

@ -1,26 +0,0 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory>219136</memory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
</os>
<devices>
<disk type='file'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<interface type='bridge'>
<mac address='52:54:00:b9:94:02'/>
<model type='virtio'/>
<source bridge="virbr0"/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<rng model='virtio'>
<backend model='random'/>
</rng>
</devices>
</domain>

View File

@ -243,12 +243,6 @@ mymain(void)
DO_TEST_FAILURE("fs-9p-unsupported-accessmode");
driver.bhyvecaps &= ~BHYVE_CAP_VIRTIO_9P;
DO_TEST_FAILURE("fs-9p");
DO_TEST("virtio-rnd");
DO_TEST_FAILURE("virtio-rnd-backend-random-non-default-file");
DO_TEST_FAILURE("virtio-rnd-backend-builtin");
DO_TEST_FAILURE("virtio-rnd-transitional");
driver.bhyvecaps &= ~BHYVE_CAP_VIRTIO_RND;
DO_TEST_FAILURE("virtio-rnd");
/* Address allocation tests */
DO_TEST("addr-single-sata-disk");

View File

@ -1,37 +0,0 @@
<domain type='bhyve'>
<name>bhyve</name>
<uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<driver name='file' type='raw'/>
<source file='/tmp/freebsd.img'/>
<target dev='hda' bus='sata'/>
<address type='drive' controller='0' bus='0' target='2' unit='0'/>
</disk>
<controller type='pci' index='0' model='pci-root'/>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:b9:94:02'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<rng model='virtio'>
<backend model='random'>/dev/random</backend>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</rng>
</devices>
</domain>

View File

@ -114,7 +114,6 @@ mymain(void)
DO_TEST_DIFFERENT("sound");
DO_TEST_DIFFERENT("isa-controller");
DO_TEST_DIFFERENT("fs-9p");
DO_TEST_DIFFERENT("virtio-rnd");
/* Address allocation tests */
DO_TEST_DIFFERENT("addr-single-sata-disk");

View File

@ -408,34 +408,6 @@ cpuTestHasFeature(const void *arg)
}
static int
cpuTestValidateFeatures(const void *arg)
{
const struct data *data = arg;
g_autoptr(virCPUDef) cpu = NULL;
int result;
if (!(cpu = cpuTestLoadXML(data->arch, data->name)))
return -1;
result = virCPUValidateFeatures(data->arch, cpu);
if (data->result == -1)
virResetLastError();
if (data->result != result) {
VIR_TEST_VERBOSE("\nExpected result %s, got %s",
cpuTestBoolWithErrorStr(data->result),
cpuTestBoolWithErrorStr(result));
/* Pad to line up with test name ... in virTestRun */
VIR_TEST_VERBOSE("%74s", "... ");
return -1;
}
return 0;
}
typedef enum {
/* No JSON data from QEMU. */
JSON_NONE,
@ -1014,10 +986,6 @@ mymain(void)
host "/" feature " (" #result ")", \
host, feature, NULL, 0, NULL, 0, result)
#define DO_TEST_VALIDATEFEATURES(arch, name, result) \
DO_TEST(arch, cpuTestValidateFeatures, name, \
NULL, name, NULL, 0, NULL, 0, result)
#define DO_TEST_GUESTCPU(arch, host, cpu, models, result) \
DO_TEST(arch, cpuTestGuestCPU, \
host "/" cpu " (" #models ")", \
@ -1267,9 +1235,6 @@ mymain(void)
"Xeon-E5-2609-v3", "Xeon-E5-2650-v4");
DO_TEST_CPUID_BASELINE(VIR_ARCH_X86_64, "Haswell+Skylake",
"Xeon-E7-8890-v3", "Xeon-Gold-5115");
DO_TEST_VALIDATEFEATURES(VIR_ARCH_AARCH64, "guest", 0);
cleanup:
#if WITH_QEMU
qemuTestDriverFree(&driver);

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