<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br>On Jan 26, 2012, at 5:32 PM, Laine Stump wrote:<br><br><blockquote type="cite">On 01/20/2012 09:56 AM, D. Herrendoerfer wrote:<br></blockquote><blockquote type="cite"><blockquote type="cite">From: "D. Herrendoerfer"<<a href="mailto:d.herrendoerfer@herrendoerfer.name">d.herrendoerfer@herrendoerfer.name</a>><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">This code adds an event service for netlink messages addressed<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">to libvirt and passes the message to registered callback handlers.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Itself, it makes use of the polling file event service and follows<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">a similar design.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Signed-off-by: D. Herrendoerfer<<a href="mailto:d.herrendoerfer@herrendoerfer.name">d.herrendoerfer@herrendoerfer.name</a>><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">---<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">daemon/Makefile.am       |    3 +-<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">daemon/libvirtd.c        |    7 +<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">src/Makefile.am          |    1 +<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">src/libvirt_private.syms |    7 +<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">src/util/netlink-event.c |  363 ++++++++++++++++++++++++++++++++++++++++++++++<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">src/util/netlink-event.h |   63 ++++++++<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">src/util/netlink.c       |    1 +<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">7 files changed, 444 insertions(+), 1 deletions(-)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">create mode 100644 src/util/netlink-event.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">create mode 100644 src/util/netlink-event.h<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/daemon/Makefile.am b/daemon/Makefile.am<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index 73a6e1f..d027ff6 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- a/daemon/Makefile.am<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/daemon/Makefile.am<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -114,7 +114,8 @@ libvirtd_LDADD += ../src/probes.o<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">endif<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">libvirtd_LDADD += \<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">-<span class="Apple-tab-span" style="white-space: pre; ">  </span>../src/libvirt-qemu.la<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">  </span>../src/libvirt-qemu.la<span class="Apple-tab-span" style="white-space: pre; ">   </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>../src/libvirt_util.la<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">if ! WITH_DRIVER_MODULES<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">if WITH_QEMU<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index d7a03d7..b118fd0 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- a/daemon/libvirtd.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/daemon/libvirtd.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -55,6 +55,8 @@<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">#include "uuid.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">#include "viraudit.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "netlink-event.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">#ifdef WITH_DRIVER_MODULES<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"># include "driver.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">#else<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -1577,6 +1579,11 @@ int main(int argc, char **argv) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">        goto cleanup;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    /* Register the netlink event service */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (netlinkEventServiceStart()<  0) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; ">     </span>VIR_WARN("Netlink service did not start. Netlink events are not available.");<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">    /* Run event loop. */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">    virNetServerRun(srv);<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">You started your service, but never stop it when libvirtd is shutting down (even though you have a function to do that).<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/src/Makefile.am b/src/Makefile.am<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index 93bf54c..abaeb9c 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- a/src/Makefile.am<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/src/Makefile.am<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -67,6 +67,7 @@ UTIL_SOURCES =<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/dnsmasq.c util/dnsmasq.h                   \<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/json.c util/json.h<span class="Apple-tab-span" style="white-space: pre; ">  </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/logging.c util/logging.h<span class="Apple-tab-span" style="white-space: pre; ">    </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/netlink-event.c util/netlink-event.h               \<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">  </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/memory.c util/memory.h<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/netlink.c util/netlink.h<span class="Apple-tab-span" style="white-space: pre; ">    </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>util/pci.c util/pci.h<span class="Apple-tab-span" style="white-space: pre; ">    </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>\<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index 48ffdf2..34a36bd 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- a/src/libvirt_private.syms<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/src/libvirt_private.syms<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -743,6 +743,13 @@ virShrinkN;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">nlComm;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#netlink-event.h<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventServiceStop;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventServiceStart;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventAddClient;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventRemoveClient;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"># netdev_bandwidth_conf.h<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">virNetDevBandwidthFormat;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">virNetDevBandwidthParse;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/src/util/netlink-event.c b/src/util/netlink-event.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">new file mode 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index 0000000..7c6746d<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- /dev/null<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/src/util/netlink-event.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -0,0 +1,363 @@<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/*<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * lldpad-event.c: event loop for monitoring netlink messages<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">name change ^^<br></blockquote><br>All agreed.<br><br><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Copyright (C) 2011,2012 IBM Corporation.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Copyright (C) 2011,2012 Dirk Herrendoerfer<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * This library is free software; you can redistribute it and/or<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * modify it under the terms of the GNU Lesser General Public<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * License as published by the Free Software Foundation; either<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * version 2.1 of the License, or (at your option) any later version.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * This library is distributed in the hope that it will be useful,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Lesser General Public License for more details.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * You should have received a copy of the GNU Lesser General Public<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * License along with this library; if not, write to the Free Software<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Author: Dirk Herrendoerfer<herrend[at]de[dot]ibm[dot]com><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<config.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<asm/types.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<sys/socket.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<netlink/netlink.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<errno.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<unistd.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<sys/types.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "event.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "logging.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "memory.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "netlink.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "netlink-event.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "virterror_internal.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#define VIR_FROM_THIS VIR_FROM_NET<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#define EVENT_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#define virNetError(code, ...)                                    \<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virReportErrorHelper(VIR_FROM_THIS, code, __FILE__,           \<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                         __FUNCTION__, __LINE__, __VA_ARGS__)<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">This file is compiled on all platforms, even those that don't support (or have chosen to compile out) netlink support. If you look at netlink.c (which is in the same situation), you'll see that it has appropriate #ifdef WITH_LIBNL lines, and stub functions to replace the working functions when libnl support isn't being compiled in for some reason. You need to do the same thing for this file.<br></blockquote><blockquote type="cite"><br></blockquote>Yes, doing so now.<br><br><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/* State for a single netlink event handle */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+struct netlinkEventHandle {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; "> </span>int watch;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    netlinkEventHandleCallback cb;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    void *opaque;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    unsigned char macaddr[6];<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    int deleted;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+};<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/* State for the main netlink event loop */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+struct netlinkEventLoop {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">    </span>virMutex lock;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    int handeled;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    size_t handlesCount;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    size_t handlesAlloc;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    struct netlinkEventHandle *handles;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+};<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/* Only have one event loop */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static struct netlinkEventLoop eventLoop;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/* Unique ID for the next netlink watch to be registered */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static int nextWatch = 1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/* Allocate extra slots for virEventPollHandle/virEventPollTimeout<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+   records in this multiple */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#define NETLINK_EVENT_ALLOC_EXTENT 10<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static netlinkEventSrvPrivatePtr server = 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/* Function definitions */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static void<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventServerLock(netlinkEventSrvPrivatePtr driver) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexLock(&driver->lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static void<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventServerUnlock(netlinkEventSrvPrivatePtr driver) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexUnlock(&driver->lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static void<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventCallback(int watch,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                        int fd ATTRIBUTE_UNUSED,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                        int events ATTRIBUTE_UNUSED,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                        void *opaque) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">        </span>netlinkEventSrvPrivatePtr srv = opaque;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    unsigned char *msg;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    struct sockaddr_nl peer;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    struct ucred *creds = NULL;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    int i, length, handeled;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    length = nl_recv(srv->netlinknh,&peer,&msg,&creds);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    netlinkEventServerLock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    handeled=0;<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">s/handeled/handled/g<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexLock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    VIR_INFO("dispatching to max %d clients, called from event watch %d",<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; ">  </span><span class="Apple-tab-span" style="white-space: pre; "> </span>  (int)eventLoop.handlesCount, watch);<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I think most of the VIR_INFOs should be VIR_DEBUG instead.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    for (i = 0 ; i<  eventLoop.handlesCount ; i++) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (eventLoop.handles[i].deleted) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            continue;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        VIR_INFO("dispatching client %d.",i);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        netlinkEventHandleCallback cb = eventLoop.handles[i].cb;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        void *cpopaque = eventLoop.handles[i].opaque;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        (cb)( msg, length,&peer,&handeled, cpopaque);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexUnlock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (handeled == 0) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; ">    </span>VIR_INFO("nobody cared.");<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    free(msg);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    for (i = 0 ; i<  eventLoop.handlesCount ; i++) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (eventLoop.handles[i].deleted == 1) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        <span class="Apple-tab-span" style="white-space: pre; ">    </span>VIR_FREE(eventLoop.handles[i].opaque);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        <span class="Apple-tab-span" style="white-space: pre; ">       </span>eventLoop.handles[i].deleted = 2;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">     </span>netlinkEventServerUnlock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+static int<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+setupNetlinkEventServer(netlinkEventSrvPrivatePtr srv) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">   </span>int fd;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    netlinkEventServerLock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    /* Allocate a new socket and get fd */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    srv->netlinknh = nl_handle_alloc();<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (!srv->netlinknh) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; ">  </span>virNetError(errno,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                    "%s", _("cannot allocate nlhandle for netlinkEvent server"));<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (nl_connect(srv->netlinknh, NETLINK_ROUTE)<  0) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; ">       </span>virNetError(errno,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                    "%s", _("cannot connect to netlink socket"));<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        goto exit_cleanup;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    fd = nl_socket_get_fd(srv->netlinknh);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    nl_socket_set_nonblocking(srv->netlinknh);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if ((srv->eventwatch = virEventAddHandle(fd,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                                               VIR_EVENT_HANDLE_READABLE,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                                               netlinkEventCallback,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                                               srv, NULL))<  0) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s",<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                    _("Failed to add netlink event handle watch"));<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        goto exit_cleanup;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    srv->netlinkfd = fd;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    VIR_INFO("netlink event listener on fd: %i",fd);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    netlinkEventServerUnlock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    return 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+exit_cleanup:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>nl_close(srv->netlinknh);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">    </span>nl_handle_destroy(srv->netlinknh);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    netlinkEventServerUnlock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; "> </span>return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * netlinkEventServiceStop:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * stop the monitor to receive netlink messages for libvirtd.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * This removes the netlink socket fd from the event handler.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * returns -1 if the monitor cannot be unregistered, 0 upon success<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventServiceStop(void) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">     </span>netlinkEventSrvPrivatePtr srv = server;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">        </span>VIR_INFO("stopping netlink event service");<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">  </span>if (server) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">   </span><span class="Apple-tab-span" style="white-space: pre; "> </span>errno = EINVAL;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">      </span>}<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I think you mean "if (!server).<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">      </span>netlinkEventServerLock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">   </span>nl_close(srv->netlinknh);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">    </span>nl_handle_destroy(srv->netlinknh);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">  </span>virEventRemoveHandle(srv->eventwatch);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>server=0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    netlinkEventServerUnlock(srv);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    return 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * netlinkEventServiceStart:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * start a monitor to receive netlink messages for libvirtd.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * This registers a netlink socket with the event interface.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * returns -1 if the monitor cannot be registered, 0 upon success<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventServiceStart(void) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">        </span>netlinkEventSrvPrivatePtr srv;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; "> </span>if (server) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">   </span><span class="Apple-tab-span" style="white-space: pre; "> </span>return 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">      </span>VIR_INFO("starting netlink event service");<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (VIR_ALLOC(srv)<  0)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        goto no_memory;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (setupNetlinkEventServer(srv)) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; "> </span>goto error;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    VIR_INFO("netlink event service running");<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    server=srv;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    return 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    no_memory:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        virReportOOMError();<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    error:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * netlinkEventAddClient:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * @cb: callback to invoke when an event occurs<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * @opaque: user data to pass to callback<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * @macaddr: macaddr to store with the data. Used to identify callers. May be null.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * register a callback for handling of netlink messages. The<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * registered function receives the entire netlink message and<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * may choose to act upon it.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * returns -1 if the file handle cannot be registered, number of monitor upon success<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventAddClient(netlinkEventHandleCallback cb,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>  void *opaque,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span><span class="Apple-tab-span" style="white-space: pre; "> </span>  const unsigned char *macaddr) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">     </span>int i;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexLock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    VIR_INFO("adding client: %d.",nextWatch);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    /* first try to re-use deleted free slots */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    for (i = 0 ; i<  eventLoop.handlesCount ; i++) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (eventLoop.handles[i].deleted == 2) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            eventLoop.handles[i].watch = nextWatch;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            eventLoop.handles[i].cb = cb;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            eventLoop.handles[i].opaque = opaque;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            eventLoop.handles[i].deleted = 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            if (!macaddr)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            <span class="Apple-tab-span" style="white-space: pre; ">    </span>memcpy(eventLoop.handles[i].macaddr, macaddr,6);<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">You mean "if (macaddr)", not "if (!macaddr)"<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Also, rather than duplicating the statements that are executed once you find an empty slot, why not have a boolean "found" that's false to begin with, is set to true in the loop if an empty slot is found, and then only do the RESIZE if found is still false (and set "i" accordingly). Then just do the assigment of stuff into the slot once, after you've picked (possibly allocating) a slot. This will prevent future bugs caused by adding something to one of the places you're doing assigment, but not the other (since there will only be one place to do it).<br></blockquote><blockquote type="cite"><br></blockquote><br>Yes, the way it is now it's not good.<br><br><blockquote type="cite">Also, I don't see any handling for the situation where someone tries to add a client for a macaddress that is already registered. I don't know enough about potential use cases to know whether or not that could be problematic.<br></blockquote><blockquote type="cite"><br></blockquote><br>I don't see the need to register several handlers for the same mac address right now, this would only make<br>sense for other network monitoring purposes, and in any  case there would only be one for each interface.<br>More general netlink message handlers can still use their watch id to deregister.<br><br><blockquote type="cite"><blockquote type="cite">+            goto cleanup;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (eventLoop.handlesCount == eventLoop.handlesAlloc) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        EVENT_DEBUG("Used %zu handle slots, adding at least %d more",<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                    eventLoop.handlesAlloc, NETLINK_EVENT_ALLOC_EXTENT);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (VIR_RESIZE_N(eventLoop.handles, eventLoop.handlesAlloc,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+                         eventLoop.handlesCount, NETLINK_EVENT_ALLOC_EXTENT)<  0) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            virMutexUnlock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    eventLoop.handles[eventLoop.handlesCount].watch = nextWatch;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    eventLoop.handles[eventLoop.handlesCount].cb = cb;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    eventLoop.handles[eventLoop.handlesCount].opaque = opaque;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    eventLoop.handles[eventLoop.handlesCount].deleted = 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (!macaddr)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    <span class="Apple-tab-span" style="white-space: pre; ">      </span>memcpy(eventLoop.handles[i].macaddr, macaddr,6);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    VIR_INFO("added client to loop slot: %d.",(int)eventLoop.handlesCount);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    eventLoop.handlesCount++;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+cleanup:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexUnlock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    return nextWatch++;<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">There is a race here (unless the C compiler guarantees that ++ is atomic (including the return value of the expression, and I don't think that's the case)  - you need to assign nextWatch++ into a temporary variable while the lock is still held, then unlock and return the temp value.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote>Will fix when I redo the above.<br><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * netlinkEventRemoveClient:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * @watch: watch whose handle to remove<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * @macaddr: macaddr whose handle to remove<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Unregister a callback from a netlink monitor.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * The handler function referenced will no longer receive netlink messages.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Either watch or macaddr may be used, the other should be null.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * returns -1 if the file handle was not registered, 0 upon success<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+netlinkEventRemoveClient(int watch, const unsigned char *macaddr) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    int i;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    if (watch<= 0&&  macaddr == 0) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        VIR_WARN("Ignoring invalid netlink client id: %d", watch);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexLock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    for (i = 0 ; i<  eventLoop.handlesCount ; i++) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (eventLoop.handles[i].deleted)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            continue;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (watch != 0&&  eventLoop.handles[i].watch == watch) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            eventLoop.handles[i].deleted = 1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            virMutexUnlock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            VIR_INFO("removed client: %d by index.",<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            <span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span>  eventLoop.handles[i].watch);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            return 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        if (watch == 0&&  memcmp(macaddr, eventLoop.handles[i].macaddr, 6)) {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            eventLoop.handles[i].deleted = 1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            virMutexUnlock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            VIR_INFO("removed client: %d by mac.",<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            <span class="Apple-tab-span" style="white-space: pre; ">    </span><span class="Apple-tab-span" style="white-space: pre; "> </span>  eventLoop.handles[i].watch);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+            return 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+        }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutexUnlock(&eventLoop.lock);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    VIR_INFO("client not found to remove.");<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    return -1;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/src/util/netlink-event.h b/src/util/netlink-event.h<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">new file mode 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index 0000000..da97395<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- /dev/null<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/src/util/netlink-event.h<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -0,0 +1,63 @@<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/*<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * lldpad-event.h: event loop for monitoring netlink messages<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">name change ^^<br></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Copyright (C) 2011,2012 IBM Corporation.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Copyright (C) 2011,2012 Dirk Herrendoerfer<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * This library is free software; you can redistribute it and/or<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * modify it under the terms of the GNU Lesser General Public<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * License as published by the Free Software Foundation; either<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * version 2.1 of the License, or (at your option) any later version.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * This library is distributed in the hope that it will be useful,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Lesser General Public License for more details.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * You should have received a copy of the GNU Lesser General Public<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * License along with this library; if not, write to the Free Software<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ *<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * Author: Dirk Herrendoerfer<herrend[at]de[dot]ibm[dot]com><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#ifndef NETLINK_EVENT_CONF_H<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+# define NETLINK_EVENT_CONF_H<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include<netlink/netlink.h><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "internal.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#include "threads.h"<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+typedef struct _netlinkEventSrvPrivate netlinkEventSrvPrivate;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+typedef netlinkEventSrvPrivate *netlinkEventSrvPrivatePtr;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+struct _netlinkEventSrvPrivate {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    virMutex lock;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    int eventwatch;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    int netlinkfd;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    struct nl_handle *netlinknh;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+};<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+typedef void (*netlinkEventHandleCallback)( unsigned char *msg, int length, struct sockaddr_nl *peer, int *handled, void *opaque);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * stopNetlinkEventServer: stop the monitor to receive netlink messages for libvirtd<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int netlinkEventServiceStop(void);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * startNetlinkEventServer: start a monitor to receive netlink messages for libvirtd<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int netlinkEventServiceStart(void);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * netlinkEventAddClient: register a callback for handling of netlink messages<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int netlinkEventAddClient(netlinkEventHandleCallback cb, void *opaque, const unsigned char *macaddr);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+/**<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ * netlinkEventRemoveClient: unregister a callback from a netlink monitor<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+ */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+int netlinkEventRemoveClient(int watch, const unsigned char *macaddr);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+#endif /* NETLINK_EVENT_CONF_H */<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">diff --git a/src/util/netlink.c b/src/util/netlink.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">index 0672184..51bd78a 100644<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">--- a/src/util/netlink.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+++ b/src/util/netlink.c<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">@@ -131,6 +131,7 @@ err_exit:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">        *respbuflen = 0;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">    }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">+    nl_close(nlhandle);<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Isn't this an unrelated bugfix? If so, you should submit a separate patch for it.<br></blockquote><blockquote type="cite"><br></blockquote>That should'nt have gone in here - The close is supposedly not needed, but it<br>makes the communitation with libvirt more robust it seems.<br><br><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">    nl_handle_destroy(nlhandle);<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">    return rc;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">}<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><br>Thank you for the comments !<br><br>DirkH<br><br><blockquote type="cite">--<br></blockquote><blockquote type="cite">libvir-list mailing list<br></blockquote><blockquote type="cite"><a href="mailto:libvir-list@redhat.com">libvir-list@redhat.com</a><br></blockquote><blockquote type="cite"><a href="https://www.redhat.com/mailman/listinfo/libvir-list">https://www.redhat.com/mailman/listinfo/libvir-list</a><br></blockquote><div><br></div></body></html>