aboutsummaryrefslogtreecommitdiff
path: root/modutils/modutils.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-10-25 04:35:22 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-10-25 04:35:22 +0100
commit77c066ea5cf4b1ee606a81e48388ff0b1d019134 (patch)
treeb51b001a013a4be3a2ad09fdc22cfdccf29bdbaf /modutils/modutils.c
parent30f3c1d5fdf8999491a01cb3fe8be8a40da52a75 (diff)
downloadbusybox-w32-77c066ea5cf4b1ee606a81e48388ff0b1d019134.tar.gz
busybox-w32-77c066ea5cf4b1ee606a81e48388ff0b1d019134.tar.bz2
busybox-w32-77c066ea5cf4b1ee606a81e48388ff0b1d019134.zip
modutils: add FEATURE_INSMOD_TRY_MMAP option
function old new delta try_to_mmap_module - 121 +121 bb_init_module_24 4514 4578 +64 bb_init_module 119 173 +54 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/0 up/down: 239/0) Total: 239 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'modutils/modutils.c')
-rw-r--r--modutils/modutils.c63
1 files changed, 53 insertions, 10 deletions
diff --git a/modutils/modutils.c b/modutils/modutils.c
index 969926db9..850a8683b 100644
--- a/modutils/modutils.c
+++ b/modutils/modutils.c
@@ -62,7 +62,7 @@ char* FAST_FUNC filename2modname(const char *filename, char *modname)
62 return modname; 62 return modname;
63} 63}
64 64
65char * FAST_FUNC parse_cmdline_module_options(char **argv) 65char* FAST_FUNC parse_cmdline_module_options(char **argv)
66{ 66{
67 char *options; 67 char *options;
68 int optlen; 68 int optlen;
@@ -77,6 +77,40 @@ char * FAST_FUNC parse_cmdline_module_options(char **argv)
77 return options; 77 return options;
78} 78}
79 79
80#if ENABLE_FEATURE_INSMOD_TRY_MMAP
81void* FAST_FUNC try_to_mmap_module(const char *filename, size_t *image_size_p)
82{
83 /* We have user reports of failure to load 3MB module
84 * on a 16MB RAM machine. Apparently even a transient
85 * memory spike to 6MB during module load
86 * is too big for that system. */
87 void *image;
88 struct stat st;
89 int fd;
90
91 fd = xopen(filename, O_RDONLY);
92 fstat(fd, &st);
93 image = NULL;
94 /* st.st_size is off_t, we can't just pass it to mmap */
95 if (st.st_size <= *image_size_p) {
96 size_t image_size = st.st_size;
97 image = mmap(NULL, image_size, PROT_READ, MAP_PRIVATE, fd, 0);
98 if (image == MAP_FAILED) {
99 image = NULL;
100 } else if (*(uint32_t*)image != SWAP_BE32(0x7f454C46)) {
101 /* No ELF signature. Compressed module? */
102 munmap(image, image_size);
103 image = NULL;
104 } else {
105 /* Success. Report the size */
106 *image_size_p = image_size;
107 }
108 }
109 close(fd);
110 return image;
111}
112#endif
113
80/* Return: 114/* Return:
81 * 0 on success, 115 * 0 on success,
82 * -errno on open/read error, 116 * -errno on open/read error,
@@ -84,9 +118,10 @@ char * FAST_FUNC parse_cmdline_module_options(char **argv)
84 */ 118 */
85int FAST_FUNC bb_init_module(const char *filename, const char *options) 119int FAST_FUNC bb_init_module(const char *filename, const char *options)
86{ 120{
87 size_t len; 121 size_t image_size;
88 char *image; 122 char *image;
89 int rc; 123 int rc;
124 bool mmaped;
90 125
91 if (!options) 126 if (!options)
92 options = ""; 127 options = "";
@@ -97,17 +132,25 @@ int FAST_FUNC bb_init_module(const char *filename, const char *options)
97 return bb_init_module_24(filename, options); 132 return bb_init_module_24(filename, options);
98#endif 133#endif
99 134
100 /* Use the 2.6 way */ 135 image_size = INT_MAX - 4095;
101 len = INT_MAX - 4095; 136 mmaped = 0;
102 errno = ENOMEM; /* may be changed by e.g. open errors below */ 137 image = try_to_mmap_module(filename, &image_size);
103 image = xmalloc_open_zipped_read_close(filename, &len); 138 if (image) {
104 if (!image) 139 mmaped = 1;
105 return -errno; 140 } else {
141 errno = ENOMEM; /* may be changed by e.g. open errors below */
142 image = xmalloc_open_zipped_read_close(filename, &image_size);
143 if (!image)
144 return -errno;
145 }
106 146
107 errno = 0; 147 errno = 0;
108 init_module(image, len, options); 148 init_module(image, image_size, options);
109 rc = errno; 149 rc = errno;
110 free(image); 150 if (mmaped)
151 munmap(image, image_size);
152 else
153 free(image);
111 return rc; 154 return rc;
112} 155}
113 156