aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-03-29 17:32:24 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-03-29 17:32:24 +0000
commit56dd0bff06b4ecdc6ea92783b7d91d6cfe088f36 (patch)
treedc9e1bd4a18eca5bd503bc561baa97623fb90968
parentb256bd334fe354420eca91ad9a1d9346b2da2b27 (diff)
downloadbusybox-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.in10
-rw-r--r--util-linux/mkswap.c152
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
291config 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
291config CONFIG_MORE 301config 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;
59static long PAGES = 0; 59static long PAGES = 0;
60static int check = 0; 60static int check = 0;
61static int badpages = 0; 61static int badpages = 0;
62#if ENABLE_FEATURE_MKSWAP_V0
62static int version = -1; 63static 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
75static struct swap_header_v1 { 83static 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
176static void page_ok(int page) 183static 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
182static 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
194static void check_blocks(void) 190static 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
222static long valid_offset(int fd, int offset) 226static 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 */
252static long get_size(const char *file) 256static 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}