summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--udev/udev-event.c6
-rw-r--r--udev/udev.xml2
-rw-r--r--udev/udevadm.c2
-rw-r--r--udev/udevadm.xml2
-rw-r--r--udev/udevd.c113
5 files changed, 55 insertions, 70 deletions
diff --git a/udev/udev-event.c b/udev/udev-event.c
index 4b00cab30d..e34f09cfe3 100644
--- a/udev/udev-event.c
+++ b/udev/udev-event.c
@@ -505,10 +505,10 @@ static int rename_netif(struct udev_event *event)
goto exit;
}
- /* wait 30 seconds for our target to become available */
+ /* wait 90 seconds for our target to become available */
util_strlcpy(ifr.ifr_name, ifr.ifr_newname, IFNAMSIZ);
util_strlcpy(ifr.ifr_newname, event->name, IFNAMSIZ);
- loop = 30 * 20;
+ loop = 90 * 20;
while (loop--) {
err = ioctl(sk, SIOCSIFNAME, &ifr);
if (err == 0) {
@@ -522,7 +522,7 @@ static int rename_netif(struct udev_event *event)
break;
}
dbg(event->udev, "wait for netif '%s' to become free, loop=%i\n",
- event->name, (30 * 20) - loop);
+ event->name, (90 * 20) - loop);
usleep(1000 * 1000 / 20);
}
}
diff --git a/udev/udev.xml b/udev/udev.xml
index f11a56cc04..4c35e19791 100644
--- a/udev/udev.xml
+++ b/udev/udev.xml
@@ -335,7 +335,7 @@
event process for a long period of time may block all further events for
this or a dependent device. Long running tasks need to be immediately
detached from the event process itself.</para>
- <para>If the specifiefd string starts with
+ <para>If the specified string starts with
<option>socket:<replaceable>path</replaceable></option>, all current event
values will be passed to the specified socket, as a message in the same
format the kernel sends an uevent. If the first character of the specified path
diff --git a/udev/udevadm.c b/udev/udevadm.c
index 0927981ab2..072280a58e 100644
--- a/udev/udevadm.c
+++ b/udev/udevadm.c
@@ -79,7 +79,7 @@ static const struct command cmds[] = {
},
{
.name = "settle",
- .cmd = udevadm_settle, "",
+ .cmd = udevadm_settle,
.help = "wait for the event queue to finish",
},
{
diff --git a/udev/udevadm.xml b/udev/udevadm.xml
index 7ed2107f88..9d905abd0c 100644
--- a/udev/udevadm.xml
+++ b/udev/udevadm.xml
@@ -227,7 +227,7 @@
<varlistentry>
<term><option>--quiet</option></term>
<listitem>
- <para>Do not print any output, like the remaining queue entries when reachin the timeout.</para>
+ <para>Do not print any output, like the remaining queue entries when reaching the timeout.</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/udev/udevd.c b/udev/udevd.c
index 9a8d791800..13a10240d7 100644
--- a/udev/udevd.c
+++ b/udev/udevd.c
@@ -29,6 +29,7 @@
#include <getopt.h>
#include <dirent.h>
#include <sys/select.h>
+#include <sys/poll.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
@@ -58,15 +59,17 @@ static void log_fn(struct udev *udev, int priority,
}
}
+static void reap_sigchilds(void);
+
static int debug_trace;
static struct udev_rules *rules;
static struct udev_ctrl *udev_ctrl;
static struct udev_monitor *kernel_monitor;
static int inotify_fd = -1;
-static int signal_pipe[2] = {-1, -1};
static volatile int sigchilds_waiting;
static volatile int udev_exit;
static volatile int reload_config;
+static volatile int signal_received;
static int run_exec_q;
static int stop_exec_q;
static int max_childs;
@@ -194,8 +197,6 @@ static void event_fork(struct udev_event *event)
udev_ctrl_unref(udev_ctrl);
if (inotify_fd >= 0)
close(inotify_fd);
- close(signal_pipe[READ_END]);
- close(signal_pipe[WRITE_END]);
logging_close();
logging_init("udevd-event");
setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY);
@@ -404,6 +405,7 @@ static void event_queue_manager(struct udev *udev)
struct udev_list_node *loop;
struct udev_list_node *tmp;
+start_over:
if (udev_list_is_empty(&event_list)) {
if (childs > 0) {
err(udev, "event list empty, but childs count is %i", childs);
@@ -433,6 +435,13 @@ static void event_queue_manager(struct udev *udev)
event_fork(loop_event);
dbg(udev, "moved seq %llu to running list\n", udev_device_get_seqnum(loop_event->dev));
+
+ /* retry if events finished in the meantime */
+ if (sigchilds_waiting) {
+ sigchilds_waiting = 0;
+ reap_sigchilds();
+ goto start_over;
+ }
}
}
@@ -520,8 +529,7 @@ static void asmlinkage sig_handler(int signum)
break;
}
- /* write to pipe, which will wakeup select() in our mainloop */
- write(signal_pipe[WRITE_END], "", 1);
+ signal_received = 1;
}
static void udev_done(int pid, int exitstatus)
@@ -633,10 +641,8 @@ static void export_initial_seqnum(struct udev *udev)
int main(int argc, char *argv[])
{
struct udev *udev;
- int err;
int fd;
struct sigaction act;
- fd_set readfds;
const char *value;
int daemonize = 0;
int resolve_names = 1;
@@ -650,7 +656,6 @@ int main(int argc, char *argv[])
{}
};
int rc = 1;
- int maxfd;
udev = udev_new();
if (udev == NULL)
@@ -744,34 +749,6 @@ int main(int argc, char *argv[])
}
udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024);
- err = pipe(signal_pipe);
- if (err < 0) {
- err(udev, "error getting pipes: %m\n");
- goto exit;
- }
-
- err = fcntl(signal_pipe[READ_END], F_GETFL, 0);
- if (err < 0) {
- err(udev, "error fcntl on read pipe: %m\n");
- goto exit;
- }
- err = fcntl(signal_pipe[READ_END], F_SETFL, err | O_NONBLOCK);
- if (err < 0) {
- err(udev, "error fcntl on read pipe: %m\n");
- goto exit;
- }
-
- err = fcntl(signal_pipe[WRITE_END], F_GETFL, 0);
- if (err < 0) {
- err(udev, "error fcntl on write pipe: %m\n");
- goto exit;
- }
- err = fcntl(signal_pipe[WRITE_END], F_SETFL, err | O_NONBLOCK);
- if (err < 0) {
- err(udev, "error fcntl on write pipe: %m\n");
- goto exit;
- }
-
rules = udev_rules_new(udev, resolve_names);
if (rules == NULL) {
err(udev, "error reading rules\n");
@@ -851,7 +828,6 @@ int main(int argc, char *argv[])
memset(&act, 0x00, sizeof(struct sigaction));
act.sa_handler = (void (*)(int)) sig_handler;
sigemptyset(&act.sa_mask);
- act.sa_flags = SA_RESTART;
sigaction(SIGINT, &act, NULL);
sigaction(SIGTERM, &act, NULL);
sigaction(SIGCHLD, &act, NULL);
@@ -898,32 +874,49 @@ int main(int argc, char *argv[])
max_childs = strtoul(value, NULL, 10);
info(udev, "initialize max_childs to %u\n", max_childs);
- maxfd = udev_ctrl_get_fd(udev_ctrl);
- maxfd = UDEV_MAX(maxfd, udev_monitor_get_fd(kernel_monitor));
- maxfd = UDEV_MAX(maxfd, signal_pipe[READ_END]);
- maxfd = UDEV_MAX(maxfd, inotify_fd);
while (!udev_exit) {
+ sigset_t blocked_mask, orig_mask;
+ struct pollfd pfd[4];
+ struct pollfd *ctrl_poll, *monitor_poll, *inotify_poll = NULL;
+ int nfds = 0;
int fdcount;
- FD_ZERO(&readfds);
- FD_SET(signal_pipe[READ_END], &readfds);
- FD_SET(udev_ctrl_get_fd(udev_ctrl), &readfds);
- FD_SET(udev_monitor_get_fd(kernel_monitor), &readfds);
- if (inotify_fd >= 0)
- FD_SET(inotify_fd, &readfds);
- fdcount = select(maxfd+1, &readfds, NULL, NULL, NULL);
+ sigfillset(&blocked_mask);
+ sigprocmask(SIG_SETMASK, &blocked_mask, &orig_mask);
+ if (signal_received) {
+ sigprocmask(SIG_SETMASK, &orig_mask, NULL);
+ goto handle_signals;
+ }
+
+ ctrl_poll = &pfd[nfds++];
+ ctrl_poll->fd = udev_ctrl_get_fd(udev_ctrl);
+ ctrl_poll->events = POLLIN;
+
+ monitor_poll = &pfd[nfds++];
+ monitor_poll->fd = udev_monitor_get_fd(kernel_monitor);
+ monitor_poll->events = POLLIN;
+
+ if (inotify_fd >= 0) {
+ inotify_poll = &pfd[nfds++];
+ inotify_poll->fd = inotify_fd;
+ inotify_poll->events = POLLIN;
+ }
+
+ fdcount = ppoll(pfd, nfds, NULL, &orig_mask);
+ sigprocmask(SIG_SETMASK, &orig_mask, NULL);
if (fdcount < 0) {
- if (errno != EINTR)
- err(udev, "error in select: %m\n");
+ if (errno == EINTR)
+ goto handle_signals;
+ err(udev, "error in select: %m\n");
continue;
}
/* get control message */
- if (FD_ISSET(udev_ctrl_get_fd(udev_ctrl), &readfds))
+ if (ctrl_poll->revents & POLLIN)
handle_ctrl_msg(udev_ctrl);
/* get kernel uevent */
- if (FD_ISSET(udev_monitor_get_fd(kernel_monitor), &readfds)) {
+ if (monitor_poll->revents & POLLIN) {
struct udev_device *dev;
dev = udev_monitor_receive_device(kernel_monitor);
@@ -938,15 +931,8 @@ int main(int argc, char *argv[])
}
}
- /* received a signal, clear our notification pipe */
- if (FD_ISSET(signal_pipe[READ_END], &readfds)) {
- char buf[256];
-
- read(signal_pipe[READ_END], &buf, sizeof(buf));
- }
-
/* rules directory inotify watch */
- if ((inotify_fd >= 0) && FD_ISSET(inotify_fd, &readfds)) {
+ if (inotify_poll && (inotify_poll->revents & POLLIN)) {
int nbytes;
/* discard all possible events, we can just reload the config */
@@ -965,6 +951,9 @@ int main(int argc, char *argv[])
}
}
+handle_signals:
+ signal_received = 0;
+
/* rules changed, set by inotify or a HUP signal */
if (reload_config) {
struct udev_rules *rules_new;
@@ -992,10 +981,6 @@ int main(int argc, char *argv[])
rc = 0;
exit:
udev_rules_unref(rules);
- if (signal_pipe[READ_END] >= 0)
- close(signal_pipe[READ_END]);
- if (signal_pipe[WRITE_END] >= 0)
- close(signal_pipe[WRITE_END]);
udev_ctrl_unref(udev_ctrl);
if (inotify_fd >= 0)
close(inotify_fd);