1 /* vi: set sw=4 ts=4: */
3 * mkswap.c - set up a linux swap device
5 * (C) 1991 Linus Torvalds. This file may be redistributed as per
10 * 20.12.91 - time began. Got VM working yesterday by doing this by hand.
12 * Usage: mkswap [-c] [-vN] [-f] device [size-in-blocks]
14 * -c for readability checking. (Use it unless you are SURE!)
15 * -vN for swap areas version N. (Only N=0,1 known today.)
16 * -f for forcing swap creation even if it would smash partition table.
18 * The device may be a block device or an image of one, but this isn't
19 * enforced (but it's not much fun on a character device :-).
21 * Patches from jaggy@purplet.demon.co.uk (Mike Jagdis) to make the
22 * size-in-blocks parameter optional added Wed Feb 8 10:33:43 1995.
24 * Version 1 swap area code (for kernel 2.1.117), aeb, 981010.
26 * Sparc fixes, jj@ultra.linux.cz (Jakub Jelinek), 981201 - mangled by aeb.
27 * V1_MAX_PAGES fixes, jj, 990325.
29 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
30 * - added Native Language Support
32 * from util-linux -- adapted for busybox by
33 * Erik Andersen <andersee@debian.org>. I ripped out Native Language
34 * Support, made some stuff smaller, and fitted for life in busybox.
44 #include <sys/ioctl.h> /* for _IO */
45 #include <sys/utsname.h>
47 #include <asm/page.h> /* for PAGE_SIZE and PAGE_SHIFT */
48 /* we also get PAGE_SIZE via getpagesize() */
51 static const char mkswap_usage[] =
52 "mkswap [-c] [-v0|-v1] device [block-count]\n"
53 #ifndef BB_FEATURE_TRIVIAL_HELP
54 "\nPrepare a disk partition to be used as a swap partition.\n\n"
55 "Options:\n" "\t-c\t\tCheck for read-ability.\n"
56 "\t-v0\t\tMake version 0 swap [max 128 Megs].\n"
57 "\t-v1\t\tMake version 1 swap [big!] (default for kernels > 2.1.117).\n"
59 "\tblock-count\tNumber of block to use (default is entire partition).\n"
66 #define BLKGETSIZE 0x1260
68 /* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
69 #define BLKGETSIZE _IO(0x12,96)
72 static char *program_name = "mkswap";
73 static char *device_name = NULL;
75 static long PAGES = 0;
77 static int badpages = 0;
78 static int version = -1;
80 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
82 static int linux_version_code(void)
84 struct utsname my_utsname;
87 if (uname(&my_utsname) == 0) {
88 p = atoi(strtok(my_utsname.release, "."));
89 q = atoi(strtok(NULL, "."));
90 r = atoi(strtok(NULL, "."));
91 return MAKE_VERSION(p, q, r);
97 * The definition of the union swap_header uses the constant PAGE_SIZE.
98 * Unfortunately, on some architectures this depends on the hardware model,
99 * and can only be found at run time -- we use getpagesize().
103 static int *signature_page;
105 struct swap_header_v1 {
106 char bootbits[1024]; /* Space for disklabel etc. */
107 unsigned int version;
108 unsigned int last_page;
109 unsigned int nr_badpages;
110 unsigned int padding[125];
111 unsigned int badpages[1];
114 static void init_signature_page()
116 pagesize = getpagesize();
119 if (pagesize != PAGE_SIZE)
120 fprintf(stderr, "Assuming pages of size %d\n", pagesize);
122 signature_page = (int *) xmalloc(pagesize);
123 memset(signature_page, 0, pagesize);
124 p = (struct swap_header_v1 *) signature_page;
127 static void write_signature(char *sig)
129 char *sp = (char *) signature_page;
131 strncpy(sp + pagesize - 10, sig, 10);
134 #define V0_MAX_PAGES (8 * (pagesize - 10))
135 /* Before 2.2.0pre9 */
136 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
138 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
140 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
141 #define SWP_OFFSET(entry) ((entry) >> 8)
142 on the various architectures. Below the result - yuk.
144 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
145 i386 2^12 o<<8 e>>8 1<<24 1<<19
146 mips 2^12 o<<15 e>>15 1<<17 1<<19
147 alpha 2^13 o<<40 e>>40 1<<24 1<<18
148 m68k 2^12 o<<12 e>>12 1<<20 1<<19
149 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
150 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
151 ppc 2^12 o<<8 e>>8 1<<24 1<<19
152 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
153 armv 2^12 o<<9 e>>9 1<<23 1<<19
155 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
157 The bad part is that we need to know this since the kernel will
158 refuse a swap space if it is too large.
160 /* patch from jj - why does this differ from the above? */
161 #if defined(__alpha__)
162 #define V1_MAX_PAGES ((1 << 24) - 1)
163 #elif defined(__mips__)
164 #define V1_MAX_PAGES ((1 << 17) - 1)
165 #elif defined(__sparc_v9__)
166 #define V1_MAX_PAGES ((3 << 29) - 1)
167 #elif defined(__sparc__)
168 #define V1_MAX_PAGES (pagesize == 8192 ? ((3 << 29) - 1) : ((1 << 18) - 1))
170 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
172 /* man page now says:
173 The maximum useful size of a swap area now depends on the architecture.
174 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
175 128GB on alpha and 3TB on sparc64.
178 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
180 static void bit_set(unsigned int *addr, unsigned int nr)
184 addr += nr / (8 * sizeof(int));
187 m = 1 << (nr & (8 * sizeof(int) - 1));
192 static int bit_test_and_clear(unsigned int *addr, unsigned int nr)
196 addr += nr / (8 * sizeof(int));
199 m = 1 << (nr & (8 * sizeof(int) - 1));
206 void die(const char *str)
208 fprintf(stderr, "%s: %s\n", program_name, str);
212 void page_ok(int page)
215 bit_set(signature_page, page);
218 void page_bad(int page)
221 bit_test_and_clear(signature_page, page);
223 if (badpages == MAX_BADPAGES)
224 die("too many bad pages");
225 p->badpages[badpages] = page;
230 void check_blocks(void)
232 unsigned int current_page;
236 buffer = xmalloc(pagesize);
238 while (current_page < PAGES) {
240 page_ok(current_page++);
243 if (do_seek && lseek(DEV, current_page * pagesize, SEEK_SET) !=
244 current_page * pagesize)
245 die("seek failed in check_blocks");
246 if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
247 page_bad(current_page++);
250 page_ok(current_page++);
253 printf("one bad page\n");
254 else if (badpages > 1)
255 printf("%d bad pages\n", badpages);
258 static long valid_offset(int fd, int offset)
262 if (lseek(fd, offset, 0) < 0)
264 if (read(fd, &ch, 1) < 1)
269 static int find_size(int fd)
271 unsigned int high, low;
274 for (high = 1; high > 0 && valid_offset(fd, high); high *= 2)
276 while (low < high - 1) {
277 const int mid = (low + high) / 2;
279 if (valid_offset(fd, mid))
287 /* return size in pages, to avoid integer overflow */
288 static long get_size(const char *file)
293 fd = open(file, O_RDONLY);
298 if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
299 int sectors_per_page = pagesize / 512;
301 size /= sectors_per_page;
303 size = find_size(fd) / pagesize;
309 int mkswap_main(int argc, char **argv)
320 program_name = *argv;
322 init_signature_page(); /* get pagesize */
326 if (argv[0][0] != '-') {
328 int blocks_per_page = pagesize / 1024;
330 PAGES = strtol(argv[0], &tmp, 0) / blocks_per_page;
334 device_name = argv[0];
336 switch (argv[0][1]) {
344 version = atoi(argv[0] + 2);
353 "%s: error: Nowhere to set up swap on?\n", program_name);
356 sz = get_size(device_name);
359 } else if (PAGES > sz && !force) {
362 "size %ld is larger than device size %d\n",
364 PAGES * (pagesize / 1024), sz * (pagesize / 1024));
369 if (PAGES <= V0_MAX_PAGES)
371 else if (linux_version_code() < MAKE_VERSION(2, 1, 117))
373 else if (pagesize < 2048)
378 if (version != 0 && version != 1) {
379 fprintf(stderr, "%s: error: unknown version %d\n",
380 program_name, version);
385 "%s: error: swap area needs to be at least %ldkB\n",
386 program_name, (long) (10 * pagesize / 1024));
390 maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
393 maxpages = V0_MAX_PAGES;
394 else if (linux_version_code() >= MAKE_VERSION(2, 2, 1))
395 maxpages = V1_MAX_PAGES;
397 maxpages = V1_OLD_MAX_PAGES;
398 if (maxpages > V1_MAX_PAGES)
399 maxpages = V1_MAX_PAGES;
402 if (PAGES > maxpages) {
404 fprintf(stderr, "%s: warning: truncating swap area to %ldkB\n",
405 program_name, PAGES * pagesize / 1024);
408 DEV = open(device_name, O_RDWR);
409 if (DEV < 0 || fstat(DEV, &statbuf) < 0) {
413 if (!S_ISBLK(statbuf.st_mode))
415 else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
416 die("Will not try to make swapdevice on '%s'");
419 if (!force && version == 0) {
420 /* Don't overwrite partition table unless forced */
421 unsigned char *buffer = (unsigned char *) signature_page;
422 unsigned short *q, sum;
424 if (read(DEV, buffer, 512) != 512)
425 die("fatal: first page unreadable");
426 if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
427 q = (unsigned short *) (buffer + 510);
428 for (sum = 0; q >= (unsigned short *) buffer;)
432 %s: Device '%s' contains a valid Sun disklabel.\n\
433 This probably means creating v0 swap would destroy your partition table\n\
434 No swap created. If you really want to create swap v0 on that device, use\n\
435 the -f option to force it.\n", program_name, device_name);
442 if (version == 0 || check)
444 if (version == 0 && !bit_test_and_clear(signature_page, 0))
445 die("fatal: first page unreadable");
447 p->version = version;
448 p->last_page = PAGES - 1;
449 p->nr_badpages = badpages;
452 goodpages = PAGES - badpages - 1;
454 die("Unable to set up swap-space: unreadable");
455 printf("Setting up swapspace version %d, size = %ld bytes\n",
456 version, (long) (goodpages * pagesize));
457 write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
459 offset = ((version == 0) ? 0 : 1024);
460 if (lseek(DEV, offset, SEEK_SET) != offset)
461 die("unable to rewind swap-device");
462 if (write(DEV, (char *) signature_page + offset, pagesize - offset)
463 != pagesize - offset)
464 die("unable to write signature page");
467 * A subsequent swapon() will fail if the signature
468 * is not actually on disk. (This is a kernel bug.)