<div dir="ltr">Hi guys,<div><br></div><div>During the last few weeks, I've been looking at how to use SPDK as QEMU's bootable rootfs disk.</div><div><br></div><div>I managed to boot up a SPDK rootfs disk by using OVMF UEFI boot-loader. And in order to deploy the guest OS before start-up(which has a unrecognizable filesystem to the host), I have written a small patch for the libguestfs. It was based on Redhat's CentOS libguestfs-1.36.10 RPM, hopefully somebody could add this SPDK support into the mainline code.</div><div><br></div><div>What I'm asking here is a new problem I encountered yesterday. When I increased the guest memory to more than 8GB, the guest kernel would crash at boot-up (see attached screen-shot). This issue would not be reproduced if I only use SPDK as the data disk.</div><div><br></div><div>Maybe there is something wrong with the boot-loader?</div><div><br></div><div>Thanks, Bob</div><div><br></div><div><br></div><div><0083-Add-SPDK-drive-support.patch><br></div><div>------------------------------------------------------</div><div><br></div><div><div>From 7927b0fa080db923989cef7181531dfaa09ccf6c Mon Sep 17 00:00:00 2001</div><div>From: Bob Chen <<a href="mailto:a175818323@gmail.com">a175818323@gmail.com</a>></div><div>Date: Fri, 27 Jul 2018 12:55:28 +0800</div><div>Subject: [PATCH 1/1] Add SPDK drive support</div><div><br></div><div>---</div><div> lib/drives.c           | 45 +++++++++++++++++++++++++++++++++++++++++++++</div><div> lib/guestfs-internal.h |  2 ++</div><div> lib/launch-direct.c    | 20 ++++++++++++++++++--</div><div> lib/launch-libvirt.c   |  3 +++</div><div> lib/qemu.c             |  3 +++</div><div> 5 files changed, 71 insertions(+), 2 deletions(-)</div><div><br></div><div>diff --git a/lib/drives.c b/lib/drives.c</div><div>index d3887c1..780b1b2 100644</div><div>--- a/lib/drives.c</div><div>+++ b/lib/drives.c</div><div>@@ -396,6 +396,45 @@ create_drive_iscsi (guestfs_h *g,</div><div> }</div><div> #endif /* DISABLED IN RHEL 7 */</div><div> </div><div>+static struct drive *</div><div>+create_drive_spdk (guestfs_h *g,</div><div>+                  const struct drive_create_data *data)</div><div>+{</div><div>+  if (data->username != NULL) {</div><div>+    error (g, _("spdk: you cannot specify a username with this protocol"));</div><div>+    return NULL;</div><div>+  }</div><div>+  if (data->secret != NULL) {</div><div>+    error (g, _("spdk: you cannot specify a secret with this protocol"));</div><div>+    return NULL;</div><div>+  }</div><div>+</div><div>+  if (data->nr_servers != 1) {</div><div>+    error (g, _("spdk: you must specify exactly one server"));</div><div>+    return NULL;</div><div>+  }</div><div>+</div><div>+  if (data->servers[0].transport != drive_transport_unix) {</div><div>+    error (g, _("spdk: only unix transport is supported"));</div><div>+    return NULL;</div><div>+  }</div><div>+</div><div>+  return create_drive_non_file (g, data);</div><div>+}</div><div>+</div><div>+bool</div><div>+guestfs_int_has_spdk_drive (guestfs_h *g)</div><div>+{</div><div>+  size_t i;</div><div>+  struct drive *drv;</div><div>+  ITER_DRIVES(g, i, drv) {</div><div>+    if (drv->src.protocol == drive_protocol_spdk) {</div><div>+      return true;</div><div>+    }</div><div>+  }</div><div>+  return false;</div><div>+}</div><div>+</div><div> /**</div><div>  * Create the special F</dev/null> drive.</div><div>  *</div><div>@@ -494,6 +533,7 @@ guestfs_int_drive_protocol_to_string (enum drive_protocol protocol)</div><div>   case drive_protocol_sheepdog: return "sheepdog";</div><div>   case drive_protocol_ssh: return "ssh";</div><div>   case drive_protocol_tftp: return "tftp";</div><div>+  case drive_protocol_spdk: return "spdk";</div><div>   }</div><div>   abort ();</div><div> }</div><div>@@ -878,6 +918,11 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,</div><div>     drv = create_drive_curl (g, &data);</div><div>   }</div><div> #endif /* DISABLED IN RHEL 7 */</div><div>+  else if (STREQ (protocol, "spdk")) {</div><div>+    data.protocol = drive_protocol_spdk;</div><div>+    data.iface = safe_strdup(g, "vhost-user-scsi-pci");</div><div>+    drv = create_drive_spdk(g, &data);</div><div>+  }</div><div>   else {</div><div>     error (g, _("unknown protocol '%s'"), protocol);</div><div>     drv = NULL; /*FALLTHROUGH*/</div><div>diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h</div><div>index 3bae02b..a0e5573 100644</div><div>--- a/lib/guestfs-internal.h</div><div>+++ b/lib/guestfs-internal.h</div><div>@@ -199,6 +199,7 @@ enum drive_protocol {</div><div>   drive_protocol_sheepdog,</div><div>   drive_protocol_ssh,</div><div>   drive_protocol_tftp,</div><div>+  drive_protocol_spdk,</div><div> };</div><div> </div><div> enum drive_transport {</div><div>@@ -829,6 +830,7 @@ extern void guestfs_int_rollback_drives (guestfs_h *g, size_t);</div><div> extern void guestfs_int_add_dummy_appliance_drive (guestfs_h *g);</div><div> extern void guestfs_int_free_drives (guestfs_h *g);</div><div> extern const char *guestfs_int_drive_protocol_to_string (enum drive_protocol protocol);</div><div>+extern bool guestfs_int_has_spdk_drive (guestfs_h *g);</div><div> </div><div> /* appliance.c */</div><div> extern int guestfs_int_build_appliance (guestfs_h *g, char **kernel, char **initrd, char **appliance);</div><div>diff --git a/lib/launch-direct.c b/lib/launch-direct.c</div><div>index 3d6e72e..f157324 100644</div><div>--- a/lib/launch-direct.c</div><div>+++ b/lib/launch-direct.c</div><div>@@ -409,8 +409,17 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)</div><div>     ADD_CMDLINE_PRINTF ("%d", g->smp);</div><div>   }</div><div> </div><div>-  ADD_CMDLINE ("-m");</div><div>-  ADD_CMDLINE_PRINTF ("%d", g->memsize);</div><div>+  if (guestfs_int_has_spdk_drive(g)) {</div><div>+    ADD_CMDLINE ("-m");</div><div>+    ADD_CMDLINE ("1G");</div><div>+    ADD_CMDLINE ("-object");</div><div>+    ADD_CMDLINE ("memory-backend-file,id=mem0,size=1G,mem-path=/dev/hugepages,share=on");</div><div>+    ADD_CMDLINE ("-numa");</div><div>+    ADD_CMDLINE ("node,memdev=mem0");</div><div>+  } else {</div><div>+    ADD_CMDLINE ("-m");</div><div>+    ADD_CMDLINE_PRINTF ("%d", g->memsize);</div><div>+  }</div><div> </div><div>   /* Force exit instead of reboot on panic */</div><div>   ADD_CMDLINE ("-no-reboot");</div><div>@@ -567,6 +576,13 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)</div><div>       goto cleanup0;</div><div>     }</div><div> #endif</div><div>+    else if (drv->iface && STREQ(drv->iface, "vhost-user-scsi-pci")) {</div><div>+      /* SPDK */</div><div>+      ADD_CMDLINE ("-chardev");</div><div>+      ADD_CMDLINE_PRINTF ("socket,id=vhost,path=%s", escaped_file);</div><div>+      ADD_CMDLINE ("-device");</div><div>+      ADD_CMDLINE ("vhost-user-scsi-pci,chardev=vhost");</div><div>+    }</div><div>     else if (drv->iface) {</div><div>       ADD_CMDLINE ("-drive");</div><div>       ADD_CMDLINE_PRINTF ("%s,if=%s", param, drv->iface);</div><div>diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c</div><div>index 05c398b..468ece9 100644</div><div>--- a/lib/launch-libvirt.c</div><div>+++ b/lib/launch-libvirt.c</div><div>@@ -1548,6 +1548,9 @@ construct_libvirt_xml_disk (guestfs_h *g,</div><div>       case drive_protocol_tftp:</div><div>         error (g, _("libvirt does not support the qemu curl driver protocols (ftp, http, etc.); try setting LIBGUESTFS_BACKEND=direct"));</div><div>         return -1;</div><div>+      case drive_protocol_spdk:</div><div>+        error (g, _("libvirt does not support SPDK driver protocol yet; try setting LIBGUESTFS_BACKEND=direct"));</div><div>+        return -1;</div><div>       }</div><div> </div><div>       if (construct_libvirt_xml_disk_target (g, xo, drv_index) == -1)</div><div>diff --git a/lib/qemu.c b/lib/qemu.c</div><div>index 887e31b..a77ea87 100644</div><div>--- a/lib/qemu.c</div><div>+++ b/lib/qemu.c</div><div>@@ -942,6 +942,8 @@ guestfs_int_drive_source_qemu_param (guestfs_h *g,</div><div>   case drive_protocol_tftp:</div><div>     return make_uri (g, "tftp", src->username, src->secret,</div><div>                      &src->servers[0], src->u.exportname);</div><div>+  case drive_protocol_spdk:</div><div>+    return safe_strdup(g, src->servers[0].u.socket);</div><div>   }</div><div> </div><div>   abort ();</div><div>@@ -1016,6 +1018,7 @@ guestfs_int_discard_possible (guestfs_h *g, struct drive *drv,</div><div>   case drive_protocol_https:</div><div>   case drive_protocol_ssh:</div><div>   case drive_protocol_tftp:</div><div>+  case drive_protocol_spdk:</div><div>     NOT_SUPPORTED (g, -1,</div><div>                    _("discard cannot be enabled on this drive: "</div><div>                      "protocol '%s' does not support discard"),</div><div>-- </div><div>1.8.3.1</div><div><br></div></div></div>