[libvirt] [PATCH 5/5] qemu: implement the 'libvirt_qemu' shim for launching guests externally

Daniel P. Berrange berrange at redhat.com
Thu Jan 11 12:26:59 UTC 2018


On Tue, Jan 09, 2018 at 03:13:41PM +0100, Martin Kletzander wrote:
> On Wed, Dec 20, 2017 at 04:47:50PM +0000, Daniel P. Berrange wrote:
> > This introduces a new binary 'libvirt_qemu' which can be used to launch
> > guests externally from libvirtd. eg
> > 
> >  libvirt_qemu -c qemu:///system /path/to/xml/file
> > 
> > This will launch a guest from the requested XML file and then connect to
> > qemu:///system to register it with libvirtd. At this point all normal
> > libvirtd operations should generally work.
> > 
> > NB, this impl has many flaws:
> > 
> > - We don't generate a unique 'id', so all guests will get id==1.
> >   Surprisingly this doesn't break the world.
> > 
> > - Tracking of unique name + UUIDs is *not* race free.
> > 
> > - No tracking/allocation of shared resource state (PCI devices,
> >   etc)
> > 
> 
> You will also not get the same events as you would when starting the domain
> as usual.

Hmm, yes, interesting. If someone is connected to libvirtd watching events
they'll  not get any startup events. That's something we'd need to fix.

> > Most other functionality works, but might have expected results.
> > 
> 
> If I start a domain with a network, it segfaults.  I'll see later if that's my
> fault or not.  It probably (and hopefully) is.

Not intentional if that's happening !


> > - The libvirt_qemu will exit if startup fails, however, it
> >   won't exit when QEMU later shuts down - you must listen
> >   for libvirtd events to detect that right now. We'll
> >   fix that
> > 
> > - Killing the libvirt_qemu shim will not kill the QEMU
> >   process. You must kill via the libvirt API as normal.
> >   This won't change, because we need to be able to
> >   ultimately restart the libvirt_qemu shim in order to
> >   apply software updates to running instance.
> >   We might wire up a special signal though to let
> >   you kill libvirt_qemu & take out QEMU at same time
> >   eg SIGQUIT or something like that perhaps.
> > 
> 
> IMHO we should use standard signals to do standard things.  TERM should
> gracefully shutdown the domain.  Not in PoC, but later.  That way users
> can treat the shim process as other processes.

I guess we can use SIGUSR1 to trigger restart of the shim while
leaving QEMU running.


> > +if WITH_QEMU
> > +if WITH_LIBVIRTD
> > +libexec_PROGRAMS += libvirt_qemu
> > +
> 
> Shouldn't I be able to launch this as a user without mgmt app?  It
> should go to bin_PROGRAMS, I presume.

Yes

> > +libvirt_qemu_SOURCES = \
> > +		$(QEMU_CONTROLLER_SOURCES) \
> > +		$(DATATYPES_SOURCES)
> > +libvirt_qemu_LDFLAGS = \
> > +		$(AM_LDFLAGS) \
> > +		$(PIE_LDFLAGS) \
> > +		$(NULL)
> > +libvirt_qemu_LDADD = \
> > +		libvirt.la \
> > +		libvirt-qemu.la \
> > +		libvirt_driver_qemu_impl.la
> > +if WITH_NETWORK
> > +libvirt_qemu_LDADD += libvirt_driver_network_impl.la
> > +endif WITH_NETWORK
> > +if WITH_STORAGE
> > +libvirt_qemu_LDADD += libvirt_driver_storage_impl.la
> > +endif WITH_STORAGE
> 
> > +libvirt_qemu_LDADD += ../gnulib/lib/libgnu.la $(LIBSOCKET)
> 
> This is not part of any condition, should be up there with libvirt.la
> just for clarity.

IIRC, libgnu.la needs to be the last library listed

> > +static void
> > +virQEMUControllerDriverFree(virQEMUDriverPtr driver)
> > +{
> > +    if (!driver)
> > +        return;
> > +
> > +    virObjectUnref(driver->config);
> > +    virObjectUnref(driver->hostdevMgr);
> > +    virHashFree(driver->sharedDevices);
> > +    virObjectUnref(driver->caps);
> > +    virObjectUnref(driver->qemuCapsCache);
> > +
> > +    virObjectUnref(driver->domains);
> > +    virObjectUnref(driver->remotePorts);
> > +    virObjectUnref(driver->webSocketPorts);
> > +    virObjectUnref(driver->migrationPorts);
> > +    virObjectUnref(driver->migrationErrors);
> > +
> > +    virObjectUnref(driver->xmlopt);
> > +
> > +    virSysinfoDefFree(driver->hostsysinfo);
> > +
> > +    virObjectUnref(driver->closeCallbacks);
> > +
> > +    VIR_FREE(driver->qemuImgBinary);
> > +
> > +    virObjectUnref(driver->securityManager);
> > +
> > +    ebtablesContextFree(driver->ebtables);
> > +
> > +    virLockManagerPluginUnref(driver->lockManager);
> > +
> > +    virMutexDestroy(&driver->lock);
> > +    VIR_FREE(driver);
> > +}
> > +
> > +static virQEMUDriverPtr virQEMUControllerNewDriver(bool privileged)
> 
> This is very similar to what I did, but I just exported this function
> privately si that there is less duplication of code and I added an enum
> that is used as a parameter instead of the bool @privileged.  It is a
> tristate (user, system, shim) that special-cases the shim slightly.

Yeah, there's definitely much more duplication here that I would like.
I would expect to refactor this better.

> The reason behind that is that I kind of presumed we need to be able to
> launch system QEMUs with non-root user.  Thinking about it I'm not sure
> that's the case for kubevirt, but it definitely is for others.  The way
> it is done now is that you initialize the driver based on geteuid(), but
> you connect to any uri specified by the user.  What I had in mind was
> that with this shim PoC users would be able to start their own VMs (if
> libvirtd permissions are set up the right way, even with some directory
> access changes done in the daemon) as system VMs as if they had seclabel
> set up for their user.  I think it's feasible, but I maybe overestimated
> what's possible for the PoC.



Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list