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>
46 #include <asm/page.h> /* for PAGE_SIZE and PAGE_SHIFT */
47 /* we also get PAGE_SIZE via getpagesize() */
51 static const int BLKGETSIZE = 0x1260;
53 /* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
54 #define BLKGETSIZE _IO(0x12,96)
57 static char *device_name = NULL;
59 static long PAGES = 0;
61 static int badpages = 0;
62 static int version = -1;
64 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
67 * The definition of the union swap_header uses the constant PAGE_SIZE.
68 * Unfortunately, on some architectures this depends on the hardware model,
69 * and can only be found at run time -- we use getpagesize().
73 static int *signature_page;
75 struct swap_header_v1 {
76 char bootbits[1024]; /* Space for disklabel etc. */
78 unsigned int last_page;
79 unsigned int nr_badpages;
80 unsigned int padding[125];
81 unsigned int badpages[1];
84 static void init_signature_page()
86 pagesize = getpagesize();
89 if (pagesize != PAGE_SIZE)
90 error_msg("Assuming pages of size %d\n", pagesize);
92 signature_page = (int *) xmalloc(pagesize);
93 memset(signature_page, 0, pagesize);
94 p = (struct swap_header_v1 *) signature_page;
97 static void write_signature(char *sig)
99 char *sp = (char *) signature_page;
101 strncpy(sp + pagesize - 10, sig, 10);
104 #define V0_MAX_PAGES (8 * (pagesize - 10))
105 /* Before 2.2.0pre9 */
106 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
108 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
110 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
111 #define SWP_OFFSET(entry) ((entry) >> 8)
112 on the various architectures. Below the result - yuk.
114 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
115 i386 2^12 o<<8 e>>8 1<<24 1<<19
116 mips 2^12 o<<15 e>>15 1<<17 1<<19
117 alpha 2^13 o<<40 e>>40 1<<24 1<<18
118 m68k 2^12 o<<12 e>>12 1<<20 1<<19
119 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
120 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
121 ppc 2^12 o<<8 e>>8 1<<24 1<<19
122 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
123 armv 2^12 o<<9 e>>9 1<<23 1<<19
125 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
127 The bad part is that we need to know this since the kernel will
128 refuse a swap space if it is too large.
130 /* patch from jj - why does this differ from the above? */
131 #if defined(__alpha__)
132 #define V1_MAX_PAGES ((1 << 24) - 1)
133 #elif defined(__mips__)
134 #define V1_MAX_PAGES ((1 << 17) - 1)
135 #elif defined(__sparc_v9__)
136 #define V1_MAX_PAGES ((3 << 29) - 1)
137 #elif defined(__sparc__)
138 #define V1_MAX_PAGES (pagesize == 8192 ? ((3 << 29) - 1) : ((1 << 18) - 1))
140 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
142 /* man page now says:
143 The maximum useful size of a swap area now depends on the architecture.
144 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
145 128GB on alpha and 3TB on sparc64.
148 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
150 static void bit_set(unsigned int *addr, unsigned int nr)
154 addr += nr / (8 * sizeof(int));
157 m = 1 << (nr & (8 * sizeof(int) - 1));
162 static int bit_test_and_clear(unsigned int *addr, unsigned int nr)
166 addr += nr / (8 * sizeof(int));
169 m = 1 << (nr & (8 * sizeof(int) - 1));
176 static void die(const char *str)
178 error_msg("%s\n", str);
182 static void page_ok(int page)
185 bit_set(signature_page, page);
188 static void page_bad(int page)
191 bit_test_and_clear(signature_page, page);
193 if (badpages == MAX_BADPAGES)
194 die("too many bad pages");
195 p->badpages[badpages] = page;
200 static void check_blocks(void)
202 unsigned int current_page;
206 buffer = xmalloc(pagesize);
208 while (current_page < PAGES) {
210 page_ok(current_page++);
213 if (do_seek && lseek(DEV, current_page * pagesize, SEEK_SET) !=
214 current_page * pagesize)
215 die("seek failed in check_blocks");
216 if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
217 page_bad(current_page++);
220 page_ok(current_page++);
223 printf("one bad page\n");
224 else if (badpages > 1)
225 printf("%d bad pages\n", badpages);
228 static long valid_offset(int fd, int offset)
232 if (lseek(fd, offset, 0) < 0)
234 if (read(fd, &ch, 1) < 1)
239 static int find_size(int fd)
241 unsigned int high, low;
244 for (high = 1; high > 0 && valid_offset(fd, high); high *= 2)
246 while (low < high - 1) {
247 const int mid = (low + high) / 2;
249 if (valid_offset(fd, mid))
257 /* return size in pages, to avoid integer overflow */
258 static long get_size(const char *file)
263 if ((fd = open(file, O_RDONLY)) < 0)
264 perror_msg_and_die("%s", file);
265 if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
266 int sectors_per_page = pagesize / 512;
268 size /= sectors_per_page;
270 size = find_size(fd) / pagesize;
276 int mkswap_main(int argc, char **argv)
286 init_signature_page(); /* get pagesize */
290 if (argv[0][0] != '-') {
292 int blocks_per_page = pagesize / 1024;
294 PAGES = strtol(argv[0], &tmp, 0) / blocks_per_page;
298 device_name = argv[0];
300 switch (argv[0][1]) {
308 version = atoi(argv[0] + 2);
316 error_msg("error: Nowhere to set up swap on?\n");
319 sz = get_size(device_name);
322 } else if (PAGES > sz && !force) {
323 error_msg("error: size %ld is larger than device size %d\n",
324 PAGES * (pagesize / 1024), sz * (pagesize / 1024));
329 if (PAGES <= V0_MAX_PAGES)
331 else if (get_kernel_revision() < MAKE_VERSION(2, 1, 117))
333 else if (pagesize < 2048)
338 if (version != 0 && version != 1) {
339 error_msg("error: unknown version %d\n", version);
343 error_msg("error: swap area needs to be at least %ldkB\n",
344 (long) (10 * pagesize / 1024));
348 maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
351 maxpages = V0_MAX_PAGES;
352 else if (get_kernel_revision() >= MAKE_VERSION(2, 2, 1))
353 maxpages = V1_MAX_PAGES;
355 maxpages = V1_OLD_MAX_PAGES;
356 if (maxpages > V1_MAX_PAGES)
357 maxpages = V1_MAX_PAGES;
360 if (PAGES > maxpages) {
362 error_msg("warning: truncating swap area to %ldkB\n",
363 PAGES * pagesize / 1024);
366 DEV = open(device_name, O_RDWR);
367 if (DEV < 0 || fstat(DEV, &statbuf) < 0)
368 perror_msg_and_die("%s", device_name);
369 if (!S_ISBLK(statbuf.st_mode))
371 else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
372 die("Will not try to make swapdevice on '%s'");
375 if (!force && version == 0) {
376 /* Don't overwrite partition table unless forced */
377 unsigned char *buffer = (unsigned char *) signature_page;
378 unsigned short *q, sum;
380 if (read(DEV, buffer, 512) != 512)
381 die("fatal: first page unreadable");
382 if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
383 q = (unsigned short *) (buffer + 510);
384 for (sum = 0; q >= (unsigned short *) buffer;)
387 error_msg("Device '%s' contains a valid Sun disklabel.\n"
388 "This probably means creating v0 swap would destroy your partition table\n"
389 "No swap created. If you really want to create swap v0 on that device, use\n"
390 "the -f option to force it.\n", device_name);
397 if (version == 0 || check)
399 if (version == 0 && !bit_test_and_clear(signature_page, 0))
400 die("fatal: first page unreadable");
402 p->version = version;
403 p->last_page = PAGES - 1;
404 p->nr_badpages = badpages;
407 goodpages = PAGES - badpages - 1;
409 die("Unable to set up swap-space: unreadable");
410 printf("Setting up swapspace version %d, size = %ld bytes\n",
411 version, (long) (goodpages * pagesize));
412 write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
414 offset = ((version == 0) ? 0 : 1024);
415 if (lseek(DEV, offset, SEEK_SET) != offset)
416 die("unable to rewind swap-device");
417 if (write(DEV, (char *) signature_page + offset, pagesize - offset)
418 != pagesize - offset)
419 die("unable to write signature page");
422 * A subsequent swapon() will fail if the signature
423 * is not actually on disk. (This is a kernel bug.)