1 /* vi: set sw=4 ts=4: */
3 * Mini insmod implementation for busybox
5 * Copyright (C) 2008 Timo Teras <timo.teras@iki.fi>
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10 //applet:IF_INSMOD(APPLET(insmod, BB_DIR_SBIN, BB_SUID_DROP))
16 /* 2.6 style insmod has no options and required filename
17 * (not module name - .ko can't be omitted) */
19 //usage:#if !ENABLE_MODPROBE_SMALL
20 //usage:#define insmod_trivial_usage
21 //usage: IF_FEATURE_2_4_MODULES("[OPTIONS] MODULE ")
22 //usage: IF_NOT_FEATURE_2_4_MODULES("FILE ")
23 //usage: "[SYMBOL=VALUE]..."
24 //usage:#define insmod_full_usage "\n\n"
25 //usage: "Load the specified kernel modules into the kernel"
26 //usage: IF_FEATURE_2_4_MODULES( "\n"
27 //usage: "\n -f Force module to load into the wrong kernel version"
28 //usage: "\n -k Make module autoclean-able"
29 //usage: "\n -v Verbose"
30 //usage: "\n -q Quiet"
31 //usage: "\n -L Lock: prevent simultaneous loads"
32 //usage: IF_FEATURE_INSMOD_LOAD_MAP(
33 //usage: "\n -m Output load map to stdout"
35 //usage: "\n -x Don't export externs"
39 static char *m_filename
;
41 static int FAST_FUNC
check_module_name_match(const char *filename
,
42 struct stat
*statbuf UNUSED_PARAM
,
43 void *userdata
, int depth UNUSED_PARAM
)
45 char *fullname
= (char *) userdata
;
48 if (fullname
[0] == '\0')
51 tmp
= bb_get_last_path_component_nostrip(filename
);
52 if (strcmp(tmp
, fullname
) == 0) {
53 /* Stop searching if we find a match */
54 m_filename
= xstrdup(filename
);
60 int insmod_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
61 int insmod_main(int argc UNUSED_PARAM
, char **argv
)
70 * 2.6 style insmod has no options and required filename
71 * (not module name - .ko can't be omitted).
72 * 2.4 style insmod can take module name without .o
73 * and performs module search in default directories
77 IF_FEATURE_2_4_MODULES(
78 getopt32(argv
, INSMOD_OPTS INSMOD_ARGS
);
88 pos
= strlen(filename
) - 2;
89 if (get_linux_version_code() < KERNEL_VERSION(2,6,0)) {
91 if (strncmp(&filename
[pos
], ".o", 2) !=0)
92 filename
= xasprintf("%s.o", filename
);
94 if (--pos
< 0) pos
= 0;
95 if (strncmp(&filename
[pos
], ".ko", 3) !=0)
96 filename
= xasprintf("%s.ko", filename
);
99 /* Get a filedesc for the module. Check if we have a complete path */
100 if (stat(filename
, &st
) < 0 || !S_ISREG(st
.st_mode
) ||
101 (fp
= fopen_for_read(filename
)) == NULL
) {
102 /* Hmm. Could not open it. Search /lib/modules/ */
106 module_dir
= xmalloc_readlink(CONFIG_DEFAULT_MODULES_DIR
);
108 module_dir
= xstrdup(CONFIG_DEFAULT_MODULES_DIR
);
109 r
= recursive_action(module_dir
, ACTION_RECURSE
,
110 check_module_name_match
, NULL
, filename
, 0);
113 bb_error_msg_and_die("'%s': module not found", filename
);
114 if (m_filename
== NULL
|| ((fp
= fopen_for_read(m_filename
)) == NULL
))
115 bb_error_msg_and_die("'%s': module not found", filename
);
116 filename
= m_filename
;
121 rc
= bb_init_module(filename
, parse_cmdline_module_options(argv
, /*quote_spaces:*/ 0));
123 bb_error_msg("can't insert '%s': %s", filename
, moderror(rc
));