diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | common.h | 2 | ||||
-rw-r--r-- | modalias.c | 87 | ||||
-rw-r--r-- | pciusb.c | 73 |
4 files changed, 93 insertions, 71 deletions
@@ -9,7 +9,7 @@ libdir = $(prefix)/lib includedir = $(prefix)/include binaries = lspcidrake -lib_objs = common.o pciusb.o pci.o usb.o pciclass.o usbclass.o dmi.o +lib_objs = common.o modalias.o pciusb.o pci.o usb.o pciclass.o usbclass.o dmi.o lib_major = libldetect.so.$(LIB_MAJOR) libraries = libldetect.so $(lib_major) $(lib_major).$(LIB_MINOR) libldetect.a CFLAGS = -Wall -W -Wstrict-prototypes -Os -fPIC -fvisibility=hidden @@ -19,6 +19,8 @@ typedef enum { extern int pciusb_find_modules(struct pciusb_entries *entries, const char *fpciusbtable, const descr_lookup, int is_pci) NON_EXPORTED; extern void pciusb_initialize(struct pciusb_entry *e) NON_EXPORTED; +extern char *modalias_resolve_module(const char *modalias) NON_EXPORTED; +extern void modalias_cleanup(void) NON_EXPORTED; #define MAX_DEVICES 100 #define BUF_SIZE 512 diff --git a/modalias.c b/modalias.c new file mode 100644 index 0000000..6df02f0 --- /dev/null +++ b/modalias.c @@ -0,0 +1,87 @@ +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/utsname.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <modprobe.h> +#include <dirent.h> +#include "common.h" + +static char *aliasdefault = NULL; + +static void set_default_alias_file(void) { + struct utsname rel_buf; + if (!aliasdefault) { + char *dirname; + char *fallback_aliases = table_name_to_file("fallback-modules.alias"); + char *aliasfilename; + struct stat st_alias, st_fallback; + + uname(&rel_buf); + asprintf(&dirname, "%s/%s", MODULE_DIR, rel_buf.release); + asprintf(&aliasfilename, "%s/modules.alias", dirname); + free(dirname); + + /* fallback on ldetect-lst's modules.alias and prefer it if more recent */ + if (stat(aliasfilename, &st_alias) || + (!stat(fallback_aliases, &st_fallback) && st_fallback.st_mtime > st_alias.st_mtime)) { + free(aliasfilename); + aliasdefault = fallback_aliases; + } else { + aliasdefault = aliasfilename; + } + } +} + +char *modalias_resolve_module(const char *modalias) { + struct module_command *commands = NULL; + struct module_options *modoptions = NULL; + struct module_alias *aliases = NULL; + struct module_blacklist *blacklist = NULL; + const char *config = NULL; + + if (!aliasdefault) + set_default_alias_file(); + + /* Returns the resolved alias, options */ + read_toplevel_config(config, modalias, 0, + 0, &modoptions, &commands, &aliases, &blacklist); + + if (!aliases) { + /* We only use canned aliases as last resort. */ + char *dkms_file = table_name_to_file("dkms-modules.alias"); + char *alias_filelist[] = { + "/lib/module-init-tools/ldetect-lst-modules.alias", + aliasdefault, + dkms_file, + NULL, + }; + char **alias_file = alias_filelist; + while (!aliases && *alias_file) { + read_config(*alias_file, modalias, 0, + 0, &modoptions, &commands, + &aliases, &blacklist); + aliases = apply_blacklist(aliases, blacklist); + alias_file++; + } + free(dkms_file); + } + if (aliases) { + // take the last one because we find eg: generic/ata_generic/sata_sil + while (aliases->next) + aliases = aliases->next; + + return strdup(aliases->module); + } + + return NULL; +} + +void modalias_cleanup(void) { + ifree(aliasdefault); +} @@ -12,72 +12,6 @@ #include <dirent.h> #include "common.h" -static char *aliasdefault = NULL; - -static void set_default_alias_file(void) { - struct utsname rel_buf; - if (!aliasdefault) { - char *dirname; - char *fallback_aliases = table_name_to_file("fallback-modules.alias"); - char *aliasfilename; - struct stat st_alias, st_fallback; - - uname(&rel_buf); - asprintf(&dirname, "%s/%s", MODULE_DIR, rel_buf.release); - asprintf(&aliasfilename, "%s/modules.alias", dirname); - free(dirname); - - /* fallback on ldetect-lst's modules.alias and prefer it if more recent */ - if (stat(aliasfilename, &st_alias) || - (!stat(fallback_aliases, &st_fallback) && st_fallback.st_mtime > st_alias.st_mtime)) { - free(aliasfilename); - aliasdefault = fallback_aliases; - } else { - aliasdefault = aliasfilename; - } - } -} - -static void resolve_and_set_modules_from_modalias(struct pciusb_entry *e, char *modalias) { - struct module_command *commands = NULL; - struct module_options *modoptions = NULL; - struct module_alias *aliases = NULL; - struct module_blacklist *blacklist = NULL; - const char *config = NULL; - - /* Returns the resolved alias, options */ - read_toplevel_config(config, modalias, 0, - 0, &modoptions, &commands, &aliases, &blacklist); - - if (!aliases) { - /* We only use canned aliases as last resort. */ - char *dkms_file = table_name_to_file("dkms-modules.alias"); - char *alias_filelist[] = { - "/lib/module-init-tools/ldetect-lst-modules.alias", - aliasdefault, - dkms_file, - NULL, - }; - char **alias_file = alias_filelist; - while (!aliases && *alias_file) { - read_config(*alias_file, modalias, 0, - 0, &modoptions, &commands, - &aliases, &blacklist); - aliases = apply_blacklist(aliases, blacklist); - alias_file++; - } - free(dkms_file); - } - if (aliases) { - // take the last one because we find eg: generic/ata_generic/sata_sil - while (aliases->next) - aliases = aliases->next; - - ifree(e->module); - e->module = strdup(aliases->module); - } -} - static void set_modules_from_modalias_file(struct pciusb_entry *e, char *modalias_path) { FILE *file; file = fopen(modalias_path, "r"); @@ -94,7 +28,8 @@ static void set_modules_from_modalias_file(struct pciusb_entry *e, char *modalia if (size) modalias[size-1] = 0; - resolve_and_set_modules_from_modalias(e, modalias); + ifree(e->module); + e->module = modalias_resolve_module(modalias); free(modalias); } else { fprintf(stderr, "Unable to read modalias from %s\n", modalias_path); @@ -152,8 +87,6 @@ static void find_modules_through_aliases_one(const char *bus, struct pciusb_entr } static void find_modules_through_aliases(const char *bus, struct pciusb_entries *entries) { - set_default_alias_file(); - unsigned int i; for (i = 0; i < entries->nb; i++) { struct pciusb_entry *e = &entries->entries[i]; @@ -164,7 +97,7 @@ static void find_modules_through_aliases(const char *bus, struct pciusb_entries find_modules_through_aliases_one(bus, e); } - ifree(aliasdefault); + modalias_cleanup(); } extern int pciusb_find_modules(struct pciusb_entries *entries, const char *fpciusbtable, const descr_lookup descr_lookup, int is_pci) { |