Previously there were two places where similiar-ish logic was used to
decide if we are going to serve over a socket activation, -s, Unix
socket, AF_VSOCK or TCP/IP. Let's abstract that into a service_mode.
One place where we did this was when calculating the $uri variable for
--run. This change adjusts and fixes this calculation (revealed as I
made the above change). In particular if --port was not set then the
$uri would contain fairly bogus values in some cases:
$ nbdkit --vsock null 1M --run 'echo $uri ; nbdinfo $uri'
nbd
nbdinfo: nbd_connect_uri: NBD URI does not have a scheme: valid NBD URIs
should start with a scheme like nbd://, nbds:// or nbd+unix://: Invalid argument
(note uri='nbd')
After this commit:
$ nbdkit --vsock null 1M --run 'echo $uri ; nbdinfo $uri'
nbd+vsock://1
protocol: newstyle-fixed without TLS, using structured packets
export="":
export-size: 1048576 (1M)
content: data
uri: nbd+vsock://1:10809/
...
---
server/internal.h | 11 +++
server/captive.c | 56 ---
server/main.c | 75 ++-
3 files changed, 91 insertions(+), 51 deletions(-)
diff --git a/server/internal.h b/server/internal.h
index fcfbf0573..0652f8a86 100644
--- a/server/internal.h
+++ b/server/internal.h
@@ -108,6 +108,16 @@ enum log_to {
LOG_TO_NULL, /* --log=null forced on the command line */
};
+enum service_mode {
+ /* These two modes cannot form an NBD URI: */
+ SERVICE_MODE_SOCKET_ACTIVATION, /* socket activation. */
+ SERVICE_MODE_LISTEN_STDIN, /* -s */
+
+ SERVICE_MODE_UNIXSOCKET,/* -U */
+ SERVICE_MODE_VSOCK, /* --vsock */
+ SERVICE_MODE_TCPIP, /* --port */
+};
+
extern int tcpip_sock_af;
extern struct debug_flag *debug_flags;
extern const char *export_name;
@@ -131,6 +141,7 @@ extern char *unixsocket;
extern const char *user, *group;
extern bool verbose;
extern bool vsock;
+extern enum service_mode service_mode;
extern bool configured;
extern int saved_stdin;
extern int saved_stdout;
diff --git a/server/captive.c b/server/captive.c
index 2361bb60b..31fd949e5 100644
--- a/server/captive.c
+++ b/server/captive.c
@@ -78,36 +78,44 @@ run_command (void)
/* Construct $uri. */
fprintf (fp, "uri=");
- if (tls == 2) /* --tls=require */
-fprintf (fp, "nbds");
- else
-fprintf (fp, "nbd");
- if (port) {
-if (!vsock) {
- fprintf (fp, "://localhost:");
- shell_quote (port, fp);
- if (strcmp (export_name, "") != 0) {
-putc ('/', fp);
-uri_quote (export_name, fp);
- }
-}
-else {
- fprintf (fp, "+vsock://1:"); /* 1 = VMADDR_CID_LOCAL */
- shell_quote (port, fp);
- if (strcmp (export_name, "") != 0) {
-putc ('/', fp);
-uri_quote (export_name, fp);
- }
-}
- }
- else if (unixsocket) {
-fprintf (fp, "+unix://");
+ switch (service_mode) {
+ case SERVICE_MODE_SOCKET_ACTIVATION:
+ case SERVICE_MODE_LISTEN_STDIN:
+break; /* can't form a URI, leave it blank */
+ case SERVICE_MODE_UNIXSOCKET:
+fprintf (fp, "nbd%s+unix://", tls == 2 ? "s" : "");
if (strcmp (export_name, "") != 0) {
putc ('/', fp);
uri_quote (export_name, fp);
}
fprintf (fp, "\\?socket=");
uri_quote (unixsocket, fp);
+break;
+ case SERVICE_MODE_VSOCK:
+/* 1 = VMADDR_CID_LOCAL */
+fprintf (fp, "nbd%s+vsock://1", tls == 2 ? "s" : "");
+if (port) {
+ putc (':', fp);
+ shell_quote (port, fp);
+}
+if (strcmp (export_name, "") != 0) {
+ putc ('/', fp);
+ uri_quote (export_name, fp);
+}
+break;
+ case SERVICE_MODE_TCPIP:
+fprintf (fp, "nbd%s://localhost", tls == 2 ? "s" : "");
+if (port) {
+ putc (':', fp);
+ shell_quote (port, fp);
+}
+if (strcmp (export_name, "") != 0) {
+ putc ('/', fp);
+ uri_quote (export_name, fp);
+}
+break;
+ default:
+abort ();
}
putc ('\n', fp);
diff --git a/server/main.c b/server/main.c
index 528a2dfea..2a332bfdd 100644
--- a/server/main.c
+++ b/server/main.c
@@ -117,6 +117,7 @@ const char *user, *group; /* -u & -g */
bool verbose; /* -v */
bool vsock; /* --vsock */
unsigned int socket_activation; /* $LISTEN_FDS and $LISTEN_PID set */
+enum service_mode service_mode; /* serving over TCP, Unix, etc */
bool configured;/* .config_complete done */
int saved_stdin = -1; /* dup'd stdin during -s/--run */
int saved_stdout = -1; /* dup'd stdout during -s/--run */
@@ -617,6 +618,18 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
+ /* By the point we have enough information to calculate the service mode. */
+ if (socket_activation)
+service_mode = SERVICE_MODE_SOCKET_ACTIVATION;
+ else if (listen_stdin)
+service_mode = SERVICE_MODE_LISTEN_STDIN;
+ else