Rather than passing passwords and cookies (which could contain
passwords) to nbdkit via commandline arguments, use the alternate format
that nbdkit supports where we can specify a file descriptor which nbdkit
will read to get the password or cookies.
Signed-off-by: Jonathon Jongsma <jjongsma(a)redhat.com>
---
build-aux/syntax-check.mk | 4 +-
src/qemu/qemu_nbdkit.c | 162 ++++++++++++++++--
src/qemu/qemu_nbdkitpriv.h | 19 +-
src/util/virutil.h | 2 +-
.../disk-cdrom-network.args.disk1 | 2 +-
.../disk-cdrom-network.args.disk1.pipe.45 | 1 +
.../disk-cdrom-network.args.disk2 | 2 +-
.../disk-cdrom-network.args.disk2.pipe.47 | 1 +
.../disk-network-http.args.disk2 | 2 +-
.../disk-network-http.args.disk2.pipe.45 | 1 +
.../disk-network-http.args.disk3 | 2 +-
.../disk-network-http.args.disk3.pipe.47 | 1 +
...work-source-curl-nbdkit-backing.args.disk0 | 2 +-
...rce-curl-nbdkit-backing.args.disk0.pipe.45 | 1 +
.../disk-network-source-curl.args.disk0 | 2 +-
...isk-network-source-curl.args.disk0.pipe.45 | 1 +
.../disk-network-source-curl.args.disk1 | 2 +-
...isk-network-source-curl.args.disk1.pipe.47 | 1 +
.../disk-network-source-curl.args.disk2 | 2 +-
...isk-network-source-curl.args.disk2.pipe.49 | 1 +
tests/qemunbdkittest.c | 57 +++++-
21 files changed, 238 insertions(+), 30 deletions(-)
create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.45
create mode 100644 tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.47
create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.45
create mode 100644 tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.47
create mode 100644
tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.45
create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.45
create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.47
create mode 100644 tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.49
diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk
index 649eb91acb..c0cf730d13 100644
--- a/build-aux/syntax-check.mk
+++ b/build-aux/syntax-check.mk
@@ -1363,10 +1363,10 @@ exclude_file_name_regexp--sc_prohibit_strdup = \
^(docs/|examples/|tests/virnetserverclientmock.c|tests/commandhelper.c|tools/nss/libvirt_nss_(leases|macs)\.c$$)
exclude_file_name_regexp--sc_prohibit_close = \
-
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/vir(file|event)\.c|src/libvirt-stream\.c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c)|tools/nss/libvirt_nss_(leases|macs)\.c)$$)
+
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/vir(file|event)\.c|src/libvirt-stream\.c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c|qemunbdkittest\.c)|tools/nss/libvirt_nss_(leases|macs)\.c)$$)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
-
(^tests/(nodedevmdevctl|virhostcpu|virpcitest|virstoragetest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
+
(^tests/(nodedevmdevctl|virhostcpu|virpcitest|virstoragetest|qemunbdkit)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
(^(src/(util/(vircommand|virdaemon)|lxc/lxc_controller)|tests/testutils)\.c$$)
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 0ecf6c6537..2b8e203d16 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -55,6 +55,76 @@ VIR_ENUM_IMPL(qemuNbdkitCaps,
"filter-readahead", /* QEMU_NBDKIT_CAPS_FILTER_READAHEAD */
);
+
+static void
+nbdkitPipeItemFree(NbdkitPipeItem *item)
+{
+ if (item->buf) {
+ virSecureErase(item->buf, item->buflen);
+ g_free(item->buf);
+ }
+
+ if (item->fd > 0)
+ VIR_FORCE_CLOSE(item->fd);
+
+ g_free(item);
+}
+
+
+void nbdkitPipeDataFree(NbdkitPipeData *self)
+{
+ size_t i;
+
+ if (!self)
+ return;
+
+ for (i = 0; i < self->nitems; i++) {
+ nbdkitPipeItemFree(self->items[i]);
+ }
+
+ g_free(self->items);
+ g_free(self);
+}
+
+
+static NbdkitPipeItem*
+nbdkitPipeItemNew(int fd, void *data, int datalen)
+{
+ NbdkitPipeItem *d;
+
+ if (!data || datalen == 0)
+ return NULL;
+
+ d = g_new0(NbdkitPipeItem, 1);
+ d->fd = fd;
+
+ if (datalen < 0) {
+ /* -1 indicates a null-terminated string */
+ d->buf = g_strdup(data);
+ d->buflen = strlen(data);
+ } else {
+ d->buf = g_malloc(datalen);
+ memcpy(d->buf, data, datalen);
+ d->buflen = datalen;
+ }
+
+ return d;
+}
+
+
+static int
+nbdkitPipeDataWrite(NbdkitPipeItem *pipe)
+{
+ if (safewrite(pipe->fd, pipe->buf, pipe->buflen) < 0) {
+ virReportSystemError(errno,
+ _("failed to write data to pipe %i for nbdkit"),
+ pipe->fd);
+ return -1;
+ }
+ return 0;
+}
+
+
struct _qemuNbdkitCaps {
GObject parent;
@@ -71,6 +141,12 @@ struct _qemuNbdkitCaps {
G_DEFINE_TYPE(qemuNbdkitCaps, qemu_nbdkit_caps, G_TYPE_OBJECT);
+enum {
+ PIPE_FD_READ = 0,
+ PIPE_FD_WRITE = 1
+};
+
+
static void
qemuNbdkitCheckCommandCap(qemuNbdkitCaps *nbdkit,
virCommand *cmd,
@@ -685,12 +761,36 @@ qemuNbdkitInitStorageSource(qemuNbdkitCaps *caps,
}
+static NbdkitPipeItem*
+commandPassDataByPipe(virCommand *cmd,
+ const char *argName,
+ char *buf,
+ size_t buflen)
+{
+ int fds[2] = { -1, -1 };
+ g_autofree char *fdfmt = NULL;
+
+ if (virPipe(fds) < 0)
+ return NULL;
+
+ /* some nbdkit arguments accept a variation where nbdkit will read the data
+ * from a file descriptor, e.g. password=-FD */
+ fdfmt = g_strdup_printf("-%i", fds[PIPE_FD_READ]);
+ virCommandAddArgPair(cmd, argName, fdfmt);
+ virCommandPassFD(cmd, fds[PIPE_FD_READ], VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+
+ return nbdkitPipeItemNew(fds[PIPE_FD_WRITE], (char*)buf, buflen);
+}
+
static int
qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
- virCommand *cmd)
+ virCommand *cmd,
+ NbdkitPipeData **pipeData)
{
g_autoptr(virURI) uri = qemuBlockStorageSourceGetURI(proc->source);
g_autofree char *uristring = virURIFormat(uri);
+ g_autoptr(GPtrArray) pipes =
+ g_ptr_array_new_with_free_func((GDestroyNotify)nbdkitPipeDataFree);
/* nbdkit plugin name */
virCommandAddArg(cmd, "curl");
@@ -702,8 +802,9 @@ qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
g_autoptr(virConnect) conn = virGetConnectSecret();
g_autofree uint8_t *secret = NULL;
size_t secretlen = 0;
- g_autofree char *password = NULL;
int secrettype;
+ virStorageAuthDef *authdef = proc->source->auth;
+ NbdkitPipeItem *pipe = NULL;
virCommandAddArgPair(cmd, "user",
proc->source->auth->username);
@@ -716,7 +817,7 @@ qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
}
if (virSecretGetSecretString(conn,
- &proc->source->auth->seclookupdef,
+ &authdef->seclookupdef,
secrettype,
&secret,
&secretlen) < 0) {
@@ -725,18 +826,28 @@ qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
return -1;
}
- /* ensure that the secret is a NULL-terminated string */
- password = g_strndup((char*)secret, secretlen);
-
- virCommandAddArgPair(cmd, "password", password);
+ if (!(pipe = commandPassDataByPipe(cmd, "password", (char*)secret,
+ secretlen))) {
+ virSecureErase(secret, secretlen);
+ return -1;
+ }
virSecureErase(secret, secretlen);
- virSecureErase(password, secretlen);
+ g_ptr_array_add(pipes, pipe);
}
- if (proc->source->ncookies > 0)
- virCommandAddArgPair(cmd, "cookie",
- qemuBlockStorageSourceGetCookieString(proc->source));
+ /* Create a pipe to send the cookies to the nbdkit process. */
+ if (proc->source->ncookies) {
+ NbdkitPipeItem *pipe = NULL;
+ g_autofree char *cookies =
+ qemuBlockStorageSourceGetCookieString(proc->source);
+
+ if (!(pipe = commandPassDataByPipe(cmd, "cookie", cookies, -1))) {
+ return -1;
+ }
+
+ g_ptr_array_add(pipes, pipe);
+ }
if (proc->source->sslverify == VIR_TRISTATE_BOOL_NO) {
virCommandAddArgPair(cmd, "sslverify", "false");
@@ -747,6 +858,10 @@ qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
virCommandAddArgPair(cmd, "timeout", timeout);
}
+ *pipeData = g_new0(NbdkitPipeData, 1);
+ (*pipeData)->nitems = pipes->len;
+ (*pipeData)->items =
(NbdkitPipeItem**)g_ptr_array_free(g_steal_pointer(&pipes), false);
+
return 0;
}
@@ -781,8 +896,17 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
}
+/* Builds a nbdkit command for the given disk source.
+ *
+ * Some sensitive data should be not be passed to nbdkit via commandline, so
+ * this command may set up one or more pipes and pass the fd of these pipes to
+ * the nbdkit command. In that case, pipeData will return information about the
+ * pipes and the information that must be written to that pipe (via
+ * nbdkitPipeDataWrite()) after the command has been executed. The pipeData
+ * elements should be freed after writing. */
virCommand *
-qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc)
+qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc,
+ NbdkitPipeData **pipeData)
{
g_autoptr(virCommand) cmd = virCommandNewArgList(proc->caps->path,
"--exit-with-parent",
@@ -806,7 +930,7 @@ qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc)
case VIR_STORAGE_NET_PROTOCOL_FTP:
case VIR_STORAGE_NET_PROTOCOL_FTPS:
case VIR_STORAGE_NET_PROTOCOL_TFTP:
- if (qemuNbdkitProcessBuildCommandCurl(proc, cmd) < 0)
+ if (qemuNbdkitProcessBuildCommandCurl(proc, cmd, pipeData) < 0)
return NULL;
break;
case VIR_STORAGE_NET_PROTOCOL_SSH:
@@ -869,8 +993,10 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
int exitstatus = 0;
int cmdret = 0;
int errfd = -1;
+ g_autoptr(NbdkitPipeData) pipes = NULL;
+ size_t i;
- if (!(cmd = qemuNbdkitProcessBuildCommand(proc)))
+ if (!(cmd = qemuNbdkitProcessBuildCommand(proc, &pipes)))
return -1;
virCommandSetErrorFD(cmd, &errfd);
@@ -888,6 +1014,14 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
goto error;
}
+ if (pipes) {
+ for (i = 0; i < pipes->nitems; i++) {
+ NbdkitPipeItem *pipe = pipes->items[i];
+ if (nbdkitPipeDataWrite(pipe) < 0)
+ goto error;
+ }
+ }
+
if ((rc = virPidFileReadPath(proc->pidfile, &proc->pid)) < 0) {
virReportSystemError(-rc,
_("Failed to read pidfile %s"),
diff --git a/src/qemu/qemu_nbdkitpriv.h b/src/qemu/qemu_nbdkitpriv.h
index 64f9bb99d8..a4cc61bb2c 100644
--- a/src/qemu/qemu_nbdkitpriv.h
+++ b/src/qemu/qemu_nbdkitpriv.h
@@ -27,5 +27,20 @@
#include "qemu_nbdkit.h"
-virCommand *
-qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc);
+typedef struct {
+ int fd;
+ void *buf;
+ size_t buflen;
+} NbdkitPipeItem;
+
+typedef struct {
+ size_t nitems;
+ NbdkitPipeItem **items;
+} NbdkitPipeData;
+
+void nbdkitPipeDataFree(NbdkitPipeData *pipedata);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(NbdkitPipeData, nbdkitPipeDataFree);
+
+virCommand* qemuNbdkitProcessBuildCommand(qemuNbdkitProcess *proc,
+ NbdkitPipeData **pipeData);
diff --git a/src/util/virutil.h b/src/util/virutil.h
index ab8511bf8d..094b399859 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -186,7 +186,7 @@ char *virGetPassword(void);
*
* Returns: -1 on error, 0 on success
*/
-int virPipe(int fds[2]);
+int virPipe(int fds[2]) G_NO_INLINE;
/*
* virPipeQuiet:
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk1
b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1
index 257e331db8..da9e507f1b 100644
--- a/tests/qemunbdkitdata/disk-cdrom-network.args.disk1
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1
@@ -6,4 +6,4 @@ nbdkit \
protocols=ftps \
url=ftps://host.name:990/url/path/file.iso \
user=testuser \
-password=iscsi-mycluster_myname-secret
+password=-44
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.45
b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.45
new file mode 100644
index 0000000000..ccdd4033fc
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk1.pipe.45
@@ -0,0 +1 @@
+iscsi-mycluster_myname-secret
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk2
b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2
index f7879a9f24..0742b29853 100644
--- a/tests/qemunbdkitdata/disk-cdrom-network.args.disk2
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2
@@ -6,4 +6,4 @@ nbdkit \
protocols=https \
'url=https://host.name:443/url/path/file.iso?test=val' \
user=testuser \
-password=iscsi-mycluster_myname-secret
+password=-46
diff --git a/tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.47
b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.47
new file mode 100644
index 0000000000..ccdd4033fc
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-cdrom-network.args.disk2.pipe.47
@@ -0,0 +1 @@
+iscsi-mycluster_myname-secret
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk2
b/tests/qemunbdkitdata/disk-network-http.args.disk2
index 7286b684a8..767ea881d8 100644
--- a/tests/qemunbdkitdata/disk-network-http.args.disk2
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk2
@@ -4,4 +4,4 @@ nbdkit \
--foreground curl \
protocols=http \
url=http://example.org:1234/test3.img \
-'cookie=test=testcookievalue; test2="blurb"'
+cookie=-44
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.45
b/tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.45
new file mode 100644
index 0000000000..2c42c95930
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk2.pipe.45
@@ -0,0 +1 @@
+test=testcookievalue; test2="blurb"
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk3
b/tests/qemunbdkitdata/disk-network-http.args.disk3
index da177c9e6d..30dfd15861 100644
--- a/tests/qemunbdkitdata/disk-network-http.args.disk3
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk3
@@ -4,5 +4,5 @@ nbdkit \
--foreground curl \
protocols=https \
'url=https://example.org:1234/test4.img?par=val&other=ble' \
-'cookie=test=testcookievalue; test2="blurb"' \
+cookie=-46 \
sslverify=false
diff --git a/tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.47
b/tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.47
new file mode 100644
index 0000000000..2c42c95930
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-http.args.disk3.pipe.47
@@ -0,0 +1 @@
+test=testcookievalue; test2="blurb"
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
index b13f5ed628..d5ad545cdc 100644
--- a/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
+++ b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0
@@ -5,4 +5,4 @@ nbdkit \
--readonly curl \
protocols=https \
url=https://https.example.org:8443/path/to/disk1.qcow2 \
-'cookie=cookie1=cookievalue1; cookie2=cookievalue2'
+cookie=-44
diff --git
a/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.45
b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.45
new file mode 100644
index 0000000000..20af4ae383
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0.pipe.45
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk0
b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0
index 6de42c626f..3ea686e14f 100644
--- a/tests/qemunbdkitdata/disk-network-source-curl.args.disk0
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0
@@ -5,4 +5,4 @@ nbdkit \
--readonly curl \
protocols=https \
url=https://https.example.org:8443/path/to/disk1.iso \
-'cookie=cookie1=cookievalue1; cookie2=cookievalue2'
+cookie=-44
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.45
b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.45
new file mode 100644
index 0000000000..20af4ae383
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk0.pipe.45
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk1
b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1
index 9abc1578dd..fb77794b56 100644
--- a/tests/qemunbdkitdata/disk-network-source-curl.args.disk1
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1
@@ -4,5 +4,5 @@ nbdkit \
--foreground curl \
protocols=https \
'url=https://https.example.org:8443/path/to/disk5.iso?foo=bar' \
-'cookie=cookie1=cookievalue1; cookie2=cookievalue2' \
+cookie=-46 \
sslverify=false
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.47
b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.47
new file mode 100644
index 0000000000..20af4ae383
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk1.pipe.47
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2
\ No newline at end of file
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk2
b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2
index 1ce11ce618..eab66746ef 100644
--- a/tests/qemunbdkitdata/disk-network-source-curl.args.disk2
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2
@@ -5,4 +5,4 @@ nbdkit \
--readonly curl \
protocols=http \
url=http://http.example.org:8080/path/to/disk2.iso \
-'cookie=cookie1=cookievalue1; cookie2=cookievalue2; cookie3=cookievalue3'
+cookie=-48
diff --git a/tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.49
b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.49
new file mode 100644
index 0000000000..5c035e84c5
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-source-curl.args.disk2.pipe.49
@@ -0,0 +1 @@
+cookie1=cookievalue1; cookie2=cookievalue2; cookie3=cookievalue3
\ No newline at end of file
diff --git a/tests/qemunbdkittest.c b/tests/qemunbdkittest.c
index c53601dac8..a18567e9b4 100644
--- a/tests/qemunbdkittest.c
+++ b/tests/qemunbdkittest.c
@@ -13,6 +13,7 @@
#include "virutil.h"
#include "virsecret.h"
#include "datatypes.h"
+#include "virmock.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -20,6 +21,41 @@ static virQEMUDriver driver;
/* Some mock implementations for testing */
+#define PIPE_FD_START 44
+static int mockpipefd = PIPE_FD_START;
+int
+virPipe(int fds[2])
+{
+ fds[0] = mockpipefd++;
+ fds[1] = mockpipefd++;
+
+ return 0;
+}
+
+static int (*real_close)(int fd);
+static void
+init_syms(void)
+{
+ VIR_MOCK_REAL_INIT(close);
+}
+
+int
+close(int fd)
+{
+ int ret;
+
+ init_syms();
+
+ if (fd >= PIPE_FD_START)
+ ret = 0;
+ else
+ ret = real_close(fd);
+
+ return ret;
+}
+
+
+
int
virSecretGetSecretString(virConnectPtr conn G_GNUC_UNUSED,
virSecretLookupTypeDef *seclookupdef,
@@ -124,6 +160,9 @@ testNbdkit(const void *data)
size_t i;
int ret = 0;
+ /* restart mock pipe fds so tests are consistent */
+ mockpipefd = PIPE_FD_START;
+
if (!virFileExists(info->infile)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"Test input file '%s' is missing",
info->infile);
@@ -149,9 +188,11 @@ testNbdkit(const void *data)
g_autoptr(virCommandDryRunToken) dryRunToken = virCommandDryRunTokenNew();
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
const char *actualCmdline = NULL;
+ g_autoptr(NbdkitPipeData) pipes = NULL;
+ size_t j;
virCommandSetDryRun(dryRunToken, &buf, true, true, NULL, NULL);
- cmd = qemuNbdkitProcessBuildCommand(srcPriv->nbdkitProcess);
+ cmd = qemuNbdkitProcessBuildCommand(srcPriv->nbdkitProcess, &pipes);
if (virCommandRun(cmd, NULL) < 0) {
ret = -1;
@@ -163,9 +204,19 @@ testNbdkit(const void *data)
continue;
}
- if (virTestCompareToFileFull(actualCmdline, cmdfile, false) < 0) {
+ if (virTestCompareToFileFull(actualCmdline, cmdfile, false) < 0)
ret = -1;
- continue;
+
+ if (pipes) {
+ for (j = 0; j < pipes->nitems; j++) {
+ NbdkitPipeItem *item = pipes->items[j];
+ g_autofree char *pipefile = g_strdup_printf("%s.pipe.%i",
+ cmdfile,
+ item->fd);
+
+ if (virTestCompareToFile(item->buf, pipefile) < 0)
+ ret = -1;
+ }
}
} else {
if (virFileExists(cmdfile)) {
--
2.37.1