summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Vignaud <tv@mageia.org>2012-12-12 10:12:16 +0000
committerThierry Vignaud <tv@mageia.org>2012-12-12 10:12:16 +0000
commitee5d3e43c585a4386ded58d76fac2ef0985d96b5 (patch)
treea6f59fa82673a7982238405197ec652de498c529
parent52c9d46227efeb02415c202866d38b4fc458d572 (diff)
downloadldetect-ee5d3e43c585a4386ded58d76fac2ef0985d96b5.tar
ldetect-ee5d3e43c585a4386ded58d76fac2ef0985d96b5.tar.gz
ldetect-ee5d3e43c585a4386ded58d76fac2ef0985d96b5.tar.bz2
ldetect-ee5d3e43c585a4386ded58d76fac2ef0985d96b5.tar.xz
ldetect-ee5d3e43c585a4386ded58d76fac2ef0985d96b5.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) (backported from trunk)
-rw-r--r--NEWS2
-rw-r--r--common.h5
-rw-r--r--hid.c10
-rw-r--r--modalias.c24
-rw-r--r--pciusb.c24
5 files changed, 38 insertions, 27 deletions
diff --git a/NEWS b/NEWS
index 8631071..e659629 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+- make ldetect 3x faster
+
Version 0.12.1 - 19 January 2012, Thierry Vignaud
- do not ignore /etc/modprobe.d/*
diff --git a/common.h b/common.h
index e6f927d..cf99de2 100644
--- a/common.h
+++ b/common.h
@@ -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
diff --git a/hid.c b/hid.c
index 5671a66..b9b5c9d 100644
--- a/hid.c
+++ b/hid.c
@@ -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);
diff --git a/modalias.c b/modalias.c
index a5b12e2..029617e 100644
--- a/modalias.c
+++ b/modalias.c
@@ -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);
}
diff --git a/pciusb.c b/pciusb.c
index 9f7f4d5..350b092 100644
--- a/pciusb.c
+++ b/pciusb.c
@@ -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) {