tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH] dhcrelay needs foreground



When upgrading from netbsd-6 to netbsd-7, I experienced this problem: 
dhcrelay would not work in the background. The -d flag got mandatory 
to have it working.

Looking at the ktrace, we can see that a background dhcrelay gets 
EBADF to all its kevent(2) calls. This is because it uses a file descriptor
obtained from a kevent(2) call before doing the fork(2). And as kqueue(2) 
man page says "The queue is not inherited by a child created with fork(2)."

In dhcrelay sources, the kqueue(2) call is made trhough dhcp_context_create(): 

#0  0xbaf9a570 in kqueue () from /usr/lib/libc.so.12
#1  0xbb5021bf in setup_watcher (mctx=0xbae03240, manager=0xbae8e000)
    at src/external/bsd/bind/dist/lib/isc/unix/socket.c:4385
#2  0xbb5026f9 in isc__socketmgr_create2 (mctx=0xbae03240, 
    managerp=0x80b3f34 <dhcp_gbl_ctx+20>, maxsocks=4096)
    at src/external/bsd/bind/dist/lib/isc/unix/socket.c:4711
#3  0xbb502368 in isc__socketmgr_create (mctx=0xbae03240, 
    managerp=0x80b3f34 <dhcp_gbl_ctx+20>)
    at src/external/bsd/bind/dist/lib/isc/unix/socket.c:4585
#4  0xbb5076c6 in isc_socketmgr_createinctx (mctx=0xbae03240, actx=0xbae8c000, 
    managerp=0x80b3f34 <dhcp_gbl_ctx+20>)
    at src/external/bsd/bind/dist/lib/isc/unix/../socket_api.c:64
#5  0x0808c92d in dhcp_context_create (flags=3, local4=0x0, local6=0x0)
    at src/external/bsd/dhcp/lib/omapip/../../dist/omapip/isclib.c:184
#6  0x0804b624 in main (argc=4, argv=0xbf7fe8a0)
    at src/external/bsd/dhcp/bin/relay/../../dist/relay/dhcrelay.c:211

The fix is to re-order the dhcp_context_create() and its dependencies after 
the fork(2), which is the way it works in dhclient(8) and dhcpd(8). If nobody
opposes I will commit the patch below and submit it upstream.

Anyone knows of an open GNATS PR for this bug?

Index: dist/relay/dhcrelay.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcp/dist/relay/dhcrelay.c,v
retrieving revision 1.5
diff -U 4 -r1.5 dhcrelay.c
--- dist/relay/dhcrelay.c       12 Jul 2014 12:09:37 -0000      1.5
+++ dist/relay/dhcrelay.c       4 Jun 2017 07:22:43 -0000
@@ -206,15 +206,8 @@
 #if !defined(DEBUG)
        setlogmask(LOG_UPTO(LOG_INFO));
 #endif 
 
-       /* Set up the isc and dns library managers */
-       status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
-                                    NULL, NULL);
-       if (status != ISC_R_SUCCESS)
-               log_fatal("Can't initialize context: %s",
-                         isc_result_totext(status));
-
        /* Set up the OMAPI. */
        status = omapi_init();
        if (status != ISC_R_SUCCESS)
                log_fatal("Can't initialize OMAPI: %s",
@@ -535,19 +528,8 @@
                                  "option definition.");
        }
 #endif
 
-       /* Get the current time... */
-       gettimeofday(&cur_tv, NULL);
-
-       /* Discover all the network interfaces. */
-       discover_interfaces(DISCOVER_RELAY);
-
-#ifdef DHCPv6
-       if (local_family == AF_INET6)
-               setup_streams();
-#endif
-
        /* Become a daemon... */
        if (!no_daemon) {
                int pid;
                FILE *pf;
@@ -586,8 +568,26 @@
 
                IGNORE_RET (chdir("/"));
        }
 
+       /* Set up the isc and dns library managers */
+       status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
+                                    NULL, NULL);
+       if (status != ISC_R_SUCCESS)
+               log_fatal("Can't initialize context: %s",
+                         isc_result_totext(status));
+
+       /* Get the current time... */
+       gettimeofday(&cur_tv, NULL);
+
+       /* Discover all the network interfaces. */
+       discover_interfaces(DISCOVER_RELAY);
+
+#ifdef DHCPv6
+       if (local_family == AF_INET6)
+               setup_streams();
+#endif
+
        /* Set up the packet handler... */
        if (local_family == AF_INET)
                bootp_packet_handler = do_relay4;
 #ifdef DHCPv6




-- 
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index