Contents of /trunk/mkinitrd-magellan/busybox/modutils/lsmod.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 4665 byte(s)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 4665 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Mini lsmod implementation for busybox |
4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * |
7 | * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and |
8 | * Nicolas Ferre <nicolas.ferre@alcove.fr> to support pre 2.1 kernels |
9 | * (which lack the query_module() interface). |
10 | * |
11 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
12 | */ |
13 | |
14 | #include "busybox.h" |
15 | |
16 | |
17 | #ifndef CONFIG_FEATURE_CHECK_TAINTED_MODULE |
18 | static void check_tainted(void) { puts(""); } |
19 | #else |
20 | #define TAINT_FILENAME "/proc/sys/kernel/tainted" |
21 | #define TAINT_PROPRIETORY_MODULE (1<<0) |
22 | #define TAINT_FORCED_MODULE (1<<1) |
23 | #define TAINT_UNSAFE_SMP (1<<2) |
24 | |
25 | static void check_tainted(void) |
26 | { |
27 | int tainted; |
28 | FILE *f; |
29 | |
30 | tainted = 0; |
31 | if ((f = fopen(TAINT_FILENAME, "r"))) { |
32 | fscanf(f, "%d", &tainted); |
33 | fclose(f); |
34 | } |
35 | if (f && tainted) { |
36 | printf(" Tainted: %c%c%c\n", |
37 | tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', |
38 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', |
39 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); |
40 | } |
41 | else { |
42 | printf(" Not tainted\n"); |
43 | } |
44 | } |
45 | #endif |
46 | |
47 | #ifdef CONFIG_FEATURE_QUERY_MODULE_INTERFACE |
48 | |
49 | struct module_info |
50 | { |
51 | unsigned long addr; |
52 | unsigned long size; |
53 | unsigned long flags; |
54 | long usecount; |
55 | }; |
56 | |
57 | |
58 | int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret); |
59 | |
60 | enum { |
61 | /* Values for query_module's which. */ |
62 | QM_MODULES = 1, |
63 | QM_DEPS = 2, |
64 | QM_REFS = 3, |
65 | QM_SYMBOLS = 4, |
66 | QM_INFO = 5, |
67 | |
68 | /* Bits of module.flags. */ |
69 | NEW_MOD_RUNNING = 1, |
70 | NEW_MOD_DELETED = 2, |
71 | NEW_MOD_AUTOCLEAN = 4, |
72 | NEW_MOD_VISITED = 8, |
73 | NEW_MOD_USED_ONCE = 16, |
74 | NEW_MOD_INITIALIZING = 64 |
75 | }; |
76 | |
77 | int lsmod_main(int argc, char **argv) |
78 | { |
79 | struct module_info info; |
80 | char *module_names, *mn, *deps, *dn; |
81 | size_t bufsize, depsize, nmod, count, i, j; |
82 | |
83 | module_names = deps = NULL; |
84 | bufsize = depsize = 0; |
85 | while (query_module(NULL, QM_MODULES, module_names, bufsize, &nmod)) { |
86 | if (errno != ENOSPC) bb_perror_msg_and_die("QM_MODULES"); |
87 | module_names = xmalloc(bufsize = nmod); |
88 | } |
89 | |
90 | deps = xmalloc(depsize = 256); |
91 | printf("Module\t\t\tSize Used by"); |
92 | check_tainted(); |
93 | |
94 | for (i = 0, mn = module_names; i < nmod; mn += strlen(mn) + 1, i++) { |
95 | if (query_module(mn, QM_INFO, &info, sizeof(info), &count)) { |
96 | if (errno == ENOENT) { |
97 | /* The module was removed out from underneath us. */ |
98 | continue; |
99 | } |
100 | /* else choke */ |
101 | bb_perror_msg_and_die("module %s: QM_INFO", mn); |
102 | } |
103 | while (query_module(mn, QM_REFS, deps, depsize, &count)) { |
104 | if (errno == ENOENT) { |
105 | /* The module was removed out from underneath us. */ |
106 | continue; |
107 | } else if (errno != ENOSPC) |
108 | bb_perror_msg_and_die("module %s: QM_REFS", mn); |
109 | deps = xrealloc(deps, count); |
110 | } |
111 | printf("%-20s%8lu%4ld", mn, info.size, info.usecount); |
112 | if (info.flags & NEW_MOD_DELETED) |
113 | printf(" (deleted)"); |
114 | else if (info.flags & NEW_MOD_INITIALIZING) |
115 | printf(" (initializing)"); |
116 | else if (!(info.flags & NEW_MOD_RUNNING)) |
117 | printf(" (uninitialized)"); |
118 | else { |
119 | if (info.flags & NEW_MOD_AUTOCLEAN) |
120 | printf(" (autoclean) "); |
121 | if (!(info.flags & NEW_MOD_USED_ONCE)) |
122 | printf(" (unused)"); |
123 | } |
124 | if (count) printf(" ["); |
125 | for (j = 0, dn = deps; j < count; dn += strlen(dn) + 1, j++) { |
126 | printf("%s%s", dn, (j==count-1)? "":" "); |
127 | } |
128 | if (count) printf("]"); |
129 | |
130 | puts(""); |
131 | } |
132 | |
133 | #ifdef CONFIG_FEATURE_CLEAN_UP |
134 | free(module_names); |
135 | #endif |
136 | |
137 | return 0; |
138 | } |
139 | |
140 | #else /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */ |
141 | |
142 | int lsmod_main(int argc, char **argv) |
143 | { |
144 | FILE *file = xfopen("/proc/modules", "r"); |
145 | |
146 | printf("Module Size Used by"); |
147 | check_tainted(); |
148 | #if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT) |
149 | { |
150 | char *line; |
151 | while ((line = xmalloc_fgets(file)) != NULL) { |
152 | char *tok; |
153 | |
154 | tok = strtok(line, " \t"); |
155 | printf("%-19s", tok); |
156 | tok = strtok(NULL, " \t\n"); |
157 | printf(" %8s", tok); |
158 | tok = strtok(NULL, " \t\n"); |
159 | /* Null if no module unloading support. */ |
160 | if (tok) { |
161 | printf(" %s", tok); |
162 | tok = strtok(NULL, "\n"); |
163 | if (!tok) |
164 | tok = ""; |
165 | /* New-style has commas, or -. If so, |
166 | truncate (other fields might follow). */ |
167 | else if (strchr(tok, ',')) { |
168 | tok = strtok(tok, "\t "); |
169 | /* Strip trailing comma. */ |
170 | if (tok[strlen(tok)-1] == ',') |
171 | tok[strlen(tok)-1] = '\0'; |
172 | } else if (tok[0] == '-' |
173 | && (tok[1] == '\0' || isspace(tok[1]))) |
174 | tok = ""; |
175 | printf(" %s", tok); |
176 | } |
177 | puts(""); |
178 | free(line); |
179 | } |
180 | fclose(file); |
181 | } |
182 | #else |
183 | xprint_and_close_file(file); |
184 | #endif /* CONFIG_FEATURE_2_6_MODULES */ |
185 | return EXIT_SUCCESS; |
186 | } |
187 | |
188 | #endif /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */ |