]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - disk-utils/mkswap.c
2 * mkswap.c - set up a linux swap device
4 * (C) 1991 Linus Torvalds. This file may be redistributed as per
9 * 20.12.91 - time began. Got VM working yesterday by doing this by hand.
11 * Usage: mkswap [-c] [-vN] [-f] device [size-in-blocks]
13 * -c for readability checking. (Use it unless you are SURE!)
14 * -vN for swap areas version N. (Only N=0,1 known today.)
15 * -f for forcing swap creation even if it would smash partition table.
17 * The device may be a block device or an image of one, but this isn't
18 * enforced (but it's not much fun on a character device :-).
20 * Patches from jaggy@purplet.demon.co.uk (Mike Jagdis) to make the
21 * size-in-blocks parameter optional added Wed Feb 8 10:33:43 1995.
23 * Version 1 swap area code (for kernel 2.1.117), aeb, 981010.
25 * Sparc fixes, jj@ultra.linux.cz (Jakub Jelinek), 981201 - mangled by aeb.
26 * V1_MAX_PAGES fixes, jj, 990325.
27 * sparc64 fixes, jj, 000219.
29 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
30 * - added Native Language Support
40 #include <sys/ioctl.h> /* for _IO */
41 #include <sys/utsname.h>
43 #include "swapheader.h"
47 #ifdef HAVE_UUID_UUID_H
48 #include <uuid/uuid.h>
53 #define BLKGETSIZE 0x1260
55 /* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
56 #define BLKGETSIZE _IO(0x12,96)
59 static char * program_name
= "mkswap";
60 static char * device_name
= NULL
;
62 static unsigned long PAGES
= 0;
63 static unsigned long badpages
= 0;
65 static int version
= -1;
67 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
70 linux_version_code(void) {
71 struct utsname my_utsname
;
74 if (uname(&my_utsname
) == 0) {
75 p
= atoi(strtok(my_utsname
.release
, "."));
76 q
= atoi(strtok(NULL
, "."));
77 r
= atoi(strtok(NULL
, "."));
78 return MAKE_VERSION(p
,q
,r
);
85 # define is_sparc64() 1
91 static int sparc64
= -1;
93 if (sparc64
!= -1) return sparc64
;
96 if (uname(&un
) < 0) return 0;
97 if (! strcmp(un
.machine
, "sparc64")) {
101 if (strcmp(un
.machine
, "sparc"))
102 return 0; /* Should not happen */
104 #ifdef HAVE_PERSONALITY
106 extern int personality(unsigned long);
108 #define PERS_LINUX 0x00000000
109 #define PERS_LINUX_32BIT 0x00800000
110 #define PERS_LINUX32 0x00000008
112 oldpers
= personality(PERS_LINUX_32BIT
);
114 if (personality(PERS_LINUX
) != -1) {
116 if (! strcmp(un
.machine
, "sparc64")) {
118 oldpers
= PERS_LINUX32
;
121 personality(oldpers
);
128 # define is_be64() is_sparc64()
129 # endif /* sparc32 */
135 * The definition of the union swap_header uses the kernel constant PAGE_SIZE.
136 * Unfortunately, on some architectures this depends on the hardware model, and
137 * can only be found at run time -- we use getpagesize(), so that we do not
138 * need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
140 * Even more unfortunately, getpagesize() does not always return the right
141 * information. For example, libc4, libc5 and glibc 2.0 do not use the system
142 * call but invent a value themselves (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC),
143 * and thus it may happen that e.g. on a sparc kernel PAGE_SIZE=4096 and
144 * getpagesize() returns 8192.
146 * What to do? Let us allow the user to specify the pagesize explicitly.
148 * Update 05-Feb-2007 (kzak):
149 * - use sysconf(_SC_PAGESIZE) to be consistent with the rest of
150 * util-linux code. It is the standardized and preferred way of
151 * querying page size.
153 static int user_pagesize
;
155 static unsigned long *signature_page
;
156 struct swap_header_v1
*p
;
159 init_signature_page(void) {
161 int kernel_pagesize
= pagesize
= (int) sysconf(_SC_PAGESIZE
);
164 if ((user_pagesize
& (user_pagesize
-1)) ||
165 user_pagesize
< 1024) {
166 fprintf(stderr
, _("Bad user-specified page size %d\n"),
170 pagesize
= user_pagesize
;
173 if (user_pagesize
&& user_pagesize
!= kernel_pagesize
)
174 fprintf(stderr
, _("Using user-specified page size %d, "
175 "instead of the system value %d\n"),
176 pagesize
, kernel_pagesize
);
178 signature_page
= (unsigned long *) malloc(pagesize
);
179 memset(signature_page
, 0, pagesize
);
180 p
= (struct swap_header_v1
*) signature_page
;
184 write_signature(char *sig
) {
185 char *sp
= (char *) signature_page
;
187 strncpy(sp
+pagesize
-10, sig
, 10);
193 return ((a
< 10) ? '0'+a
: 'a'+a
-10);
197 uuid_unparse(unsigned char *uuid
, char *s
) {
200 for (i
=0; i
<16; i
++) {
201 if (i
== 4 || i
== 6 || i
== 8 || i
== 10)
203 *s
++ = tohex((uuid
[i
] >> 4) & 0xf);
204 *s
++ = tohex(uuid
[i
] & 0xf);
211 write_uuid_and_label(char *uuid
, char *volume_name
) {
212 struct swap_header_v1_2
*h
;
215 if (sizeof(struct swap_header_v1
) !=
216 sizeof(struct swap_header_v1_2
)) {
218 _("Bad swap header size, no label written.\n"));
222 h
= (struct swap_header_v1_2
*) signature_page
;
224 memcpy(h
->uuid
, uuid
, sizeof(h
->uuid
));
226 xstrncpy(h
->volume_name
, volume_name
, sizeof(h
->volume_name
));
227 if (strlen(volume_name
) > strlen(h
->volume_name
))
228 fprintf(stderr
, _("Label was truncated.\n"));
230 if (uuid
|| volume_name
) {
232 printf("LABEL=%s, ", h
->volume_name
);
234 printf(_("no label, "));
235 #ifdef HAVE_UUID_UUID_H
237 char uuid_string
[37];
238 uuid_unparse(uuid
, uuid_string
);
239 printf("UUID=%s\n", uuid_string
);
242 printf(_("no uuid\n"));
247 * Find out what the maximum amount of swap space is that the kernel will
248 * handle. This wouldn't matter if the kernel just used as much of the
249 * swap space as it can handle, but until 2.3.4 it would return an error
250 * to swapon() if the swapspace was too large.
252 #define V0_MAX_PAGES (8 * (pagesize - 10))
253 /* Before 2.2.0pre9 */
254 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
255 /* Since 2.2.0pre9, before 2.3.4:
256 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
258 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
259 #define SWP_OFFSET(entry) ((entry) >> 8)
260 on the various architectures. Below the result - yuk.
262 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
263 i386 2^12 o<<8 e>>8 1<<24 1<<19
264 mips 2^12 o<<15 e>>15 1<<17 1<<19
265 alpha 2^13 o<<40 e>>40 1<<24 1<<18
266 m68k 2^12 o<<12 e>>12 1<<20 1<<19
267 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
268 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
269 ppc 2^12 o<<8 e>>8 1<<24 1<<19
270 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
271 armv 2^12 o<<9 e>>9 1<<23 1<<19
273 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
275 The bad part is that we need to know this since the kernel will
276 refuse a swap space if it is too large.
278 /* patch from jj - why does this differ from the above? */
279 /* 32bit kernels have a second limitation of 2GB, sparc64 is limited by
280 the size of virtual address space allocation for vmalloc */
281 #if defined(__alpha__)
282 #define V1_MAX_PAGES ((1 << 24) - 1)
283 #elif defined(__mips__)
284 #define V1_MAX_PAGES ((1 << 17) - 1)
285 #elif defined(__sparc__)
286 #define V1_MAX_PAGES (is_sparc64() ? ((3 << 29) - 1) : ((1 << 18) - 1))
287 #elif defined(__ia64__)
289 * The actual size will depend on the amount of virtual address space
290 * available to vmalloc the swap map.
292 #define V1_MAX_PAGES ((1UL << 54) - 1)
294 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
296 /* man page now says:
297 The maximum useful size of a swap area now depends on the architecture.
298 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
299 128GB on alpha and 3TB on sparc64.
302 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
305 * One more point of lossage - Linux swapspace really is a mess.
306 * The definition of the bitmap used is architecture dependent,
307 * and requires one to know whether the machine is bigendian,
308 * and if so, whether it will use 32-bit or 64-bit units in
310 * davem writes: "... is based upon an unsigned long type of
311 * the cpu and the native endianness".
312 * So, it seems we can write `unsigned long' below.
313 * However, sparc64 uses 64-bit units in the kernel, while
314 * mkswap may have been translated with 32-bit longs. Thus,
315 * we need an explicit test for version 0 swap on sparc64.
319 bit_set (unsigned long *addr
, unsigned int nr
) {
323 unsigned long long *bitmap
= (unsigned long long *) addr
;
324 unsigned long long bitnum
= (unsigned long long) nr
;
325 unsigned long long rl
, ml
;
327 bitmap
+= bitnum
/ (8 * sizeof(long long));
329 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
334 addr
+= nr
/ (8 * sizeof(unsigned long));
336 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
341 bit_test_and_clear (unsigned long *addr
, unsigned int nr
) {
345 unsigned long long *bitmap
= (unsigned long long *) addr
;
346 unsigned long long bitnum
= (unsigned long long) nr
;
347 unsigned long long rl
, ml
;
349 bitmap
+= bitnum
/ (8 * sizeof(long long));
351 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
353 return ((rl
& ml
) != 0ULL);
356 addr
+= nr
/ (8 * sizeof(unsigned long));
358 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
366 _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] [-L label] /dev/name [blocks]\n"),
372 die(const char *str
) {
373 fprintf(stderr
, "%s: %s\n", program_name
, str
);
380 bit_set(signature_page
, page
);
386 bit_test_and_clear(signature_page
, page
);
388 if (badpages
== MAX_BADPAGES
)
389 die(_("too many bad pages"));
390 p
->badpages
[badpages
] = page
;
397 unsigned int current_page
;
401 buffer
= malloc(pagesize
);
403 die(_("Out of memory"));
405 while (current_page
< PAGES
) {
407 page_ok(current_page
++);
410 if (do_seek
&& lseek(DEV
,current_page
*pagesize
,SEEK_SET
) !=
411 current_page
*pagesize
)
412 die(_("seek failed in check_blocks"));
413 if ((do_seek
= (pagesize
!= read(DEV
, buffer
, pagesize
)))) {
414 page_bad(current_page
++);
417 page_ok(current_page
++);
420 printf(_("one bad page\n"));
421 else if (badpages
> 1)
422 printf(_("%lu bad pages\n"), badpages
);
426 valid_offset (int fd
, off_t offset
) {
429 if (lseek (fd
, offset
, 0) < 0)
431 if (read (fd
, &ch
, 1) < 1)
441 for (high
= 1; high
> 0 && valid_offset (fd
, high
); high
*= 2)
443 while (low
< high
- 1) {
444 const off_t mid
= (low
+ high
) / 2;
446 if (valid_offset (fd
, mid
))
454 /* return size in pages, to avoid integer overflow */
456 get_size(const char *file
) {
460 fd
= open(file
, O_RDONLY
);
465 if (ioctl(fd
, BLKGETSIZE
, &size
) >= 0) {
466 int sectors_per_page
= pagesize
/512;
467 size
/= sectors_per_page
;
469 size
= find_size(fd
) / pagesize
;
477 return (c
>= '1' && c
<= '9');
482 * Check to make certain that our new filesystem won't be created on
483 * an already mounted partition. Code adapted from mke2fs, Copyright
484 * (C) 1994 Theodore Ts'o. Also licensed under GPL.
485 * (C) 2006 Karel Zak -- port to mkswap
492 if ((f
= setmntent (MOUNTED
, "r")) == NULL
)
494 while ((mnt
= getmntent (f
)) != NULL
)
495 if (strcmp (device_name
, mnt
->mnt_fsname
) == 0)
504 main(int argc
, char ** argv
) {
507 unsigned long maxpages
;
508 unsigned long goodpages
;
512 char *block_count
= 0;
514 char *opt_label
= NULL
;
516 #ifdef HAVE_UUID_UUID_H
520 program_name
= (argc
&& *argv
) ? argv
[0] : "mkswap";
521 if ((pp
= strrchr(program_name
, '/')) != NULL
)
524 setlocale(LC_ALL
, "");
525 bindtextdomain(PACKAGE
, LOCALEDIR
);
529 (!strcmp(argv
[1], "-V") || !strcmp(argv
[1], "--version"))) {
530 printf(_("%s (%s)\n"), program_name
, PACKAGE_STRING
);
534 for (i
=1; i
<argc
; i
++) {
535 if (argv
[i
][0] == '-') {
536 switch (argv
[i
][1]) {
545 if (!*pp
&& i
+1 < argc
)
548 user_pagesize
= atoi(pp
);
554 if (!*pp
&& i
+1 < argc
)
559 version
= atoi(argv
[i
]+2);
564 } else if (!device_name
) {
565 device_name
= argv
[i
];
566 } else if (!block_count
) {
567 block_count
= argv
[i
];
572 #ifdef HAVE_UUID_UUID_H
573 uuid_generate(uuid_dat
);
577 init_signature_page(); /* get pagesize */
581 _("%s: error: Nowhere to set up swap on?\n"),
586 /* this silly user specified the number of blocks
589 int blocks_per_page
= pagesize
/1024;
590 PAGES
= strtoul(block_count
,&tmp
,0)/blocks_per_page
;
594 sz
= get_size(device_name
);
597 } else if (PAGES
> sz
&& !force
) {
600 "size %lu is larger than device size %lu\n"),
602 PAGES
*(pagesize
/1024), sz
*(pagesize
/1024));
607 /* labels only for v1 */
611 /* use version 1 as default, if possible */
612 if (PAGES
<= V0_MAX_PAGES
&& PAGES
> V1_MAX_PAGES
)
614 else if (linux_version_code() < MAKE_VERSION(2,1,117))
616 else if (pagesize
< 2048)
621 if (version
!= 0 && version
!= 1) {
622 fprintf(stderr
, _("%s: error: unknown version %d\n"),
623 program_name
, version
);
629 _("%s: error: swap area needs to be at least %ldkB\n"),
630 program_name
, (long)(10 * pagesize
/ 1000));
635 maxpages
= V0_MAX_PAGES
;
636 else if (linux_version_code() >= MAKE_VERSION(2,3,4))
638 else if (linux_version_code() >= MAKE_VERSION(2,2,1))
639 maxpages
= V1_MAX_PAGES
;
641 maxpages
= V1_OLD_MAX_PAGES
;
643 if (PAGES
> maxpages
) {
646 _("%s: warning: truncating swap area to %ldkB\n"),
647 program_name
, PAGES
* pagesize
/ 1000);
650 if (opt_label
&& version
== 0) {
652 _("%s: error: label only with v1 swap area\n"),
657 DEV
= open(device_name
,O_RDWR
);
658 if (DEV
< 0 || fstat(DEV
, &statbuf
) < 0) {
663 /* Want a block device. Probably not /dev/hda or /dev/hdb. */
664 if (!S_ISBLK(statbuf
.st_mode
))
666 else if (statbuf
.st_rdev
== 0x0300 || statbuf
.st_rdev
== 0x0340) {
669 "will not try to make swapdevice on '%s'\n"),
670 program_name
, device_name
);
672 } else if (check_mount()) {
675 "%s is mounted; will not make swapspace.\n"),
676 program_name
, device_name
);
681 if (!force
&& version
== 0) {
682 /* Don't overwrite partition table unless forced */
683 unsigned char *buffer
= (unsigned char *)signature_page
;
684 unsigned short *q
, sum
;
686 if (read(DEV
, buffer
, 512) != 512)
687 die(_("fatal: first page unreadable"));
688 if (buffer
[508] == 0xDA && buffer
[509] == 0xBE) {
689 q
= (unsigned short *)(buffer
+ 510);
690 for (sum
= 0; q
>= (unsigned short *) buffer
;)
694 %s: Device '%s' contains a valid Sun disklabel.\n\
695 This probably means creating v0 swap would destroy your partition table\n\
696 No swap created. If you really want to create swap v0 on that device, use\n\
697 the -f option to force it.\n"),
698 program_name
, device_name
);
705 if (version
== 0 || check
)
707 if (version
== 0 && !bit_test_and_clear(signature_page
,0))
708 die(_("fatal: first page unreadable"));
710 p
->version
= version
;
711 p
->last_page
= PAGES
-1;
712 p
->nr_badpages
= badpages
;
715 goodpages
= PAGES
- badpages
- 1;
716 if ((long) goodpages
<= 0)
717 die(_("Unable to set up swap-space: unreadable"));
718 printf(_("Setting up swapspace version %d, size = %llu kB\n"),
719 version
, (unsigned long long)goodpages
* pagesize
/ 1000);
720 write_signature((version
== 0) ? "SWAP-SPACE" : "SWAPSPACE2");
723 write_uuid_and_label(uuid
, opt_label
);
725 offset
= ((version
== 0) ? 0 : 1024);
726 if (lseek(DEV
, offset
, SEEK_SET
) != offset
)
727 die(_("unable to rewind swap-device"));
728 if (write(DEV
,(char*)signature_page
+offset
, pagesize
-offset
)
730 die(_("unable to write signature page"));
733 * A subsequent swapon() will fail if the signature
734 * is not actually on disk. (This is a kernel bug.)
738 die(_("fsync failed"));