From: Roy Marples Date: Wed, 9 Jun 2010 15:26:55 +0000 (+0000) Subject: -n, --rebind now re-reads the configuration file, removes stale X-Git-Tag: v5.2.5~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ed2a3f8f8861a352de3a1d85077a4d024025390;p=thirdparty%2Fdhcpcd.git -n, --rebind now re-reads the configuration file, removes stale interfaces and rebinds existing ones. --- diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 3ab00577..ecd147de 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 18, 2010 +.Dd June 9, 2010 .Dt DHCPCD 8 SMM .Os .Sh NAME @@ -254,26 +254,12 @@ Request the DHCP variable for use in .Pa @SCRIPT@ . .It Fl n , -rebind -Notifies an existing +Notifies .Nm -process running on the -.Ar interface -to rebind its lease. -.Nm -will not re-configure itself or use any other command line arguments. -.Nm -will timeout the rebind after 30 seconds at which point the lease will be -expired and -.Nm -will enter the discovery state to obtain a new lease. -Use the -.Fl t , -timeout -option to change this. +to reload its configuration and rebind its interfaces. If .Nm is not running, then it starts up as normal. -This option used to be renew, but rebind is more accurate as we need to -broadcast the request instead of unicasting. .It Fl p , -persistent .Nm normally de-configures the diff --git a/dhcpcd.c b/dhcpcd.c index 81ca9ee1..0d7d830c 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -1324,14 +1324,93 @@ handle_link(_unused void *arg) syslog(LOG_ERR, "manage_link: %m"); } +static void +reboot(struct interface *iface, int argc, char **argv) +{ + const struct if_options *ifo; + int opt; + + ifo = iface->state->options; + opt = ifo->options; + configure_interface(iface, argc, argv); + ifo = iface->state->options; + iface->state->interval = 0; + if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) && + iface->addr.s_addr != ifo->req_addr.s_addr) || + (opt & (DHCPCD_INFORM | DHCPCD_STATIC) && + !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))) + { + drop_config(iface, "EXPIRE"); + } else { + free(iface->state->offer); + iface->state->offer = NULL; + } + start_interface(iface); +} + +static void +reconf_reboot(int action, int argc, char **argv, int oi) +{ + struct interface *ifl, *ifn, *ifp, *ifs, *ift; + + ifs = discover_interfaces(argc - oi, argv + oi); + if (ifs == NULL) + return; + + /* Remove any old interfaces */ + if (ifaces) { + for (ifl = NULL; ifl != ifaces;) { + /* Work our way backwards */ + for (ifp = ifaces; ifp; ifp = ifp->next) + if (ifp->next == ifl) { + ifl = ifp; + break; + } + for (ifn = ifs; ifn; ifn = ifn->next) + if (strcmp(ifn->name, ifp->name) == 0) + break; + if (ifn == NULL) + stop_interface(ifp); + } + } + + for (ifp = ifs; ifp && (ift = ifp->next, 1); ifp = ift) { + ifl = NULL; + for (ifn = ifaces; ifn; ifn = ifn->next) { + if (strcmp(ifn->name, ifp->name) == 0) + break; + ifl = ifn; + } + if (ifn) { + if (action) + reboot(ifn, argc, argv); + else if (ifn->state->new) + configure(ifn); + free_interface(ifp); + } else { + ifp->next = NULL; + init_state(ifp, argc, argv); + start_interface(ifp); + if (ifl) + ifl->next = ifp; + else + ifaces = ifp; + } + } + + sort_interfaces(); +} + /* ARGSUSED */ static void handle_signal(_unused void *arg) { - struct interface *iface, *ifl; + struct interface *ifp, *ifl; + struct if_options *ifo; int sig = signal_read(); - int do_release = 0; + int do_release, do_rebind; + do_rebind = do_release = 0; switch (sig) { case SIGINT: syslog(LOG_INFO, "received SIGINT, stopping"); @@ -1340,19 +1419,26 @@ handle_signal(_unused void *arg) syslog(LOG_INFO, "received SIGTERM, stopping"); break; case SIGALRM: - syslog(LOG_INFO, "received SIGALRM, rebinding lease"); - for (iface = ifaces; iface; iface = iface->next) - start_interface(iface); + syslog(LOG_INFO, "received SIGALRM, rebinding"); + ifo = read_config(cffile, NULL, NULL, NULL); + /* We need to preserve these two options. */ + if (options & DHCPCD_MASTER) + ifo->options |= DHCPCD_MASTER; + if (options & DHCPCD_DAEMONISED) + ifo->options |= DHCPCD_DAEMONISED; + options = ifo->options; + free_options(ifo); + reconf_reboot(1, 0, NULL, 0); return; case SIGHUP: - syslog(LOG_INFO, "received SIGHUP, releasing lease"); + syslog(LOG_INFO, "received SIGHUP, releasing"); do_release = 1; break; case SIGUSR1: syslog(LOG_INFO, "received SIGUSR, reconfiguring"); - for (iface = ifaces; iface; iface = iface->next) - if (iface->state->new) - configure(iface); + for (ifp = ifaces; ifp; ifp = ifp->next) + if (ifp->state->new) + configure(ifp); return; case SIGPIPE: syslog(LOG_WARNING, "received SIGPIPE"); @@ -1371,50 +1457,26 @@ handle_signal(_unused void *arg) for (;;) { /* Be sane and drop the last config first */ ifl = NULL; - for (iface = ifaces; iface; iface = iface->next) { - if (iface->next == NULL) + for (ifp = ifaces; ifp; ifp = ifp->next) { + if (ifp->next == NULL) break; - ifl = iface; + ifl = ifp; } - if (iface == NULL) + if (ifp == NULL) break; - if (iface->carrier != LINK_DOWN && + if (ifp->carrier != LINK_DOWN && (do_release || - iface->state->options->options & DHCPCD_RELEASE)) - send_release(iface); - stop_interface(iface); + ifp->state->options->options & DHCPCD_RELEASE)) + send_release(ifp); + stop_interface(ifp); } exit(EXIT_FAILURE); } -static void -reconf_reboot(struct interface *iface, int argc, char **argv) -{ - const struct if_options *ifo; - int opt; - - ifo = iface->state->options; - opt = ifo->options; - configure_interface(iface, argc, argv); - ifo = iface->state->options; - iface->state->interval = 0; - if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) && - iface->addr.s_addr != ifo->req_addr.s_addr) || - (opt & (DHCPCD_INFORM | DHCPCD_STATIC) && - !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))) - { - drop_config(iface, "EXPIRE"); - } else { - free(iface->state->offer); - iface->state->offer = NULL; - } - start_interface(iface); -} - int handle_args(struct fd_list *fd, int argc, char **argv) { - struct interface *ifs, *ifp, *ifl, *ifn, *ift; + struct interface *ifp; int do_exit = 0, do_release = 0, do_reboot = 0, do_reconf = 0; int opt, oi = 0; ssize_t len; @@ -1537,32 +1599,7 @@ handle_args(struct fd_list *fd, int argc, char **argv) return 0; } - if ((ifs = discover_interfaces(argc - optind, argv + optind))) { - for (ifp = ifs; ifp && (ift = ifp->next, 1); ifp = ift) { - ifl = NULL; - for (ifn = ifaces; ifn; ifn = ifn->next) { - if (strcmp(ifn->name, ifp->name) == 0) - break; - ifl = ifn; - } - if (ifn) { - if (do_reboot) - reconf_reboot(ifn, argc, argv); - else if (do_reconf && ifn->state->new) - configure(ifn); - free_interface(ifp); - } else { - ifp->next = NULL; - init_state(ifp, argc, argv); - start_interface(ifp); - if (ifl) - ifl->next = ifp; - else - ifaces = ifp; - } - } - sort_interfaces(); - } + reconf_reboot(do_reboot, argc, argv, optind); return 0; }