diff options
author | Thierry Vignaud <tv@mageia.org> | 2012-09-12 10:37:40 +0000 |
---|---|---|
committer | Thierry Vignaud <tv@mageia.org> | 2012-09-12 10:37:40 +0000 |
commit | 54ef68f584de6f12defa217ecc61fcf395ecd7e2 (patch) | |
tree | 19a8bd7b24cdf96ff3b5d5e58369aa9e8f4c6a23 | |
parent | 42b81d579dc2f0323c6728e4d12002b1b8ed349b (diff) | |
download | ldetect-54ef68f584de6f12defa217ecc61fcf395ecd7e2.tar ldetect-54ef68f584de6f12defa217ecc61fcf395ecd7e2.tar.gz ldetect-54ef68f584de6f12defa217ecc61fcf395ecd7e2.tar.bz2 ldetect-54ef68f584de6f12defa217ecc61fcf395ecd7e2.tar.xz ldetect-54ef68f584de6f12defa217ecc61fcf395ecd7e2.zip |
make ldetect 3x faster (and even faster on machines quite quite a lot
of devices such as servers)
(modalias_init) split it out of modalias_resolve_module()
(modalias_cleanup) move libkmod related cleanups here
(hid_probe,find_modules_through_aliases) only initialize libkmod once
(which reduces user time from 0.26 to 0.08s & elapsed time from 0.28 to
0.9s)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | common.h | 5 | ||||
-rw-r--r-- | hid.c | 10 | ||||
-rw-r--r-- | modalias.c | 24 | ||||
-rw-r--r-- | pciusb.c | 24 |
5 files changed, 38 insertions, 27 deletions
@@ -1,3 +1,5 @@ +- make ldetect 3x faster + Version 0.12.2 - 30 August 2012, Thierry Vignaud - fix retrieving info about USB devices with kernel-3.5+ (mga#7248) @@ -19,8 +19,9 @@ 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; +extern struct kmod_ctx* modalias_init() NON_EXPORTED; +extern char *modalias_resolve_module(struct kmod_ctx *ctx, const char *modalias) NON_EXPORTED; +extern void modalias_cleanup(struct kmod_ctx *ctx) NON_EXPORTED; #define MAX_DEVICES 100 #define BUF_SIZE 512 @@ -4,6 +4,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <libkmod.h> #include "libsysfs.h" #include "libldetect.h" @@ -79,7 +80,7 @@ static void add_entry(struct hid_entries *entry_list, char *name, char *module) } } -static void parse_device(struct hid_entries *entries, const char *dev) +static void parse_device(struct kmod_ctx *ctx, struct hid_entries *entries, const char *dev) { char keyfile[SYSFS_PATH_MAX]; char *modalias; @@ -111,12 +112,11 @@ static void parse_device(struct hid_entries *entries, const char *dev) else device_name = strdup("HID Device"); - modname = modalias_resolve_module(modalias); + modname = modalias_resolve_module(ctx, modalias); free(modalias); DEBUG("%s: module name is [%s]\n", HID_BUS_NAME, modname); if (modname != NULL) add_entry(entries, device_name, modname); - modalias_cleanup(); } @@ -125,6 +125,7 @@ struct hid_entries hid_probe(void) DIR *dir; struct dirent *dent; struct hid_entries entry_list = {NULL, 0}; + struct kmod_ctx *ctx = modalias_init(); dir = opendir(sysfs_hid_path); if (dir == NULL) @@ -134,10 +135,11 @@ struct hid_entries hid_probe(void) if (dent->d_name[0] == '.') continue; DEBUG("%s: device found %s\n", HID_BUS_NAME, dent->d_name); - parse_device(&entry_list, dent->d_name); + parse_device(ctx, &entry_list, dent->d_name); } end_probe: + modalias_cleanup(ctx); if (dir) closedir(dir); @@ -24,7 +24,7 @@ static void get_version(void) { } -char*dirname; +char *dirname, *dkms_file; static void set_default_alias_file(void) { struct utsname rel_buf; @@ -51,11 +51,8 @@ static void set_default_alias_file(void) { } } -char *modalias_resolve_module(const char *modalias) { +struct kmod_ctx* modalias_init() { struct kmod_ctx *ctx; - struct kmod_list *l, *list = NULL; - int err; - char* dkms_file, *str = NULL; if (!aliasdefault) set_default_alias_file(); @@ -78,11 +75,18 @@ char *modalias_resolve_module(const char *modalias) { ctx = kmod_new(dirname, alias_filelist); if (!ctx) { fputs("Error: kmod_new() failed!\n", stderr); - goto exit; + free(dkms_file); + kmod_unref(ctx); + ctx = NULL; } kmod_load_resources(ctx); + return ctx; +} - err = kmod_module_new_from_lookup(ctx, modalias, &list); +char *modalias_resolve_module(struct kmod_ctx *ctx, const char *modalias) { + struct kmod_list *l, *list = NULL; + char *str = NULL; + int err = kmod_module_new_from_lookup(ctx, modalias, &list); if (err < 0) goto exit; @@ -112,12 +116,12 @@ char *modalias_resolve_module(const char *modalias) { kmod_module_unref_list(list); exit: - free(dkms_file); - kmod_unref(ctx); return str; } -void modalias_cleanup(void) { +void modalias_cleanup(struct kmod_ctx *ctx) { ifree(aliasdefault); ifree(version); + free(dkms_file); + kmod_unref(ctx); } @@ -9,9 +9,10 @@ #include <stdlib.h> #include <string.h> #include <dirent.h> +#include <libkmod.h> #include "common.h" -static void set_modules_from_modalias_file(struct pciusb_entry *e, char *modalias_path) { +static void set_modules_from_modalias_file(struct kmod_ctx *ctx, struct pciusb_entry *e, char *modalias_path) { FILE *file; file = fopen(modalias_path, "r"); if (file) { @@ -28,7 +29,7 @@ static void set_modules_from_modalias_file(struct pciusb_entry *e, char *modalia modalias[size-1] = 0; ifree(e->module); - e->module = modalias_resolve_module(modalias); + e->module = modalias_resolve_module(ctx, modalias); free(modalias); } else { fprintf(stderr, "Unable to read modalias from %s\n", modalias_path); @@ -36,16 +37,16 @@ static void set_modules_from_modalias_file(struct pciusb_entry *e, char *modalia } } -static void find_pci_modules_through_aliases(struct pciusb_entry *e) { +static void find_pci_modules_through_aliases(struct kmod_ctx *ctx, struct pciusb_entry *e) { char *modalias_path; asprintf(&modalias_path, "/sys/bus/pci/devices/%04x:%02x:%02x.%x/modalias", e->pci_domain, e->pci_bus, e->pci_device, e->pci_function); - set_modules_from_modalias_file(e, modalias_path); + set_modules_from_modalias_file(ctx, e, modalias_path); free(modalias_path); } -static void find_usb_modules_through_aliases(struct pciusb_entry *e) { +static void find_usb_modules_through_aliases(struct kmod_ctx *ctx, struct pciusb_entry *e) { char *usb_prefix, *sysfs_path; DIR *dir; struct dirent *dent; @@ -63,7 +64,7 @@ static void find_usb_modules_through_aliases(struct pciusb_entry *e) { !strncmp(usb_prefix, dent->d_name, strlen(usb_prefix))) { char *modalias_path; asprintf(&modalias_path, "%s/%s/modalias", sysfs_path, dent->d_name); - set_modules_from_modalias_file(e, modalias_path); + set_modules_from_modalias_file(ctx, e, modalias_path); free(modalias_path); /* maybe we would need a "other_modules" field in pciusb_entry to list modules from all USB interfaces */ @@ -77,26 +78,27 @@ end: free(usb_prefix); } -static void find_modules_through_aliases_one(const char *bus, struct pciusb_entry *e) { +static void find_modules_through_aliases_one(struct kmod_ctx *ctx, const char *bus, struct pciusb_entry *e) { if (!strcmp("pci", bus)) { - find_pci_modules_through_aliases(e); + find_pci_modules_through_aliases(ctx, e); } else if (!strcmp("usb", bus)) { - find_usb_modules_through_aliases(e); + find_usb_modules_through_aliases(ctx, e); } } static void find_modules_through_aliases(const char *bus, struct pciusb_entries *entries) { unsigned int i; + struct kmod_ctx *ctx = modalias_init(); for (i = 0; i < entries->nb; i++) { struct pciusb_entry *e = &entries->entries[i]; // No special case found in pcitable ? Then lookup modalias for PCI devices if (e->module && strcmp(e->module, "unknown")) continue; - find_modules_through_aliases_one(bus, e); + find_modules_through_aliases_one(ctx, bus, e); } - modalias_cleanup(); + modalias_cleanup(ctx); } extern int pciusb_find_modules(struct pciusb_entries *entries, const char *fpciusbtable, const descr_lookup descr_lookup, int is_pci) { |