Commit Graph

13 Commits

Author SHA1 Message Date
Michal Privoznik
52a937d8a2 qemu_shim: Don't hang if failed to start domain
The qemu shim spawns a separate thread in which the event loop is
ran. The virEventRunDefaultImpl() call is wrapped in a while()
loop, just like it should. There are few lines of code around
which try to ensure that domain is destroyed (when quitting) and
that the last round of event loop is ran after the
virDomainDestroy() call. Only after that the loop is quit from
and the thread quits.

However, if domain creation fails, there is no @dom to call
destroy over, the @quit flag is never set and while() never
exits. Set the flag regardless of @dom pointer.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1920337
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2021-03-12 17:05:52 +01:00
Michal Privoznik
76f3b2988b qemu_shim: Always pre-create root dir
This problem is reproducible only with secret driver. When
starting a domain via virt-qemu-run and both secret and
(nonexistent) root directory specified this is what happens:

1) virt-qemu-run opens "secret:///embed?root=$rootdir"
   connection, which results in the secret driver initialization
   (done in secretStateInitialize()). During this process, the
   driver creates its own configDir (derived from $rootdir)
   including those parents which don't exists yet. This is all
   done with the mode S_IRWXU and thus results in the $rootdir
   being created with very restrictive mode (specifically, +x is
   missing for group and others).

2) now, virt-qemu-run opens "qemu:///embed?root=$rootdir" and
   calls virDomainCreateXML(). This results in the master-key.aes
   being written somewhere under the $rootdir and telling qemu
   where to find it.

But because the secret driver created $rootdir with too
restrictive mode, qemu can't access the file (even though it
knows the full path) and fails to start.

It looks like the best solution is to pre-create the root
directory before opening any connection (letting any driver
initialize itself) and set its mode to something less
restrictive.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1859873
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2021-03-12 15:40:13 +01:00
Michal Privoznik
859f7e2072 qemu_shim: URI escape root directory
The root directory can be provided by user (or a temporary one is
generated) and is always formatted into connection URI for both
secret driver and QEMU driver, like this:

  qemu:///embed?root=$root

But if it so happens that there is an URI unfriendly character in
root directory or path to it (say a space) then invalid URI is
formatted which results in unexpected results. We can trust
g_dir_make_tmp() to generate valid URI but we can't trust user.
Escape user provided root directory. Always.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1920400
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2021-02-12 17:59:42 +01:00
Pavel Hrdina
b2b1702341 src: add missing headers to various files
All these headers are indirectly included provided by virfile.h having
virstoragefile.h which will be removed in the following patch.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2021-01-06 13:15:17 +01:00
Daniel P. Berrangé
4b696beee3 qemu: remove use of gettid() syscall
This is not expose in most historical versions of glibc, nor
non-glibc impls. We must use our wrapper API instead.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-08-07 13:51:16 +01:00
Daniel P. Berrangé
11188d5a19 qemu: fix race in signal interrupt during QEMU startup
If a Ctrl-C arrives while we are in the middle of executing the
virDomainCreateXML call, we will have no "virDomainPtr" object
available, but QEMU may none the less be running.

This means we'll never try to stop the QEMU process before we
honour the Ctrl-C and exit.

To deal with this race we need to postpone quit of the event
loop if it is requested while in the middle of domain startup.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-08-07 12:44:57 +01:00
Michal Privoznik
084c04b5bb qemu_shim: Ignore SIGPIPE
I've found that if my virtlogd is socket activated but the daemon
doesn't run yet, then the virt-qemu-run is killed right after it
tries to start the domain. The problem is that because the default
setting is to use virtlogd, the domain create code tries to
connect to virtlogd socket, which in turn tries to detect who is
connecting (virNetSocketGetUNIXIdentity()) and as a part of it,
it will try to open /proc/${PID_OF_SHIM}/stat which is denied by
SELinux:

  type=AVC msg=audit(1582903501.927:323): avc:  denied  { search } for  \
  pid=1210 comm="virtlogd" name="1843" dev="proc" ino=37224 \
  scontext=system_u:system_r:virtlogd_t:s0-s0:c0.c1023 \
  tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=dir \
  permissive=0

Virtlogd reacts by closing the connection which the shim sees as
SIGPIPE. Since the default response to the signal is Term, we
don't even get to reporting any error nor to removing the
temporary directory.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2020-03-05 11:24:51 +01:00
Michal Privoznik
63af64d78d qemu_shim: Allow other users to enter the root dir
When virt-qemu-run is ran without any root directory specified on
the command line, a temporary directory is made and used instead.
But since we are using g_dir_make_tmp() to create the directory
it is going to have 0700 mode. So even though we create the whole
directory structure under it and label everything, QEMU is very
likely to not have the access. This is because in this case there
is no qemu.conf and thus distro default UID:GID is used to run
QEMU (e.g. qemu:kvm on Fedora). Change the mode of the temporary
directory so that everybody has eXecute permission.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2020-03-05 11:24:38 +01:00
Ján Tomko
7e0d11be5b virsh: include virutil.h where used
Include virutil.h in all files that use it,
instead of relying on it being pulled in somehow.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
2020-02-24 23:15:50 +01:00
Andrea Bolognani
c8a3a5d79b qemu_shim: Update temporary directory template
The template still references libvirt-qemu-shim, which was at one
point the name used to refer to what we now know as virt-qemu-run.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
2020-01-27 17:57:43 +01:00
Andrea Bolognani
7dca28e229 qemu_shim: Fix typos
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
2020-01-27 17:57:08 +01:00
Ján Tomko
26a42e7315 qemu_shim: cosmetic fixes
Remove bogus G_GNUC_UNUSED attribute and add a missing space.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Fixes: d600667278
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2020-01-27 17:36:05 +01:00
Daniel P. Berrangé
d600667278 qemu: introduce a new "virt-qemu-run" program
The previous "QEMU shim" proof of concept was taking an approach of only
caring about initial spawning of the QEMU process. It was then
registered with the libvirtd daemon who took over management of it. The
intent was that later libvirtd would be refactored so that the shim
retained control over the QEMU monitor and libvirt just forwarded APIs
to each shim as needed. This forwarding of APIs would require quite alot
of significant refactoring of libvirtd to achieve.

This impl thus takes a quite different approach, explicitly deciding to
keep the VMs completely separate from those seen & managed by libvirtd.
Instead it uses the new "qemu:///embed" URI scheme to embed the entire
QEMU driver in the shim, running with a custom root directory.

Once the driver is initialization, the shim starts a VM and then waits
to shutdown automatically when QEMU shuts down, or should kill QEMU if
it is terminated itself. This ought to use the AUTO_DESTROY feature but
that is not yet available in embedded mode, so we rely on installing a
few signal handlers to gracefully kill QEMU. This isn't reliable if
we crash of course, but you can restart with the same root dir.

Note this program does not expose any way to manage the QEMU process,
since there's no RPC interface enabled. It merely starts the VM and
cleans up when the guest shuts down at the end. This program is
installed to /usr/bin/virt-qemu-run enabling direct use by end users.
Most use cases will probably want to integrate the concept directly
into their respective application codebases. This standalone binary
serves as a nice demo though, and also provides a way to measure
performance of the startup process quite simply.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2020-01-27 11:05:02 +00:00