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"
28 //usage: "\n -f Force module to load into the wrong kernel version"
29 //usage: "\n -k Make module autoclean-able"
30 //usage: "\n -v Verbose"
31 //usage: "\n -q Quiet"
32 //usage: "\n -L Lock: prevent simultaneous loads"
33 //usage: IF_FEATURE_INSMOD_LOAD_MAP(
34 //usage: "\n -m Output load map to stdout"
36 //usage: "\n -x Don't export externs"
40 static char *m_filename
;
42 static int FAST_FUNC
check_module_name_match(const char *filename
,
43 struct stat
*statbuf UNUSED_PARAM
,
44 void *userdata
, int depth UNUSED_PARAM
)
46 char *fullname
= (char *) userdata
;
49 if (fullname
[0] == '\0')
52 tmp
= bb_get_last_path_component_nostrip(filename
);
53 if (strcmp(tmp
, fullname
) == 0) {
54 /* Stop searching if we find a match */
55 m_filename
= xstrdup(filename
);
61 int insmod_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
62 int insmod_main(int argc UNUSED_PARAM
, char **argv
)
71 * 2.6 style insmod has no options and required filename
72 * (not module name - .ko can't be omitted).
73 * 2.4 style insmod can take module name without .o
74 * and performs module search in default directories
78 IF_FEATURE_2_4_MODULES(
79 getopt32(argv
, INSMOD_OPTS INSMOD_ARGS
);
89 pos
= strlen(filename
) - 2;
90 if (get_linux_version_code() < KERNEL_VERSION(2,6,0)) {
92 if (strncmp(&filename
[pos
], ".o", 2) !=0)
93 filename
= xasprintf("%s.o", filename
);
95 if (--pos
< 0) pos
= 0;
96 if (strncmp(&filename
[pos
], ".ko", 3) !=0)
97 filename
= xasprintf("%s.ko", filename
);
100 /* Get a filedesc for the module. Check if we have a complete path */
101 if (stat(filename
, &st
) < 0 || !S_ISREG(st
.st_mode
) ||
102 (fp
= fopen_for_read(filename
)) == NULL
) {
103 /* Hmm. Could not open it. Search /lib/modules/ */
107 module_dir
= xmalloc_readlink(CONFIG_DEFAULT_MODULES_DIR
);
109 module_dir
= xstrdup(CONFIG_DEFAULT_MODULES_DIR
);
110 r
= recursive_action(module_dir
, ACTION_RECURSE
,
111 check_module_name_match
, NULL
, filename
, 0);
114 bb_error_msg_and_die("'%s': module not found", filename
);
115 if (m_filename
== NULL
|| ((fp
= fopen_for_read(m_filename
)) == NULL
))
116 bb_error_msg_and_die("'%s': module not found", filename
);
117 filename
= m_filename
;
122 rc
= bb_init_module(filename
, parse_cmdline_module_options(argv
));
124 bb_error_msg("can't insert '%s': %s", filename
, moderror(rc
));