/[soft]/ldetect/trunk/modalias.c
ViewVC logotype

Contents of /ldetect/trunk/modalias.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5820 - (show annotations) (download)
Wed Sep 12 10:37:40 2012 UTC (11 years, 6 months ago) by tv
File MIME type: text/plain
File size: 2832 byte(s)
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)
1 #define _GNU_SOURCE
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <sys/wait.h>
5 #include <sys/utsname.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <libkmod.h>
12 #include <dirent.h>
13 #include "common.h"
14
15 static char *aliasdefault = NULL;
16 static char * version = NULL;
17
18 static void get_version(void) {
19 if (version != NULL)
20 return;
21 struct utsname buf;
22 uname(&buf);
23 version = strdup(buf.release);
24 }
25
26
27 char *dirname, *dkms_file;
28
29 static void set_default_alias_file(void) {
30 struct utsname rel_buf;
31 if (!aliasdefault) {
32 char *dirname;
33 char *fallback_aliases = table_name_to_file("fallback-modules.alias");
34 char *aliasfilename;
35 struct stat st_alias, st_fallback;
36
37 uname(&rel_buf);
38 asprintf(&dirname, "%s/%s", "/lib/modules", rel_buf.release);
39 asprintf(&aliasfilename, "%s/modules.alias", dirname);
40 free(dirname);
41
42 /* fallback on ldetect-lst's modules.alias and prefer it if more recent */
43 if (stat(aliasfilename, &st_alias) ||
44 (!stat(fallback_aliases, &st_fallback) && st_fallback.st_mtime > st_alias.st_mtime)) {
45 free(aliasfilename);
46 aliasdefault = fallback_aliases;
47 } else {
48 aliasdefault = aliasfilename;
49 free(fallback_aliases);
50 }
51 }
52 }
53
54 struct kmod_ctx* modalias_init() {
55 struct kmod_ctx *ctx;
56
57 if (!aliasdefault)
58 set_default_alias_file();
59
60 get_version();
61
62 /* We only use canned aliases as last resort. */
63 dkms_file = table_name_to_file("dkms-modules.alias");
64 const char *alias_filelist[] = {
65 "/run/modprobe.d",
66 "/etc/modprobe.d",
67 "/lib/modprobe.d",
68 "/lib/module-init-tools/ldetect-lst-modules.alias",
69 aliasdefault,
70 dkms_file,
71 NULL,
72 };
73
74 /* Init libkmod */
75 ctx = kmod_new(dirname, alias_filelist);
76 if (!ctx) {
77 fputs("Error: kmod_new() failed!\n", stderr);
78 free(dkms_file);
79 kmod_unref(ctx);
80 ctx = NULL;
81 }
82 kmod_load_resources(ctx);
83 return ctx;
84 }
85
86 char *modalias_resolve_module(struct kmod_ctx *ctx, const char *modalias) {
87 struct kmod_list *l, *list = NULL;
88 char *str = NULL;
89 int err = kmod_module_new_from_lookup(ctx, modalias, &list);
90 if (err < 0)
91 goto exit;
92
93 // No module found...
94 if (list == NULL)
95 goto exit;
96
97 // filter through blacklist
98 struct kmod_list *filtered = NULL;
99 err = kmod_module_get_filtered_blacklist(ctx, list, &filtered);
100 kmod_module_unref_list(list);
101 if (err <0)
102 goto exit;
103 list = filtered;
104
105 kmod_list_foreach(l, list) {
106 struct kmod_module *mod = kmod_module_get_module(l);
107 //if (str) // keep last one
108 // free(str);
109 if (!str) // keep first one
110 str = strdup(kmod_module_get_name(mod));
111 kmod_module_unref(mod);
112 if (err < 0)
113 break;
114 }
115
116 kmod_module_unref_list(list);
117
118 exit:
119 return str;
120 }
121
122 void modalias_cleanup(struct kmod_ctx *ctx) {
123 ifree(aliasdefault);
124 ifree(version);
125 free(dkms_file);
126 kmod_unref(ctx);
127 }

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.30