]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: invoke lldpcli at start
authorVincent Bernat <bernat@luffy.cx>
Sat, 19 Jan 2013 15:13:50 +0000 (16:13 +0100)
committerVincent Bernat <bernat@luffy.cx>
Tue, 22 Jan 2013 08:51:29 +0000 (09:51 +0100)
To configure itself, lldpd now invokes lldpcli when
starting. Currently, it does not really check if everything works as
expected but in the future, lldpcli will ask lldpd to "start".

The configuration files are:
 - ${sysconfdir}/lldpd.conf
 - ${sysconfdir}/lldpd.d/*.conf

src/client/lldpcli.c
src/daemon/Makefile.am
src/daemon/lldpd.8
src/daemon/lldpd.c
src/daemon/priv.c

index f878c97cc26af8b5d4c6cb6f2e93e01f145f0f5d..5834d5e0dc2a250a6f93cf26bf73e2f57cf73684 100644 (file)
@@ -355,7 +355,7 @@ main(int argc, char *argv[])
        int ch, debug = 1, rc = EXIT_FAILURE;
        const char *fmt = "plain";
        lldpctl_conn_t *conn = NULL;
-       const char *options = is_lldpctl(argv[0])?"hdvf:":"hdvf:c:";
+       const char *options = is_lldpctl(argv[0])?"hdvf:":"hdsvf:c:";
 
        int gotinputs = 0;
        struct inputs inputs;
@@ -365,6 +365,7 @@ main(int argc, char *argv[])
        while ((ch = getopt(argc, argv, options)) != -1) {
                switch (ch) {
                case 'd': debug++; break;
+               case 's': debug--; break;
                }
        }
        log_init(debug, __progname);
@@ -374,6 +375,7 @@ main(int argc, char *argv[])
        while ((ch = getopt(argc, argv, options)) != -1) {
                switch (ch) {
                case 'd': break;
+               case 's': break;
                case 'h':
                        usage();
                        break;
index a0dc7bf5a3c1059055927311b8b288b1aad1172f..21567af8b8f5e1b61185646623c2b9057d347bee 100644 (file)
@@ -17,6 +17,7 @@ liblldpd_la_SOURCES  = \
        interfaces.c \
        event.c lldpd.c
 liblldpd_la_CFLAGS   = $(AM_CFLAGS) @LIBEVENT_CFLAGS@
+liblldpd_la_CPPFLAGS = -DSYSCONFDIR='"$(sysconfdir)"' -DLLDPCLI_PATH='"$(sbindir)/lldpcli"'
 liblldpd_la_LIBADD   = \
        $(top_builddir)/src/libcommon-daemon-client.la \
        $(top_builddir)/src/libcommon-daemon-lib.la @LIBEVENT_LIBS@
index 580439c3edeb89645cd41085ecf6dc127e40d704..57520d148d3efd8a5f894694d6ab7c6b1bb5930e 100644 (file)
@@ -31,6 +31,7 @@
 .Op Fl C Ar interfaces
 .Op Fl M Ar class
 .Op Fl H Ar hide
+.Op Fl L Ar lldpcli
 .Sh DESCRIPTION
 .Nm
 is a daemon able to receive and send
@@ -233,6 +234,12 @@ transmit sensible information like serial numbers.
 Filter neighbors. See section
 .Sx FILTERING NEIGHBORS
 for details.
+.It Fl L Ar lldpcli
+Provide an alternative path to
+.Nm lldpcli
+for configuration. If empty, does not use
+.Nm lldpcli
+for configuration.
 .It Fl v
 Show
 .Nm
index 356a1260278367914179a96f75762224b9e1102c..855034d4fe1060f7221b9a96922038f9e4903d21 100644 (file)
@@ -992,6 +992,51 @@ lldpd_exit(struct lldpd *cfg)
        }
 }
 
+/**
+ * Run lldpcli to configure lldpd.
+ *
+ * @return PID of running lldpcli or -1 if error.
+ */
+static pid_t
+lldpd_configure(int debug, const char *path)
+{
+       pid_t lldpcli = fork();
+       int devnull;
+
+       switch (lldpcli) {
+       case -1:
+               log_warn("main", "unable to fork");
+               return -1;
+       case 0:
+               /* Child, exec lldpcli */
+               if ((devnull = open("/dev/null", O_RDWR, 0)) != -1) {
+                       char sdebug[debug + 3];
+                       memset(sdebug, 'd', debug + 3);
+                       sdebug[debug + 2] = '\0';
+                       sdebug[0] = '-'; sdebug[1] = 's';
+
+                       dup2(devnull,   STDIN_FILENO);
+                       if (devnull > 2) close(devnull);
+
+                       log_debug("main", "invoke %s %s", path, sdebug);
+                       if (execl(path, "lldpcli", sdebug,
+                               "-c", SYSCONFDIR "/lldpd.conf",
+                               "-c", SYSCONFDIR "/lldpd.d",
+                               NULL) == -1) {
+                               log_warn("main", "unable to execute %s", path);
+                               log_warnx("main", "configuration may be incomplete");
+                       }
+               }
+               exit(127);
+               break;
+       default:
+               /* Father, don't do anything stupid */
+               return lldpcli;
+       }
+       /* Should not be here */
+       return -1;
+}
+
 struct intint { int a; int b; };
 static const struct intint filters[] = {
        {  0, 0 },
@@ -1108,8 +1153,8 @@ lldpd_main(int argc, char *argv[])
        char *mgmtp = NULL;
        char *cidp = NULL;
        char *interfaces = NULL;
-       char *popt, opts[] = 
-               "H:vhkrdD:xX:m:4:6:I:C:p:M:P:S:i@                    ";
+       char *popt, opts[] =
+               "H:vhkrdD:xX:m:4:6:I:C:p:M:P:S:iL:@                    ";
        int i, found, advertise_version = 1;
 #ifdef ENABLE_LLDPMED
        int lldpmed = 0, noinventory = 0;
@@ -1117,6 +1162,7 @@ lldpd_main(int argc, char *argv[])
        char *descr_override = NULL;
        char *platform_override = NULL;
        char *lsb_release = NULL;
+       const char *lldpcli = LLDPCLI_PATH;
        int smart = 15;
        int receiveonly = 0;
        int ctl;
@@ -1163,6 +1209,9 @@ lldpd_main(int argc, char *argv[])
                case 'C':
                        cidp = optarg;
                        break;
+               case 'L':
+                       if (strlen(optarg)) lldpcli = optarg;
+                       else lldpcli = NULL;
                case 'k':
                        advertise_version = 0;
                        break;
@@ -1284,6 +1333,13 @@ lldpd_main(int argc, char *argv[])
        /* Disable SIGPIPE */
        signal(SIGPIPE, SIG_IGN);
 
+       /* Configuration with lldpcli */
+       if (lldpcli) {
+               log_debug("main", "invoking lldpcli for configuration");
+               if (lldpd_configure(debug, lldpcli) == -1)
+                       fatal("main", "unable to spawn lldpcli");
+       }
+
        /* Daemonization, unless started by upstart, systemd or launchd or debug */
 #ifndef HOST_OS_OSX
        if (!lldpd_started_by_upstart() && !lldpd_started_by_systemd() &&
index ad4746d282e3a51ef91197e9c4d5a939f143a252..8fdd7c9b41ca2d1027fb670f5dd6772c96a7cb0b 100644 (file)
@@ -619,11 +619,7 @@ priv_loop()
 }
 
 static void
-priv_exit()
-{
-       int status;
-       int rc;
-       rc = waitpid(monitored, &status, WNOHANG);
+priv_exit_rc_status(int rc, int status) {
        switch (rc) {
        case 0:
                log_debug("privsep", "killing child");
@@ -655,6 +651,15 @@ priv_exit()
        }
 }
 
+static void
+priv_exit()
+{
+       int status;
+       int rc;
+       rc = waitpid(monitored, &status, WNOHANG);
+       priv_exit_rc_status(rc, status);
+}
+
 /* If priv parent gets a TERM or HUP, pass it through to child instead */
 static void
 sig_pass_to_chld(int sig)
@@ -669,8 +674,17 @@ sig_pass_to_chld(int sig)
 static void
 sig_chld(int sig)
 {
-       log_debug("privsep", "received signal %d, exiting", sig);
-       priv_exit();
+       int status;
+       int rc = waitpid(monitored, &status, WNOHANG);
+       if (rc == 0) {
+               while ((rc = waitpid(-1, &status, WNOHANG)) > 0) {
+                       if (rc == monitored) priv_exit_rc_status(rc, status);
+                       else log_debug("privsep", "unrelated process %d has died",
+                               rc);
+               }
+               return;
+       }
+       priv_exit_rc_status(rc, status);
 }
 
 /* Initialization */