summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-07-27 11:45:21 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2015-07-27 11:45:21 +0200
commit327add8c702edd5515b79fbfc29d9ef0b07084f4 (patch)
treeab5f9b0917494a65a3d68b028cc8203bfcb262c9
parent220dac758391cdc650e2dd9bdc259e950fcb3955 (diff)
downloadnlplug-327add8c702edd5515b79fbfc29d9ef0b07084f4.tar.bz2
nlplug-327add8c702edd5515b79fbfc29d9ef0b07084f4.tar.xz
nlplug: use libkmod to load modules
-rw-r--r--Makefile8
-rw-r--r--nlplug.c73
2 files changed, 67 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 67347f5..afc06cb 100644
--- a/Makefile
+++ b/Makefile
@@ -2,11 +2,17 @@
CFLAGS ?= -Wall -Werror -g
CFLAGS += -D_GNU_SOURCE -DDEBUG
+PKGCONFIG ?= pkg-config
+LIBKMOD_CFLAGS := $(shell $(PKGCONFIG) --cflags libkmod)
+LIBKMOD_LIBS := $(shell $(PKGCONFIG) --libs libkmod)
+
nlsockd_SRCS = nlsockd.c
nlsockd_OBJS = $(nlsockd_SRCS:%.c=%.o)
nlplug_SRCS = nlplug.c
nlplug_OBJS = $(nlplug_SRCS:%.c=%.o)
+nlplug_CFLAGS = $(LIBKMOD_CFLAGS)
+nlplug_LIBS = $(LIBKMOD_LIBS)
handler_SRCS = handler.c
handler_OBJS = $(handler_SRCS:%.c=%.o)
@@ -19,7 +25,7 @@ handler: $(handler_OBJS)
handler nlsockd nlplug:
- $(CC) -o $@ $(CFLAGS) $($@_CFLAGS) $($@_OBJS) $(LDFLAGS) $($@_LDFLAGS)
+ $(CC) -o $@ $(CFLAGS) $($@_CFLAGS) $($@_OBJS) $(LDFLAGS) $($@_LIBS)
clean:
rm -f nlplug nlsockd
diff --git a/nlplug.c b/nlplug.c
index d8212fb..fda8a84 100644
--- a/nlplug.c
+++ b/nlplug.c
@@ -21,6 +21,8 @@
#include <linux/netlink.h>
+#include <libkmod.h>
+
#include "arg.h"
#define EVENT_TIMEOUT 2000
@@ -31,7 +33,7 @@ char *argv0;
#if defined(DEBUG)
#include <stdarg.h>
void
-dbg(char *fmt, ...)
+dbg(const char *fmt, ...)
{
va_list fmtargs;
@@ -65,9 +67,56 @@ run_child(char **argv)
fork_count++;
}
+
+int load_kmod(const char *modalias)
+{
+ static struct kmod_ctx *ctx = NULL;
+ struct kmod_list *list = NULL;
+ struct kmod_list *node;
+ int r, count=0;
+
+ dbg("loading alias '%s'", modalias);
+
+ if (ctx == NULL) {
+ dbg("initializing kmod");
+ ctx = kmod_new("/", NULL);
+ if (ctx == NULL)
+ return -1;
+ kmod_set_log_fn(ctx, NULL, NULL);
+ r = kmod_load_resources(ctx);
+ dbg("load kmod resources: %i", r);
+ }
+
+ r = kmod_module_new_from_lookup(ctx, modalias, &list);
+ if (r < 0) {
+ dbg("alias '%s' lookup failure", modalias);
+ return r;
+ }
+
+ kmod_list_foreach(node, list) {
+ struct kmod_module *mod = kmod_module_get_module(node);
+ const char *fmt;
+ r = kmod_module_probe_insert_module(mod,
+ KMOD_PROBE_APPLY_BLACKLIST,
+ NULL, NULL, NULL, NULL);
+ if (r == 0) {
+ fmt = "module '%s' inserted";
+ count++;
+ } else if (r == KMOD_PROBE_APPLY_BLACKLIST) {
+ fmt = "module '%s' is blacklisted";
+ } else {
+ fmt = "module '%s' failed";
+ }
+ dbg(fmt, kmod_module_get_name(mod));
+ kmod_module_unref(mod);
+ }
+ kmod_module_unref_list(list);
+ return count;
+}
+
int process_kbuf(char *buf, const size_t len, char **argv, const char *subsys)
{
- char *modalias = NULL;
+ char *modalias = NULL, *action = NULL;
int i, slen = 0;
char *key, *value;
@@ -91,7 +140,7 @@ int process_kbuf(char *buf, const size_t len, char **argv, const char *subsys)
continue;
}
- if (subsys && !strncmp(key, "SUBSYSTEM=", 10)
+ if (subsys && strncmp(key, "SUBSYSTEM=", 10) == 0
&& !strstr(key+10, subsys)) {
dbg("subsystem filter '%s' applied.", subsys);
break;
@@ -100,8 +149,11 @@ int process_kbuf(char *buf, const size_t len, char **argv, const char *subsys)
value[0] = '\0';
value++;
- if (!strncmp(key, "MODALIAS", 9))
+ if (strncmp(key, "MODALIAS", 9) == 0) {
modalias = value;
+ } else if (strncmp(key, "ACTION", 6) == 0) {
+ action = value;
+ }
/*
* We generally trust the kernel. But there
@@ -112,16 +164,11 @@ int process_kbuf(char *buf, const size_t len, char **argv, const char *subsys)
dbg("%s = \"%s\"", key, value);
}
}
- if (getenv("ACTION") != NULL) {
- if (modalias != NULL)
- dbg("MODALIAS: %s", modalias);
- else if (getenv("DEVNAME") != NULL) {
+ if (action != NULL) {
+ if (modalias != NULL && strncmp(action, "add", 3) == 0) {
+ load_kmod(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;