[PATCH libnbd v2 0/4] api: Implement concurrent writer.
by Richard W.M. Jones
v1:
https://www.redhat.com/archives/libguestfs/2019-June/msg00014.html
I pushed a few bits which are uncontroversial. The main
changes since v1 are:
An extra patch removes the want_to_send / check for nbd_aio_is_ready
in examples/threaded-reads-and-writes.c. This logic was wrong since
commit 6af72b87 as was pointed out by Eric in his review. Comments
and structure of examples/concurrent-writes.c has been updated to
match.
Callbacks now return int instead of void. In some cases we ignore
this return value.
I added a lot more commentary in the commit message for the main patch
(now patch 3 in this series).
Rich.
5 years, 4 months
[libnbd] How close are we to declaring a stable API?
by Richard W.M. Jones
As the subject says, how close are we to being able to declare a
stable API for libnbd?
I believe these are the main topics:
* Do we need to have an extra thread for writing? I'm unclear about
whether b92392b717 (which allows the state machine to break during
reply processing) means we definitely don't need threads. I imagine
that two threads doing simultaneous send(2) and recv(2) calls could
still improve performance (eg. having two cores copying skbs from
userspace to and from kernel).
* Should ‘nbd_shutdown’ take an extra parameter to indicate that it
should be delayed until all commands in the queue are retired?
Is there anything else?
We could also consider doing a "soft stable API" release where we bump
the version up to 0.9.x, announce that we're going to make the API
stable soon, have a much higher bar for breaking the API, but don't
actually prevent API breaks in cases where it's necessary.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
5 years, 4 months
[libnbd PATCH] tests: Enhance errors test
by Eric Blake
Let's check for a quite a few more errors. Among other things, this
adds some coverage for a few things I've patched recently.
---
And these enhancements set me up for my next fix: making NBD_CMD_DISC
prevent future commands.
tests/errors.c | 167 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 154 insertions(+), 13 deletions(-)
diff --git a/tests/errors.c b/tests/errors.c
index 99d5820..415c378 100644
--- a/tests/errors.c
+++ b/tests/errors.c
@@ -27,12 +27,40 @@
#include <libnbd.h>
+#define MAXSIZE (65 * 1024 * 1024) /* Oversize on purpose */
+
+static char *progname;
+static char buf[MAXSIZE];
+
+static void
+check (int experr, const char *prefix)
+{
+ const char *msg = nbd_get_error ();
+ int errnum = nbd_get_errno ();
+
+ printf ("error: \"%s\"\n", msg);
+ printf ("errno: %d (%s)\n", errnum, strerror (errnum));
+ if (strncmp (msg, prefix, strlen (prefix)) != 0) {
+ fprintf (stderr, "%s: test failed: missing context prefix: %s\n",
+ progname, msg);
+ exit (EXIT_FAILURE);
+ }
+ if (errnum != experr) {
+ fprintf (stderr, "%s: test failed: "
+ "expected errno = %d (%s), but got %d\n",
+ progname, experr, strerror (experr), errnum);
+ exit (EXIT_FAILURE);
+ }
+}
+
int
main (int argc, char *argv[])
{
struct nbd_handle *nbd;
- const char *msg;
- int errnum;
+ const char *cmd[] = { "nbdkit", "-s", "--exit-with-parent", "memory",
+ "size=128m", NULL };
+
+ progname = argv[0];
nbd = nbd_create ();
if (nbd == NULL) {
@@ -47,23 +75,136 @@ main (int argc, char *argv[])
argv[0]);
exit (EXIT_FAILURE);
}
- msg = nbd_get_error ();
- errnum = nbd_get_errno ();
- printf ("error: \"%s\"\n", msg);
- printf ("errno: %d (%s)\n", errnum, strerror (errnum));
- if (strncmp (msg, "nbd_pread: ", strlen ("nbd_pread: ")) != 0) {
- fprintf (stderr, "%s: test failed: missing context prefix: %s\n",
- argv[0], msg);
+ check (ENOTCONN, "nbd_pread: ");
+
+ /* Request a name that is too long. */
+ memset (buf, 'a', 4999);
+ buf[4999] = '\0';
+ if (nbd_set_export_name (nbd, buf) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_set_export_name did not reject large name\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (ENAMETOOLONG, "nbd_set_export_name: ");
+
+ /* Poll while there is no fd. */
+ if (nbd_aio_get_fd (nbd) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_aio_get_fd did not fail prior to connection\n",
+ argv[0]);
+ }
+ check (EINVAL, "nbd_aio_get_fd: ");
+ if (nbd_poll (nbd, 1000) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_poll did not fail prior to connection\n",
+ argv[0]);
+ }
+ check (EINVAL, "nbd_poll: ");
+
+ /* Connect to a working server, then try to connect again. */
+ if (nbd_connect_command (nbd, (char **) cmd) == -1) {
+ fprintf (stderr, "%s: %s\n", argv[0], nbd_get_error ());
+ exit (EXIT_FAILURE);
+ }
+ if (nbd_connect_command (nbd, (char **) cmd) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_connect_command did not reject repeat attempt\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (EINVAL, "nbd_connect_command: ");
+
+ /* Try to notify that writes are ready when we aren't blocked on POLLOUT */
+ if (nbd_aio_notify_write (nbd) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_aio_notify_write in wrong state did not fail\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (EINVAL, "nbd_aio_notify_write: ");
+
+ /* Check for status of a bogus handle */
+ if (nbd_aio_command_completed (nbd, 0) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_aio_command_completed on bogus handle did not fail\n",
+ argv[0]);
exit (EXIT_FAILURE);
}
- if (errnum != ENOTCONN) {
+ check (EINVAL, "nbd_aio_command_completed: ");
+
+ /* Read from an invalid offset */
+ if (nbd_pread (nbd, NULL, 0, -1, 0) != -1) {
fprintf (stderr, "%s: test failed: "
- "expected errno = ENOTCONN, but got %d\n",
- argv[0], errnum);
+ "nbd_pread did not fail with bogus offset\n",
+ argv[0]);
exit (EXIT_FAILURE);
}
+ check (EINVAL, "nbd_pread: ");
- /* XXX Test some more stuff here. */
+ /* Use unknown command flags */
+ if (nbd_pread (nbd, NULL, 0, 0, -1) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_pread did not fail with bogus flags\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (EINVAL, "nbd_pread: ");
+
+ /* Check that oversized requests are rejected */
+ if (nbd_pread (nbd, buf, MAXSIZE, 0, 0) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_pread did not fail with oversize request\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (ERANGE, "nbd_pread: ");
+ if (nbd_aio_pwrite (nbd, buf, MAXSIZE, 0, 0) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_aio_pwrite did not fail with oversize request\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (ERANGE, "nbd_aio_pwrite: ");
+
+ /* Queue up a write command so large that we block on POLLIN, then queue
+ * multiple disconnects. XXX The last one should fail.
+ */
+ if (nbd_aio_pwrite (nbd, buf, 2 * 1024 * 1024, 0, 0) == -1) {
+ fprintf (stderr, "%s: %s\n", argv[0], nbd_get_error ());
+ exit (EXIT_FAILURE);
+ }
+ if ((nbd_aio_get_direction (nbd) & LIBNBD_AIO_DIRECTION_WRITE) == 0) {
+ fprintf (stderr, "%s: test failed: "
+ "expect to be blocked on write\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ if (nbd_aio_disconnect (nbd, 0) == -1) {
+ fprintf (stderr, "%s: %s\n", argv[0], nbd_get_error ());
+ exit (EXIT_FAILURE);
+ }
+ if (nbd_aio_disconnect (nbd, 0) == -1) { /* XXX */
+ fprintf (stderr, "%s: %s\n", argv[0], nbd_get_error ());
+ exit (EXIT_FAILURE);
+ }
+
+ /* Flush the queue (whether this one fails is a race with how fast
+ * the server shuts down, so don't enforce status), then try to send
+ * another command while CLOSED/DEAD
+ */
+ if (nbd_shutdown (nbd) == -1) {
+ fprintf (stderr, "%s: ignoring %s\n", argv[0], nbd_get_error ());
+ }
+ else
+ fprintf (stderr, "%s: shutdown completed successfully\n", argv[0]);
+ if (nbd_pread (nbd, NULL, 0, 0, 0) != -1) {
+ fprintf (stderr, "%s: test failed: "
+ "nbd_pread did not fail on non-connected handle\n",
+ argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ check (EINVAL, "nbd_pread: ");
nbd_close (nbd);
exit (EXIT_SUCCESS);
--
2.20.1
5 years, 4 months
[nbdkit PATCH 0/2] Use new libnbd _notify functions
by Eric Blake
I'm not observing any noticeable performance differences, but I'm
liking the diffstat. I can't push this patch until we release a new
libnbd version with the _notify API addition, but am posting it now
for playing with things.
Eric Blake (2):
nbd: Move transaction info from heap to stack
nbd: Use nbdkit aio_*_notify variants
plugins/nbd/nbd.c | 217 +++++++++++++++++++---------------------------
1 file changed, 91 insertions(+), 126 deletions(-)
--
2.20.1
5 years, 4 months