mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
rpc: Don't rewrite msg->fds on every read dispatch
When we are receiving data in smaller chunks it might happen that virNetServerClientDispatchRead() will be called multiple times. And as that happens, if it is a message that also transfer headers, we decode the number of them every single time and, unfortunately, also allocate the memory for them. That causes a leak, in the best scenario. Best viewed with '-w'. Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
545e5571f9
commit
133c511b52
@ -1107,36 +1107,38 @@ static void virNetServerClientDispatchRead(virNetServerClientPtr client)
|
||||
|
||||
/* Now figure out if we need to read more data to get some
|
||||
* file descriptors */
|
||||
if (msg->header.type == VIR_NET_CALL_WITH_FDS &&
|
||||
virNetMessageDecodeNumFDs(msg) < 0) {
|
||||
virNetMessageQueueServe(&client->rx);
|
||||
virNetMessageFree(msg);
|
||||
client->wantClose = true;
|
||||
return; /* Error */
|
||||
}
|
||||
|
||||
/* Try getting the file descriptors (may fail if blocking) */
|
||||
for (i = msg->donefds; i < msg->nfds; i++) {
|
||||
int rv;
|
||||
if ((rv = virNetSocketRecvFD(client->sock, &(msg->fds[i]))) < 0) {
|
||||
if (msg->header.type == VIR_NET_CALL_WITH_FDS) {
|
||||
if (msg->nfds == 0 &&
|
||||
virNetMessageDecodeNumFDs(msg) < 0) {
|
||||
virNetMessageQueueServe(&client->rx);
|
||||
virNetMessageFree(msg);
|
||||
client->wantClose = true;
|
||||
return; /* Error */
|
||||
}
|
||||
|
||||
/* Try getting the file descriptors (may fail if blocking) */
|
||||
for (i = msg->donefds; i < msg->nfds; i++) {
|
||||
int rv;
|
||||
if ((rv = virNetSocketRecvFD(client->sock, &(msg->fds[i]))) < 0) {
|
||||
virNetMessageQueueServe(&client->rx);
|
||||
virNetMessageFree(msg);
|
||||
client->wantClose = true;
|
||||
return;
|
||||
}
|
||||
if (rv == 0) /* Blocking */
|
||||
break;
|
||||
msg->donefds++;
|
||||
}
|
||||
|
||||
/* Need to poll() until FDs arrive */
|
||||
if (msg->donefds < msg->nfds) {
|
||||
/* Because DecodeHeader/NumFDs reset bufferOffset, we
|
||||
* put it back to what it was, so everything works
|
||||
* again next time we run this method
|
||||
*/
|
||||
client->rx->bufferOffset = client->rx->bufferLength;
|
||||
return;
|
||||
}
|
||||
if (rv == 0) /* Blocking */
|
||||
break;
|
||||
msg->donefds++;
|
||||
}
|
||||
|
||||
/* Need to poll() until FDs arrive */
|
||||
if (msg->donefds < msg->nfds) {
|
||||
/* Because DecodeHeader/NumFDs reset bufferOffset, we
|
||||
* put it back to what it was, so everything works
|
||||
* again next time we run this method
|
||||
*/
|
||||
client->rx->bufferOffset = client->rx->bufferLength;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Definitely finished reading, so remove from queue */
|
||||
|
Loading…
Reference in New Issue
Block a user