This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new 6830e297c dhcpd: Supports kernel mode compilation
6830e297c is described below
commit 6830e297cf0bcb5730b3a4b87b64c01027ed2bc3
Author: zhangshuai39 <[email protected]>
AuthorDate: Thu Aug 7 14:33:52 2025 +0800
dhcpd: Supports kernel mode compilation
The previous method of terminating the dhcp daemon via a global variable
has been removed; instead, the `kill pid` command is used. Also, because the
original `dhcp_start` method creates tasks via `task_create`, which is not
supported in kernel mode, `dhcp_start` is not compiled in kernel mode. The
daemon can be started in kernel mode using `dhcpd xxx &`.
Signed-off-by: zhangshuai39 <[email protected]>
---
examples/dhcpd/CMakeLists.txt | 36 +++++-----
examples/dhcpd/Makefile | 14 +++-
examples/dhcpd/dhcpd_daemon.c | 8 ++-
netutils/dhcpd/dhcpd.c | 150 +++++++++++++++++++++++++++---------------
4 files changed, 133 insertions(+), 75 deletions(-)
diff --git a/examples/dhcpd/CMakeLists.txt b/examples/dhcpd/CMakeLists.txt
index b59cb5485..5b2ba7cd2 100644
--- a/examples/dhcpd/CMakeLists.txt
+++ b/examples/dhcpd/CMakeLists.txt
@@ -30,23 +30,27 @@ if(CONFIG_EXAMPLES_DHCPD)
STACKSIZE
${CONFIG_DEFAULT_TASK_STACKSIZE})
- nuttx_add_application(
- NAME
- dhcpd_start
- SRCS
- dhcpd_start.c
- dhcpd_daemon.c
- STACKSIZE
- ${CONFIG_DEFAULT_TASK_STACKSIZE})
+ if(NOT CONFIG_BUILD_KERNEL)
+ nuttx_add_application(
+ NAME
+ dhcpd_start
+ SRCS
+ dhcpd_start.c
+ dhcpd_daemon.c
+ STACKSIZE
+ ${CONFIG_DEFAULT_TASK_STACKSIZE})
+ endif()
- nuttx_add_application(
- NAME
- dhcpd_stop
- SRCS
- dhcpd_stop.c
- dhcpd_daemon.c
- STACKSIZE
- ${CONFIG_DEFAULT_TASK_STACKSIZE})
+ if(CONFIG_SCHED_WAITPID)
+ nuttx_add_application(
+ NAME
+ dhcpd_stop
+ SRCS
+ dhcpd_stop.c
+ dhcpd_daemon.c
+ STACKSIZE
+ ${CONFIG_DEFAULT_TASK_STACKSIZE})
+ endif()
add_definitions(-DCONFIG_NETUTILS_DHCPD_HOST=1 -DHAVE_SO_REUSEADDR=1
-DHAVE_SO_BROADCAST=1)
diff --git a/examples/dhcpd/Makefile b/examples/dhcpd/Makefile
index 84ce2efc4..6c6ab3ba8 100644
--- a/examples/dhcpd/Makefile
+++ b/examples/dhcpd/Makefile
@@ -26,13 +26,23 @@ include $(APPDIR)/Make.defs
CSRCS = dhcpd_daemon.c
-MAINSRC = dhcpd_start.c dhcpd_stop.c target.c
+MAINSRC = target.c
# DHCPD built-in application info
-PROGNAME = dhcpd_start dhcpd_stop dhcpd
+PROGNAME = dhcpd
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_DHCPD)
+ifneq ($(CONFIG_BUILD_KERNEL),y)
+MAINSRC += dhcpd_start.c
+PROGNAME += dhcpd_start
+endif
+
+ifeq ($(CONFIG_SCHED_WAITPID),y)
+MAINSRC += dhcpd_stop.c
+PROGNAME += dhcpd_stop
+endif
+
include $(APPDIR)/Application.mk
diff --git a/examples/dhcpd/dhcpd_daemon.c b/examples/dhcpd/dhcpd_daemon.c
index 5b8f52186..b4f16e787 100644
--- a/examples/dhcpd/dhcpd_daemon.c
+++ b/examples/dhcpd/dhcpd_daemon.c
@@ -128,10 +128,12 @@ int dhcpd_daemon(int argc, FAR char *argv[], bool daemon)
/* Then start the dhcpd */
- if (daemon)
+#ifndef CONFIG_BUILD_KERNEL
+ if (!daemon)
{
- return dhcpd_run(devname);
+ return dhcpd_start(devname);
}
+#endif
- return dhcpd_start(devname);
+ return dhcpd_run(devname);
}
diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c
index 367dda526..558991c22 100644
--- a/netutils/dhcpd/dhcpd.c
+++ b/netutils/dhcpd/dhcpd.c
@@ -47,6 +47,7 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <sys/wait.h>
#include <inttypes.h>
#include <sched.h>
@@ -276,8 +277,6 @@ struct dhcpd_state_s
struct dhcpd_daemon_s
{
uint8_t ds_state; /* See enum dhcpd_daemon_e */
- sem_t ds_lock; /* Used to protect the whole structure */
- sem_t ds_sync; /* Used to synchronize start and stop
events */
pid_t ds_pid; /* Task ID of the DHCPD daemon */
FAR struct dhcpd_state_s *ds_data; /* DHCPD daemon data */
};
@@ -314,8 +313,6 @@ static const uint8_t g_magiccookie[4] =
static struct dhcpd_daemon_s g_dhcpd_daemon =
{
DHCPD_NOT_RUNNING,
- SEM_INITIALIZER(1),
- SEM_INITIALIZER(0),
-1,
NULL
};
@@ -1019,7 +1016,7 @@ static int dhcpd_sendpacket(int sockfd, int bbroadcast)
#endif
/* Create a socket to respond with a packet to the client. We
- * cannot re-use the listener socket because it is not bound correctly
+ * cannot reuse the listener socket because it is not bound correctly
*/
/* Then send the response to the DHCP client port at that address */
@@ -1407,7 +1404,7 @@ static inline int dhcpd_decline(void)
lease = dhcpd_findbymac(g_state.ds_inpacket.chaddr);
if (lease)
{
- /* Disassociate the IP from the MAC, but prevent re-used of this
+ /* Disassociate the IP from the MAC, but prevent reused of this
* address for a period of time.
*/
@@ -1497,10 +1494,74 @@ static inline int dhcpd_openlistener(FAR const char
*interface)
* Name: dhcpd_task_run
****************************************************************************/
+#ifndef CONFIG_BUILD_KERNEL
static int dhcpd_task_run(int argc, char **argv)
{
return dhcpd_run(argv[1]);
}
+#endif
+
+/****************************************************************************
+ * Name: dhcpd_get_pid
+ *
+ * Description:
+ * Use /proc filesystem to get dhcpd process PID
+ *
+ * Returned Value:
+ * PID of dhcpd process on success, -1 on failure
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_SCHED_WAITPID)
+static pid_t dhcpd_get_pid(void)
+{
+ pid_t pid = -1;
+
+#if !defined(CONFIG_BUILD_KERNEL)
+ pid = g_dhcpd_daemon.ds_pid;
+#elif defined(CONFIG_SYSTEM_POPEN)
+ FAR FILE *fp;
+ char line[32];
+
+ fp = popen(("pidof dhcpd"), "r");
+ if (fp == NULL)
+ {
+ return -errno;
+ }
+
+ if (fgets(line, sizeof(line), fp) != NULL)
+ {
+ pid = atoi(line);
+ }
+
+ pclose(fp);
+#endif
+
+ return pid;
+}
+#endif
+
+/****************************************************************************
+ * Name: dhcpd_signal_handler
+ *
+ * Description:
+ * Signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP
+ * This function allows dhcpd_stop to terminate dhcpd daemon
+ *
+ * Input Parameters:
+ * signo - Signal number
+ * info - Signal information
+ * ctx - Signal context
+ *
+ ****************************************************************************/
+
+static void
+dhcpd_signal_handler(int signo, FAR siginfo_t *info, FAR void *ctx)
+{
+ /* Set global flag to indicate stop request */
+
+ g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED;
+}
/****************************************************************************
* Public Functions
@@ -1512,7 +1573,8 @@ static int dhcpd_task_run(int argc, char **argv)
int dhcpd_run(FAR const char *interface)
{
- int sockfd;
+ struct sigaction act;
+ int sockfd = -1;
int nbytes;
ninfo("Started\n");
@@ -1538,15 +1600,19 @@ int dhcpd_run(FAR const char *interface)
g_dhcpd_daemon.ds_pid = getpid();
+ /* Install signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP */
+
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = dhcpd_signal_handler;
+ act.sa_flags = SA_SIGINFO;
+ sigaction(CONFIG_NETUTILS_DHCPD_SIGWAKEUP, &act, NULL);
+
/* Indicate that we have started */
g_dhcpd_daemon.ds_state = DHCPD_RUNNING;
- sem_post(&g_dhcpd_daemon.ds_sync);
-
/* Now loop indefinitely, reading packets from the DHCP server socket */
- sockfd = -1;
while (g_dhcpd_daemon.ds_state != DHCPD_STOP_REQUESTED)
{
/* Create a socket to listen for requests from DHCP clients */
@@ -1631,7 +1697,6 @@ int dhcpd_run(FAR const char *interface)
g_dhcpd_daemon.ds_data = NULL;
g_dhcpd_daemon.ds_pid = -1;
g_dhcpd_daemon.ds_state = DHCPD_STOPPED;
- sem_post(&g_dhcpd_daemon.ds_sync);
return OK;
}
@@ -1648,6 +1713,7 @@ int dhcpd_run(FAR const char *interface)
*
****************************************************************************/
+#ifndef CONFIG_BUILD_KERNEL
int dhcpd_start(FAR const char *interface)
{
FAR char *argv[2];
@@ -1658,17 +1724,13 @@ int dhcpd_start(FAR const char *interface)
/* Is the DHCPD in a non-running state? */
- sem_wait(&g_dhcpd_daemon.ds_lock);
- if (g_dhcpd_daemon.ds_state == DHCPD_NOT_RUNNING ||
- g_dhcpd_daemon.ds_state == DHCPD_STOPPED)
+ if (dhcpd_get_pid() < 0)
{
/* Start the DHCPD daemon */
- g_dhcpd_daemon.ds_state = DHCPD_STARTED;
- pid =
- task_create("DHCPD daemon", CONFIG_NETUTILS_DHCPD_PRIORITY,
- CONFIG_NETUTILS_DHCPD_STACKSIZE, dhcpd_task_run,
- argv);
+ pid = task_create("dhcpd", CONFIG_NETUTILS_DHCPD_PRIORITY,
+ CONFIG_NETUTILS_DHCPD_STACKSIZE, dhcpd_task_run,
+ argv);
/* Handle failures to start the DHCPD daemon */
@@ -1676,24 +1738,14 @@ int dhcpd_start(FAR const char *interface)
{
int errval = errno;
- g_dhcpd_daemon.ds_state = DHCPD_STOPPED;
nerr("ERROR: Failed to start the DHCPD daemon: %d\n", errval);
- sem_post(&g_dhcpd_daemon.ds_lock);
return -errval;
}
-
- /* Wait for any daemon state change */
-
- do
- {
- sem_wait(&g_dhcpd_daemon.ds_sync);
- }
- while (g_dhcpd_daemon.ds_state == DHCPD_STARTED);
}
- sem_post(&g_dhcpd_daemon.ds_lock);
return OK;
}
+#endif
/****************************************************************************
* Name: dhcpd_stop
@@ -1707,46 +1759,36 @@ int dhcpd_start(FAR const char *interface)
*
****************************************************************************/
+#ifdef CONFIG_SCHED_WAITPID
int dhcpd_stop(void)
{
- int ret;
+ pid_t pid;
/* Is the DHCPD in a running state? */
- sem_wait(&g_dhcpd_daemon.ds_lock);
- if (g_dhcpd_daemon.ds_state == DHCPD_STARTED ||
- g_dhcpd_daemon.ds_state == DHCPD_RUNNING)
+ pid = dhcpd_get_pid();
+ if (pid >= 0)
{
/* Yes.. request that the daemon stop. */
- g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED;
-
- /* Wait for any daemon state change */
-
- do
+ if (kill(pid, CONFIG_NETUTILS_DHCPD_SIGWAKEUP) < 0)
{
- /* Signal the DHCPD client */
-
- ret = kill(g_dhcpd_daemon.ds_pid,
- CONFIG_NETUTILS_DHCPD_SIGWAKEUP);
-
- if (ret < 0)
- {
- nerr("ERROR: kill pid %d failed: %d\n",
- g_dhcpd_daemon.ds_pid, errno);
- break;
- }
+ nerr("ERROR: kill pid %d failed: %d\n", pid, errno);
+ return -errno;
+ }
- /* Wait for the DHCPD client to respond to the stop request */
+ /* Wait for the DHCPD client to respond to the stop request */
- sem_wait(&g_dhcpd_daemon.ds_sync);
+ if (waitpid(pid, NULL, 0) < 0)
+ {
+ nerr("ERROR: waitpid failed: %d\n", errno);
+ return -errno;
}
- while (g_dhcpd_daemon.ds_state == DHCPD_STOP_REQUESTED);
}
- sem_post(&g_dhcpd_daemon.ds_lock);
return OK;
}
+#endif
/****************************************************************************
* Name: dhcpd_set_startip