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\n"
53 "Prepare a disk partition to be used as a swap partition.\n\n"
54 "Options:\n" "\t-c\t\tCheck for read-ability.\n"
55 "\t-v0\t\tMake version 0 swap [max 128 Megs].\n"
56 "\t-v1\t\tMake version 1 swap [big!] (default for kernels > 2.1.117).\n"
58 "\tblock-count\tNumber of block to use (default is entire partition).\n";
63 #define BLKGETSIZE 0x1260
65 /* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
66 #define BLKGETSIZE _IO(0x12,96)
69 static char *program_name = "mkswap";
70 static char *device_name = NULL;
72 static long PAGES = 0;
74 static int badpages = 0;
75 static int version = -1;
77 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
79 static int linux_version_code(void)
81 struct utsname my_utsname;
84 if (uname(&my_utsname) == 0) {
85 p = atoi(strtok(my_utsname.release, "."));
86 q = atoi(strtok(NULL, "."));
87 r = atoi(strtok(NULL, "."));
88 return MAKE_VERSION(p, q, r);
94 * The definition of the union swap_header uses the constant PAGE_SIZE.
95 * Unfortunately, on some architectures this depends on the hardware model,
96 * and can only be found at run time -- we use getpagesize().
100 static int *signature_page;
102 struct swap_header_v1 {
103 char bootbits[1024]; /* Space for disklabel etc. */
104 unsigned int version;
105 unsigned int last_page;
106 unsigned int nr_badpages;
107 unsigned int padding[125];
108 unsigned int badpages[1];
111 static void init_signature_page()
113 pagesize = getpagesize();
116 if (pagesize != PAGE_SIZE)
117 fprintf(stderr, "Assuming pages of size %d\n", pagesize);
119 signature_page = (int *) xmalloc(pagesize);
120 memset(signature_page, 0, pagesize);
121 p = (struct swap_header_v1 *) signature_page;
124 static void write_signature(char *sig)
126 char *sp = (char *) signature_page;
128 strncpy(sp + pagesize - 10, sig, 10);
131 #define V0_MAX_PAGES (8 * (pagesize - 10))
132 /* Before 2.2.0pre9 */
133 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
135 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
137 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
138 #define SWP_OFFSET(entry) ((entry) >> 8)
139 on the various architectures. Below the result - yuk.
141 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
142 i386 2^12 o<<8 e>>8 1<<24 1<<19
143 mips 2^12 o<<15 e>>15 1<<17 1<<19
144 alpha 2^13 o<<40 e>>40 1<<24 1<<18
145 m68k 2^12 o<<12 e>>12 1<<20 1<<19
146 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
147 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
148 ppc 2^12 o<<8 e>>8 1<<24 1<<19
149 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
150 armv 2^12 o<<9 e>>9 1<<23 1<<19
152 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
154 The bad part is that we need to know this since the kernel will
155 refuse a swap space if it is too large.
157 /* patch from jj - why does this differ from the above? */
158 #if defined(__alpha__)
159 #define V1_MAX_PAGES ((1 << 24) - 1)
160 #elif defined(__mips__)
161 #define V1_MAX_PAGES ((1 << 17) - 1)
162 #elif defined(__sparc_v9__)
163 #define V1_MAX_PAGES ((3 << 29) - 1)
164 #elif defined(__sparc__)
165 #define V1_MAX_PAGES (pagesize == 8192 ? ((3 << 29) - 1) : ((1 << 18) - 1))
167 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
169 /* man page now says:
170 The maximum useful size of a swap area now depends on the architecture.
171 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
172 128GB on alpha and 3TB on sparc64.
175 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
177 static void bit_set(unsigned int *addr, unsigned int nr)
181 addr += nr / (8 * sizeof(int));
184 m = 1 << (nr & (8 * sizeof(int) - 1));
189 static int bit_test_and_clear(unsigned int *addr, unsigned int nr)
193 addr += nr / (8 * sizeof(int));
196 m = 1 << (nr & (8 * sizeof(int) - 1));
203 void die(const char *str)
205 fprintf(stderr, "%s: %s\n", program_name, str);
209 void page_ok(int page)
212 bit_set(signature_page, page);
215 void page_bad(int page)
218 bit_test_and_clear(signature_page, page);
220 if (badpages == MAX_BADPAGES)
221 die("too many bad pages");
222 p->badpages[badpages] = page;
227 void check_blocks(void)
229 unsigned int current_page;
233 buffer = xmalloc(pagesize);
235 while (current_page < PAGES) {
237 page_ok(current_page++);
240 if (do_seek && lseek(DEV, current_page * pagesize, SEEK_SET) !=
241 current_page * pagesize)
242 die("seek failed in check_blocks");
243 if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
244 page_bad(current_page++);
247 page_ok(current_page++);
250 printf("one bad page\n");
251 else if (badpages > 1)
252 printf("%d bad pages\n", badpages);
255 static long valid_offset(int fd, int offset)
259 if (lseek(fd, offset, 0) < 0)
261 if (read(fd, &ch, 1) < 1)
266 static int find_size(int fd)
268 unsigned int high, low;
271 for (high = 1; high > 0 && valid_offset(fd, high); high *= 2)
273 while (low < high - 1) {
274 const int mid = (low + high) / 2;
276 if (valid_offset(fd, mid))
284 /* return size in pages, to avoid integer overflow */
285 static long get_size(const char *file)
290 fd = open(file, O_RDONLY);
295 if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
296 int sectors_per_page = pagesize / 512;
298 size /= sectors_per_page;
300 size = find_size(fd) / pagesize;
306 int mkswap_main(int argc, char **argv)
317 program_name = *argv;
319 init_signature_page(); /* get pagesize */
323 if (argv[0][0] != '-') {
325 int blocks_per_page = pagesize / 1024;
327 PAGES = strtol(argv[0], &tmp, 0) / blocks_per_page;
331 device_name = argv[0];
333 switch (argv[0][1]) {
341 version = atoi(argv[0] + 2);
350 "%s: error: Nowhere to set up swap on?\n", program_name);
353 sz = get_size(device_name);
356 } else if (PAGES > sz && !force) {
359 "size %ld is larger than device size %d\n",
361 PAGES * (pagesize / 1024), sz * (pagesize / 1024));
366 if (PAGES <= V0_MAX_PAGES)
368 else if (linux_version_code() < MAKE_VERSION(2, 1, 117))
370 else if (pagesize < 2048)
375 if (version != 0 && version != 1) {
376 fprintf(stderr, "%s: error: unknown version %d\n",
377 program_name, version);
382 "%s: error: swap area needs to be at least %ldkB\n",
383 program_name, (long) (10 * pagesize / 1024));
387 maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
390 maxpages = V0_MAX_PAGES;
391 else if (linux_version_code() >= MAKE_VERSION(2, 2, 1))
392 maxpages = V1_MAX_PAGES;
394 maxpages = V1_OLD_MAX_PAGES;
395 if (maxpages > V1_MAX_PAGES)
396 maxpages = V1_MAX_PAGES;
399 if (PAGES > maxpages) {
401 fprintf(stderr, "%s: warning: truncating swap area to %ldkB\n",
402 program_name, PAGES * pagesize / 1024);
405 DEV = open(device_name, O_RDWR);
406 if (DEV < 0 || fstat(DEV, &statbuf) < 0) {
410 if (!S_ISBLK(statbuf.st_mode))
412 else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
413 die("Will not try to make swapdevice on '%s'");
416 if (!force && version == 0) {
417 /* Don't overwrite partition table unless forced */
418 unsigned char *buffer = (unsigned char *) signature_page;
419 unsigned short *q, sum;
421 if (read(DEV, buffer, 512) != 512)
422 die("fatal: first page unreadable");
423 if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
424 q = (unsigned short *) (buffer + 510);
425 for (sum = 0; q >= (unsigned short *) buffer;)
429 %s: Device '%s' contains a valid Sun disklabel.\n\
430 This probably means creating v0 swap would destroy your partition table\n\
431 No swap created. If you really want to create swap v0 on that device, use\n\
432 the -f option to force it.\n", program_name, device_name);
439 if (version == 0 || check)
441 if (version == 0 && !bit_test_and_clear(signature_page, 0))
442 die("fatal: first page unreadable");
444 p->version = version;
445 p->last_page = PAGES - 1;
446 p->nr_badpages = badpages;
449 goodpages = PAGES - badpages - 1;
451 die("Unable to set up swap-space: unreadable");
452 printf("Setting up swapspace version %d, size = %ld bytes\n",
453 version, (long) (goodpages * pagesize));
454 write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
456 offset = ((version == 0) ? 0 : 1024);
457 if (lseek(DEV, offset, SEEK_SET) != offset)
458 die("unable to rewind swap-device");
459 if (write(DEV, (char *) signature_page + offset, pagesize - offset)
460 != pagesize - offset)
461 die("unable to write signature page");
464 * A subsequent swapon() will fail if the signature
465 * is not actually on disk. (This is a kernel bug.)