summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Härdeman2025-11-16 13:00:36 +0000
committerÁlvaro Fernández Rojas2025-11-17 09:07:03 +0000
commit0a4d4e11c91cfeaa9bcad96856d30c5c5f538f19 (patch)
treee99e7f428bba44fd098edc82d9456456f602031d
parent8ffe79e3f08691335e37548bfa92d9aaa9b2134e (diff)
downloadodhcpd-0a4d4e11c91cfeaa9bcad96856d30c5c5f538f19.tar.gz
odhcpd: simplify signal handling
Currently, odhcpd's main() function will: - call uloop_init() - set up some signal handlers for SIGUSR1/SIGINT/SIGTERM (SIGUSR1 is ignored, the other handlers call uloop_end()) - call odhcpd_run(), which will: - set up some signal handlers for SIGTERM/SIGINT/SIGHUP (the first two call uloop_end(), SIGHUP calls odhcpd_reload()) Note that uloop_init() will call uloop_setup_signals() which will call uloop_setup_signals() which will install handlers for SIGINT/SIGTERM which will set uloop_cancelled to true (e.g. the same thing that uloop_end() does). In other words, the signal handlers are modified three times, and since the default "exit" action is to call uloop_end(), there's nothing that will actually react to signals until uloop_run() is called, meaning that the startup will be uninterruptible if e.g. ubus_init() fails since it'll just retry in a loop with no handling of signals. So, simplify and fix this by letting uloop handle the signals and checking if uloop has been told to exit, removing a bunch of special-purpose code. Signed-off-by: David Härdeman <david@hardeman.nu> Link: https://github.com/openwrt/odhcpd/pull/312 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
-rw-r--r--src/config.c41
-rw-r--r--src/odhcpd.c22
-rw-r--r--src/odhcpd.h2
3 files changed, 21 insertions, 44 deletions
diff --git a/src/config.c b/src/config.c
index 9246d64..a84021e 100644
--- a/src/config.c
+++ b/src/config.c
@@ -24,7 +24,6 @@
#include "dhcpv6-pxe.h"
static struct blob_buf b;
-static int reload_pipe[2] = { -1, -1 };
static int lease_cfg_cmp(const void *k1, const void *k2, void *ptr);
static void lease_cfg_update(struct vlist_tree *tree, struct vlist_node *node_new,
@@ -2433,40 +2432,28 @@ void odhcpd_reload(void)
uci_free_context(uci);
}
-static void handle_signal(int signal)
+static void signal_reload(_o_unused struct uloop_signal *signal)
{
- char b[1] = {0};
-
- if (signal == SIGHUP) {
- if (write(reload_pipe[1], b, sizeof(b)) < 0) {}
- } else
- uloop_end();
-}
-
-static void reload_cb(struct uloop_fd *u, _o_unused unsigned int events)
-{
- char b[512];
- if (read(u->fd, b, sizeof(b)) < 0) {}
-
odhcpd_reload();
}
-static struct uloop_fd reload_fd = { .fd = -1, .cb = reload_cb };
-
-void odhcpd_run(void)
+int odhcpd_run(void)
{
- if (pipe2(reload_pipe, O_NONBLOCK | O_CLOEXEC) < 0) {}
+ static struct uloop_signal sighup = { .signo = SIGHUP, .cb = signal_reload };
- reload_fd.fd = reload_pipe[0];
- uloop_fd_add(&reload_fd, ULOOP_READ);
-
- signal(SIGTERM, handle_signal);
- signal(SIGINT, handle_signal);
- signal(SIGHUP, handle_signal);
-
- while (ubus_init())
+ while (ubus_init()) {
+ if (uloop_cancelled)
+ return EXIT_FAILURE;
sleep(1);
+ }
odhcpd_reload();
+
+ /* uloop_init() already handles SIGINT/SIGTERM */
+ if (uloop_signal_add(&sighup) < 0)
+ return EXIT_FAILURE;
+
uloop_run();
+
+ return EXIT_SUCCESS;
}
diff --git a/src/odhcpd.c b/src/odhcpd.c
index 1f2417b..bc0a833 100644
--- a/src/odhcpd.c
+++ b/src/odhcpd.c
@@ -67,11 +67,6 @@ void __iflog(int lvl, const char *fmt, ...)
va_end(ap);
}
-static void sighandler(_o_unused int signal)
-{
- uloop_end();
-}
-
static void print_usage(const char *app)
{
printf("== %s Usage ==\n"
@@ -146,6 +141,11 @@ int main(int argc, char **argv)
}
}
+ if (getuid() != 0) {
+ error("Must be run as root!");
+ return 2;
+ }
+
if (config.log_syslog) {
openlog("odhcpd", LOG_PERROR | LOG_PID, LOG_DAEMON);
setlogmask(LOG_UPTO(config.log_level));
@@ -153,19 +153,10 @@ int main(int argc, char **argv)
uloop_init();
- if (getuid() != 0) {
- error("Must be run as root!");
- return 2;
- }
-
ioctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (ioctl_sock < 0)
return 4;
- signal(SIGUSR1, SIG_IGN);
- signal(SIGINT, sighandler);
- signal(SIGTERM, sighandler);
-
if (netlink_init())
return 4;
@@ -187,8 +178,7 @@ int main(int argc, char **argv)
return 4;
#endif
- odhcpd_run();
- return 0;
+ return odhcpd_run();
}
diff --git a/src/odhcpd.h b/src/odhcpd.h
index eadb0fc..f41aaa1 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -536,7 +536,7 @@ int odhcpd_get_flags(const struct interface *iface);
struct interface* odhcpd_get_interface_by_index(int ifindex);
void odhcpd_urandom(void *data, size_t len);
-void odhcpd_run(void);
+int odhcpd_run(void);
time_t odhcpd_time(void);
ssize_t odhcpd_unhexlify(uint8_t *dst, size_t len, const char *src);
void odhcpd_hexlify(char *dst, const uint8_t *src, size_t len);