summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-07-06 11:22:07 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2015-07-06 11:22:07 +0200
commit220dac758391cdc650e2dd9bdc259e950fcb3955 (patch)
tree4cf4ad5e4b687d7800da7d74138e045c004e6c64
parente53d75aedebbeb6ec739a575c23bcde1c899a82a (diff)
downloadnlplug-220dac758391cdc650e2dd9bdc259e950fcb3955.tar.bz2
nlplug-220dac758391cdc650e2dd9bdc259e950fcb3955.tar.xz
nlplug: refactor to reduce forks
- prepare for loading modaliases with libkmod - only fork/exec when there is a DEVNAME
-rw-r--r--Makefile11
-rw-r--r--nlplug.c110
2 files changed, 78 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index bbd1213..67347f5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CFLAGS ?= -Wall -Werror -g
-CFLAGS += -D_GNU_SOURCE
+CFLAGS += -D_GNU_SOURCE -DDEBUG
nlsockd_SRCS = nlsockd.c
nlsockd_OBJS = $(nlsockd_SRCS:%.c=%.o)
@@ -8,14 +8,17 @@ nlsockd_OBJS = $(nlsockd_SRCS:%.c=%.o)
nlplug_SRCS = nlplug.c
nlplug_OBJS = $(nlplug_SRCS:%.c=%.o)
-all: nlsockd nlplug
+handler_SRCS = handler.c
+handler_OBJS = $(handler_SRCS:%.c=%.o)
-nlsockd: $(nlsockd_OBJS)
+all: nlsockd nlplug handler
+nlsockd: $(nlsockd_OBJS)
nlplug: $(nlplug_OBJS)
+handler: $(handler_OBJS)
-nlsockd nlplug:
+handler nlsockd nlplug:
$(CC) -o $@ $(CFLAGS) $($@_CFLAGS) $($@_OBJS) $(LDFLAGS) $($@_LDFLAGS)
clean:
diff --git a/nlplug.c b/nlplug.c
index ed3dbcd..d8212fb 100644
--- a/nlplug.c
+++ b/nlplug.c
@@ -9,6 +9,7 @@
#include <err.h>
#include <errno.h>
#include <poll.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -44,13 +45,15 @@ dbg(char *fmt, ...)
#define dbg(...)
#endif
+static int fork_count = 0, modalias_count = 0, event_count = 0;
+
void
run_child(char **argv)
{
pid_t pid;
if (!(pid = fork())) {
- dbg("running %s", runpath);
+ dbg("running %s", argv[0]);
if (execv(argv[0], argv) < 0)
err(1, argv[0]);
exit(0);
@@ -59,8 +62,70 @@ run_child(char **argv)
err(1,"fork");
waitpid(pid, NULL, 0);
+ fork_count++;
}
+int process_kbuf(char *buf, const size_t len, char **argv, const char *subsys)
+{
+ char *modalias = NULL;
+
+ int i, slen = 0;
+ char *key, *value;
+
+ clearenv();
+ setenv("PATH", "/sbin:/bin", 1);
+
+ for (i = 0; i < len; i += slen + 1) {
+
+ key = buf + i;
+ value = strchr(key, '=');
+ slen = strlen(buf+i);
+
+ if (!slen) {
+ dbg("=== empty string ===");
+ continue;
+ }
+
+ if (value == NULL) {
+ dbg("=== uevent: '%s'", key);
+ continue;
+ }
+
+ if (subsys && !strncmp(key, "SUBSYSTEM=", 10)
+ && !strstr(key+10, subsys)) {
+ dbg("subsystem filter '%s' applied.", subsys);
+ break;
+ }
+
+ value[0] = '\0';
+ value++;
+
+ if (!strncmp(key, "MODALIAS", 9))
+ modalias = value;
+
+ /*
+ * We generally trust the kernel. But there
+ * might be some udev flaw. (It's >20k sloc!)
+ */
+ if (strcmp(key, "PATH")) {
+ setenv(key, value, 1);
+ dbg("%s = \"%s\"", key, value);
+ }
+ }
+ if (getenv("ACTION") != NULL) {
+ if (modalias != NULL)
+ dbg("MODALIAS: %s", modalias);
+ else if (getenv("DEVNAME") != NULL) {
+ run_child(argv);
+/*
+ else if(getenv("DEVPATH") != NULL &&
+ getenv("SUBSYSTEM") != NULL &&
+ getenv("SEQNUM") != NULL) {
+*/
+ }
+ }
+ return modalias != NULL ? 1 : 0;
+}
void
usage(void)
@@ -103,8 +168,6 @@ int main(int argc, char *argv[])
fds.events = POLLIN;
while ((r = poll(&fds, 1, EVENT_TIMEOUT)) > 0) {
size_t len;
- int i, slen;
- char *key, *value;
struct iovec iov;
char cbuf[CMSG_SPACE(sizeof(struct ucred))];
char buf[16384];
@@ -113,9 +176,6 @@ int main(int argc, char *argv[])
struct msghdr hdr;
struct sockaddr_nl cnls;
- clearenv();
- setenv("PATH", "/sbin:/bin", 1);
-
if (!(fds.revents & POLLIN))
continue;
@@ -170,39 +230,9 @@ int main(int argc, char *argv[])
continue;
}
- for (i = 0; i < len; i += slen + 1) {
- key = buf + i;
- value = strchr(key, '=');
- slen = strlen(buf+i);
-
- if (!slen || value == NULL)
- continue;
- if (subsystem && !strncmp(key, "SUBSYSTEM=", 10)
- && !strstr(key+10, subsystem)) {
- dbg("subsystem filter '%s' applied.",
- subsystem);
- break;
- }
-
- value[0] = '\0';
- value++;
-
- /*
- * We generally trust the kernel. But there
- * might be some udev flaw. (It's >20k sloc!)
- */
- if (strcmp(key, "PATH")) {
- setenv(key, value, 1);
- dbg("%s = \"%s\"", key, value);
- }
- }
- if (getenv("ACTION") != NULL &&
- getenv("DEVPATH") != NULL &&
- getenv("SUBSYSTEM") != NULL &&
- getenv("SEQNUM") != NULL) {
- run_child(argv);
- }
-
+ modalias_count += process_kbuf(buf, len, argv, subsystem);
+ event_count++;
+ dbg("-------------------------\n");
if (fds.revents & POLLHUP) {
dbg("parent hung up\n");
return 0;
@@ -213,6 +243,8 @@ int main(int argc, char *argv[])
if (r == 0)
dbg("exit due to timeout");
+ dbg("modaliases: %i, forks: %i, events: %i", modalias_count, fork_count,
+ event_count);
return 0;
}