rtnetlink_server: Fix edge triggering

We need to receive messages until there are no more pending or else we
will leave messages in the file descriptor.

Change-Id: I3f4a5a7e57ccca62be76591d47c8317d995e527e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/netlink.cpp b/src/netlink.cpp
index 5a3dc74..1577161 100644
--- a/src/netlink.cpp
+++ b/src/netlink.cpp
@@ -125,7 +125,7 @@
 
 } // namespace detail
 
-void receive(int sock, ReceiveCallback cb)
+size_t receive(int sock, ReceiveCallback cb)
 {
     // We need to make sure we have enough room for an entire packet otherwise
     // it gets truncated. The netlink docs guarantee packets will not exceed 8K
@@ -146,27 +146,29 @@
 
     // We only do multiple recvs if we have a MULTI type message
     bool done = true;
+    size_t num_msgs = 0;
     do
     {
         ssize_t recvd = recvmsg(sock, &hdr, 0);
-        if (recvd < 0)
+        if (recvd < 0 && errno != EAGAIN)
         {
             throw std::system_error(errno, std::generic_category(),
                                     "netlink recvmsg");
         }
-        if (recvd == 0)
+        if (recvd <= 0)
         {
             if (!done)
             {
                 throw std::runtime_error("netlink recvmsg: Got empty payload");
             }
-            return;
+            return num_msgs;
         }
 
         std::string_view msgs(buf.data(), recvd);
         do
         {
             detail::processMsg(msgs, done, cb);
+            num_msgs++;
         } while (!done && !msgs.empty());
 
         if (done && !msgs.empty())
@@ -174,6 +176,7 @@
             throw std::runtime_error("Extra unprocessed netlink messages");
         }
     } while (!done);
+    return num_msgs;
 }
 
 std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data)
diff --git a/src/netlink.hpp b/src/netlink.hpp
index 754b4b4..be44d24 100644
--- a/src/netlink.hpp
+++ b/src/netlink.hpp
@@ -34,7 +34,7 @@
  *  @param[in] sock - The socket to receive the messages on
  *  @param[in] cb   - Called for each response message payload
  */
-void receive(int sock, ReceiveCallback cb);
+size_t receive(int sock, ReceiveCallback cb);
 
 /* @brief Call on an rtnetlink payload
  *        Updates the input to remove the attr parsed out.
diff --git a/src/rtnetlink_server.cpp b/src/rtnetlink_server.cpp
index cf68340..2c093bc 100644
--- a/src/rtnetlink_server.cpp
+++ b/src/rtnetlink_server.cpp
@@ -61,7 +61,8 @@
 
 static void eventHandler(sdeventplus::source::IO&, int fd, uint32_t)
 {
-    receive(fd, handler);
+    while (receive(fd, handler) > 0)
+        ;
 }
 
 static stdplus::ManagedFd makeSock()