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 is pending the AUTO_DESTROY improvements
mentioned in the previous patch.
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 at the end. It is probably quite rare this would be used as
is, though potentially users might find it useful scripting throwaway
VMs during automation that they wish to keep hidden from the rest of
libvirtd instances.
Mostly though it serves as example code for how to use the new
"qemu:///embed" URI syntax. A more advanced application can copy this
code into their own codebase, and thus have the full range of QEMU
driver APIs available.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/qemu/Makefile.inc.am | 7 ++++
src/qemu/qemu_shim.c | 70 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+)
create mode 100644 src/qemu/qemu_shim.c
diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
index fd32a90d56..461704c79d 100644
--- a/src/qemu/Makefile.inc.am
+++ b/src/qemu/Makefile.inc.am
@@ -166,3 +166,10 @@ EXTRA_DIST += \
qemu/THREADS.txt \
libvirt_qemu_probes.d \
$(NULL)
+
+libexec_PROGRAMS += libvirt_qemu_shim
+
+libvirt_qemu_shim_SOURCES = qemu/qemu_shim.c
+
+libvirt_qemu_shim_LDADD = libvirt.la
+libvirt_qemu_shim_LDFLAGS = -Wl,--export-dynamic
diff --git a/src/qemu/qemu_shim.c b/src/qemu/qemu_shim.c
new file mode 100644
index 0000000000..df4385d956
--- /dev/null
+++ b/src/qemu/qemu_shim.c
@@ -0,0 +1,70 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+#include <pthread.h>
+#include <stdbool.h>
+
+#include "virfile.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+static void *eventLoop(void *opaque)
+{
+ bool *quit = opaque;
+ while (!*quit)
+ virEventRunDefaultImpl();
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ pthread_t eventLoopThread;
+ bool quit = false;
+ virConnectPtr conn;
+ virDomainPtr dom;
+ char *xml = NULL;
+ char *uri;
+
+ if (argc != 3) {
+ fprintf(stderr, "syntax: %s ROOT XML\n", argv[0]);
+ return 1;
+ }
+ if (virFileReadAll(argv[2], 102400, &xml) < 0) {
+ fprintf(stderr, "cannot read %s: %s\n", argv[2],
virGetLastErrorMessage());
+ return 1;
+ }
+
+ virFileActivateDirOverride(argv[0]);
+ virEventRegisterDefaultImpl();
+
+ pthread_create(&eventLoopThread, NULL, eventLoop, &quit);
+
+ if (virAsprintf(&uri, "qemu:///embed?root=%s", argv[1]) < 0) {
+ return 1;
+ }
+ conn = virConnectOpen(uri);
+ if (!conn) {
+ fprintf(stderr, "cannot open QEMU: %s\n", virGetLastErrorMessage());
+ return 1;
+ }
+
+ dom = virDomainCreateXML(conn, xml, 0);
+ if (!dom) {
+ fprintf(stderr, "cannot start VM: %s\n", virGetLastErrorMessage());
+ virConnectClose(conn);
+ return 1;
+ }
+
+ fprintf(stderr, "Running for 10 seconds\n");
+ sleep(10);
+
+ virDomainDestroy(dom);
+
+ virConnectClose(conn);
+
+ return 0;
+}
--
2.21.0