Laszlo Ersek
2023-Mar-23 12:10 UTC
[Libguestfs] [libnbd PATCH v3 18/19] generator: Add APIs to get/set the socket activation socket name
From: "Richard W.M. Jones" <rjones at redhat.com> 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. [Laszlo's note: originally posted by Rich at <https://listman.redhat.com/archives/libguestfs/2023-January/030557.html>. I've renamed "sa_name" to "sact_name", due to <signal.h> reserving symbols with the "sa_" prefix. This corresponds to earlier patches in this series, such as 'socket activation: rename sa_(tmpdir|sockpath) to sact_(tmpdir|sockpath)' and 'ocaml: rename "sa_u" to "saddr_u"'.] Message-Id: <20230130225521.1771496-4-rjones at redhat.com> Signed-off-by: Laszlo Ersek <lersek at redhat.com> Reviewed-by: Richard W.M. Jones <rjones at redhat.com> --- Notes: v4: - pick up Rich's R-b lib/internal.h | 1 + generator/API.ml | 49 +++++++++++++++++ lib/handle.c | 56 ++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/lib/internal.h b/lib/internal.h index 35cb5e8994ee..2de8e4e5e043 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 *sact_name; /* Socket activation name, can be NULL. */ /* TLS settings. */ int tls; /* 0 = disable, 1 = enable, 2 = require */ diff --git a/generator/API.ml b/generator/API.ml index 91e57a4c7c4f..24f97e647d2c 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 @@ "get_uri", { "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 8468b964240b..0f11bee56221 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 @@ -159,6 +160,7 @@ nbd_close (struct nbd_handle *h) waitpid (h->pid, NULL, 0); free (h->export_name); + free (h->sact_name); free (h->tls_certificates); free (h->tls_username); free (h->tls_psk_file); @@ -197,6 +199,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->sact_name); + h->sact_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->sact_name); + h->sact_name = new_name; + return 0; +} + +char * +nbd_unlocked_get_socket_activation_name (struct nbd_handle *h) +{ + char *copy = strdup (h->sact_name ? h->sact_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) {
Eric Blake
2023-Mar-23 19:17 UTC
[Libguestfs] [libnbd PATCH v3 18/19] generator: Add APIs to get/set the socket activation socket name
On Thu, Mar 23, 2023 at 01:10:15PM +0100, Laszlo Ersek wrote:> From: "Richard W.M. Jones" <rjones at redhat.com> > > 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. > > [Laszlo's note: originally posted by Rich at > <https://listman.redhat.com/archives/libguestfs/2023-January/030557.html>. > I've renamed "sa_name" to "sact_name", due to <signal.h> reserving symbols > with the "sa_" prefix. This corresponds to earlier patches in this series, > such as 'socket activation: rename sa_(tmpdir|sockpath) to > sact_(tmpdir|sockpath)' and 'ocaml: rename "sa_u" to "saddr_u"'.] > > Message-Id: <20230130225521.1771496-4-rjones at redhat.com> > Signed-off-by: Laszlo Ersek <lersek at redhat.com> > Reviewed-by: Richard W.M. Jones <rjones at redhat.com> > --- >> +++ 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";I recommend adding permitted_states = [ Created ]; on this one - it makes no sense to change the socket name after connection.> + 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.qemu-storage-daemon doesn't do it yet, but there's a strong likelihood of it moving that direction, so I don't mind leaving this statement as-is describing what we hope is the future state of things.> + > +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";Unlike set_ which only makes sense in Created, get_ makes sense over the entire life of the handle, so no permitted_state entry needed here. My suggested one-line addition is easy enough to add that I'm fine if you do that without needing a v5. Reviewed-by: Eric Blake <eblake at redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org