]> xenbits.xensource.com Git - libvirt.git/commitdiff
client: Report proper close reason
authorJiri Denemark <jdenemar@redhat.com>
Tue, 2 May 2017 14:39:57 +0000 (16:39 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 2 May 2017 16:53:24 +0000 (18:53 +0200)
When we get a POLLHUP or VIR_EVENT_HANDLE_HANGUP event for a client, we
still want to read from the socket to process any accumulated data. But
doing so inevitably results in an error and a call to
virNetClientMarkClose before we get to processing the hangup event (and
another call to virNetClientMarkClose). However the close reason passed
to the second virNetClientMarkClose call is ignored because another one
was already set. We need to pass the correct close reason when marking
the socket to be closed for the first time.

https://bugzilla.redhat.com/show_bug.cgi?id=1373859

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
src/rpc/virnetclient.c

index c9597479494dd13cd4627b8b8dc4347b23491d8c..837a8a70748b87ad3b32ffbf8b81be2a2b4bcc8a 100644 (file)
@@ -1595,6 +1595,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 {
     struct pollfd fds[2];
     bool error = false;
+    int closeReason;
     int ret;
 
     fds[0].fd = virNetSocketGetFD(client->sock);
@@ -1703,9 +1704,14 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
             }
         }
 
+        if (fds[0].revents & POLLHUP)
+            closeReason = VIR_CONNECT_CLOSE_REASON_EOF;
+        else
+            closeReason = VIR_CONNECT_CLOSE_REASON_ERROR;
+
         if (fds[0].revents & POLLOUT) {
             if (virNetClientIOHandleOutput(client) < 0) {
-                virNetClientMarkClose(client, VIR_CONNECT_CLOSE_REASON_ERROR);
+                virNetClientMarkClose(client, closeReason);
                 error = true;
                 /* Fall through to process any pending data. */
             }
@@ -1713,7 +1719,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
 
         if (fds[0].revents & POLLIN) {
             if (virNetClientIOHandleInput(client) < 0) {
-                virNetClientMarkClose(client, VIR_CONNECT_CLOSE_REASON_ERROR);
+                virNetClientMarkClose(client, closeReason);
                 error = true;
                 /* Fall through to process any pending data. */
             }
@@ -1746,13 +1752,13 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
         if (fds[0].revents & POLLHUP) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("received hangup event on socket"));
-            virNetClientMarkClose(client, VIR_CONNECT_CLOSE_REASON_EOF);
+            virNetClientMarkClose(client, closeReason);
             goto error;
         }
         if (fds[0].revents & POLLERR) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("received error event on socket"));
-            virNetClientMarkClose(client, VIR_CONNECT_CLOSE_REASON_ERROR);
+            virNetClientMarkClose(client, closeReason);
             goto error;
         }
     }
@@ -1968,6 +1974,7 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
                                void *opaque)
 {
     virNetClientPtr client = opaque;
+    int closeReason;
 
     virObjectLock(client);
 
@@ -1981,23 +1988,25 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
 
     VIR_DEBUG("Event fired %p %d", sock, events);
 
+    if (events & VIR_EVENT_HANDLE_HANGUP)
+        closeReason = VIR_CONNECT_CLOSE_REASON_EOF;
+    else
+        closeReason = VIR_CONNECT_CLOSE_REASON_ERROR;
+
     if (events & VIR_EVENT_HANDLE_WRITABLE) {
         if (virNetClientIOHandleOutput(client) < 0)
-            virNetClientMarkClose(client, VIR_CONNECT_CLOSE_REASON_ERROR);
+            virNetClientMarkClose(client, closeReason);
     }
 
     if (events & VIR_EVENT_HANDLE_READABLE) {
         if (virNetClientIOHandleInput(client) < 0)
-            virNetClientMarkClose(client, VIR_CONNECT_CLOSE_REASON_ERROR);
+            virNetClientMarkClose(client, closeReason);
     }
 
     if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) {
         VIR_DEBUG("VIR_EVENT_HANDLE_HANGUP or "
                   "VIR_EVENT_HANDLE_ERROR encountered");
-        virNetClientMarkClose(client,
-                              (events & VIR_EVENT_HANDLE_HANGUP) ?
-                              VIR_CONNECT_CLOSE_REASON_EOF :
-                              VIR_CONNECT_CLOSE_REASON_ERROR);
+        virNetClientMarkClose(client, closeReason);
         goto done;
     }