aboutsummaryrefslogtreecommitdiff
path: root/modutils/modprobe.c
diff options
context:
space:
mode:
authorRobert Griebl <griebl@gmx.de>2002-05-14 23:42:08 +0000
committerRobert Griebl <griebl@gmx.de>2002-05-14 23:42:08 +0000
commit52e8d060a95877d3070c18e3bf05f3fe8854357f (patch)
tree96492d3e3eeb644c9df45220d16616c2fbc3325c /modutils/modprobe.c
parentd77601178d9c9f5084e3842d0156dc4723592e44 (diff)
downloadbusybox-w32-52e8d060a95877d3070c18e3bf05f3fe8854357f.tar.gz
busybox-w32-52e8d060a95877d3070c18e3bf05f3fe8854357f.tar.bz2
busybox-w32-52e8d060a95877d3070c18e3bf05f3fe8854357f.zip
Complete rewrite to support stack loading/unloading with proper
handling of duplicates in the dependencies list.
Diffstat (limited to 'modutils/modprobe.c')
-rw-r--r--modutils/modprobe.c239
1 files changed, 145 insertions, 94 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 2f797ec4a..b13b9b04f 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -3,11 +3,12 @@
3 * really dumb modprobe implementation for busybox 3 * really dumb modprobe implementation for busybox
4 * Copyright (C) 2001 Lineo, davidm@lineo.com 4 * Copyright (C) 2001 Lineo, davidm@lineo.com
5 * 5 *
6 * CONFIG_MODPROBE_DEPEND stuff was added and is 6 * dependency specific stuff completly rewritten and
7 * Copyright (C) 2002 Robert Griebl, griebl@gmx.de 7 * copyright (c) 2002 by Robert Griebl, griebl@gmx.de
8 * 8 *
9 */ 9 */
10 10
11#include <sys/utsname.h>
11#include <stdio.h> 12#include <stdio.h>
12#include <getopt.h> 13#include <getopt.h>
13#include <stdlib.h> 14#include <stdlib.h>
@@ -17,22 +18,27 @@
17#include <ctype.h> 18#include <ctype.h>
18#include "busybox.h" 19#include "busybox.h"
19 20
20static char cmd[128];
21
22#define CONFIG_MODPROBE_DEPEND
23 21
24#ifdef CONFIG_MODPROBE_DEPEND
25
26#include <sys/utsname.h>
27 22
28struct dep_t { 23struct dep_t {
29 char * m_module; 24 char * m_module;
25
30 int m_depcnt; 26 int m_depcnt;
31 char ** m_deparr; 27 char ** m_deparr;
32 28
33 struct dep_t * m_next; 29 struct dep_t * m_next;
34}; 30};
35 31
32struct mod_list_t {
33 char * m_module;
34
35 struct mod_list_t * m_prev;
36 struct mod_list_t * m_next;
37};
38
39
40static struct dep_t *depend = 0;
41
36 42
37static struct dep_t *build_dep ( void ) 43static struct dep_t *build_dep ( void )
38{ 44{
@@ -99,7 +105,7 @@ static struct dep_t *build_dep ( void )
99 current-> m_module = mod; 105 current-> m_module = mod;
100 current-> m_depcnt = 0; 106 current-> m_depcnt = 0;
101 current-> m_deparr = 0; 107 current-> m_deparr = 0;
102 current-> m_next = 0; 108 current-> m_next = 0;
103 109
104 //printf ( "%s:\n", mod ); 110 //printf ( "%s:\n", mod );
105 111
@@ -154,70 +160,142 @@ static struct dep_t *build_dep ( void )
154} 160}
155 161
156 162
157static struct dep_t *find_dep ( struct dep_t *dt, char *mod ) 163static int mod_process ( struct mod_list_t *list, int do_insert, int autoclean, int quiet, int do_syslog, int show_only, int verbose )
158{ 164{
159 int lm = xstrlen ( mod ); 165 char lcmd [256];
160 int extpos = 0; 166 int rc = 0;
161 167
168 if ( !list )
169 return 1;
170
171 while ( list ) {
172 if ( do_insert )
173 snprintf ( lcmd, sizeof( lcmd ) - 1, "insmod %s %s %s %s 2>/dev/null", do_syslog ? "-s" : "", autoclean ? "-k" : "", quiet ? "-q" : "", list-> m_module );
174 else
175 snprintf ( lcmd, sizeof( lcmd ) - 1, "rmmod %s %s 2>/dev/null", do_syslog ? "-s" : "", list-> m_module );
176
177 if ( verbose )
178 printf ( "%s\n", lcmd );
179 if ( !show_only )
180 rc |= system ( lcmd );
181
182 list = do_insert ? list-> m_prev : list-> m_next;
183 }
184 return rc;
185}
186
187static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t **tail )
188{
189 struct mod_list_t *find;
190 struct dep_t *dt;
191
192 int lm;
193
194 // remove .o extension
195 lm = xstrlen ( mod );
162 if (( mod [lm-2] == '.' ) && ( mod [lm-1] == 'o' )) 196 if (( mod [lm-2] == '.' ) && ( mod [lm-1] == 'o' ))
163 extpos = 2; 197 mod [lm-2] = 0;
164 198
165 if ( extpos > 0 ) 199 //printf ( "check_dep: %s\n", mod );
166 mod [lm - extpos] = 0;
167 200
168 while ( dt ) { 201 // search for duplicates
169 if ( !strcmp ( dt-> m_module, mod )) 202 for ( find = *head; find; find = find-> m_next ) {
170 break; 203 if ( !strcmp ( mod, find-> m_module )) {
204 // found -> dequeue it
205
206 if ( find-> m_prev )
207 find-> m_prev-> m_next = find-> m_next;
208 else
209 *head = find-> m_next;
210
211 if ( find-> m_next )
212 find-> m_next-> m_prev = find-> m_prev;
213 else
214 *tail = find-> m_prev;
215
216 //printf ( "DUP\n" );
217
218 break; // there can be only one duplicate
219 }
220 }
171 221
172 dt = dt-> m_next; 222 if ( !find ) { // did not find a duplicate
223 find = (struct mod_list_t *) xmalloc ( sizeof(struct mod_list_t));
224 find-> m_module = mod;
173 } 225 }
174 if ( extpos > 0 )
175 mod [lm - extpos] = '.';
176 226
177 return dt; 227 // enqueue at tail
228 if ( *tail )
229 (*tail)-> m_next = find;
230 find-> m_prev = *tail;
231 find-> m_next = 0;
232
233 if ( !*head )
234 *head = find;
235 *tail = find;
236
237 // check dependencies
238 for ( dt = depend; dt; dt = dt-> m_next ) {
239 if ( !strcmp ( dt-> m_module, mod )) {
240 int i;
241
242 for ( i = 0; i < dt-> m_depcnt; i++ )
243 check_dep ( dt-> m_deparr [i], head, tail );
244 }
245 }
178} 246}
179 247
180#define MODPROBE_EXECUTE 0x1
181#define MODPROBE_INSERT 0x2
182#define MODPROBE_REMOVE 0x4
183 248
184static void check_dep ( char *mod, int do_syslog, 249
185 int show_only, int verbose, int flags ) 250static int mod_insert ( char *mod, int argc, char **argv, int autoclean, int quiet, int do_syslog, int show_only, int verbose )
186{ 251{
187 static struct dep_t *depend = (struct dep_t *) -1; 252 struct mod_list_t *tail = 0;
188 struct dep_t *dt; 253 struct mod_list_t *head = 0;
254 int rc = 0;
189 255
190 if ( depend == (struct dep_t *) -1 ) 256 // get dep list for module mod
191 depend = build_dep ( ); 257 check_dep ( mod, &head, &tail );
192 258
193 if (( dt = find_dep ( depend, mod ))) { 259 if ( head && tail ) {
194 int i; 260 int i;
195 261
196 for ( i = 0; i < dt-> m_depcnt; i++ ) 262 // append module args
197 check_dep ( dt-> m_deparr [i], do_syslog, 263 head-> m_module = xmalloc ( 256 );
198 show_only, verbose, flags|MODPROBE_EXECUTE); 264 strcpy ( head-> m_module, mod );
199 } 265
200 if ( flags & MODPROBE_EXECUTE ) { 266 for ( i = 0; i < argc; i++ ) {
201 char lcmd [256]; 267 strcat ( head-> m_module, " " );
202 if ( flags & MODPROBE_INSERT ) { 268 strcat ( head-> m_module, argv [i] );
203 snprintf(lcmd, sizeof(lcmd)-1, "insmod %s -q -k %s 2>/dev/null",
204 do_syslog ? "-s" : "", mod );
205 }
206 if ( flags & MODPROBE_REMOVE ) {
207 snprintf(lcmd, sizeof(lcmd)-1, "insmod %s -q -k %s 2>/dev/null",
208 do_syslog ? "-s" : "", mod );
209 }
210 if ( flags & (MODPROBE_REMOVE|MODPROBE_INSERT) ) {
211 if (verbose)
212 printf("%s\n", lcmd);
213 if (!show_only)
214 system ( lcmd );
215 } 269 }
270
271 // process tail ---> head
272 rc |= mod_process ( tail, 1, autoclean, quiet, do_syslog, show_only, verbose );
216 } 273 }
217} 274 else
275 rc = 1;
276
277 return rc;
278}
279
280static void mod_remove ( char *mod, int do_syslog, int show_only, int verbose )
281{
282 static struct mod_list_t rm_a_dummy = { "-a", 0, 0 };
283
284 struct mod_list_t *head = 0;
285 struct mod_list_t *tail = 0;
286
287 if ( mod )
288 check_dep ( mod, &head, &tail );
289 else // autoclean
290 head = tail = &rm_a_dummy;
291
292 if ( head && tail ) {
293 // process head ---> tail
294 mod_process ( head, 0, 0, 0, do_syslog, show_only, verbose );
295 }
296}
297
218 298
219#endif
220
221 299
222extern int modprobe_main(int argc, char** argv) 300extern int modprobe_main(int argc, char** argv)
223{ 301{
@@ -281,24 +359,18 @@ extern int modprobe_main(int argc, char** argv)
281 if (list) 359 if (list)
282 exit(EXIT_SUCCESS); 360 exit(EXIT_SUCCESS);
283 361
362 depend = build_dep ( );
363
364 if ( !depend ) {
365 fprintf (stderr, "could not parse modules.dep\n" );
366 exit (EXIT_FAILURE);
367 }
368
284 if (remove_opt) { 369 if (remove_opt) {
285 do { 370 do {
286 sprintf(cmd, "rmmod %s %s %s", 371 mod_remove ( optind < argc ? argv [optind] : 0, do_syslog, show_only, verbose );
287 optind >= argc ? "-a" : "", 372 } while ( ++optind < argc );
288 do_syslog ? "-s" : "", 373
289 optind < argc ? argv[optind] : "");
290 if (do_syslog)
291 syslog(LOG_INFO, "%s", cmd);
292 if (verbose)
293 printf("%s\n", cmd);
294 if (!show_only)
295 rc = system(cmd);
296
297#ifdef CONFIG_MODPROBE_DEPEND
298 if ( optind < argc )
299 check_dep ( argv [optind], do_syslog, show_only, verbose, MODPROBE_REMOVE);
300#endif
301 } while (++optind < argc);
302 exit(EXIT_SUCCESS); 374 exit(EXIT_SUCCESS);
303 } 375 }
304 376
@@ -306,29 +378,8 @@ extern int modprobe_main(int argc, char** argv)
306 fprintf(stderr, "No module or pattern provided\n"); 378 fprintf(stderr, "No module or pattern provided\n");
307 exit(EXIT_FAILURE); 379 exit(EXIT_FAILURE);
308 } 380 }
309 381
310 sprintf(cmd, "insmod %s %s %s", 382 rc = mod_insert ( argv [optind], argc - optind - 1, argv + optind + 1, autoclean, quiet, do_syslog, show_only, verbose );
311 do_syslog ? "-s" : "",
312 quiet ? "-q" : "",
313 autoclean ? "-k" : "");
314
315#ifdef CONFIG_MODPROBE_DEPEND
316 check_dep ( argv [optind], do_syslog, show_only, verbose, MODPROBE_INSERT);
317#endif
318
319 while (optind < argc) {
320 strcat(cmd, " ");
321 strcat(cmd, argv[optind]);
322 optind++;
323 }
324 if (do_syslog)
325 syslog(LOG_INFO, "%s", cmd);
326 if (verbose)
327 printf("%s\n", cmd);
328 if (!show_only)
329 rc = system(cmd);
330 else
331 rc = 0;
332 383
333 exit(rc ? EXIT_FAILURE : EXIT_SUCCESS); 384 exit(rc ? EXIT_FAILURE : EXIT_SUCCESS);
334} 385}