Commit Graph

1693 Commits

Author SHA1 Message Date
Michal Privoznik
b20a5e9a4d lib: use struct zero initializer instead of memset
This is a more concise approach and guarantees there is
no time window where the struct is uninitialized.

Generated using the following semantic patch:

  @@
  type T;
  identifier X;
  @@
  -  T X;
  +  T X = { 0 };
     ... when exists
  (
  -  memset(&X, 0, sizeof(X));
  |
  -  memset(&X, 0, sizeof(T));
  )

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Claudio Fontana <cfontana@suse.de>
2023-08-03 16:41:19 +02:00
Nikolai Barybin
2d6659e778 qemu: prevent SIGSEGV in qemuProcessHandleDumpCompleted
If VIR_ASYNC_JOB_NONE flag is present, job.current is equal
to NULL, which leads to SIGSEGV. Thus, this check should be
moved up.

Fixes: v8.0.0-427-gf304de0df6
Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2023-06-27 12:39:50 +02:00
Michal Privoznik
d09b73b560 qemu: Drop @unionMems argument from qemuProcessSetupPid()
The @unionMems argument of qemuProcessSetupPid() function is not
necessary really as all callers pass 'true'. Drop it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-06-08 09:39:20 +02:00
Michal Privoznik
83adba541a qemu: Allow more generous cpuset.mems for vCPUs and IOThreads
The unit that cpuset CGroups controller works with is a
thread/process, not individual memory allocations. Therefore,
after we've set cpuset.mems for emulator (after previous commit
it's set to union of all host NUMA nodes allowed for given
domain), and as we try to set up cpuset.mems for vCPUs/IOThreads,
memory is migrated to selected NUMA node(s). We are effectively
saying: "this thread (vCPU thread) can have memory only from
these NUMA node(s)".

That's not really what we want though. The cpuset controller
doesn't differentiate memory "belonging" to the emulator thread
and vCPU thread or IOThread even.

Therefore, set union of all allowed host NUMA nodes, just like
we're doing for the emulator thread.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2138150
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-06-08 09:39:20 +02:00
Michal Privoznik
fddbb2f12f qemu: Don't try to 'fix up' cpuset.mems after QEMU's memory allocation
In ideal world, my plan was perfect. We allow union of all host
nodes in cpuset.mems and once QEMU has allocated its memory, we
'fix up' restriction of its emulator thread by writing the
original value we wanted to set all along. But in fact, we can't
do it because that triggers memory movement. For instance,
consider the following <numatune/>:

  <numatune>
    <memory mode="strict" nodeset="0"/>
    <memnode cellid="1" mode="strict" nodeset="1"/>
  </numatune>

  <numa>
    <cell id="0" cpus="0-1" memory="1024000" unit="KiB" />
    <cell id="1" cpus="2-3" memory="1048576" unit="KiB"/>
  </numa>

This is meant to create 1:1 mapping between guest and host NUMA
nodes. So we start QEMU with cpuset.mems set to "0-1" (so that it
can allocate memory even for guest node #1 and have the memory
come fro host node #1) and then, set cpuset.mems to "0" (because
that's where we wanted emulator thread to live).

But this in turn triggers movement of all memory (even the
allocated one) to host NUMA node #0. Therefore, we have to just
keep cpuset.mems untouched and rely on .host-nodes passed on the
QEMU cmd line.

The placement still suffers because of cpuset.mems set for vcpus
or iothreads, but that's fixed in next commit.

Fixes: 3ec6d586bc
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-06-08 09:39:20 +02:00
Peter Krempa
9d6867198d qemuMonitorSetBlockIoThrottle: Drop 'diskalias' argument
Every caller will pass 'qdevid' as it's populated in the data
mandatorily with qemu-4.2 and onwards due to mandatory -blockdev use.

Thus we can drop compatibility with the old way of matching the disk via
alias.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-06-05 13:20:13 +02:00
Michal Privoznik
8b9d2bda8a qemu: Set proper PCI backend for <interface/>-s that are actually hostdevs
When starting a domain, it's done so in two steps (actually more,
but lets focus on just the following two):

  1) qemuProcessPrepareDomain(), followed by

  2) qemuProcessPrepareHost().

Now, in the first step (PrepareDomain()), PCI backends for all
hostdevs is set (qemuProcessPrepareDomain() ->
qemuProcessPrepareDomainHostdevs() -> qemuDomainPrepareHostdev()
-> qemuDomainPrepareHostdevPCI()). Perfect.

But then, additional hostdevs may appear, because in the host
prepare phase we may insert some hostdevs into domain definition
(qemuProcessPrepareHost() -> qemuProcessNetworkPrepareDevices()).

Now, these additional hostdevs don't undergo the same prepare as
hostdevs that were already present in the domain definition (i.e.
in qemuProcessPrepareDomain() phase). Therefore, we have to call
corresponding prepare function explicitly.

NB, the interface hotplug code (qemuDomainAttachNetDevice()) does
not suffer from this problem, because it calls top level
qemuDomainAttachHostDevice() which is used to hotplug regular
hostdevs too and as such calls qemuDomainPrepareHostdev().

Fixes: 3b87709c76
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2209853
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-06-05 12:18:53 +02:00
Michal Privoznik
e53291514c qemu_hotplug: Temporarily allow emulator thread to access other NUMA nodes during mem hotplug
Again, this fixes the same problem as one of previous commits,
but this time for memory hotplug. Long story short, if there's a
domain running and the emulator thread is restricted to a subset
of host NUMA nodes, but the memory that's about to be hotplugged
requires memory from a host NUMA node that's not in the set we
need to allow emulator thread to access the node, temporarily.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-23 17:21:16 +02:00
Michal Privoznik
3ec6d586bc qemu: Start emulator thread with more generous cpuset.mems
Consider a domain with two guest NUMA nodes and the following
<numatune/> setting :

  <numatune>
    <memory mode="strict" nodeset="0"/>
    <memnode cellid="0" mode="strict" nodeset="1"/>
  </numatune>

What this means is the emulator thread is pinned onto host NUMA
node #0 (by setting corresponding cpuset.mems to "0"), and two
memory-backend-* objects are created:

  -object '{"qom-type":"memory-backend-ram","id":"ram-node0", .., "host-nodes":[1],"policy":"bind"}' \
  -numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \
  -object '{"qom-type":"memory-backend-ram","id":"ram-node1", .., "host-nodes":[0],"policy":"bind"}' \
  -numa node,nodeid=1,cpus=2-3,memdev=ram-node1 \

Note, the emulator thread is pinned well before QEMU is even
exec()-ed.

Now, the way memory allocation works in QEMU is: the emulator
thread calls mmap() followed by mbind() (which is sane, that's
how everybody should do it). BUT, because the thread is already
restricted by CGroups to just NUMA node #0, calling:

  mbind(host-nodes:[1]); /* made up syntax (TM) */

fails. This is expected though. Kernel was instructed to place
the memory at NUMA node "0" and yet, process is trying to place
it elsewhere.

We used to solve this by not restricting emulator thread at all
initially, and only after it's done initializing (i.e. we got the
QMP greeting) we placed it onto desired nodes. But this had its
own problems (e.g. QEMU might have locked pieces of its memory
which were then unable to migrate onto different NUMA nodes).

Therefore, in v5.1.0-rc1~282 we've changed this and set cgroups
upfront (even before exec()-ing QEMU). And this used to work, but
something has changed (I can't really put my finger on it).

Therefore, for the initialization start the thread with union of
all configured host NUMA nodes ("0-1" in our example) and fix the
placement only after QEMU is started.

NB, the memory hotplug suffers the same problem, but that will
be fixed in the next commit.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2138150
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-23 17:21:16 +02:00
Michal Privoznik
c4a7f8007c qemuProcessSetupPid: Use @numatune variable more
Inside of qemuProcessSetupPid() there's @numatune variable which
is set to vm->def->numa, but it lives only in one block. In the
rest of places the expanded form (vm->def->numa) is used instead.
Move the variable declaration at the beginning of the function
and use it instead of the expanded form.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-23 17:21:16 +02:00
Michal Privoznik
37e41b7f16 qemu: Drop @forceVFIO argument of qemuDomainGetMemLockLimitBytes()
After previous cleanup, there's not a single caller that would
call qemuDomainGetMemLockLimitBytes() with @forceVFIO set. All
callers pass false.

Drop the unneeded argument from the function.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-16 14:43:43 +02:00
Andrea Bolognani
934113d376 qemu: Find helpers at runtime
Use the recently introduced virFindFileInPathFull() function to
discover the path for qemu-bridge-helper and qemu-pr-helper at
runtime.

Note that it's still possible for the administrator to prevent
this lookup and use arbitrary binaries by setting the
appropriate keys in qemu.conf: this simply removes the need to
perform the lookup at build time, and thus to have the helpers
installed in the build environment.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-10 18:54:09 +02:00
Michal Privoznik
4644aba0b0 qemu: Stop virQEMUCaps propagation into qemuHostdevPreparePCIDevices()
After previous cleanups, qemuHostdevPreparePCIDevices() no longer
needs virQEMUCaps. Drop its passing from callers.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-04-25 12:36:31 +02:00
Michal Privoznik
430fc2ec26 qemu: Remove empty functions
After previous cleanup, there are some functions that do nothing:

  qemuConnectDomainXMLToNativePrepareHostHostdev()
  qemuConnectDomainXMLToNativePrepareHost()
  qemuProcessPrepareHostHostdev()
  qemuProcessPrepareHostHostdevs()

Remove them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-04-25 12:36:31 +02:00
Michal Privoznik
fea0d8c40d qemu: Move <hostdev> SCSI path generation into qemuDomainPrepareHostdev()
When preparing a SCSI <hostdev/> with passthrough of a host SCSI
adapter (i.e. no protocol), a virStorageSource structure is
initialized and stored inside virDomainHostdevDef. But the source
structure is filled in many places, with almost the same code.

Firstly, qemuProcessPrepareHostHostdev() and
qemuConnectDomainXMLToNativePrepareHostHostdev() are the same.

Secondly, qemuDomainPrepareHostdev() allocates the src structure,
only to let qemuProcessPrepareHostHostdev() fill src->path later.

Well, src->path can be filled at the same place where the src
structure is allocated (qemuDomainPrepareHostdev()) which renders
the other two functions needless.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-04-25 12:36:30 +02:00
Peter Krempa
b60efa9a39 qemuProcessRefreshDisks: Extract update of a single disk
Extract the logic to update one single disk (without emitting any
events) so that it can be reused when updating the state after a disk
hotplug.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-04-24 12:57:56 +02:00
Peter Krempa
c8e7ed7f7b qemuProcessRefreshDisks: Properly compare tray status
The code compares the 'tray_open' boolean from 'struct
qemuDomainDiskInfo' directly against 'disk->tray_status' which is
declared as virDomainDiskTray (enum). Now the logic works correctly
because the _OPEN enum has value '1'.

Separate the event emission code from the update code and remember the
old tray state in a separate variable rather than having the sneaky
logic we have today.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-04-24 12:57:56 +02:00
Martin Kletzander
383caddea1 qemu, ch: Move threads to cgroup dir before changing parameters
With cgroupv2 this has better effect on the resource allocation.  An
excerpt from Documentation/admin-guide/cgroup-v2.rst explains is this
way:

  Migrating a process across cgroups is a relatively expensive operation
  and stateful resources such as memory are not moved together with the
  process.  This is an explicit design decision as there often exist
  inherent trade-offs between migration and various hot paths in terms
  of synchronization cost.

  [...]

  Setting a non-empty value to "cpuset.mems" causes memory of
  tasks within the cgroup to be migrated to the designated nodes if
  they are currently using memory outside of the designated nodes.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-04-20 12:39:49 +02:00
Jiri Denemark
49f2835ee3 qemu/qemu_process: Update format strings in translated messages
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2023-04-01 11:40:34 +02:00
Michal Privoznik
b4ccb0dc41 qemu: Move cpuset preference evaluation into a separate function
The set of if()-s that determines the preference in cpumask used
for setting things like emulatorpin, vcpupin, etc. is going to be
re-used. Separate it out into a function.

You may think that this changes behaviour, but
qemuProcessPrepareDomainNUMAPlacement() ensures that
priv->autoCpuset is set for VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2023-03-15 12:46:40 +01:00
Laine Stump
75056f61f1 security: make it possible to set SELinux label of child process from its binary
Normally when a child process is started by libvirt, the SELinux label
of that process is set to virtd_t (plus an MCS range). In at least one
case (passt) we need for the SELinux label of a child process label to
match the label that the binary would have transitioned to
automatically if it had been run standalone (in the case of passt,
that label is passt_t).

This patch modifies virSecuritySELinuxSetChildProcessLabel() (and all
the functions above it in the call chain) so that the toplevel
function can set a new argument "useBinarySpecificLabel" to true. If
it is true, then virSecuritySELinuxSetChildProcessLabel() will call
the new function virSecuritySELinuxContextSetFromFile(), which uses
the selinux library function security_compute_create() to determine
what would be the label of the new process if it had been run
standalone (rather than being run by libvirt) - the MCS range from the
normally-used label is added to this newly derived label, and that is
what is used for the new process rather than whatever is in the
domain's security label (which will usually be virtd_t).

In order to easily verify that nothing was broken by these changes to
the call chain, all callers currently set useBinarySpecificPath =
false, so all behavior should be completely unchanged. (The next
patch will set it to true only for the case of running passt.)

https://bugzilla.redhat.com/2172267
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-03-10 14:09:29 -05:00
Jonathon Jongsma
464a87ec52 conf: use enum variable for video type
Rather than storing the video type as an integer, use the proper enum
type within the struct.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-03-08 13:05:05 -06:00
Peter Krempa
f6967e2b77 conf: cpu: Remove NULL check from virCPUDefCopy
Make all callers always pass a valid pointer which in turn allows us to
remove return value check from the callers.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-03-06 20:55:50 +01:00
Peter Krempa
f9b97f6b10 conf: cpu: Remove NULL check from virCPUDefCopyWithoutModel
Make all callers always pass a valid pointer which in turn allows us to
remove return value check from the callers.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-03-06 20:55:50 +01:00
Peter Krempa
8432392f51 cpu: Remove return value from virCPUDefCopyModel(Filter)
The functions were always returning 0.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-03-06 20:55:50 +01:00
Peter Krempa
bd9ee45f0e qemu: Always assume support for iothreads
iothreads were introduced in qemu-2.0 and can't be compiled out thus we
can always assume qemu supports them.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-03-06 13:22:37 +01:00
Andrea Bolognani
9567f3ba1f qemu: Move firmware selection from startup to postparse
Currently, firmware selection is performed as part of the
domain startup process. This mostly works fine, but there's a
significant downside to this approach: since the process is
affected by factors outside of libvirt's control, specifically
the contents of the various JSON firmware descriptors and
their names, it's pretty much impossible to guarantee that the
outcome is always going to be the same. It would only take an
edk2 update, or a change made by the local admin, to render a
domain unbootable or downgrade its boot security.

To avoid this, move firmware selection to the postparse phase.
This way it will only be performed once, when the domain is
first defined; subsequent boots will not need to go through
the process again, as all the paths that were picked during
firmware selection are recorded in the domain XML.

Care is taken to ensure that existing domains are handled
correctly, even if their firmware configuration can't be
successfully resolved. Failure to complete the firmware
selection process is only considered fatal when defining a
new domain; in all other cases the error will be reported
during startup, as is already the case today.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-03-03 13:49:56 +01:00
Laine Stump
f62ce81b8a qemu: respond to NETDEV_STREAM_DISCONNECTED event
When a QEMU netdev is of type "stream", if the socket it uses for
connectivity to the host network gets closed, then QEMU will send a
NETDEV_STREAM_DISCONNECTED event. We know that any stream netdev we've
created is backed by a passt process, and if the socket was closed,
that means the passt process has disappeared.

When we receive this event, we can respond by starting a new passt
process with the same options (including socket path) we originally
used. If we have previously created the stream netdev device with a
"reconnect" option, then QEMU will automatically reconnect to this new
passt process. (If we hadn't used "reconnect", then QEMU will never
try to reconnect to the new passt process, so there's no point in
starting it.)

Note that NETDEV_STREAM_DISCONNECTED is an event sent for the netdev
(ie "host side") of the network device, and so it sends the
"netdev-id" to specify which device was disconnected. But libvirt's
virDomainNetDef (the object used to keep track of network devices) is
the internal representation of both the host-side "netdev", and the
guest side device, and virDomainNetDef doesn't directly keep track of
the netdev-id, only of the device's "alias" (which is the "id"
parameter of the *guest* side of the device). Fortunately, by convention
libvirt always names the host-side of devices as "host" + alias, so in
order to search for the affected NetDef, all we need to do is trim the
1st 4 characters from the netdev-id and look for the NetDef having
that resulting trimmed string as its alias. (Contrast this to
NIC_RX_FILTER_CHANGED, which is an event received for the guest side
of the device, and so directly contains the device alias.)

Resolves: https://bugzilla.redhat.com/2172098
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-02-22 08:36:13 -05:00
Peter Krempa
86cfe93ef7 qemuProcessRefreshDisks: Don't skip filling of disk information if tray state didn't change
Commit 5ef2582646 added emitting of even when refreshign disk state,
where it wanted to avoid sending the event if disk state didn't change.
This was achieved by using 'continue' in the loop filling the
information. Unfortunately this skips extraction of whether the device
has a tray which is propagated into internal structures, which in turn
broke cdrom media change as the code thought there's no tray for the
device.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2166411
Fixes: 5ef2582646
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Kristina Hanicova <khanicov@redhat.com>
2023-02-09 10:17:08 +01:00
Michal Privoznik
697c16e39a qemu_process: Produce better debug message wrt domain namespaces
When going through debug log of a domain startup process, one can
meet the following line:

  debug : qemuProcessLaunch:7668 : Building mount namespace

But this is in fact wrong. Firstly, domain namespaces are just
enabled in domain's privateData. Secondly, the debug message says
nothing about actual state of namespace - whether it was enabled
or not.

Therefore, move the debug printing into
qemuProcessEnableDomainNamespaces() and tweak it so that the
actual value is reflected.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jim Fehlig <jfehlig@suse.com>
2023-02-08 08:37:28 +01:00
Michal Privoznik
5c4007ddc6 qemuProcessLaunch: Tighten rules for external devices wrt incoming migration
When starting a guest, helper processes are started first. But
they need a bit of special handling. Just consider a regular cold
boot and an incoming migration. For instance, in case of swtpm
with its state on a shared volume, we want to set label on the
state for the cold boot case, but don't want to touch the label
in case of incoming migration (because the source very
specifically did not restore it either).

Until now, these two cases were differentiated by testing
@incoming against NULL. And while that makes sense for other
aspects of domain startup, for external devices we need a bit
more, because a restore from a save file is also 'incoming
migration'.

Now, there is a difference between regular migration and restore
from a save file. In the former case we do not want to set
seclabels in the save state. BUT, in the latter case we do need
to set them, because the code that saves the machine restored
seclabels.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2161557
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-02-06 16:33:26 +01:00
Michal Privoznik
88f0fbf638 qemuProcessStop: Fix detection of outgoing migration for external devices
When cleaning up host in qemuProcessStop(), our external helper
processes (e.g. swtpm) want to know whether the domain is being
migrated out or not (so that they restore seclabels on a device
state that's on a shared storage).

This fact is reflected in the @outgoingMigration variable which
is set to true if asyncJob is anything but
VIR_ASYNC_JOB_MIGRATION_IN. Well, we have a specific job for
outgoing migration (VIR_ASYNC_JOB_MIGRATION_OUT) and thus we
should check for that.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-02-06 16:33:26 +01:00
Michal Privoznik
61d1b9e659 qemu: Don't remove macvtaps on failed start
If a domain is configured to create a macvtap/macvlan but the
target link already exists, startup fails (as expected) with:

  error: error creating macvtap interface test@eth0 (52:54:00:d9:0b:db): File exists

Okay, we could make that error message better, but that's not the
point. Since this error originated while generating cmd line
(the caller is qemuProcessStart(), transitively), the cleanup
after failed start is performed (qemuProcessStop()). Here,
virNetDevMacVLanDeleteWithVPortProfile() is called which removes
the macvtap interface we did not create (as it made us fail in
the first place).

Therefore, we need to track which macvtap/macvlan interface was
created successfully and remove only those.

You'll notice that only qemuProcessStop() has the new check. For
the (failed) hotplug case (qemuDomainAttachNetDevice()) this
function is already in place (the @iface_connected variable), or
not needed (qemuDomainRemoveNetDevice() - we're removing an
interface that was already attached to QEMU).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2166235
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-02-01 15:44:26 +01:00
Michal Privoznik
c0f671e7c9 virnetdevmacvlan: Drop G_GNUC_WARN_UNUSED_RESULT annotation for virNetDevMacVLanDeleteWithVPortProfile()
Every single caller of the
virNetDevMacVLanDeleteWithVPortProfile() function is calling it
wrapped inside of ignore_value() macro. This is because the
function is annotated as G_GNUC_WARN_UNUSED_RESULT. This makes no
sense. Drop the annotation and the macro envelope.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-02-01 15:44:20 +01:00
Martin Kletzander
1c61bd718a Support multiple watchdog devices
This is already possible with qemu, and actually already happening with
q35 machines and a specified watchdog since q35 already includes a
watchdog we do not include in the XML.  In order to express such
posibility multiple watchdogs need to be supported.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-01-26 16:40:30 +01:00
Peter Krempa
5764930463 qemu: Remove 'memAliasOrderMismatch' field from VM private data
The field is no longer used so we can remove it and the code filling it.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2023-01-24 13:14:12 +01:00
Shaleen Bathla
228e5a98d2 qemuProcessEventSubmit : Unref event->vm instead of vm
In error case, unref event->vm instead of vm. This makes it
easier for the reader to understand as it is the event struct
that's holding the reference.

Signed-off-by: Shaleen Bathla <shaleen.bathla@oracle.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-01-24 09:02:43 +01:00
Laine Stump
a56f0168d5 qemu: hook up passt config to qemu domains
This consists of (1) adding the necessary args to the qemu commandline
netdev option, and (2) starting a passt process prior to starting
qemu, and making sure that it is terminated when it's no longer
needed. Under normal circumstances, passt will terminate itself as
soon as qemu closes its socket, but in case of some error where qemu
is never started, or fails to startup completely, we need to terminate
passt manually.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2023-01-10 01:19:25 -05:00
Peter Krempa
4c9ce062d3 qemu: domain: Introduce qemuDomainStartupCleanup
The new helper qemuDomainStartupCleanup is used to perform cleanup after
a startup of a VM (successful or not). The initial implementation just
calls qemuDomainSecretDestroy, which can be un-exported.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2023-01-09 14:59:43 +01:00
Pavel Hrdina
cadbf40d05 qemu_process: abort snapshot delete when daemon starts
If the daemon crashes or is restarted while the snapshot delete is in
progress we have to handle it gracefully to not leave any block jobs
active.

For now we will simply abort the snapshot delete operation so user can
start it again. We need to refuse deleting external snapshots if there
is already another active job as we would have to figure out which jobs
we can abort.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2023-01-09 13:33:16 +01:00
Jiri Denemark
7050dad5f9 qemu: Remember failed post-copy migration in job
When post-copy migration fails, the domain stays running on the
destination with a VIR_DOMAIN_RUNNING_POSTCOPY_FAILED reason. Both the
state and the reason can later be rewritten in case the domain gets
paused for other reasons (such as an I/O error). Thus we need a separate
place to remember the post-copy migration failed to be able to resume
the migration.

https://bugzilla.redhat.com/show_bug.cgi?id=2111948

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-01-06 16:17:38 +01:00
Jiri Denemark
49a5754063 conf: Add job parameter to virDomainObjIsFailedPostcopy
Unused for now, but this will change soon.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-01-06 16:17:38 +01:00
Jiri Denemark
b92cba67c6 conf: Drop virDomainJobOperation parameter from virDomainObjIsPostcopy
The parameter was only used to select which states correspond to an
active or failed post-copy migration. But these states are either
applicable to both operations or the check would just paper over a code
bug in case of an impossible combination of state and operation. By
dropping the check we can make the code simpler and also reuse existing
virDomainObjIsFailedPostcopy function and only check for active
post-copy states.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-01-06 16:17:38 +01:00
Peter Krempa
aa8e187fa9 qemu: Use new connection close callbacks API
The qemu driver uses connection close callbacks in more places requiring
more changes than other drivers, but luckily the changes are very
straightforward. The migration code was written in a way ensuring that
there's just one callback present so this can be preserved directly.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2023-01-06 15:30:09 +01:00
Jiang Jiacheng
37520bb46e qemuProcessLaunch: fix a misspelling in log
Signed-off-by: Jiang Jiacheng <jiangjiacheng@huawei.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-01-06 10:16:25 +01:00
Kristina Hanicova
5ef2582646 qemu_process: add tray changed event to queue in refresh disks
There are some cases when the internal state of disks can change
without qemu sending events about it (e.g. a disk can close
during reset). In case this happens, we should emit an event
about the modified disk.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1824722#c20

Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2022-12-13 18:01:41 +01:00
Kristina Hanicova
75952d1874 qemu: refresh state after reboot initiated from the guest
Internal domain state needs to be refreshed after reset from the guest
side because it may be inconsistent with the internal qemu state.

Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2022-12-06 16:24:52 +01:00
Michal Privoznik
7a20341270 qemu: Init ext devices paths on reconnect
Paths for external devices (well, so far only vTPM) are not
stored in the status XML. Therefore, we need to regenerate them
after we've been restarted and reconnecting to a running domain.
Otherwise these will remain NULL which may later lead to a NULL
dereference.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2150760
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-12-05 14:25:25 +01:00
Michal Privoznik
107ebe62f4 qemu_process: Document qemuProcessPrepare{Domain,Host}() order
The domain startup process is split into multiple phases. One of
them is preparing the domain (at that point live) XML, private
data, various paths, etc - see qemuProcessPrepareDomain(); the
other prepares the host - see qemuProcessPrepareHost(). It's
obvious that the domain XML preparation function must be called
before the host preparation function (e.g. the host preparation
might try to create a file which path is generated in the domain
preparation phase). Nevertheless, let's document this
expectation.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2022-12-05 14:21:33 +01:00
Jiri Denemark
bf77578c9c qemu: Always restore post-copy migration job on reconnect
We need the restored job even in case the migration already finished
even though we will stop it just a few lines below as the functions we
call in between require an existing migration job.

This fixes a crash on reconnect when post-copy migration finished while
the daemon was not running.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2022-11-21 18:17:44 +01:00