[Libguestfs] [libnbd PATCH 2/3] states: Split ISSUE_COMMAND.SEND_REQUEST
Richard W.M. Jones
rjones at redhat.com
Tue May 21 17:02:43 UTC 2019
On Tue, May 21, 2019 at 10:09:29AM -0500, Eric Blake wrote:
> In order to handle reading an in-flight response while in the middle
> of sending a second command, we'll need a way to jump back into the
> middle of a command being sent. This is easier if the state that sets
> wbuf is distinct from the state that reads into wbuf, and if we don't
> move the command to the in-flight queue until after the writes finish.
> ---
> generator/generator | 14 ++++++++++
> generator/states-issue-command.c | 45 ++++++++++++++++++++------------
> 2 files changed, 42 insertions(+), 17 deletions(-)
>
> diff --git a/generator/generator b/generator/generator
> index a1bf41d..a4ad362 100755
> --- a/generator/generator
> +++ b/generator/generator
> @@ -637,12 +637,26 @@ and issue_command_state_machine = [
> external_events = [ NotifyWrite, "" ];
> };
>
> + State {
> + default_state with
> + name = "PREPARE_WRITE_PAYLOAD";
> + comment = "Prepare the write payload to send to the remote server";
> + external_events = [];
> + };
> +
> State {
> default_state with
> name = "SEND_WRITE_PAYLOAD";
> comment = "Sending the write payload to the remote server";
> external_events = [ NotifyWrite, "" ];
> };
> +
> +State {
> + default_state with
> + name = "FINISH";
> + comment = "Finish issuing a command";
> + external_events = [];
> + };
> ]
>
> (* Receiving a reply from the server. *)
> diff --git a/generator/states-issue-command.c b/generator/states-issue-command.c
> index a57f40f..e24ea34 100644
> --- a/generator/states-issue-command.c
> +++ b/generator/states-issue-command.c
> @@ -24,9 +24,6 @@
>
> assert (conn->cmds_to_issue != NULL);
> cmd = conn->cmds_to_issue;
> - conn->cmds_to_issue = cmd->next;
> - cmd->next = conn->cmds_in_flight;
> - conn->cmds_in_flight = cmd;
>
> conn->sbuf.request.magic = htobe32 (NBD_REQUEST_MAGIC);
> conn->sbuf.request.flags = htobe16 (cmd->flags);
> @@ -40,29 +37,43 @@
> return 0;
>
> ISSUE_COMMAND.SEND_REQUEST:
> - struct command_in_flight *cmd;
> -
> switch (send_from_wbuf (conn)) {
> case -1: SET_NEXT_STATE (%.DEAD); return -1;
> - case 0:
> - assert (conn->cmds_in_flight != NULL);
> - cmd = conn->cmds_in_flight;
> - assert (cmd->handle == be64toh (conn->sbuf.request.handle));
> - if (cmd->type == NBD_CMD_WRITE) {
> - conn->wbuf = cmd->data;
> - conn->wlen = cmd->count;
> - SET_NEXT_STATE (%SEND_WRITE_PAYLOAD);
> - }
> - else
> - SET_NEXT_STATE (%.READY);
> + case 0: SET_NEXT_STATE (%PREPARE_WRITE_PAYLOAD);
> }
> return 0;
>
> + ISSUE_COMMAND.PREPARE_WRITE_PAYLOAD:
> + struct command_in_flight *cmd;
> +
> + assert (conn->cmds_to_issue != NULL);
> + cmd = conn->cmds_to_issue;
> + assert (cmd->handle == be64toh (conn->sbuf.request.handle));
> + if (cmd->type == NBD_CMD_WRITE) {
> + conn->wbuf = cmd->data;
> + conn->wlen = cmd->count;
> + SET_NEXT_STATE (%SEND_WRITE_PAYLOAD);
> + }
> + else
> + SET_NEXT_STATE (%FINISH);
> + return 0;
> +
> ISSUE_COMMAND.SEND_WRITE_PAYLOAD:
> switch (send_from_wbuf (conn)) {
> case -1: SET_NEXT_STATE (%.DEAD); return -1;
> - case 0: SET_NEXT_STATE (%.READY);
> + case 0: SET_NEXT_STATE (%FINISH);
> }
> return 0;
>
> + ISSUE_COMMAND.FINISH:
> + struct command_in_flight *cmd;
> +
> + assert (conn->cmds_to_issue != NULL);
> + cmd = conn->cmds_to_issue;
> + conn->cmds_to_issue = cmd->next;
> + cmd->next = conn->cmds_in_flight;
> + conn->cmds_in_flight = cmd;
> + SET_NEXT_STATE (%.READY);
> + return 0;
> +
> } /* END STATE MACHINE */
This is a simple state splitting, along with a later move of the
command to the in-flight list.
Since no more commands could be added to the cmds_to_issue queue while
we're not in the READY state, actually I think cmds_to_issue might
just be a single command pointer after all.
The patch however is generally fine.
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
More information about the Libguestfs
mailing list