2 * Common modutils related functions for busybox
4 * Copyright (C) 2008 by Timo Teras <timo.teras@iki.fi>
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
11 extern int init_module(void *module
, unsigned long len
, const char *options
);
12 extern int delete_module(const char *module
, unsigned int flags
);
14 # include <sys/syscall.h>
15 # define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
16 # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
19 void FAST_FUNC
replace(char *s
, char what
, char with
)
28 char* FAST_FUNC
replace_underscores(char *s
)
34 int FAST_FUNC
string_to_llist(char *string
, llist_t
**llist
, const char *delim
)
39 while ((tok
= strsep(&string
, delim
)) != NULL
) {
42 llist_add_to_end(llist
, xstrdup(tok
));
48 char* FAST_FUNC
filename2modname(const char *filename
, char *modname
)
56 modname
= xmalloc(MODULE_NAME_LEN
);
57 // Disabled since otherwise "modprobe dir/name" would work
58 // as if it is "modprobe name". It is unclear why
59 // 'basenamization' was here in the first place.
60 //from = bb_get_last_path_component_nostrip(filename);
62 for (i
= 0; i
< (MODULE_NAME_LEN
-1) && from
[i
] != '\0' && from
[i
] != '.'; i
++)
63 modname
[i
] = (from
[i
] == '-') ? '_' : from
[i
];
69 char* FAST_FUNC
parse_cmdline_module_options(char **argv
, int quote_spaces
)
82 options
= xrealloc(options
, optlen
+ 2 + strlen(var
) + 2);
84 val
= strchrnul(var
, '=');
87 * modprobe (module-init-tools version 3.11.1) compat:
89 * var="val with spaces", not "var=val with spaces"
90 * (note: var *name* is not checked for spaces!)
92 if (*val
) { /* has var=val format. skip '=' */
98 optlen
+= sprintf(options
+ optlen
, fmt
, (int)(val
- var
), var
, val
);
100 /* Remove trailing space. Disabled */
101 /* if (optlen != 0) options[optlen-1] = '\0'; */
105 #if ENABLE_FEATURE_INSMOD_TRY_MMAP
106 void* FAST_FUNC
try_to_mmap_module(const char *filename
, size_t *image_size_p
)
108 /* We have user reports of failure to load 3MB module
109 * on a 16MB RAM machine. Apparently even a transient
110 * memory spike to 6MB during module load
111 * is too big for that system. */
116 fd
= xopen(filename
, O_RDONLY
);
119 /* st.st_size is off_t, we can't just pass it to mmap */
120 if (st
.st_size
<= *image_size_p
) {
121 size_t image_size
= st
.st_size
;
122 image
= mmap(NULL
, image_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
123 if (image
== MAP_FAILED
) {
125 } else if (*(uint32_t*)image
!= SWAP_BE32(0x7f454C46)) {
126 /* No ELF signature. Compressed module? */
127 munmap(image
, image_size
);
130 /* Success. Report the size */
131 *image_size_p
= image_size
;
141 * -errno on open/read error,
142 * errno on init_module() error
144 int FAST_FUNC
bb_init_module(const char *filename
, const char *options
)
154 //TODO: audit bb_init_module_24 to match error code convention
155 #if ENABLE_FEATURE_2_4_MODULES
156 if (get_linux_version_code() < KERNEL_VERSION(2,6,0))
157 return bb_init_module_24(filename
, options
);
160 image_size
= INT_MAX
- 4095;
162 image
= try_to_mmap_module(filename
, &image_size
);
166 errno
= ENOMEM
; /* may be changed by e.g. open errors below */
167 image
= xmalloc_open_zipped_read_close(filename
, &image_size
);
173 init_module(image
, image_size
, options
);
176 munmap(image
, image_size
);
182 int FAST_FUNC
bb_delete_module(const char *module
, unsigned int flags
)
185 delete_module(module
, flags
);
189 const char* FAST_FUNC
moderror(int err
)
192 case -1: /* btw: it's -EPERM */
193 return "no such module";
195 return "invalid module format";
197 return "unknown symbol in module, or unknown parameter";
199 return "module has wrong symbol version";
201 return "kernel does not support requested operation";
203 if (err
< 0) /* should always be */
205 return strerror(err
);