libiscsi_version = '1.18.0'
libiscsi_dep = dependency('libiscsi', version: '>=' + libiscsi_version, required: get_option('libiscsi'))
+libnbd_version = '1.0'
+libnbd_dep = dependency('libnbd', version: '>=' + libnbd_version, required: get_option('libnbd'))
+if libnbd_dep.found()
+ conf.set('WITH_LIBNBD', 1)
+endif
+
libnl_version = '3.0'
if not get_option('libnl').disabled() and host_machine.system() == 'linux'
libnl_dep = dependency('libnl-3.0', version: '>=' + libnl_version, required: get_option('libnl'))
'glusterfs': glusterfs_dep.found(),
'libiscsi': libiscsi_dep.found(),
'libkvm': libkvm_dep.found(),
+ 'libnbd': libnbd_dep.found(),
'libnl': libnl_dep.found(),
'libparted': libparted_dep.found(),
'libpcap': libpcap_dep.found(),
option('fuse', type: 'feature', value: 'auto', description: 'fuse support')
option('glusterfs', type: 'feature', value: 'auto', description: 'glusterfs support')
option('libiscsi', type: 'feature', value: 'auto', description: 'libiscsi support')
+option('libnbd', type: 'feature', value: 'auto', description: 'libnbd support')
option('libnl', type: 'feature', value: 'auto', description: 'libnl support')
option('libpcap', type: 'feature', value: 'auto', description: 'libpcap support')
option('libssh', type: 'feature', value: 'auto', description: 'libssh support')
access_dep,
capng_dep,
gnutls_dep,
+ libnbd_dep,
libnl_dep,
log_dep,
selinux_dep,
#include <config.h>
#include <glib.h>
+#if WITH_LIBNBD
+# include <libnbd.h>
+#endif
#include <sys/syscall.h>
#include "vircommand.h"
g_autofree char *basename = g_strdup_printf("%s-nbdkit-%i", vm->def->name, proc->source->id);
int logfd = -1;
g_autoptr(qemuLogContext) logContext = NULL;
+#if WITH_LIBNBD
+ struct nbd_handle *nbd = NULL;
+#endif
if (!(cmd = qemuNbdkitProcessBuildCommand(proc)))
return -1;
while (virTimeBackOffWait(&timebackoff)) {
if (virFileExists(proc->socketfile)) {
+#if WITH_LIBNBD
+ /* if the disk source was misconfigured, nbdkit will not produce an error
+ * until somebody connects to the socket and tries to access the nbd
+ * export. This results in poor user experience because the only error we
+ * would get from qemu is something like "Requested export not available".
+ * So let's try to access it ourselves so that we can error out early and
+ * provide a useful message to the user.
+ */
+ nbd = nbd_create();
+ if (nbd_connect_unix(nbd, proc->socketfile) < 0) {
+ VIR_WARN("nbd_connect_unix failed: %s", nbd_get_error());
+ nbd_close(nbd);
+ goto errorlog;
+ }
+ nbd_close(nbd);
+
+#endif
if (qemuNbdkitProcessStartMonitor(proc, vm) < 0)
goto error;
return 0;