diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-03-29 17:32:24 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-03-29 17:32:24 +0000 |
commit | 56dd0bff06b4ecdc6ea92783b7d91d6cfe088f36 (patch) | |
tree | dc9e1bd4a18eca5bd503bc561baa97623fb90968 | |
parent | b256bd334fe354420eca91ad9a1d9346b2da2b27 (diff) | |
download | busybox-w32-56dd0bff06b4ecdc6ea92783b7d91d6cfe088f36.tar.gz busybox-w32-56dd0bff06b4ecdc6ea92783b7d91d6cfe088f36.tar.bz2 busybox-w32-56dd0bff06b4ecdc6ea92783b7d91d6cfe088f36.zip |
- shrink mkswap and make v0 support optional. Thanks also to Tito for his ideas.
http://busybox.net/lists/busybox/2006-March/019326.html
2137 8 28 2173 87d util-linux/mkswap.o.orig
1890 8 28 1926 786 util-linux/mkswap.o.v0+v1
1560 4 28 1592 638 util-linux/mkswap.o.v1
-rw-r--r-- | util-linux/Config.in | 10 | ||||
-rw-r--r-- | util-linux/mkswap.c | 152 |
2 files changed, 83 insertions, 79 deletions
diff --git a/util-linux/Config.in b/util-linux/Config.in index 28292bd40..33567d9a9 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in | |||
@@ -288,6 +288,16 @@ config CONFIG_MKSWAP | |||
288 | Once you have created swap space using 'mkswap' you need to enable | 288 | Once you have created swap space using 'mkswap' you need to enable |
289 | the swap space using the 'swapon' utility. | 289 | the swap space using the 'swapon' utility. |
290 | 290 | ||
291 | config CONFIG_FEATURE_MKSWAP_V0 | ||
292 | bool " version 0 support" | ||
293 | default n | ||
294 | depends on CONFIG_MKSWAP | ||
295 | # depends on CONFIG_MKSWAP && CONFIG_DEPRECATED | ||
296 | help | ||
297 | Enable support for the old v0 style. | ||
298 | If your kernel is older than 2.1.117, then v0 support is the | ||
299 | only option. | ||
300 | |||
291 | config CONFIG_MORE | 301 | config CONFIG_MORE |
292 | bool "more" | 302 | bool "more" |
293 | default n | 303 | default n |
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c index 4107329a6..ce123e502 100644 --- a/util-linux/mkswap.c +++ b/util-linux/mkswap.c | |||
@@ -59,9 +59,17 @@ static int DEV = -1; | |||
59 | static long PAGES = 0; | 59 | static long PAGES = 0; |
60 | static int check = 0; | 60 | static int check = 0; |
61 | static int badpages = 0; | 61 | static int badpages = 0; |
62 | #if ENABLE_FEATURE_MKSWAP_V0 | ||
62 | static int version = -1; | 63 | static int version = -1; |
63 | |||
64 | #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r)) | 64 | #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r)) |
65 | #else | ||
66 | #define version 1 | ||
67 | /* and make sure that we optimize away anything which would deal with checking | ||
68 | * the kernel revision as we have v1 support only anyway. | ||
69 | */ | ||
70 | #define MAKE_VERSION(p,q,r) 1 | ||
71 | #define get_kernel_revision() 1 | ||
72 | #endif | ||
65 | 73 | ||
66 | /* | 74 | /* |
67 | * The definition of the union swap_header uses the constant PAGE_SIZE. | 75 | * The definition of the union swap_header uses the constant PAGE_SIZE. |
@@ -74,7 +82,7 @@ static unsigned int *signature_page; | |||
74 | 82 | ||
75 | static struct swap_header_v1 { | 83 | static struct swap_header_v1 { |
76 | char bootbits[1024]; /* Space for disklabel etc. */ | 84 | char bootbits[1024]; /* Space for disklabel etc. */ |
77 | unsigned int version; | 85 | unsigned int swap_version; |
78 | unsigned int last_page; | 86 | unsigned int last_page; |
79 | unsigned int nr_badpages; | 87 | unsigned int nr_badpages; |
80 | unsigned int padding[125]; | 88 | unsigned int padding[125]; |
@@ -172,23 +180,11 @@ static int bit_test_and_clear(unsigned int *addr, unsigned int nr) | |||
172 | return (r & m) != 0; | 180 | return (r & m) != 0; |
173 | } | 181 | } |
174 | 182 | ||
175 | |||
176 | static void page_ok(int page) | 183 | static void page_ok(int page) |
177 | { | 184 | { |
178 | if (version == 0) | 185 | if (ENABLE_FEATURE_MKSWAP_V0) { |
179 | bit_set(signature_page, page); | 186 | bit_set(signature_page, page); |
180 | } | ||
181 | |||
182 | static inline void page_bad(int page) | ||
183 | { | ||
184 | if (version == 0) | ||
185 | bit_test_and_clear(signature_page, page); | ||
186 | else { | ||
187 | if (badpages == MAX_BADPAGES) | ||
188 | bb_error_msg_and_die("too many bad pages"); | ||
189 | p->badpages[badpages] = page; | ||
190 | } | 187 | } |
191 | badpages++; | ||
192 | } | 188 | } |
193 | 189 | ||
194 | static void check_blocks(void) | 190 | static void check_blocks(void) |
@@ -200,7 +196,7 @@ static void check_blocks(void) | |||
200 | buffer = xmalloc(pagesize); | 196 | buffer = xmalloc(pagesize); |
201 | current_page = 0; | 197 | current_page = 0; |
202 | while (current_page < PAGES) { | 198 | while (current_page < PAGES) { |
203 | if (!check) { | 199 | if (!check && version == 0) { |
204 | page_ok(current_page++); | 200 | page_ok(current_page++); |
205 | continue; | 201 | continue; |
206 | } | 202 | } |
@@ -208,15 +204,23 @@ static void check_blocks(void) | |||
208 | current_page * pagesize) | 204 | current_page * pagesize) |
209 | bb_error_msg_and_die("seek failed in check_blocks"); | 205 | bb_error_msg_and_die("seek failed in check_blocks"); |
210 | if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) { | 206 | if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) { |
211 | page_bad(current_page++); | 207 | current_page++; |
208 | if (version == 0) | ||
209 | bit_test_and_clear(signature_page, current_page); | ||
210 | else { | ||
211 | if (badpages == MAX_BADPAGES) | ||
212 | bb_error_msg_and_die("too many bad pages"); | ||
213 | p->badpages[badpages] = current_page; | ||
214 | } | ||
215 | badpages++; | ||
212 | continue; | 216 | continue; |
213 | } | 217 | } |
214 | page_ok(current_page++); | 218 | page_ok(current_page++); |
215 | } | 219 | } |
216 | if (badpages == 1) | 220 | if (ENABLE_FEATURE_CLEAN_UP) |
217 | printf("one bad page\n"); | 221 | free(buffer); |
218 | else if (badpages > 1) | 222 | if (badpages > 0) |
219 | printf("%d bad pages\n", badpages); | 223 | printf("%d bad page%s\n", badpages, (badpages==1)?"":"s"); |
220 | } | 224 | } |
221 | 225 | ||
222 | static long valid_offset(int fd, int offset) | 226 | static long valid_offset(int fd, int offset) |
@@ -249,17 +253,15 @@ static int find_size(int fd) | |||
249 | } | 253 | } |
250 | 254 | ||
251 | /* return size in pages, to avoid integer overflow */ | 255 | /* return size in pages, to avoid integer overflow */ |
252 | static long get_size(const char *file) | 256 | static inline long get_size(const char *file) |
253 | { | 257 | { |
254 | int fd; | 258 | int fd; |
255 | long size; | 259 | long size; |
256 | 260 | ||
257 | if ((fd = open(file, O_RDONLY)) < 0) | 261 | if ((fd = open(file, O_RDONLY)) < 0) /* TODO: bb_xopen3 */ |
258 | bb_perror_msg_and_die("%s", file); | 262 | bb_perror_msg_and_die("%s", file); |
259 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) { | 263 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) { |
260 | int sectors_per_page = pagesize / 512; | 264 | size /= pagesize / 512; |
261 | |||
262 | size /= sectors_per_page; | ||
263 | } else { | 265 | } else { |
264 | size = find_size(fd) / pagesize; | 266 | size = find_size(fd) / pagesize; |
265 | } | 267 | } |
@@ -274,66 +276,53 @@ int mkswap_main(int argc, char **argv) | |||
274 | int sz; | 276 | int sz; |
275 | int maxpages; | 277 | int maxpages; |
276 | int goodpages; | 278 | int goodpages; |
277 | int offset; | 279 | #ifdef __sparc__ |
278 | int force = 0; | 280 | int force = 0; |
281 | #endif | ||
279 | 282 | ||
280 | init_signature_page(); /* get pagesize */ | 283 | init_signature_page(); /* get pagesize */ |
281 | 284 | ||
282 | while (argc-- > 1) { | 285 | bb_opt_complementally = "?"; /* call bb_show_usage internally */ |
283 | argv++; | 286 | sz = bb_getopt_ulflags(argc, argv, "+cfv:", &tmp); |
284 | if (argv[0][0] != '-') { | 287 | if (sz & 1) |
285 | if (device_name) { | 288 | check = 1; |
286 | int blocks_per_page = pagesize / 1024; | 289 | #ifdef __sparc__ |
287 | 290 | if (sz & 2) | |
288 | PAGES = strtol(argv[0], &tmp, 0) / blocks_per_page; | 291 | force = 1; |
289 | if (*tmp) | 292 | #endif |
290 | bb_show_usage(); | 293 | #if ENABLE_FEATURE_MKSWAP_V0 |
291 | } else | 294 | if (sz & 4) { |
292 | device_name = argv[0]; | 295 | version = bb_xgetlarg(tmp, 10, 0, 1); |
296 | } else { | ||
297 | if (get_kernel_revision() < MAKE_VERSION(2, 1, 117)) | ||
298 | version = 0; | ||
299 | else | ||
300 | version = 1; | ||
301 | } | ||
302 | #endif | ||
303 | |||
304 | argv += optind; | ||
305 | argc -= optind; | ||
306 | |||
307 | goodpages = pagesize / 1024; /* cache division */ | ||
308 | while (argc--) { | ||
309 | if (device_name) { | ||
310 | PAGES = bb_xgetlarg(argv[0], 0, 10, sz * goodpages) / goodpages; | ||
311 | argc = 0; /* ignore any surplus args.. */ | ||
293 | } else { | 312 | } else { |
294 | switch (argv[0][1]) { | 313 | device_name = argv[0]; |
295 | case 'c': | 314 | sz = get_size(device_name); |
296 | check = 1; | 315 | argv++; |
297 | break; | ||
298 | case 'f': | ||
299 | force = 1; | ||
300 | break; | ||
301 | case 'v': | ||
302 | version = atoi(argv[0] + 2); | ||
303 | break; | ||
304 | default: | ||
305 | bb_show_usage(); | ||
306 | } | ||
307 | } | 316 | } |
308 | } | 317 | } |
318 | |||
309 | if (!device_name) { | 319 | if (!device_name) { |
310 | bb_error_msg("error: Nowhere to set up swap on?"); | 320 | bb_error_msg_and_die("error: Nowhere to set up swap on?"); |
311 | bb_show_usage(); | ||
312 | } | 321 | } |
313 | sz = get_size(device_name); | ||
314 | if (!PAGES) { | 322 | if (!PAGES) { |
315 | PAGES = sz; | 323 | PAGES = sz; |
316 | } else if (PAGES > sz && !force) { | ||
317 | bb_error_msg("error: size %ld is larger than device size %d", | ||
318 | PAGES * (pagesize / 1024), sz * (pagesize / 1024)); | ||
319 | return EXIT_FAILURE; | ||
320 | } | 324 | } |
321 | 325 | ||
322 | if (version == -1) { | ||
323 | if (get_kernel_revision() < MAKE_VERSION(2, 1, 117)) | ||
324 | version = 0; | ||
325 | else | ||
326 | version = 1; | ||
327 | } | ||
328 | if (version != 0 && version != 1) { | ||
329 | bb_error_msg("error: unknown version %d", version); | ||
330 | bb_show_usage(); | ||
331 | } | ||
332 | if (PAGES < 10) { | ||
333 | bb_error_msg("error: swap area needs to be at least %ldkB", | ||
334 | (long) (10 * pagesize / 1024)); | ||
335 | bb_show_usage(); | ||
336 | } | ||
337 | #if 0 | 326 | #if 0 |
338 | maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES); | 327 | maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES); |
339 | #else | 328 | #else |
@@ -350,7 +339,7 @@ int mkswap_main(int argc, char **argv) | |||
350 | if (PAGES > maxpages) { | 339 | if (PAGES > maxpages) { |
351 | PAGES = maxpages; | 340 | PAGES = maxpages; |
352 | bb_error_msg("warning: truncating swap area to %ldkB", | 341 | bb_error_msg("warning: truncating swap area to %ldkB", |
353 | PAGES * pagesize / 1024); | 342 | PAGES * goodpages); |
354 | } | 343 | } |
355 | 344 | ||
356 | DEV = open(device_name, O_RDWR); | 345 | DEV = open(device_name, O_RDWR); |
@@ -389,7 +378,7 @@ int mkswap_main(int argc, char **argv) | |||
389 | if (version == 0 && !bit_test_and_clear(signature_page, 0)) | 378 | if (version == 0 && !bit_test_and_clear(signature_page, 0)) |
390 | bb_error_msg_and_die("fatal: first page unreadable"); | 379 | bb_error_msg_and_die("fatal: first page unreadable"); |
391 | if (version == 1) { | 380 | if (version == 1) { |
392 | p->version = version; | 381 | p->swap_version = version; |
393 | p->last_page = PAGES - 1; | 382 | p->last_page = PAGES - 1; |
394 | p->nr_badpages = badpages; | 383 | p->nr_badpages = badpages; |
395 | } | 384 | } |
@@ -401,11 +390,12 @@ int mkswap_main(int argc, char **argv) | |||
401 | version, (long) (goodpages * pagesize)); | 390 | version, (long) (goodpages * pagesize)); |
402 | write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2"); | 391 | write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2"); |
403 | 392 | ||
404 | offset = ((version == 0) ? 0 : 1024); | 393 | sz = ((version == 0) ? 0 : 1024); /* offset */ |
405 | if (lseek(DEV, offset, SEEK_SET) != offset) | 394 | if (lseek(DEV, sz, SEEK_SET) != sz) |
406 | bb_error_msg_and_die("unable to rewind swap-device"); | 395 | bb_error_msg_and_die("unable to rewind swap-device"); |
407 | if (write(DEV, (char *) signature_page + offset, pagesize - offset) | 396 | goodpages = pagesize - sz; /* cache substraction */ |
408 | != pagesize - offset) | 397 | if (write(DEV, (char *) signature_page + sz, goodpages) |
398 | != goodpages) | ||
409 | bb_error_msg_and_die("unable to write signature page"); | 399 | bb_error_msg_and_die("unable to write signature page"); |
410 | 400 | ||
411 | /* | 401 | /* |
@@ -414,5 +404,9 @@ int mkswap_main(int argc, char **argv) | |||
414 | */ | 404 | */ |
415 | if (fsync(DEV)) | 405 | if (fsync(DEV)) |
416 | bb_error_msg_and_die("fsync failed"); | 406 | bb_error_msg_and_die("fsync failed"); |
407 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
408 | close(DEV); | ||
409 | free(signature_page); | ||
410 | } | ||
417 | return EXIT_SUCCESS; | 411 | return EXIT_SUCCESS; |
418 | } | 412 | } |