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 /util-linux | |
| 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
Diffstat (limited to 'util-linux')
| -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 | } |
