On 22.02.2019 18:15, John Ferlan wrote: > > > On 2/15/19 9:10 AM, Nikolay Shirokovskiy wrote: >> Message of API call that creates stream and stream itself have >> same rpc serial. This can lead to issues. If stream got error >> immediately after creation then notification can be delivered >> before API call reply arrived. This is possible because the >> reply and the error message are sent from different threads >> (rpc worker thread and event loop thread respectively). As >> we don't check for message type in virNetClientCallCompleteAllWaitingReply >> we complete the API call which leads to API call error [1] >> as there is no actual reply. Later when reply arrives connection >> will be closed due to protocol error (see check in virNetClientCallDispatchReply). >> Let's fix virNetClientCallCompleteAllWaitingReply. >> >> Queue inspection on arriving VIR_NET_CONTINUE message in >> virNetClientCallDispatchStream is safe because there we check for >> status field also. Queue inspection on arriving VIR_NET_OK is safe >> too as this message can not arrive before we call virFinishAbort(Finish) >> which is not possible before API call that creates streams returns. >> But just to be sure let's add checking message type in these places too. >> >> [1] error: internal error: Unexpected message type 0 >> >> Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> >> --- >> src/rpc/virnetclient.c | 9 ++++++--- >> 1 file changed, 6 insertions(+), 3 deletions(-) >> > > The commit message was hard to read, but I know it's an english is not > the first language type thing. > >> diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c >> index 64855fb..0393587 100644 >> --- a/src/rpc/virnetclient.c >> +++ b/src/rpc/virnetclient.c >> @@ -1163,7 +1163,8 @@ static void virNetClientCallCompleteAllWaitingReply(virNetClientPtr client) >> virNetClientCallPtr call; >> >> for (call = client->waitDispatch; call; call = call->next) { >> - if (call->msg->header.prog == client->msg.header.prog && >> + if (call->msg->header.type == VIR_NET_STREAM && > > What about VIR_NET_STREAM_HOLE ? Here and in the other places we care only on "dummy recv"/finish/abort messages (only such messages have expectReply flag set) and they all have type VIR_NET_STREAM. > > Hopefully someone with greater working knowledge of the processing of > this code can help out here. I guess I'm just concerned about some odd > processing case that may have expected to be called, but now wouldn't be > because of this change. > > BTW: any thoughts to perhaps extracting out the common parts between the > three places changed into it's own helper/method? e.g.: > > thecall->msg->header.prog == client->msg.header.prog && > thecall->msg->header.vers == client->msg.header.vers && > thecall->msg->header.serial == client->msg.header.serial && > thecall->expectReply > > and then the follow-up patch to add the additional '.type' checks? > I'm ok. Nikolay > >> + call->msg->header.prog == client->msg.header.prog && >> call->msg->header.vers == client->msg.header.vers && >> call->msg->header.serial == client->msg.header.serial && >> call->expectReply) >> @@ -1207,7 +1208,8 @@ static int virNetClientCallDispatchStream(virNetClientPtr client) >> >> /* Find oldest dummy message waiting for incoming data. */ >> for (thecall = client->waitDispatch; thecall; thecall = thecall->next) { >> - if (thecall->msg->header.prog == client->msg.header.prog && >> + if (thecall->msg->header.type == VIR_NET_STREAM && >> + thecall->msg->header.prog == client->msg.header.prog && >> thecall->msg->header.vers == client->msg.header.vers && >> thecall->msg->header.serial == client->msg.header.serial && >> thecall->expectReply && >> @@ -1225,7 +1227,8 @@ static int virNetClientCallDispatchStream(virNetClientPtr client) >> case VIR_NET_OK: >> /* Find oldest abort/finish message. */ >> for (thecall = client->waitDispatch; thecall; thecall = thecall->next) { >> - if (thecall->msg->header.prog == client->msg.header.prog && >> + if (thecall->msg->header.type == VIR_NET_STREAM && >> + thecall->msg->header.prog == client->msg.header.prog && >> thecall->msg->header.vers == client->msg.header.vers && >> thecall->msg->header.serial == client->msg.header.serial && >> thecall->expectReply && >> -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list