On 1/30/23 23:55, Richard W.M. Jones wrote:
> To allow us to name the socket passed down to the NBD server when
> calling nbd_connect_systemd_socket_activation(3), we need to add the
> field to the handle and add access functions.
> ---
>  generator/API.ml | 49 ++++++++++++++++++++++++++++++++++++++++++
>  lib/handle.c     | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/internal.h   |  1 +
>  3 files changed, 106 insertions(+)
> 
> diff --git a/generator/API.ml b/generator/API.ml
> index 25a612a2e8..08fc80960b 100644
> --- a/generator/API.ml
> +++ b/generator/API.ml
> @@ -2036,15 +2036,62 @@   "connect_systemd_socket_activation", {
>  
>  When the NBD handle is closed the server subprocess
>  is killed.
> +
> +=head3 Socket name
> +
> +The socket activation protocol lets you optionally give
> +the socket a name.  If used, the name is passed to the
> +NBD server using the C<LISTEN_FDNAMES> environment
> +variable.  To provide a socket name, call
> +L<nbd_set_socket_activation_name(3)> before calling
> +the connect function.
>  " ^ blocking_connect_call_description;
>      see_also = [Link "aio_connect_systemd_socket_activation";
>                  Link "connect_command"; Link "kill_subprocess";
>                  Link "set_opt_mode";
> +                Link "set_socket_activation_name";
> +                Link "get_socket_activation_name";
>                  ExternalLink ("qemu-nbd", 1);
>                  URLLink 
> "http://0pointer.de/blog/projects/socket-activation.html";];
>      example = Some "examples/open-qcow2.c";
>    };
>  
> +  "set_socket_activation_name", {
> +    default_call with
> +    args = [ String "socket_name" ]; ret = RErr;
> +    shortdesc = "set the socket activation name";
> +    longdesc = "\
> +When running an NBD server using
> +L<nbd_connect_systemd_socket_activation(3)> you can optionally
> +name the socket.  Call this function before connecting to the
> +server.
> +
> +Some servers such as L<qemu-storage-daemon(1)>
> +can use this information to associate the socket with a name
> +used on the command line, but most servers will ignore it.
> +The name is passed through the C<LISTEN_FDNAMES> environment
> +variable.
> +
> +The parameter C<socket_name> can be a short alphanumeric string.
> +If it is set to the empty string (also the default when the handle
> +is created) then no name is passed to the server.";
> +    see_also = [Link "connect_systemd_socket_activation";
> +                Link "get_socket_activation_name"];
> +  };
> +
> +  "get_socket_activation_name", {
> +    default_call with
> +    args = []; ret = RString;
> +    shortdesc = "get the socket activation name";
> +    longdesc = "\
> +Return the socket name used when you call
> +L<nbd_connect_systemd_socket_activation(3)> on the same
> +handle.  By default this will return the empty string
> +meaning that no name is passed to the server.";
> +    see_also = [Link "connect_systemd_socket_activation";
> +                Link "set_socket_activation_name"];
> +  };
> +
>    "is_read_only", {
>      default_call with
>      args = []; ret = RBool;
> @@ -3844,6 +3891,8 @@ let first_version =
>    "aio_opt_structured_reply", (1, 16);
>    "opt_starttls", (1, 16);
>    "aio_opt_starttls", (1, 16);
> +  "set_socket_activation_name", (1, 16);
> +  "get_socket_activation_name", (1, 16);
>  
>    (* These calls are proposed for a future version of libnbd, but
>     * have not been added to any released version so far.
> diff --git a/lib/handle.c b/lib/handle.c
> index 4a186f8fa9..96c8b1f2b1 100644
> --- a/lib/handle.c
> +++ b/lib/handle.c
> @@ -28,6 +28,7 @@
>  #include <sys/types.h>
>  #include <sys/wait.h>
>  
> +#include "ascii-ctype.h"
>  #include "internal.h"
>  
>  static void
> @@ -161,6 +162,7 @@ nbd_close (struct nbd_handle *h)
>      waitpid (h->pid, NULL, 0);
>  
>    free (h->export_name);
> +  free (h->sa_name);
>    free (h->tls_certificates);
>    free (h->tls_username);
>    free (h->tls_psk_file);
> @@ -200,6 +202,60 @@ nbd_unlocked_get_handle_name (struct nbd_handle *h)
>    return copy;
>  }
>  
> +int
> +nbd_unlocked_set_socket_activation_name (struct nbd_handle *h,
> +                                         const char *name)
> +{
> +  size_t i, len;
> +  char *new_name;
> +
> +  len = strlen (name);
> +
> +  /* Setting it to empty string stores NULL in the handle. */
> +  if (len == 0) {
> +    free (h->sa_name);
> +    h->sa_name = NULL;
> +    return 0;
> +  }
> +
> +  /* Check the proposed name is short and alphanumeric. */
> +  if (len > 32) {
> +    set_error (ENAMETOOLONG, "socket activation name should be "
> +               "<= 32 characters");
> +    return -1;
> +  }
> +  for (i = 0; i < len; ++i) {
> +    if (! ascii_isalnum (name[i])) {
> +      set_error (EINVAL, "socket activation name should contain "
> +                 "only alphanumeric ASCII characters");
> +      return -1;
> +    }
> +  }
> +
> +  new_name = strdup (name);
> +  if (!new_name) {
> +    set_error (errno, "strdup");
> +    return -1;
> +  }
> +
> +  free (h->sa_name);
> +  h->sa_name = new_name;
> +  return 0;
> +}
> +
> +char *
> +nbd_unlocked_get_socket_activation_name (struct nbd_handle *h)
> +{
> +  char *copy = strdup (h->sa_name ? h->sa_name : "");
> +
> +  if (!copy) {
> +    set_error (errno, "strdup");
> +    return NULL;
> +  }
> +
> +  return copy;
> +}
> +
>  uintptr_t
>  nbd_unlocked_set_private_data (struct nbd_handle *h, uintptr_t data)
>  {
> diff --git a/lib/internal.h b/lib/internal.h
> index bbbd26393f..19d7f0af60 100644
> --- a/lib/internal.h
> +++ b/lib/internal.h
> @@ -101,6 +101,7 @@ struct nbd_handle {
>    _Atomic uintptr_t private_data;
>  
>    char *export_name;            /* Export name, never NULL. */
> +  char *sa_name;                /* Socket activation name, can be NULL. */
>  
>    /* TLS settings. */
>    int tls;                      /* 0 = disable, 1 = enable, 2 = require */

"lib/handle.c" includes <signal.h>, and <signal.h> reserves symbols
starting with the prefix "sa_":

https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_02

While the fields of unions and structures live in a separate namespace,
that's no protection from macros.

Otherwise the patch looks OK to me.

(I'm noticing we already have fields called "sa_tmpdir" and
"sa_sockpath"; that's not ideal, although it may not matter in practice.)

Reviewed-by: Laszlo Ersek <ler...@redhat.com>

Laszlo
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to