ConfD User Community

How to HUP the daemon in the intro/1-2-3-start-query-model example?


#1

Hi I am following one of the examples from examples.confd (dhcp.c). for the section before the while loop which goes:

rename("dhcpd.conf.tmp", "dhcpd.conf");
/* This is the place to HUP the daemon */

is there any advice on what should i do here?
I was forking and running a new process using execl() but its not functioning correctly.

Is there an example somewhere I can follow that does somethign similar to this then later at this point here:

fprintf(stderr, “Read new config, updating dhcpd config \n”);
rename(“dhcpd.conf.tmp”, “dhcpd.conf”);
/* this is the place to HUP the daemon */

I feel i am over complicating this. I just want to make the change and read new config and restart.

Thanks,


#2

From the Linux dhcpd(8) man page:

Whenever changes are made to the dhcpd.conf file, dhcpd must be restarted. To restart dhcpd, send a SIGTERM (signal 15) to the process ID contained in RUNDIR/dhcpd.pid, and then re-invoke dhcpd. Because the DHCP server data‐ base is not as lightweight as a BOOTP database, dhcpd does not automatically restart itself when it sees a change to the dhcpd.conf file.

Note: We get a lot of complaints about this. We realize that it would be nice if one could send a SIGHUP to the server and have it reload the data‐ base. This is not technically impossible, but it would require a great deal of work, our resources are extremely limited, and they can be better spent elsewhere. So please don’t complain about this on the mailing list unless you’re prepared to fund a project to implement this feature, or prepared to do it yourself.


#3

Modified the example for running with the Internet Systems Consortium DHCP Server:

$ dhcpd --version
isc-dhcpd-4.3.1
$ diff -u ../../../examples.confd-orig/intro/1-2-3-start-query-model/dhcpd_conf.c dhcpd_conf.c 
--- ../../../examples.confd-orig/intro/1-2-3-start-query-model/dhcpd_conf.c	2015-07-17 04:56:53.000000000 +0200
+++ dhcpd_conf.c	2015-08-25 19:30:23.945732261 +0200
@@ -18,6 +18,8 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <signal.h>
+#include <fcntl.h>
 
 #include <confd_lib.h>
 #include <confd_cdb.h>
@@ -58,7 +60,7 @@
        fprintf(fp, " %s ", inet_ntoa(ip));
        cdb_get_ipv4(rsock, &ip, "range/hiAddr");
        fprintf(fp, " %s ", inet_ntoa(ip));
-       fprintf(fp, "\n");
+       fprintf(fp, ";\n");
    }
    if(cdb_get_str(rsock, &buf[0], BUFSIZ, "routers") == CONFD_OK) {
 
@@ -67,7 +69,7 @@
            if (*ptr == ' ')
                *ptr = ',';
        }
-       fprintf(fp, " option routers %s\n", buf);
+       fprintf(fp, " option routers %s;\n", buf);
    }
 
 
@@ -75,8 +77,8 @@
    cdb_get(rsock, &vv,  "maxLeaseTime");
 
    cdb_get_duration(rsock, &dur, "maxLeaseTime");
-   fprintf(fp, " max-lease-time %d\n", duration_to_secs(&dur));
-   fprintf(fp, "};\n");
+   fprintf(fp, " max-lease-time %d;\n", duration_to_secs(&dur));
+   fprintf(fp, "}\n");
 }
 
 static int read_conf(struct sockaddr_in *addr)
@@ -101,21 +103,21 @@
         return CONFD_ERR;
     }
     cdb_get_duration(rsock, &dur, "/dhcp/defaultLeaseTime");
-    fprintf(fp, "default-lease-time %d\n", duration_to_secs(&dur));
+    fprintf(fp, "default-lease-time %d;\n", duration_to_secs(&dur));
 
     cdb_get_duration(rsock, &dur, "/dhcp/maxLeaseTime");
-    fprintf(fp, "max-lease-time %d\n", duration_to_secs(&dur));
+    fprintf(fp, "max-lease-time %d;\n", duration_to_secs(&dur));
 
     cdb_get_enum_value(rsock, &tmp, "/dhcp/logFacility");
     switch (tmp) {
     case dhcpd_kern:
-        fprintf(fp, "log-facility kern\n");
+        fprintf(fp, "log-facility kern;\n");
         break;
     case dhcpd_mail:
-        fprintf(fp, "log-facility mail\n");
+        fprintf(fp, "log-facility mail;\n");
         break;
     case dhcpd_local7:
-        fprintf(fp, "log-facility local7\n");
+        fprintf(fp, "log-facility local7;\n");
         break;
     }
     n = cdb_num_instances(rsock, "/dhcp/SubNets/subNet");
@@ -146,6 +148,43 @@
     return cdb_close(rsock);
 }
 
+void restart_dhcpd(void)
+{
+  int fd = -1;
+  char buffer[BUFSIZ];
+  char command[BUFSIZ];
+  int pid;
+  
+  if ((fd = open("/var/run/dhcpd.pid", O_RDONLY)) == -1) {
+    goto RESTART;
+  }
+  if (read(fd, buffer, BUFSIZ - 1) == -1) {
+    fprintf(stderr, "Couldn't read from pid file");
+    goto EXIT;
+  }
+  close(fd);
+  fd = -1;
+  
+  pid = atoi(buffer);
+  if (pid <= 1) {
+    fprintf(stderr, "Bad pid value");
+    goto EXIT;
+  }
+  if (kill(pid, SIGTERM) == -1) {
+    fprintf(stderr, "Unable to send SIGTERM");
+    goto EXIT;
+  }
+  unlink("/var/run/dhcpd.pid");
+  
+ EXIT:
+  if (fd != -1)
+    close(fd);
+
+ RESTART:
+    snprintf(command, BUFSIZ - 1, "/usr/sbin/dhcpd");
+    system(command);
+}
+
 /********************************************************************/
 
 int main(int argc, char **argv)
@@ -187,9 +226,10 @@
         fprintf(stderr, "Terminate: read_conf %d\n", status);
         exit(0);
     }
-    rename("dhcpd.conf.tmp", "dhcpd.conf");
+    rename("dhcpd.conf.tmp", "/etc/dhcp/dhcpd.conf");
     /* This is the place to HUP the daemon */
-
+    restart_dhcpd();
+    
     while (1) {
         static int poll_fail_counter=0;
         struct pollfd set[1];
@@ -224,9 +264,10 @@
                 }
             }
             fprintf(stderr, "Read new config, updating dhcpd config \n");
-            rename("dhcpd.conf.tmp", "dhcpd.conf");
+            rename("dhcpd.conf.tmp", "/etc/dhcpd/dhcpd.conf");
             /* this is the place to HUP the daemon */
-
+	    restart_dhcpd();
+	    
             if ((status = cdb_sync_subscription_socket(subsock,
                                                        CDB_DONE_PRIORITY))
                 != CONFD_OK) {

Configure SSH tunneling in confd
Netconf server extension