A common command line use case for the nbd plugin is
( sock=`mktemp -u` &&
nbdkit --exit-with-parent nbd socket=$sock &
exec /path/to/server -k $sock)
As long as the first client to nbdkit doesn't try to connect until
after /path/to/server has created $sock, we are fine. But on a heavily
loaded system, it would be nice to give nbdkit some leeway to try
again to connect to the socket if a client connects quickly to nbdkit.
This becomes even more useful in the next patch when adding an option
for the nbd plugin to connect during .config_complete rather than
during .open, as the window of time for the external server to make
the socket available is no longer dependent on when nbdkit's first
client arrives.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
plugins/nbd/nbdkit-nbd-plugin.pod | 6 ++++++
plugins/nbd/nbd.c | 24 ++++++++++++++++++++++--
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/plugins/nbd/nbdkit-nbd-plugin.pod b/plugins/nbd/nbdkit-nbd-plugin.pod
index 913d1e5..4f9efa1 100644
--- a/plugins/nbd/nbdkit-nbd-plugin.pod
+++ b/plugins/nbd/nbdkit-nbd-plugin.pod
@@ -5,6 +5,7 @@ nbdkit-nbd-plugin - nbdkit nbd plugin
=head1 SYNOPSIS
nbdkit nbd { socket=SOCKNAME | hostname=HOST [port=PORT] } [export=NAME]
+ [retry=N]
=head1 DESCRIPTION
@@ -50,6 +51,11 @@ If this parameter is given, and the server speaks new style protocol,
then connect to the named export instead of the default export (the
empty string).
+=item B<retry=>N
+
+If the initial connection attempt to the server fails, retry up to
+B<N> times more after a second delay between tries (default 0).
+
=back
=head1 EXAMPLES
diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index 1195eb8..6665cd9 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -70,6 +70,9 @@ static char *servname;
/* Name of export on remote server, default '', ignored for oldstyle */
static const char *export;
+/* Number of retries */
+static unsigned long retry;
+
static void
nbd_unload (void)
{
@@ -79,11 +82,14 @@ nbd_unload (void)
/* Called for each key=value passed on the command line. This plugin
* accepts socket=<sockname> or hostname=<hostname>/port=<port>
- * (exactly one connection required) and export=<name> (optional).
+ * (exactly one connection required), and optional parameters
+ * export=<name>, retry=<n>.
*/
static int
nbd_config (const char *key, const char *value)
{
+ char *end;
+
if (strcmp (key, "socket") == 0) {
/* See FILENAMES AND PATHS in nbdkit-plugin(3) */
free (sockname);
@@ -97,6 +103,14 @@ nbd_config (const char *key, const char *value)
port = value;
else if (strcmp (key, "export") == 0)
export = value;
+ else if (strcmp (key, "retry") == 0) {
+ errno = 0;
+ retry = strtoul (value, &end, 0);
+ if (value == end || errno) {
+ nbdkit_error ("could not parse retry as integer (%s)", value);
+ return -1;
+ }
+ }
else {
nbdkit_error ("unknown parameter '%s'", key);
return -1;
@@ -960,12 +974,18 @@ nbd_open (int readonly)
return NULL;
}
+ retry:
if (sockname)
h->fd = nbd_connect_unix ();
else
h->fd = nbd_connect_tcp ();
- if (h->fd == -1)
+ if (h->fd == -1) {
+ if (retry--) {
+ sleep (1);
+ goto retry;
+ }
goto err;
+ }
/* old and new handshake share same meaning of first 16 bytes */
if (read_full (h->fd, &old, offsetof (struct old_handshake, exportsize))) {
--
2.20.1