From: Lucas De Marchi Date: Wed, 14 Dec 2011 19:19:19 +0000 (-0200) Subject: kmod_config: parse kernel command line for options and blacklist X-Git-Tag: v1~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8;p=platform%2Fupstream%2Fkmod.git kmod_config: parse kernel command line for options and blacklist --- diff --git a/TODO b/TODO index 28b4fcd..4d85327 100644 --- a/TODO +++ b/TODO @@ -25,8 +25,6 @@ Features: * Implement soft dependencies -* Parse kernel command line (modname.opt=val) - * provide 1:1 compatibility with module-init-tools's modprobe - show modversions (needs elf manipulation) - dump configuration diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c index 44fad72..d36f17f 100644 --- a/libkmod/libkmod-config.c +++ b/libkmod/libkmod-config.c @@ -242,6 +242,67 @@ static void kmod_config_free_blacklist(struct kmod_config *config, config->blacklists = kmod_list_remove(l); } +static void kcmdline_parse_result(struct kmod_config *config, char *modname, + char *param, char *value) +{ + if (modname == NULL || param == NULL || value == NULL) + return; + + DBG(config->ctx, "%s %s\n", modname, param); + + if (streq(modname, "modprobe") && !strncmp(param, "blacklist=", 10)) { + for (;;) { + char *t = strsep(&value, ","); + if (t == NULL) + break; + + kmod_config_add_blacklist(config, t); + } + } else { + kmod_config_add_options(config, + underscores(config->ctx, modname), param); + } +} + +static int kmod_config_parse_kcmdline(struct kmod_config *config) +{ + char buf[KCMD_LINE_SIZE]; + int fd, err; + char *p, *modname, *param = NULL, *value = NULL; + + fd = open("/proc/cmdline", O_RDONLY); + err = read_str_safe(fd, buf, sizeof(buf)); + close(fd); + if (err < 0) { + ERR(config->ctx, "could not read from '/proc/cmdline': %s\n", + strerror(-err)); + return err; + } + + for (p = buf, modname = buf; *p != '\0' && *p != '\n'; p++) { + switch (*p) { + case ' ': + *p = '\0'; + kcmdline_parse_result(config, modname, param, value); + param = value = NULL; + modname = p + 1; + break; + case '.': + *p = '\0'; + param = p + 1; + break; + case '=': + value = p + 1; + break; + } + } + + *p = '\0'; + kcmdline_parse_result(config, modname, param, value); + + return 0; +} + /* * Take an fd and own it. It will be closed on return. filename is used only * for debug messages @@ -513,5 +574,7 @@ int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **p_config, closedir(d); } + kmod_config_parse_kcmdline(config); + return 0; } diff --git a/libkmod/libkmod-private.h b/libkmod/libkmod-private.h index c22e805..6c6abca 100644 --- a/libkmod/libkmod-private.h +++ b/libkmod/libkmod-private.h @@ -34,6 +34,8 @@ static __always_inline __printf_format(2, 3) void #define KMOD_EXPORT __attribute__ ((visibility("default"))) +#define KCMD_LINE_SIZE 4096 + void kmod_log(const struct kmod_ctx *ctx, int priority, const char *file, int line, const char *fn, const char *format, ...) __attribute__((format(printf, 6, 7))) __attribute__((nonnull(1, 3, 5)));