diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-25 04:35:22 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-25 04:35:22 +0100 |
commit | 77c066ea5cf4b1ee606a81e48388ff0b1d019134 (patch) | |
tree | b51b001a013a4be3a2ad09fdc22cfdccf29bdbaf /modutils/modutils.c | |
parent | 30f3c1d5fdf8999491a01cb3fe8be8a40da52a75 (diff) | |
download | busybox-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.c | 63 |
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 | ||
65 | char * FAST_FUNC parse_cmdline_module_options(char **argv) | 65 | char* 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 | ||
81 | void* 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 | */ |
85 | int FAST_FUNC bb_init_module(const char *filename, const char *options) | 119 | int 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 | ||