Allow the appliance / root filesystem to be placed on a virtual NVDIMM
and accessed directly by the guest kernel (DAX).
This requires corresponding changes in supermin.
---
src/launch-direct.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 13 deletions(-)
diff --git a/src/launch-direct.c b/src/launch-direct.c
index a6f06ee..daeff67 100644
--- a/src/launch-direct.c
+++ b/src/launch-direct.c
@@ -235,6 +235,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
struct hv_param *hp;
bool has_kvm;
int force_tcg;
+ bool dax;
const char *cpu_model;
/* At present you must add drives before starting the appliance. In
@@ -374,15 +375,29 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
warning (g, "qemu debugging is enabled, connect gdb to tcp::1234 to
begin");
}
+ /* Can we use DAX? */
+#ifdef __x86_64__
+ dax = guestfs_int_version_ge (&data->qemu_version, 2, 6, 0) &&
+ guestfs_int_qemu_supports_device (g, data->qemu_data, "nvdimm");
+#else
+ dax = false;
+#endif
+
ADD_CMDLINE ("-machine");
ADD_CMDLINE_PRINTF (
#ifdef MACHINE_TYPE
MACHINE_TYPE ","
+ "%s"
+#elif __x86_64__
+ "pc,%s"
+#else
+ "%s"
#endif
#ifdef __aarch64__
"gic-version=host,"
#endif
"accel=%s",
+ dax ? "nvdimm," : "",
!force_tcg ? "kvm:tcg" : "tcg");
cpu_model = guestfs_int_get_cpu_model (has_kvm && !force_tcg);
@@ -397,7 +412,10 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
}
ADD_CMDLINE ("-m");
- ADD_CMDLINE_PRINTF ("%d", g->memsize);
+ if (dax)
+ ADD_CMDLINE_PRINTF ("%d,maxmem=32G,slots=32", g->memsize);
+ else
+ ADD_CMDLINE_PRINTF ("%d", g->memsize);
/* Force exit instead of reboot on panic */
ADD_CMDLINE ("-no-reboot");
@@ -551,21 +569,43 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
/* Add the ext2 appliance drive (after all the drives). */
if (has_appliance_drive) {
- ADD_CMDLINE ("-drive");
- ADD_CMDLINE_PRINTF ("file=%s,snapshot=on,id=appliance,"
- "cache=unsafe,if=none,format=raw",
- appliance);
+ if (dax) {
+ struct stat statbuf;
- if (virtio_scsi) {
- ADD_CMDLINE ("-device");
- ADD_CMDLINE ("scsi-hd,drive=appliance");
- }
- else {
+ if (stat (appliance, &statbuf) == -1) {
+ perrorf (g, "stat: %s", appliance);
+ goto cleanup0;
+ }
+
+ ADD_CMDLINE ("-object");
+ /* share=off corresponds to mmap MAP_PRIVATE inside qemu, so
+ * this should not affect the underlying file. IOW parallel
+ * access should be fine.
+ */
+ ADD_CMDLINE_PRINTF ("memory-backend-file,id=mem1,share=off,"
+ "mem-path=%s,size=%" PRIu64 "b",
+ appliance, (uint64_t) statbuf.st_size);
ADD_CMDLINE ("-device");
- ADD_CMDLINE (VIRTIO_BLK ",drive=appliance");
- }
+ ADD_CMDLINE ("nvdimm,memdev=mem1,id=nv1");
- appliance_dev = make_appliance_dev (g, virtio_scsi);
+ appliance_dev = safe_strdup (g, "/dev/pmem0");
+ } else {
+ ADD_CMDLINE ("-drive");
+ ADD_CMDLINE_PRINTF ("file=%s,snapshot=on,id=appliance,"
+ "cache=unsafe,if=none,format=raw",
+ appliance);
+
+ if (virtio_scsi) {
+ ADD_CMDLINE ("-device");
+ ADD_CMDLINE ("scsi-hd,drive=appliance");
+ }
+ else {
+ ADD_CMDLINE ("-device");
+ ADD_CMDLINE (VIRTIO_BLK ",drive=appliance");
+ }
+
+ appliance_dev = make_appliance_dev (g, virtio_scsi);
+ }
}
/* Create the virtio serial bus. */
--
2.7.4