[Libguestfs] [libnbd PATCH v3 19/29] CONNECT_COMMAND.START: set the NBD error when fcntl() fails
Richard W.M. Jones
rjones at redhat.com
Wed Feb 15 16:56:13 UTC 2023
On Wed, Feb 15, 2023 at 03:11:48PM +0100, Laszlo Ersek wrote:
> Furthermore, explain in a comment that *not* calling set_error() upon
> nbd_internal_socket_create() failing is intentional, and not an omission.
>
> Signed-off-by: Laszlo Ersek <lersek at redhat.com>
> ---
>
> Notes:
> context:-W
>
> generator/states-connect.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/generator/states-connect.c b/generator/states-connect.c
> index 95a96b9114c6..83d7f316828e 100644
> --- a/generator/states-connect.c
> +++ b/generator/states-connect.c
> @@ -240,71 +240,73 @@ CONNECT_TCP.NEXT_ADDRESS:
> CONNECT_COMMAND.START:
> int sv[2];
> pid_t pid;
> int flags;
>
> assert (!h->sock);
> assert (h->argv.ptr);
> assert (h->argv.ptr[0]);
> if (nbd_internal_socketpair (AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
> SET_NEXT_STATE (%.DEAD);
> set_error (errno, "socketpair");
> return 0;
> }
>
> pid = fork ();
> if (pid == -1) {
> SET_NEXT_STATE (%.DEAD);
> set_error (errno, "fork");
> close (sv[0]);
> close (sv[1]);
> return 0;
> }
> if (pid == 0) { /* child - run command */
> close (0);
> close (1);
> close (sv[0]);
> dup2 (sv[1], 0);
> dup2 (sv[1], 1);
> close (sv[1]);
>
> /* Restore SIGPIPE back to SIG_DFL. */
> signal (SIGPIPE, SIG_DFL);
>
> execvp (h->argv.ptr[0], h->argv.ptr);
> nbd_internal_fork_safe_perror (h->argv.ptr[0]);
> if (errno == ENOENT)
> _exit (127);
> else
> _exit (126);
> }
>
> /* Parent. */
> close (sv[1]);
>
> h->pid = pid;
>
> /* Only the parent-side end of the socket pair must be set to non-blocking,
> * because the child may not be expecting a non-blocking socket.
> */
> flags = fcntl (sv[0], F_GETFL, 0);
> if (flags == -1 ||
> fcntl (sv[0], F_SETFL, flags|O_NONBLOCK) == -1) {
> SET_NEXT_STATE (%.DEAD);
> + set_error (errno, "fcntl");
> close (sv[0]);
> return 0;
> }
>
> h->sock = nbd_internal_socket_create (sv[0]);
> if (!h->sock) {
> SET_NEXT_STATE (%.DEAD);
> + /* nbd_internal_socket_create() calls set_error() internally */
> close (sv[0]);
> return 0;
> }
>
> /* The sockets are connected already, we can jump directly to
> * receiving the server magic.
> */
> SET_NEXT_STATE (%^MAGIC.START);
> return 0;
>
> } /* END STATE MACHINE */
Reviewed-by: Richard W.M. Jones <rjones at redhat.com>
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
nbdkit - Flexible, fast NBD server with plugins
https://gitlab.com/nbdkit/nbdkit
More information about the Libguestfs
mailing list