diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-07-27 11:45:21 +0200 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-07-27 11:45:21 +0200 |
commit | 327add8c702edd5515b79fbfc29d9ef0b07084f4 (patch) | |
tree | ab5f9b0917494a65a3d68b028cc8203bfcb262c9 | |
parent | 220dac758391cdc650e2dd9bdc259e950fcb3955 (diff) | |
download | nlplug-327add8c702edd5515b79fbfc29d9ef0b07084f4.tar.bz2 nlplug-327add8c702edd5515b79fbfc29d9ef0b07084f4.tar.xz |
nlplug: use libkmod to load modules
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | nlplug.c | 73 |
2 files changed, 67 insertions, 14 deletions
@@ -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 @@ -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; |