On Wed, Oct 26, 2022 at 05:17:59PM -0500, Eric Blake wrote:
> Instead of using magic numbers, track connection status via an enum.
> While at it, convert functions whose return value is not used to
> instead be void.  No semantic change.
> ---
>  server/internal.h    |  16 +++++--
>  server/connections.c |  29 ++++++------
>  server/protocol.c    | 107 ++++++++++++++++++++++---------------------
>  server/public.c      |   3 +-
>  server/test-public.c |   4 +-
>  5 files changed, 84 insertions(+), 75 deletions(-)
> 
> diff --git a/server/internal.h b/server/internal.h
> index ed52c1bf..fa658364 100644
> --- a/server/internal.h
> +++ b/server/internal.h
> @@ -1,5 +1,5 @@
>  /* nbdkit
> - * Copyright (C) 2013-2021 Red Hat Inc.
> + * Copyright (C) 2013-2022 Red Hat Inc.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions are
> @@ -232,13 +232,19 @@ struct context {
>    int can_cache;
>  };
> 
> +typedef enum {
> +  STATUS_DEAD,         /* Connection is closed */
> +  STATUS_CLIENT_DONE,  /* Client has sent NBD_CMD_DISC */
> +  STATUS_ACTIVE,       /* Client can make requests */
> +} conn_status;
> +
>  struct connection {
>    pthread_mutex_t request_lock;
>    pthread_mutex_t read_lock;
>    pthread_mutex_t write_lock;
>    pthread_mutex_t status_lock;
> 
> -  int status; /* 1 for more I/O with client, 0 for shutdown, -1 on error */
> +  conn_status status;
>    int status_pipe[2]; /* track status changes via poll when nworkers > 1 */
>    void *crypto_session;
>    int nworkers;
> @@ -264,8 +270,8 @@ struct connection {
>  };
> 
>  extern void handle_single_connection (int sockin, int sockout);
> -extern int connection_get_status (void);
> -extern int connection_set_status (int value);
> +extern conn_status connection_get_status (void);
> +extern void connection_set_status (conn_status value);
> 
>  /* protocol-handshake.c */
>  extern int protocol_handshake (void);
> @@ -280,7 +286,7 @@ extern int protocol_handshake_oldstyle (void);
>  extern int protocol_handshake_newstyle (void);
> 
>  /* protocol.c */
> -extern int protocol_recv_request_send_reply (void);
> +extern void protocol_recv_request_send_reply (void);
> 
>  /* The context ID of base:allocation.  As far as I can tell it doesn't
>   * matter what this is as long as nbdkit always returns the same
> diff --git a/server/connections.c b/server/connections.c
> index 29e4cd58..27177d70 100644
> --- a/server/connections.c
> +++ b/server/connections.c
> @@ -1,5 +1,5 @@
>  /* nbdkit
> - * Copyright (C) 2013-2021 Red Hat Inc.
> + * Copyright (C) 2013-2022 Red Hat Inc.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions are
> @@ -64,11 +64,11 @@ static int raw_send_other (const void *buf, size_t len, 
> int flags);
>  #endif
>  static void raw_close (void);
> 
> -int
> +conn_status
>  connection_get_status (void)
>  {
>    GET_CONN;
> -  int r;
> +  conn_status r;
> 
>    if (conn->nworkers &&
>        pthread_mutex_lock (&conn->status_lock))
> @@ -80,11 +80,9 @@ connection_get_status (void)
>    return r;
>  }
> 
> -/* Update the status if the new value is lower than the existing value.
> - * For convenience, return the incoming value.
> - */
> -int
> -connection_set_status (int value)
> +/* Update the status if the new value is lower than the existing value. */
> +void
> +connection_set_status (conn_status value)
>  {
>    GET_CONN;
> 
> @@ -92,7 +90,7 @@ connection_set_status (int value)
>        pthread_mutex_lock (&conn->status_lock))
>      abort ();
>    if (value < conn->status) {
> -    if (conn->nworkers && conn->status > 0) {
> +    if (conn->nworkers && conn->status > STATUS_CLIENT_DONE) {
>        char c = 0;
> 
>        assert (conn->status_pipe[1] >= 0);
> @@ -104,7 +102,6 @@ connection_set_status (int value)
>    if (conn->nworkers &&
>        pthread_mutex_unlock (&conn->status_lock))
>      abort ();
> -  return value;
>  }
> 
>  struct worker_data {
> @@ -125,7 +122,7 @@ connection_worker (void *data)
>    threadlocal_set_conn (conn);
>    free (worker);
> 
> -  while (!quit && connection_get_status () > 0)
> +  while (!quit && connection_get_status () > STATUS_CLIENT_DONE)
>      protocol_recv_request_send_reply ();
>    debug ("exiting worker thread %s", threadlocal_get_name ());
>    free (name);
> @@ -177,7 +174,7 @@ handle_single_connection (int sockin, int sockout)
>    if (!nworkers) {
>      /* No need for a separate thread. */
>      debug ("handshake complete, processing requests serially");
> -    while (!quit && connection_get_status () > 0)
> +    while (!quit && connection_get_status () > STATUS_CLIENT_DONE)
>        protocol_recv_request_send_reply ();
>    }
>    else {
> @@ -196,13 +193,13 @@ handle_single_connection (int sockin, int sockout)
> 
>        if (unlikely (!worker)) {
>          perror ("malloc");
> -        connection_set_status (-1);
> +        connection_set_status (STATUS_DEAD);
>          goto wait;
>        }
>        if (unlikely (asprintf (&worker->name, "%s.%d", plugin_name, nworkers)
>                      < 0)) {
>          perror ("asprintf");
> -        connection_set_status (-1);
> +        connection_set_status (STATUS_DEAD);
>          free (worker);
>          goto wait;
>        }
> @@ -212,7 +209,7 @@ handle_single_connection (int sockin, int sockout)
>        if (unlikely (err)) {
>          errno = err;
>          perror ("pthread_create");
> -        connection_set_status (-1);
> +        connection_set_status (STATUS_DEAD);
>          free (worker);
>          goto wait;
>        }
> @@ -264,7 +261,7 @@ new_connection (int sockin, int sockout, int nworkers)
>      goto error1;
>    }
> 
> -  conn->status = 1;
> +  conn->status = STATUS_ACTIVE;
>    conn->nworkers = nworkers;
>    if (nworkers) {
>  #ifdef HAVE_PIPE2
> diff --git a/server/protocol.c b/server/protocol.c
> index 2ac77055..d1e01502 100644
> --- a/server/protocol.c
> +++ b/server/protocol.c
> @@ -1,5 +1,5 @@
>  /* nbdkit
> - * Copyright (C) 2013-2021 Red Hat Inc.
> + * Copyright (C) 2013-2022 Red Hat Inc.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions are
> @@ -362,7 +362,7 @@ nbd_errno (int error, uint16_t flags)
>    }
>  }
> 
> -static int
> +static void
>  send_simple_reply (uint64_t handle, uint16_t cmd, uint16_t flags,
>                     const char *buf, uint32_t count,
>                     uint32_t error)
> @@ -380,7 +380,8 @@ send_simple_reply (uint64_t handle, uint16_t cmd, 
> uint16_t flags,
>    r = conn->send (&reply, sizeof reply, f);
>    if (r == -1) {
>      nbdkit_error ("write reply: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
> +    return;
>    }
> 
>    /* Send the read data buffer. */
> @@ -388,14 +389,12 @@ send_simple_reply (uint64_t handle, uint16_t cmd, 
> uint16_t flags,
>      r = conn->send (buf, count, 0);
>      if (r == -1) {
>        nbdkit_error ("write data: %s: %m", name_of_nbd_cmd (cmd));
> -      return connection_set_status (-1);
> +      connection_set_status (STATUS_DEAD);
>      }
>    }
> -
> -  return 1;                     /* command processed ok */
>  }
> 
> -static int
> +static void
>  send_structured_reply_read (uint64_t handle, uint16_t cmd,
>                              const char *buf, uint32_t count, uint64_t offset)
>  {
> @@ -421,7 +420,8 @@ send_structured_reply_read (uint64_t handle, uint16_t cmd,
>    r = conn->send (&reply, sizeof reply, SEND_MORE);
>    if (r == -1) {
>      nbdkit_error ("write reply: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
> +    return;
>    }
> 
>    /* Send the offset + read data buffer. */
> @@ -429,16 +429,15 @@ send_structured_reply_read (uint64_t handle, uint16_t 
> cmd,
>    r = conn->send (&offset_data, sizeof offset_data, SEND_MORE);
>    if (r == -1) {
>      nbdkit_error ("write data: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
> +    return;
>    }
> 
>    r = conn->send (buf, count, 0);
>    if (r == -1) {
>      nbdkit_error ("write data: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
>    }
> -
> -  return 1;                     /* command processed ok */
>  }
> 
>  /* Convert a list of extents into NBD_REPLY_TYPE_BLOCK_STATUS blocks.
> @@ -523,7 +522,7 @@ extents_to_block_descriptors (struct nbdkit_extents 
> *extents,
>    return blocks;
>  }
> 
> -static int
> +static void
>  send_structured_reply_block_status (uint64_t handle,
>                                      uint16_t cmd, uint16_t flags,
>                                      uint32_t count, uint64_t offset,
> @@ -543,8 +542,10 @@ send_structured_reply_block_status (uint64_t handle,
> 
>    blocks = extents_to_block_descriptors (extents, flags, count, offset,
>                                           &nr_blocks);
> -  if (blocks == NULL)
> -    return connection_set_status (-1);
> +  if (blocks == NULL) {
> +    connection_set_status (STATUS_DEAD);
> +    return;
> +  }
> 
>    reply.magic = htobe32 (NBD_STRUCTURED_REPLY_MAGIC);
>    reply.handle = handle;
> @@ -556,7 +557,8 @@ send_structured_reply_block_status (uint64_t handle,
>    r = conn->send (&reply, sizeof reply, SEND_MORE);
>    if (r == -1) {
>      nbdkit_error ("write reply: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
> +    return;
>    }
> 
>    /* Send the base:allocation context ID. */
> @@ -564,7 +566,8 @@ send_structured_reply_block_status (uint64_t handle,
>    r = conn->send (&context_id, sizeof context_id, SEND_MORE);
>    if (r == -1) {
>      nbdkit_error ("write reply: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
> +    return;
>    }
> 
>    /* Send each block descriptor. */
> @@ -573,14 +576,12 @@ send_structured_reply_block_status (uint64_t handle,
>                      i == nr_blocks - 1 ? 0 : SEND_MORE);
>      if (r == -1) {
>        nbdkit_error ("write reply: %s: %m", name_of_nbd_cmd (cmd));
> -      return connection_set_status (-1);
> +      connection_set_status (STATUS_DEAD);
>      }
>    }
> -
> -  return 1;                     /* command processed ok */
>  }
> 
> -static int
> +static void
>  send_structured_reply_error (uint64_t handle, uint16_t cmd, uint16_t flags,
>                               uint32_t error)
>  {
> @@ -599,7 +600,8 @@ send_structured_reply_error (uint64_t handle, uint16_t 
> cmd, uint16_t flags,
>    r = conn->send (&reply, sizeof reply, SEND_MORE);
>    if (r == -1) {
>      nbdkit_error ("write error reply: %m");
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
> +    return;
>    }
> 
>    /* Send the error. */
> @@ -608,18 +610,17 @@ send_structured_reply_error (uint64_t handle, uint16_t 
> cmd, uint16_t flags,
>    r = conn->send (&error_data, sizeof error_data, 0);
>    if (r == -1) {
>      nbdkit_error ("write data: %s: %m", name_of_nbd_cmd (cmd));
> -    return connection_set_status (-1);
> +    connection_set_status (STATUS_DEAD);
>    }
>    /* No human readable error message at the moment. */
> -
> -  return 1;                     /* command processed ok */
>  }
> 
> -int
> +void
>  protocol_recv_request_send_reply (void)
>  {
>    GET_CONN;
>    int r;
> +  conn_status cs;
>    struct nbd_request request;
>    uint16_t cmd, flags;
>    uint32_t magic, count, error = 0;
> @@ -630,24 +631,27 @@ protocol_recv_request_send_reply (void)
>    /* Read the request packet. */
>    {
>      ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&conn->read_lock);
> -    r = connection_get_status ();
> -    if (r <= 0)
> -      return r;
> +    cs = connection_get_status ();
> +    if (cs <= STATUS_CLIENT_DONE)
> +      return;
>      r = conn->recv (&request, sizeof request);
>      if (r == -1) {
>        nbdkit_error ("read request: %m");
> -      return connection_set_status (-1);
> +      connection_set_status (STATUS_DEAD);
> +      return;
>      }
>      if (r == 0) {
>        debug ("client closed input socket, closing connection");
> -      return connection_set_status (0); /* disconnect */
> +      connection_set_status (STATUS_CLIENT_DONE); /* disconnect */
> +      return;
>      }
> 
>      magic = be32toh (request.magic);
>      if (magic != NBD_REQUEST_MAGIC) {
>        nbdkit_error ("invalid request: 'magic' field is incorrect (0x%x)",
>                      magic);
> -      return connection_set_status (-1);
> +      connection_set_status (STATUS_DEAD);
> +      return;
>      }
> 
>      flags = be16toh (request.flags);
> @@ -658,14 +662,17 @@ protocol_recv_request_send_reply (void)
> 
>      if (cmd == NBD_CMD_DISC) {
>        debug ("client sent %s, closing connection", name_of_nbd_cmd (cmd));
> -      return connection_set_status (0); /* disconnect */
> +      connection_set_status (STATUS_CLIENT_DONE); /* disconnect */
> +      return;
>      }
> 
>      /* Validate the request. */
>      if (!validate_request (cmd, flags, offset, count, &error)) {
>        if (cmd == NBD_CMD_WRITE &&
> -          skip_over_write_buffer (conn->sockin, count) < 0)
> -        return connection_set_status (-1);
> +          skip_over_write_buffer (conn->sockin, count) < 0) {
> +        connection_set_status (STATUS_DEAD);
> +        return;
> +      }
>        goto send_reply;
>      }
> 
> @@ -677,8 +684,10 @@ protocol_recv_request_send_reply (void)
>        if (buf == NULL) {
>          error = ENOMEM;
>          if (cmd == NBD_CMD_WRITE &&
> -            skip_over_write_buffer (conn->sockin, count) < 0)
> -          return connection_set_status (-1);
> +            skip_over_write_buffer (conn->sockin, count) < 0) {
> +          connection_set_status (STATUS_DEAD);
> +          return;
> +        }
>          goto send_reply;
>        }
>      }
> @@ -702,13 +711,14 @@ protocol_recv_request_send_reply (void)
>        }
>        if (r == -1) {
>          nbdkit_error ("read data: %s: %m", name_of_nbd_cmd (cmd));
> -        return connection_set_status (-1);
> +        connection_set_status (STATUS_DEAD);
> +        return;
>        }
>      }
>    }
> 
>    /* Perform the request.  Only this part happens inside the request lock. */
> -  if (quit || !connection_get_status ()) {
> +  if (quit || connection_get_status () == STATUS_CLIENT_DONE) {
>      error = ESHUTDOWN;
>    }
>    else {
> @@ -720,8 +730,8 @@ protocol_recv_request_send_reply (void)
> 
>    /* Send the reply packet. */
>   send_reply:
> -  if (connection_get_status () < 0)
> -    return -1;
> +  if (connection_get_status () < STATUS_CLIENT_DONE)
> +    return;
> 
>    if (error != 0) {
>      /* Since we're about to send only the limited NBD_E* errno to the
> @@ -742,19 +752,14 @@ protocol_recv_request_send_reply (void)
>        (cmd == NBD_CMD_READ || cmd == NBD_CMD_BLOCK_STATUS)) {
>      if (!error) {
>        if (cmd == NBD_CMD_READ)
> -        return send_structured_reply_read (request.handle, cmd,
> -                                           buf, count, offset);
> +        send_structured_reply_read (request.handle, cmd, buf, count, offset);
>        else /* NBD_CMD_BLOCK_STATUS */
> -        return send_structured_reply_block_status (request.handle,
> -                                                   cmd, flags,
> -                                                   count, offset,
> -                                                   extents);
> +        send_structured_reply_block_status (request.handle, cmd, flags,
> +                                            count, offset, extents);
>      }
>      else
> -      return send_structured_reply_error (request.handle, cmd, flags,
> -                                          error);
> +      send_structured_reply_error (request.handle, cmd, flags, error);
>    }
>    else
> -    return send_simple_reply (request.handle, cmd, flags, buf, count,
> -                              error);
> +    send_simple_reply (request.handle, cmd, flags, buf, count, error);
>  }
> diff --git a/server/public.c b/server/public.c
> index 472ca623..6a9840bb 100644
> --- a/server/public.c
> +++ b/server/public.c
> @@ -727,7 +727,8 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
>     */
>    bool has_quit = quit;
>    assert (has_quit ||
> -          (conn && conn->nworkers > 0 && connection_get_status () < 1) ||
> +          (conn && conn->nworkers > 0 &&
> +           connection_get_status () < STATUS_ACTIVE) ||
>            (conn && (fds[2].revents & (POLLRDHUP | POLLHUP | POLLERR |
>                                        POLLNVAL))));
>    if (has_quit)
> diff --git a/server/test-public.c b/server/test-public.c
> index 1cb759d1..1d83354f 100644
> --- a/server/test-public.c
> +++ b/server/test-public.c
> @@ -1,5 +1,5 @@
>  /* nbdkit
> - * Copyright (C) 2018-2021 Red Hat Inc.
> + * Copyright (C) 2018-2022 Red Hat Inc.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions are
> @@ -83,7 +83,7 @@ threadlocal_get_context (void)
>    abort ();
>  }
> 
> -int
> +conn_status
>  connection_get_status (void)
>  {
>    abort ();
> -- 
> 2.37.3
> 
> _______________________________________________
> Libguestfs mailing list
> Libguestfs@redhat.com
> https://listman.redhat.com/mailman/listinfo/libguestfs

Reviewed-by: Richard W.M. Jones <rjo...@redhat.com>

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to