diff --git a/0001-Add-mandir-to-dump-config-output.patch b/0001-Add-mandir-to-dump-config-output.patch index d3703fb..0152b67 100644 --- a/0001-Add-mandir-to-dump-config-output.patch +++ b/0001-Add-mandir-to-dump-config-output.patch @@ -1,7 +1,7 @@ From 5294b7d8cc011f8b5e068aad744f612df7414a82 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 31 Oct 2015 13:24:52 +0000 -Subject: [PATCH 1/5] Add mandir to --dump-config output. +Subject: [PATCH 01/10] Add mandir to --dump-config output. This is useful for external plugins that want to install a man page. @@ -35,5 +35,5 @@ index cd676c0..1248a8e 100644 printf ("%s=%s\n", "plugindir", plugindir); printf ("%s=%s\n", "sbindir", sbindir); -- -2.5.0 +2.7.4 diff --git a/0002-Update-TODO.patch b/0002-Update-TODO.patch index c59c910..7f2c244 100644 --- a/0002-Update-TODO.patch +++ b/0002-Update-TODO.patch @@ -1,7 +1,7 @@ From 4b562134c3dad1a84aa92c1658e72046569e1570 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 11 Jan 2016 15:34:57 +0000 -Subject: [PATCH 2/5] Update TODO. +Subject: [PATCH 02/10] Update TODO. --- TODO | 5 +++++ @@ -31,5 +31,5 @@ index bcf2276..a05aa5b 100644 NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS and NBDKIT_THREAD_MODEL_PARALLEL are the same, because we handle -- -2.5.0 +2.7.4 diff --git a/0003-Add-support-for-newstyle-NBD-protocol-RHBZ-1297100.patch b/0003-Add-support-for-newstyle-NBD-protocol-RHBZ-1297100.patch index 940b242..05f2930 100644 --- a/0003-Add-support-for-newstyle-NBD-protocol-RHBZ-1297100.patch +++ b/0003-Add-support-for-newstyle-NBD-protocol-RHBZ-1297100.patch @@ -1,7 +1,7 @@ From f93807114634d58ca2ef0d64f7637ebd87e48a50 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 11 Jan 2016 17:08:51 +0000 -Subject: [PATCH 3/5] Add support for newstyle NBD protocol (RHBZ#1297100). +Subject: [PATCH 03/10] Add support for newstyle NBD protocol (RHBZ#1297100). --- .gitignore | 1 + @@ -756,5 +756,5 @@ index 7abf5af..c369150 100644 /* Declare program_name. */ #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME == 1 -- -2.5.0 +2.7.4 diff --git a/0004-xz-Fix-various-printf-warnings-on-32-bit.patch b/0004-xz-Fix-various-printf-warnings-on-32-bit.patch index 5919543..2718a4d 100644 --- a/0004-xz-Fix-various-printf-warnings-on-32-bit.patch +++ b/0004-xz-Fix-various-printf-warnings-on-32-bit.patch @@ -1,7 +1,7 @@ From 0759d15aa3649d088eeae91fcd174d0b37e1ccde Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 11 Jan 2016 19:02:53 +0000 -Subject: [PATCH 4/5] xz: Fix various printf warnings on 32 bit. +Subject: [PATCH 04/10] xz: Fix various printf warnings on 32 bit. xzfile.c: In function 'xzfile_read_block': xzfile.c:456:19: warning: format '%zu' expects argument of type 'size_t', but argument 2 has type 'uint64_t {aka long long unsigned int}' [-Wformat=] @@ -45,5 +45,5 @@ index fcc2937..3633099 100644 *size_rtn); goto err1; -- -2.5.0 +2.7.4 diff --git a/0005-ocaml-Avoid-race-when-building-NBDKit.cmi.patch b/0005-ocaml-Avoid-race-when-building-NBDKit.cmi.patch index b16153e..9ffed79 100644 --- a/0005-ocaml-Avoid-race-when-building-NBDKit.cmi.patch +++ b/0005-ocaml-Avoid-race-when-building-NBDKit.cmi.patch @@ -1,7 +1,7 @@ From b6db2f65596470492f0ad76d1ed63ddb98b17167 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 11 Jan 2016 19:46:37 +0000 -Subject: [PATCH 5/5] ocaml: Avoid race when building NBDKit.cmi. +Subject: [PATCH 05/10] ocaml: Avoid race when building NBDKit.cmi. If both the NBDKit.cmi and NBDKit.cmx builds run in parallel, both will try to build NBDKit.cmi, resulting in a corrupt NBDKit.cmi file. @@ -24,5 +24,5 @@ index d4776b3..f63ba33 100644 NBDKit.o: NBDKit.cmx -- -2.5.0 +2.7.4 diff --git a/0006-Test-the-o-oldstyle-command-line-option.patch b/0006-Test-the-o-oldstyle-command-line-option.patch new file mode 100644 index 0000000..010f817 --- /dev/null +++ b/0006-Test-the-o-oldstyle-command-line-option.patch @@ -0,0 +1,154 @@ +From 1c359d1140fee575cf478e2b4bf0c5ca0af9d05e Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 11 Jan 2016 20:34:28 +0000 +Subject: [PATCH 06/10] Test the -o (oldstyle) command line option. + +--- + .gitignore | 1 + + tests/Makefile.am | 8 ++++ + tests/test-oldstyle.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 111 insertions(+) + create mode 100644 tests/test-oldstyle.c + +diff --git a/.gitignore b/.gitignore +index 9ea072f..bc151ca 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -46,6 +46,7 @@ Makefile.in + /tests/test-newstyle + /tests/test-ocaml + /tests/test-ocaml-plugin.so ++/tests/test-oldstyle + /tests/test-perl + /tests/test-python + /tests/test-streaming +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 8d27032..1e6114c 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -111,6 +111,14 @@ test_newstyle_SOURCES = test-newstyle.c test.h + test_newstyle_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS) + test_newstyle_LDADD = libtest.la $(LIBGUESTFS_LIBS) + ++# oldstyle protocol test. ++check_PROGRAMS += test-oldstyle ++TESTS += test-oldstyle ++ ++test_oldstyle_SOURCES = test-oldstyle.c test.h ++test_oldstyle_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS) ++test_oldstyle_LDADD = libtest.la $(LIBGUESTFS_LIBS) ++ + # gzip plugin test. + if HAVE_ZLIB + if HAVE_GUESTFISH +diff --git a/tests/test-oldstyle.c b/tests/test-oldstyle.c +new file mode 100644 +index 0000000..d809a0c +--- /dev/null ++++ b/tests/test-oldstyle.c +@@ -0,0 +1,102 @@ ++/* nbdkit ++ * Copyright (C) 2013-2016 Red Hat Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * * Neither the name of Red Hat nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ++ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "test.h" ++ ++int ++main (int argc, char *argv[]) ++{ ++ guestfs_h *g; ++ int r; ++ char *data; ++ size_t i, size; ++ ++ if (test_start_nbdkit ("-o", NBDKIT_PLUGIN ("file"), "file=file-data", ++ NULL) == -1) ++ exit (EXIT_FAILURE); ++ ++ g = guestfs_create (); ++ if (g == NULL) { ++ perror ("guestfs_create"); ++ exit (EXIT_FAILURE); ++ } ++ ++ /* Using exportname = "" causes qemu to use the oldstyle protocol. */ ++ r = guestfs_add_drive_opts (g, "", ++ GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", ++ GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd", ++ GUESTFS_ADD_DRIVE_OPTS_SERVER, server, ++ -1); ++ if (r == -1) ++ exit (EXIT_FAILURE); ++ ++ if (guestfs_launch (g) == -1) ++ exit (EXIT_FAILURE); ++ ++ /* Check the data in the file is \x01-\x08 repeated 512 times. */ ++ data = guestfs_pread_device (g, "/dev/sda", 8 * 512, 0, &size); ++ if (!data) ++ exit (EXIT_FAILURE); ++ if (size != 8 * 512) { ++ fprintf (stderr, "%s FAILED: unexpected size (actual: %zu, expected: 512)\n", ++ program_name, size); ++ exit (EXIT_FAILURE); ++ } ++ ++ for (i = 0; i < 512 * 8; i += 8) { ++ if (data[i] != 1 || data[i+1] != 2 || ++ data[i+2] != 3 || data[i+3] != 4 || ++ data[i+4] != 5 || data[i+5] != 6 || ++ data[i+6] != 7 || data[i+7] != 8) { ++ fprintf (stderr, "%s FAILED: unexpected data returned at offset %zu\n", ++ program_name, i); ++ exit (EXIT_FAILURE); ++ } ++ } ++ ++ free (data); ++ ++ guestfs_close (g); ++ exit (EXIT_SUCCESS); ++} +-- +2.7.4 + diff --git a/0007-protocol-Send-limited-range-of-errno-values-to-the-c.patch b/0007-protocol-Send-limited-range-of-errno-values-to-the-c.patch new file mode 100644 index 0000000..e978393 --- /dev/null +++ b/0007-protocol-Send-limited-range-of-errno-values-to-the-c.patch @@ -0,0 +1,116 @@ +From f141228d1b6baddadcd516137d76b3d852af8cde Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 12 Jan 2016 12:16:48 +0000 +Subject: [PATCH 07/10] protocol: Send limited range of errno values to the + client. + +See the proposal here: +http://article.gmane.org/gmane.linux.drivers.nbd.general/3154 + +This implementation is based on Paolo Bonzini's for qemu-nbd: +http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785bc0b51862e62ebb +--- + TODO | 6 ------ + src/connections.c | 36 +++++++++++++++++++++++++++++++++++- + src/protocol.h | 12 +++++++++++- + 3 files changed, 46 insertions(+), 8 deletions(-) + +diff --git a/TODO b/TODO +index d39e64c..177a07c 100644 +--- a/TODO ++++ b/TODO +@@ -1,9 +1,3 @@ +-* There is a proposal to narrow the range of possible errnos that the +- server can return, and also to encode them in an OS-independent way. +- See: http://article.gmane.org/gmane.linux.drivers.nbd.general/3154 +- Implemented in QEMU already: +- http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785bc0b51862e62ebb +- + * Can we do language bindings using #!'s? + You would enter: + nbdkit foo [args] +diff --git a/src/connections.c b/src/connections.c +index 6bdf4ef..f0a7662 100644 +--- a/src/connections.c ++++ b/src/connections.c +@@ -639,6 +639,31 @@ skip_over_write_buffer (int sock, size_t count) + } + } + ++/* Convert a system errno to an NBD_E* error code. */ ++static int ++nbd_errno (int error) ++{ ++ switch (error) { ++ case 0: ++ return NBD_SUCCESS; ++ case EPERM: ++ return NBD_EPERM; ++ case EIO: ++ return NBD_EIO; ++ case ENOMEM: ++ return NBD_ENOMEM; ++#ifdef EDQUOT ++ case EDQUOT: ++#endif ++ case EFBIG: ++ case ENOSPC: ++ return NBD_ENOSPC; ++ case EINVAL: ++ default: ++ return NBD_EINVAL; ++ } ++} ++ + static int + recv_request_send_reply (struct connection *conn) + { +@@ -722,7 +747,16 @@ recv_request_send_reply (struct connection *conn) + send_reply: + reply.magic = htobe32 (NBD_REPLY_MAGIC); + reply.handle = request.handle; +- reply.error = htobe32 (error); ++ reply.error = htobe32 (nbd_errno (error)); ++ ++ if (error != 0) { ++ /* Since we're about to send only the limited NBD_E* errno to the ++ * client, don't lose the information about what really happened ++ * on the server side. Make sure there is a way for the operator ++ * to retrieve the real error. ++ */ ++ debug ("sending error reply: %s", strerror (error)); ++ } + + r = xwrite (conn->sockout, &reply, sizeof reply); + if (r == -1) { +diff --git a/src/protocol.h b/src/protocol.h +index 2f9a341..fcbc145 100644 +--- a/src/protocol.h ++++ b/src/protocol.h +@@ -118,7 +118,7 @@ struct request { + /* Reply (server -> client). */ + struct reply { + uint32_t magic; /* NBD_REPLY_MAGIC. */ +- uint32_t error; /* 0 = ok, error code */ ++ uint32_t error; /* NBD_SUCCESS or one of NBD_E*. */ + uint64_t handle; /* Opaque handle. */ + } __attribute__((packed)); + +@@ -133,4 +133,14 @@ struct reply { + #define NBD_CMD_MASK_COMMAND 0xffff + #define NBD_CMD_FLAG_FUA (1<<16) + ++/* Error codes (previously errno). ++ * See http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785bc0b51862e62ebb ++ */ ++#define NBD_SUCCESS 0 ++#define NBD_EPERM 1 ++#define NBD_EIO 5 ++#define NBD_ENOMEM 12 ++#define NBD_EINVAL 22 ++#define NBD_ENOSPC 28 ++ + #endif /* NBDKIT_PROTOCOL_H */ +-- +2.7.4 + diff --git a/0008-protocol-Pack-fixed_new_option_reply-struct.patch b/0008-protocol-Pack-fixed_new_option_reply-struct.patch new file mode 100644 index 0000000..f46740d --- /dev/null +++ b/0008-protocol-Pack-fixed_new_option_reply-struct.patch @@ -0,0 +1,27 @@ +From e5a945ea1e759e6441773c1e7663a1ac2492c8e4 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 17 May 2016 19:40:29 +0100 +Subject: [PATCH 08/10] protocol: Pack fixed_new_option_reply struct. + +This struct was not packed, but we were sending a reply by sending the +struct directly onto the wire. I think we got away with it, but not good. +--- + src/protocol.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/protocol.h b/src/protocol.h +index fcbc145..de511a6 100644 +--- a/src/protocol.h ++++ b/src/protocol.h +@@ -72,7 +72,7 @@ struct fixed_new_option_reply { + uint32_t reply; /* NBD_REP_* */ + uint32_t replylen; /* we always send zero at the moment */ + /* reply data follows, but we currently never send any */ +-}; ++} __attribute__((packed)); + + #define NEW_OPTION_REPLY UINT64_C(0x3e889045565a9) + +-- +2.7.4 + diff --git a/0009-protocol-Rename-NEW_OPTION_REPLY-as-NBD_REP_MAGIC.patch b/0009-protocol-Rename-NEW_OPTION_REPLY-as-NBD_REP_MAGIC.patch new file mode 100644 index 0000000..fbd639c --- /dev/null +++ b/0009-protocol-Rename-NEW_OPTION_REPLY-as-NBD_REP_MAGIC.patch @@ -0,0 +1,48 @@ +From f989fbad9b0527925c38f4350190cb1536a4d8c2 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 17 May 2016 19:42:35 +0100 +Subject: [PATCH 09/10] protocol: Rename NEW_OPTION_REPLY as NBD_REP_MAGIC. + +To be consistent with qemu's implementation. +--- + src/connections.c | 2 +- + src/protocol.h | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/connections.c b/src/connections.c +index f0a7662..34566b3 100644 +--- a/src/connections.c ++++ b/src/connections.c +@@ -235,7 +235,7 @@ send_newstyle_option_reply (struct connection *conn, + { + struct fixed_new_option_reply fixed_new_option_reply; + +- fixed_new_option_reply.magic = htobe64 (NEW_OPTION_REPLY); ++ fixed_new_option_reply.magic = htobe64 (NBD_REP_MAGIC); + fixed_new_option_reply.option = htobe32 (option); + fixed_new_option_reply.reply = htobe32 (reply); + fixed_new_option_reply.replylen = htobe32 (0); +diff --git a/src/protocol.h b/src/protocol.h +index de511a6..71a8098 100644 +--- a/src/protocol.h ++++ b/src/protocol.h +@@ -67,14 +67,14 @@ struct new_option { + + /* Fixed newstyle handshake reply message. */ + struct fixed_new_option_reply { +- uint64_t magic; /* NEW_OPTION_REPLY, network byte order */ ++ uint64_t magic; /* NBD_REP_MAGIC, network byte order */ + uint32_t option; /* option we are replying to */ + uint32_t reply; /* NBD_REP_* */ + uint32_t replylen; /* we always send zero at the moment */ + /* reply data follows, but we currently never send any */ + } __attribute__((packed)); + +-#define NEW_OPTION_REPLY UINT64_C(0x3e889045565a9) ++#define NBD_REP_MAGIC UINT64_C(0x3e889045565a9) + + /* New-style handshake server reply. */ + struct new_handshake_finish { +-- +2.7.4 + diff --git a/0010-Implement-newstyle-export-names.patch b/0010-Implement-newstyle-export-names.patch new file mode 100644 index 0000000..e767bc1 --- /dev/null +++ b/0010-Implement-newstyle-export-names.patch @@ -0,0 +1,360 @@ +From 0095b003b56894baad8e6789d523cf3c51905c05 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 17 May 2016 19:43:16 +0100 +Subject: [PATCH 10/10] Implement newstyle export names. + +This is now required by qemu >= 2.6. See this lengthy qemu-devel +thread for details: +https://lists.nongnu.org/archive/html/qemu-devel/2016-05/threads.html#02752 +--- + TODO | 13 ------------- + docs/nbdkit.pod | 52 ++++++++++++++++++++++++++++++++------------------- + src/connections.c | 49 ++++++++++++++++++++++++++++++++++++++++-------- + src/internal.h | 1 + + src/main.c | 32 +++++++++++++++++++++++-------- + src/protocol.h | 3 +-- + tests/test-newstyle.c | 7 +++++-- + 7 files changed, 105 insertions(+), 52 deletions(-) + +diff --git a/TODO b/TODO +index 177a07c..30bf72e 100644 +--- a/TODO ++++ b/TODO +@@ -11,19 +11,6 @@ + + * Performance - measure and improve it. + +-* Implement export names. With export names it should be possible to +- have multiple plugins on the command line (each responding to a +- different export of course): +- +- nbdkit --export /foo plugin.so --export /bar another-plugin.so +- +- Note it should also be possible to either elect one plugin as the +- default that accepts all exportnames, or to divide the export name +- "space" up using regexps or wildcards. +- +- Export names are not actually paths (although that is how they are +- often used), but arbitrary UTF-8 text strings. +- + * Implement true parallel request handling. Currently + NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS and + NBDKIT_THREAD_MODEL_PARALLEL are the same, because we handle +diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod +index 7204a38..728aad3 100644 +--- a/docs/nbdkit.pod ++++ b/docs/nbdkit.pod +@@ -6,7 +6,7 @@ nbdkit - A toolkit for creating NBD servers + + =head1 SYNOPSIS + +- nbdkit [--dump-config] [-f] [-g GROUP] [-i IPADDR] ++ nbdkit [--dump-config] [-e EXPORTNAME] [-f] [-g GROUP] [-i IPADDR] + [--newstyle] [--oldstyle] [-P PIDFILE] [-p PORT] [-r] + [--run CMD] [-s] [-U SOCKET] [-u USER] [-v] [-V] + PLUGIN [key=value [key=value [...]]] +@@ -74,6 +74,19 @@ Display brief command line usage information and exit. + + Dump out the compile-time configuration values and exit. + ++=item B<-e> EXPORTNAME ++ ++=item B<--export> EXPORTNAME ++ ++=item B<--export-name> EXPORTNAME ++ ++=item B<--exportname> EXPORTNAME ++ ++Set the exportname and use the newstyle protocol (implies I<-n>). ++ ++If not set, exportname C<""> (empty string) is used. Exportnames are ++not allowed with the oldstyle protocol. ++ + =item B<-f> + + =item B<--foreground> +@@ -118,9 +131,10 @@ protocol. See L below. + + =item B<--oldstyle> + +-Use the oldstyle NBD protocol. This is currently the default, so this +-flag does nothing, but it is possible we might change the default +-protocol in future. See L below. ++Use the oldstyle NBD protocol. This is currently the default (unless ++you use I<-n> or I<-e>), so this flag does nothing, but it is possible ++we might change the default protocol in future. See L below. + + =item B<-P> PIDFILE + +@@ -307,27 +321,29 @@ use depends on the client and cannot be known in advance, nor can it + be negotiated from the server side. + + nbdkit currently defaults to the oldstyle protocol for compatibility +-with qemu and libguestfs. This is also the same behaviour as +-qemu-nbd. Use the I<-n> or I<--newstyle> flag on the command line to +-use the newstyle protocol. Use the I<-o> or I<--oldstyle> flag to +-force the oldstyle protocol. ++with qemu and libguestfs. This is also the same behaviour as qemu-nbd ++E 2.5. Use the I<-n> or I<--newstyle> flag on the command line to ++use the newstyle protocol. Use the I<-e> or I<--exportname> flag to ++set the exportname for the newstyle protocol. Use the I<-o> or ++I<--oldstyle> flag to force the oldstyle protocol. + + Some common clients and the protocol they require: + +- Client Protocol ++ Client Protocol + ------------------------------------------------------------ +- qemu without exportname oldstyle +- qemu with exportname newstyle +- nbd-client < 3.10 client can talk either protocol +- nbd-client >= 3.10 newstyle ++ qemu <= 2.5 without exportname oldstyle ++ qemu <= 2.5 with exportname newstyle ++ qemu >= 2.6 client can talk either protocol ++ nbd-client < 3.10 client can talk either protocol ++ nbd-client >= 3.10 newstyle + +-If you use qemu without the exportname field against a newstyle +-server, it will give the error: ++If you use qemu E 2.5 without the exportname field against a ++newstyle server, it will give the error: + + Server requires an export name + +-If you use qemu with the exportname field against an oldstyle server, +-it will give the error: ++If you use qemu E 2.5 with the exportname field against an ++oldstyle server, it will give the error: + + Server does not support export names + +@@ -341,8 +357,6 @@ document says should be the case (which isn't based in reality), then + you should always use newstyle when using port 10809, and use oldstyle + on all other ports. + +-nbdkit ignores export names at present (see also the C file). +- + =head1 SIGNALS + + C responds to the following signals: +diff --git a/src/connections.c b/src/connections.c +index 34566b3..0c93f35 100644 +--- a/src/connections.c ++++ b/src/connections.c +@@ -222,13 +222,8 @@ _negotiate_handshake_oldstyle (struct connection *conn) + return 0; + } + +-/* Receive newstyle options. +- * +- * Currently we ignore NBD_OPT_EXPORT_NAME (see TODO), we close the +- * connection if sent NBD_OPT_ABORT, we send a canned list of +- * options for NBD_OPT_LIST, and we send NBD_REP_ERR_UNSUP for +- * everything else. +- */ ++/* Receive newstyle options. */ ++ + static int + send_newstyle_option_reply (struct connection *conn, + uint32_t option, uint32_t reply) +@@ -250,6 +245,39 @@ send_newstyle_option_reply (struct connection *conn, + } + + static int ++send_newstyle_option_reply_exportname (struct connection *conn, ++ uint32_t option, uint32_t reply, ++ const char *exportname) ++{ ++ struct fixed_new_option_reply fixed_new_option_reply; ++ size_t name_len = strlen (exportname); ++ uint32_t len; ++ ++ fixed_new_option_reply.magic = htobe64 (NBD_REP_MAGIC); ++ fixed_new_option_reply.option = htobe32 (option); ++ fixed_new_option_reply.reply = htobe32 (reply); ++ fixed_new_option_reply.replylen = htobe32 (name_len + sizeof (len)); ++ ++ if (xwrite (conn->sockout, ++ &fixed_new_option_reply, sizeof fixed_new_option_reply) == -1) { ++ nbdkit_error ("write: %m"); ++ return -1; ++ } ++ ++ len = htobe32 (name_len); ++ if (xwrite (conn->sockout, &len, sizeof len) == -1) { ++ nbdkit_error ("write: %m"); ++ return -1; ++ } ++ if (xwrite (conn->sockout, exportname, name_len) == -1) { ++ nbdkit_error ("write: %m"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int + _negotiate_handshake_newstyle_options (struct connection *conn) + { + struct new_option new_option; +@@ -309,7 +337,12 @@ _negotiate_handshake_newstyle_options (struct connection *conn) + continue; + } + +- /* Since we don't support export names, there is nothing to list. */ ++ /* Send back the exportname. */ ++ debug ("newstyle negotiation: advertising export '%s'", exportname); ++ if (send_newstyle_option_reply_exportname (conn, option, NBD_REP_SERVER, ++ exportname) == -1) ++ return -1; ++ + if (send_newstyle_option_reply (conn, option, NBD_REP_ACK) == -1) + return -1; + break; +diff --git a/src/internal.h b/src/internal.h +index 0603779..f58086a 100644 +--- a/src/internal.h ++++ b/src/internal.h +@@ -48,6 +48,7 @@ + #endif + + /* main.c */ ++extern const char *exportname; + extern const char *ipaddr; + extern int newstyle; + extern const char *port; +diff --git a/src/main.c b/src/main.c +index db4361e..9529f19 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -65,6 +65,7 @@ static void fork_into_background (void); + static uid_t parseuser (const char *); + static gid_t parsegroup (const char *); + ++const char *exportname; /* -e */ + int foreground; /* -f */ + const char *ipaddr; /* -i */ + int newstyle; /* -n */ +@@ -84,10 +85,13 @@ static char *random_fifo = NULL; + + enum { HELP_OPTION = CHAR_MAX + 1 }; + +-static const char *short_options = "fg:i:nop:P:rsu:U:vV"; ++static const char *short_options = "e:fg:i:nop:P:rsu:U:vV"; + static const struct option long_options[] = { + { "help", 0, NULL, HELP_OPTION }, + { "dump-config",0, NULL, 0 }, ++ { "export", 1, NULL, 'e' }, ++ { "export-name",1, NULL, 'e' }, ++ { "exportname", 1, NULL, 'e' }, + { "foreground", 0, NULL, 'f' }, + { "no-fork", 0, NULL, 'f' }, + { "group", 1, NULL, 'g' }, +@@ -115,7 +119,7 @@ static const struct option long_options[] = { + static void + usage (void) + { +- printf ("nbdkit [--dump-config] [-f] [-g GROUP] [-i IPADDR]\n" ++ printf ("nbdkit [--dump-config] [-e EXPORTNAME] [-f] [-g GROUP] [-i IPADDR]\n" + " [--newstyle] [--oldstyle] [-P PIDFILE] [-p PORT] [-r]\n" + " [--run CMD] [-s] [-U SOCKET] [-u USER] [-v] [-V]\n" + " PLUGIN [key=value [key=value [...]]]\n" +@@ -173,6 +177,11 @@ main (int argc, char *argv[]) + } + break; + ++ case 'e': ++ exportname = optarg; ++ newstyle = 1; ++ break; ++ + case 'f': + foreground = 1; + break; +@@ -190,9 +199,6 @@ main (int argc, char *argv[]) + break; + + case 'o': +- /* XXX When we add support for exportnames, we will need to +- * ensure that the user does not use -o + --export. +- */ + newstyle = 0; + break; + +@@ -263,12 +269,22 @@ main (int argc, char *argv[]) + exit (EXIT_FAILURE); + } + ++ /* Oldstyle protocol + exportname not allowed. */ ++ if (newstyle == 0 && exportname != NULL) { ++ fprintf (stderr, ++ "%s: cannot use oldstyle protocol (-o) and exportname (-e)\n", ++ program_name); ++ exit (EXIT_FAILURE); ++ } ++ ++ /* If exportname was not set on the command line, use "". */ ++ if (exportname == NULL) ++ exportname = ""; ++ + /* Remaining command line arguments define the plugins and plugin + * configuration. If --help or --version was specified, we still + * partially parse these in order that we can display the per-plugin +- * help/version information. In future (when the new protocol and +- * export names are permitted) we will allow multiple plugins to be +- * given, but at the moment only one plugin is allowed. ++ * help/version information. + */ + while (optind < argc) { + const char *filename = argv[optind]; +diff --git a/src/protocol.h b/src/protocol.h +index 71a8098..c885d9e 100644 +--- a/src/protocol.h ++++ b/src/protocol.h +@@ -70,8 +70,7 @@ struct fixed_new_option_reply { + uint64_t magic; /* NBD_REP_MAGIC, network byte order */ + uint32_t option; /* option we are replying to */ + uint32_t reply; /* NBD_REP_* */ +- uint32_t replylen; /* we always send zero at the moment */ +- /* reply data follows, but we currently never send any */ ++ uint32_t replylen; + } __attribute__((packed)); + + #define NBD_REP_MAGIC UINT64_C(0x3e889045565a9) +diff --git a/tests/test-newstyle.c b/tests/test-newstyle.c +index b1d8ce7..adcc568 100644 +--- a/tests/test-newstyle.c ++++ b/tests/test-newstyle.c +@@ -44,6 +44,8 @@ + + #include "test.h" + ++#define EXPORTNAME "/" ++ + int + main (int argc, char *argv[]) + { +@@ -52,7 +54,8 @@ main (int argc, char *argv[]) + char *data; + size_t i, size; + +- if (test_start_nbdkit ("-n", NBDKIT_PLUGIN ("file"), "file=file-data", ++ if (test_start_nbdkit ("-e", EXPORTNAME, ++ "-n", NBDKIT_PLUGIN ("file"), "file=file-data", + NULL) == -1) + exit (EXIT_FAILURE); + +@@ -63,7 +66,7 @@ main (int argc, char *argv[]) + } + + /* Using any exportname causes qemu to use the newstyle protocol. */ +- r = guestfs_add_drive_opts (g, "/" /* exportname */, ++ r = guestfs_add_drive_opts (g, EXPORTNAME, + GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", + GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd", + GUESTFS_ADD_DRIVE_OPTS_SERVER, server, +-- +2.7.4 + diff --git a/nbdkit.spec b/nbdkit.spec index 3c5c65d..1e557f6 100644 --- a/nbdkit.spec +++ b/nbdkit.spec @@ -6,7 +6,7 @@ Name: nbdkit Version: 1.1.11 -Release: 7%{?dist} +Release: 8%{?dist} Summary: NBD server License: BSD @@ -15,11 +15,17 @@ URL: https://github.com/libguestfs/nbdkit Source0: http://libguestfs.org/download/nbdkit/%{name}-%{version}.tar.gz # All patches are upstream since 1.1.11. -Patch1: 0001-Add-mandir-to-dump-config-output.patch -Patch2: 0002-Update-TODO.patch -Patch3: 0003-Add-support-for-newstyle-NBD-protocol-RHBZ-1297100.patch -Patch4: 0004-xz-Fix-various-printf-warnings-on-32-bit.patch -Patch5: 0005-ocaml-Avoid-race-when-building-NBDKit.cmi.patch +Patch0001: 0001-Add-mandir-to-dump-config-output.patch +Patch0002: 0002-Update-TODO.patch +Patch0003: 0003-Add-support-for-newstyle-NBD-protocol-RHBZ-1297100.patch +Patch0004: 0004-xz-Fix-various-printf-warnings-on-32-bit.patch +Patch0005: 0005-ocaml-Avoid-race-when-building-NBDKit.cmi.patch +Patch0006: 0006-Test-the-o-oldstyle-command-line-option.patch +Patch0007: 0007-protocol-Send-limited-range-of-errno-values-to-the-c.patch +Patch0008: 0008-protocol-Pack-fixed_new_option_reply-struct.patch +Patch0009: 0009-protocol-Rename-NEW_OPTION_REPLY-as-NBD_REP_MAGIC.patch +Patch0010: 0010-Implement-newstyle-export-names.patch + # Because patch3 & patch5 patches Makefile.am, we need: BuildRequires: automake, autoconf, libtool @@ -258,15 +264,12 @@ export LIBGUESTFS_TRACE=1 # Unlikely that libguestfs will work on ARM and PPC, so don't try running the # tests there. %ifnarch %{arm} ppc %{power64} -# Broken on i686 because of https://bugzilla.redhat.com/show_bug.cgi?id=1302071 -%ifnarch %{ix86} make check || { cat tests/test-suite.log exit 1 } %endif %endif -%endif %ifarch %{ocaml_native_compiler} @@ -368,6 +371,10 @@ make check || { %changelog +* Thu May 19 2016 Richard W.M. Jones - 1.1.11-8 +- Add all patches upstream since 1.1.11 (fixes RHBZ#1336758). +- Reenable tests on x86. + * Tue May 17 2016 Jitka Plesnikova - 1.1.11-7 - Perl 5.24 rebuild