Re: [Libguestfs] [PATCH nbdkit 01/10] server: Introduce service_mode concept

2023-09-11 Thread Eric Blake
On Sat, Sep 09, 2023 at 02:57:49PM +0100, Richard W.M. Jones wrote:
> 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/
>   ...

Nice.

> ---
>  server/internal.h | 11 +++
>  server/captive.c  | 56 ---
>  server/main.c | 75 ++-
>  3 files changed, 91 insertions(+), 51 deletions(-)
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org
___
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs



[Libguestfs] [PATCH nbdkit 01/10] server: Introduce service_mode concept

2023-09-09 Thread Richard W.M. Jones
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