From 5cab7caa2a767b16211c15f0051a2e21a96ebfd9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 19 Oct 2004 04:37:30 -0700 Subject: [PATCH 1/1] [PATCH] cleanup udevd/udevstart Change to the same timeout loop we use in the rest of the code. Change some comments and names to be more descriptive. I'm mostly finished with the overall cleanup. I will post a new patch for the udevd-nofork experiment, which will be much smaller now. --- udevd.c | 52 ++++++++++++++++++++++++---------------------------- udevd.h | 4 +++- udevsend.c | 15 ++++++--------- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/udevd.c b/udevd.c index 9e0f71b58..c5267d6d9 100644 --- a/udevd.c +++ b/udevd.c @@ -46,7 +46,7 @@ static int pipefds[2]; static unsigned long long expected_seqnum = 0; -static volatile int children_waiting; +static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; static int run_exec_q; @@ -58,7 +58,7 @@ static LIST_HEAD(running_list); static void exec_queue_manager(void); static void msg_queue_manager(void); static void user_sighandler(void); -static void reap_kids(void); +static void reap_sigchilds(void); char *udev_bin; #ifdef LOG @@ -325,7 +325,7 @@ static void asmlinkage sig_handler(int signum) break; case SIGCHLD: /* set flag, then write to pipe if needed */ - children_waiting = 1; + sigchilds_waiting = 1; goto do_write; break; default: @@ -366,9 +366,8 @@ static void udev_done(int pid) } } -static void reap_kids(void) +static void reap_sigchilds(void) { - /* reap all dead children */ while(1) { int pid = waitpid(-1, NULL, WNOHANG); if ((pid == -1) || (pid == 0)) @@ -378,13 +377,13 @@ static void reap_kids(void) } /* just read everything from the pipe and clear the flag, - * the useful flags were set in the signal handler + * the flags was set in the signal handler */ static void user_sighandler(void) { int sig; while(1) { - int rc = read(pipefds[0],&sig,sizeof(sig)); + int rc = read(pipefds[0], &sig, sizeof(sig)); if (rc < 0) break; @@ -392,14 +391,13 @@ static void user_sighandler(void) } } - -int main(int argc, char *argv[]) +int main(int argc, char *argv[], char *envp[]) { int ssock, maxsockplus; struct sockaddr_un saddr; socklen_t addrlen; int retval, fd; - const int on = 1; + const int feature_on = 1; struct sigaction act; fd_set readfds; @@ -408,11 +406,13 @@ int main(int argc, char *argv[]) if (getuid() != 0) { dbg("need to be root, exit"); - exit(1); + _exit(1); } - /* make sure we are at top of dir */ + + /* make sure we don't lock any path */ chdir("/"); - umask( umask( 077 ) | 022 ); + umask(umask(077) | 022); + /* Set fds to dev/null */ fd = open( "/dev/null", O_RDWR ); if ( fd < 0 ) { @@ -424,7 +424,8 @@ int main(int argc, char *argv[]) dup2(fd, 2); if (fd > 2) close(fd); - /* Get new session id so stray signals don't come our way. */ + + /* become session leader */ setsid(); /* setup signal handler pipe */ @@ -456,7 +457,6 @@ int main(int argc, char *argv[]) exit(1); } - /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; sigemptyset(&act.sa_mask); @@ -493,7 +493,7 @@ int main(int argc, char *argv[]) } /* enable receiving of the sender credentials */ - setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); /* possible override of udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); @@ -522,9 +522,9 @@ int main(int argc, char *argv[]) if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); - if (children_waiting) { - children_waiting = 0; - reap_kids(); + if (sigchilds_waiting) { + sigchilds_waiting = 0; + reap_sigchilds(); } if (run_msg_q) { @@ -533,14 +533,10 @@ int main(int argc, char *argv[]) } if (run_exec_q) { - /* this is tricky. exec_queue_manager() loops over exec_list, and - * calls running_with_devpath(), which loops over running_list. This gives - * O(N*M), which can get *nasty*. Clean up running_list before - * calling exec_queue_manager(). - */ - if (children_waiting) { - children_waiting = 0; - reap_kids(); + /* clean up running_list before calling exec_queue_manager() */ + if (sigchilds_waiting) { + sigchilds_waiting = 0; + reap_sigchilds(); } run_exec_q = 0; @@ -550,5 +546,5 @@ int main(int argc, char *argv[]) exit: close(ssock); logging_close(); - exit(1); + return 1; } diff --git a/udevd.h b/udevd.h index 9be581d42..657f684e3 100644 --- a/udevd.h +++ b/udevd.h @@ -26,8 +26,10 @@ #define UDEV_MAGIC "udevd_" UDEV_VERSION #define EVENT_TIMEOUT_SEC 10 -#define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ #define UDEVD_SOCK_PATH "udevd" +#define SEND_WAIT_MAX_SECONDS 3 +#define SEND_WAIT_LOOP_PER_SECOND 10 + struct hotplug_msg { char magic[20]; diff --git a/udevsend.c b/udevsend.c index 883181c1b..84c46bc0c 100644 --- a/udevsend.c +++ b/udevsend.c @@ -95,9 +95,9 @@ static void run_udev(const char *subsystem) switch (pid) { case 0: /* child */ - execl(UDEV_BIN, "udev", subsystem, NULL); + execl(UDEV_BIN, UDEV_BIN, subsystem, NULL); dbg("exec of child failed"); - exit(1); + _exit(1); break; case -1: dbg("fork of child failed"); @@ -117,7 +117,6 @@ int main(int argc, char* argv[]) unsigned long long seq; int retval = 1; int loop; - struct timespec tspec; int sock = -1; struct sockaddr_un saddr; socklen_t addrlen; @@ -176,8 +175,8 @@ int main(int argc, char* argv[]) strfieldcpy(msg.subsystem, subsystem); /* If we can't send, try to start daemon and resend message */ - loop = UDEVSEND_CONNECT_RETRY; - while (loop--) { + loop = SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND; + while (--loop) { retval = sendto(sock, &msg, sizeof(struct hotplug_msg), 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { @@ -200,10 +199,8 @@ int main(int argc, char* argv[]) dbg("daemon started"); started_daemon = 1; } else { - dbg("retry to connect %d", UDEVSEND_CONNECT_RETRY - loop); - tspec.tv_sec = 0; - tspec.tv_nsec = 100000000; /* 100 millisec */ - nanosleep(&tspec, NULL); + dbg("retry to connect %d", SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND - loop); + usleep(1000 * 1000 / SEND_WAIT_LOOP_PER_SECOND); } } -- 2.30.2