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>
44 #ifdef HAVE_LIBSELINUX
45 #include <selinux/selinux.h>
46 #include <selinux/context.h>
49 #include "swapheader.h"
54 #include <uuid/uuid.h>
59 #define BLKGETSIZE 0x1260
61 /* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
62 #define BLKGETSIZE _IO(0x12,96)
65 static char * program_name
= "mkswap";
66 static char * device_name
= NULL
;
68 static unsigned long PAGES
= 0;
69 static unsigned long badpages
= 0;
71 static int version
= -1;
73 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
75 #define SELINUX_SWAPFILE_TYPE "swapfile_t"
78 linux_version_code(void) {
79 struct utsname my_utsname
;
82 if (uname(&my_utsname
) == 0) {
83 p
= atoi(strtok(my_utsname
.release
, "."));
84 q
= atoi(strtok(NULL
, "."));
85 r
= atoi(strtok(NULL
, "."));
86 return MAKE_VERSION(p
,q
,r
);
93 # define is_sparc64() 1
99 static int sparc64
= -1;
101 if (sparc64
!= -1) return sparc64
;
104 if (uname(&un
) < 0) return 0;
105 if (! strcmp(un
.machine
, "sparc64")) {
109 if (strcmp(un
.machine
, "sparc"))
110 return 0; /* Should not happen */
112 #ifdef HAVE_PERSONALITY
114 extern int personality(unsigned long);
116 #define PERS_LINUX 0x00000000
117 #define PERS_LINUX_32BIT 0x00800000
118 #define PERS_LINUX32 0x00000008
120 oldpers
= personality(PERS_LINUX_32BIT
);
122 if (personality(PERS_LINUX
) != -1) {
124 if (! strcmp(un
.machine
, "sparc64")) {
126 oldpers
= PERS_LINUX32
;
129 personality(oldpers
);
136 # define is_be64() is_sparc64()
137 # endif /* sparc32 */
143 * The definition of the union swap_header uses the kernel constant PAGE_SIZE.
144 * Unfortunately, on some architectures this depends on the hardware model, and
145 * can only be found at run time -- we use getpagesize(), so that we do not
146 * need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
148 * Even more unfortunately, getpagesize() does not always return the right
149 * information. For example, libc4, libc5 and glibc 2.0 do not use the system
150 * call but invent a value themselves (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC),
151 * and thus it may happen that e.g. on a sparc kernel PAGE_SIZE=4096 and
152 * getpagesize() returns 8192.
154 * What to do? Let us allow the user to specify the pagesize explicitly.
156 * Update 05-Feb-2007 (kzak):
157 * - use sysconf(_SC_PAGESIZE) to be consistent with the rest of
158 * util-linux code. It is the standardized and preferred way of
159 * querying page size.
161 static int user_pagesize
;
163 static unsigned long *signature_page
;
164 struct swap_header_v1
*p
;
167 init_signature_page(void) {
169 int kernel_pagesize
= pagesize
= (int) sysconf(_SC_PAGESIZE
);
172 if ((user_pagesize
& (user_pagesize
-1)) ||
173 user_pagesize
< 1024) {
174 fprintf(stderr
, _("Bad user-specified page size %d\n"),
178 pagesize
= user_pagesize
;
181 if (user_pagesize
&& user_pagesize
!= kernel_pagesize
)
182 fprintf(stderr
, _("Using user-specified page size %d, "
183 "instead of the system value %d\n"),
184 pagesize
, kernel_pagesize
);
186 signature_page
= (unsigned long *) malloc(pagesize
);
187 memset(signature_page
, 0, pagesize
);
188 p
= (struct swap_header_v1
*) signature_page
;
192 write_signature(char *sig
) {
193 char *sp
= (char *) signature_page
;
195 strncpy(sp
+pagesize
-10, sig
, 10);
199 write_uuid_and_label(unsigned char *uuid
, char *volume_name
) {
200 struct swap_header_v1_2
*h
;
203 if (sizeof(struct swap_header_v1
) !=
204 sizeof(struct swap_header_v1_2
)) {
206 _("Bad swap header size, no label written.\n"));
210 h
= (struct swap_header_v1_2
*) signature_page
;
212 memcpy(h
->uuid
, uuid
, sizeof(h
->uuid
));
214 xstrncpy(h
->volume_name
, volume_name
, sizeof(h
->volume_name
));
215 if (strlen(volume_name
) > strlen(h
->volume_name
))
216 fprintf(stderr
, _("Label was truncated.\n"));
218 if (uuid
|| volume_name
) {
220 printf("LABEL=%s, ", h
->volume_name
);
222 printf(_("no label, "));
225 char uuid_string
[37];
226 uuid_unparse(uuid
, uuid_string
);
227 printf("UUID=%s\n", uuid_string
);
230 printf(_("no uuid\n"));
235 * Find out what the maximum amount of swap space is that the kernel will
236 * handle. This wouldn't matter if the kernel just used as much of the
237 * swap space as it can handle, but until 2.3.4 it would return an error
238 * to swapon() if the swapspace was too large.
240 #define V0_MAX_PAGES (8 * (pagesize - 10))
241 /* Before 2.2.0pre9 */
242 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
243 /* Since 2.2.0pre9, before 2.3.4:
244 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
246 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
247 #define SWP_OFFSET(entry) ((entry) >> 8)
248 on the various architectures. Below the result - yuk.
250 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
251 i386 2^12 o<<8 e>>8 1<<24 1<<19
252 mips 2^12 o<<15 e>>15 1<<17 1<<19
253 alpha 2^13 o<<40 e>>40 1<<24 1<<18
254 m68k 2^12 o<<12 e>>12 1<<20 1<<19
255 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
256 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
257 ppc 2^12 o<<8 e>>8 1<<24 1<<19
258 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
259 armv 2^12 o<<9 e>>9 1<<23 1<<19
261 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
263 The bad part is that we need to know this since the kernel will
264 refuse a swap space if it is too large.
266 /* patch from jj - why does this differ from the above? */
267 /* 32bit kernels have a second limitation of 2GB, sparc64 is limited by
268 the size of virtual address space allocation for vmalloc */
269 #if defined(__alpha__)
270 #define V1_MAX_PAGES ((1 << 24) - 1)
271 #elif defined(__mips__)
272 #define V1_MAX_PAGES ((1 << 17) - 1)
273 #elif defined(__sparc__)
274 #define V1_MAX_PAGES (is_sparc64() ? ((3 << 29) - 1) : ((1 << 18) - 1))
275 #elif defined(__ia64__)
277 * The actual size will depend on the amount of virtual address space
278 * available to vmalloc the swap map.
280 #define V1_MAX_PAGES ((1UL << 54) - 1)
282 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
284 /* man page now says:
285 The maximum useful size of a swap area now depends on the architecture.
286 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
287 128GB on alpha and 3TB on sparc64.
290 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
293 * One more point of lossage - Linux swapspace really is a mess.
294 * The definition of the bitmap used is architecture dependent,
295 * and requires one to know whether the machine is bigendian,
296 * and if so, whether it will use 32-bit or 64-bit units in
298 * davem writes: "... is based upon an unsigned long type of
299 * the cpu and the native endianness".
300 * So, it seems we can write `unsigned long' below.
301 * However, sparc64 uses 64-bit units in the kernel, while
302 * mkswap may have been translated with 32-bit longs. Thus,
303 * we need an explicit test for version 0 swap on sparc64.
307 bit_set (unsigned long *addr
, unsigned int nr
) {
311 unsigned long long *bitmap
= (unsigned long long *) addr
;
312 unsigned long long bitnum
= (unsigned long long) nr
;
313 unsigned long long rl
, ml
;
315 bitmap
+= bitnum
/ (8 * sizeof(long long));
317 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
322 addr
+= nr
/ (8 * sizeof(unsigned long));
324 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
329 bit_test_and_clear (unsigned long *addr
, unsigned int nr
) {
333 unsigned long long *bitmap
= (unsigned long long *) addr
;
334 unsigned long long bitnum
= (unsigned long long) nr
;
335 unsigned long long rl
, ml
;
337 bitmap
+= bitnum
/ (8 * sizeof(long long));
339 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
341 return ((rl
& ml
) != 0ULL);
344 addr
+= nr
/ (8 * sizeof(unsigned long));
346 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
354 _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] [-L label] /dev/name [blocks]\n"),
360 die(const char *str
) {
361 fprintf(stderr
, "%s: %s\n", program_name
, str
);
368 bit_set(signature_page
, page
);
374 bit_test_and_clear(signature_page
, page
);
376 if (badpages
== MAX_BADPAGES
)
377 die(_("too many bad pages"));
378 p
->badpages
[badpages
] = page
;
385 unsigned int current_page
;
389 buffer
= malloc(pagesize
);
391 die(_("Out of memory"));
393 while (current_page
< PAGES
) {
395 page_ok(current_page
++);
398 if (do_seek
&& lseek(DEV
,current_page
*pagesize
,SEEK_SET
) !=
399 current_page
*pagesize
)
400 die(_("seek failed in check_blocks"));
401 if ((do_seek
= (pagesize
!= read(DEV
, buffer
, pagesize
)))) {
402 page_bad(current_page
++);
405 page_ok(current_page
++);
408 printf(_("one bad page\n"));
409 else if (badpages
> 1)
410 printf(_("%lu bad pages\n"), badpages
);
414 valid_offset (int fd
, off_t offset
) {
417 if (lseek (fd
, offset
, 0) < 0)
419 if (read (fd
, &ch
, 1) < 1)
429 for (high
= 1; high
> 0 && valid_offset (fd
, high
); high
*= 2)
431 while (low
< high
- 1) {
432 const off_t mid
= (low
+ high
) / 2;
434 if (valid_offset (fd
, mid
))
442 /* return size in pages, to avoid integer overflow */
444 get_size(const char *file
) {
448 fd
= open(file
, O_RDONLY
);
453 if (ioctl(fd
, BLKGETSIZE
, &size
) >= 0) {
454 int sectors_per_page
= pagesize
/512;
455 size
/= sectors_per_page
;
457 size
= find_size(fd
) / pagesize
;
465 return (c
>= '1' && c
<= '9');
470 * Check to make certain that our new filesystem won't be created on
471 * an already mounted partition. Code adapted from mke2fs, Copyright
472 * (C) 1994 Theodore Ts'o. Also licensed under GPL.
473 * (C) 2006 Karel Zak -- port to mkswap
480 if ((f
= setmntent (MOUNTED
, "r")) == NULL
)
482 while ((mnt
= getmntent (f
)) != NULL
)
483 if (strcmp (device_name
, mnt
->mnt_fsname
) == 0)
492 main(int argc
, char ** argv
) {
495 unsigned long maxpages
;
496 unsigned long goodpages
;
500 char *block_count
= 0;
502 char *opt_label
= NULL
;
503 unsigned char *uuid
= NULL
;
508 program_name
= (argc
&& *argv
) ? argv
[0] : "mkswap";
509 if ((pp
= strrchr(program_name
, '/')) != NULL
)
512 setlocale(LC_ALL
, "");
513 bindtextdomain(PACKAGE
, LOCALEDIR
);
517 (!strcmp(argv
[1], "-V") || !strcmp(argv
[1], "--version"))) {
518 printf(_("%s (%s)\n"), program_name
, PACKAGE_STRING
);
522 for (i
=1; i
<argc
; i
++) {
523 if (argv
[i
][0] == '-') {
524 switch (argv
[i
][1]) {
533 if (!*pp
&& i
+1 < argc
)
536 user_pagesize
= atoi(pp
);
542 if (!*pp
&& i
+1 < argc
)
547 version
= atoi(argv
[i
]+2);
552 } else if (!device_name
) {
553 device_name
= argv
[i
];
554 } else if (!block_count
) {
555 block_count
= argv
[i
];
561 uuid_generate(uuid_dat
);
565 init_signature_page(); /* get pagesize */
569 _("%s: error: Nowhere to set up swap on?\n"),
574 /* this silly user specified the number of blocks
577 int blocks_per_page
= pagesize
/1024;
578 PAGES
= strtoul(block_count
,&tmp
,0)/blocks_per_page
;
582 sz
= get_size(device_name
);
585 } else if (PAGES
> sz
&& !force
) {
588 "size %lu is larger than device size %lu\n"),
590 PAGES
*(pagesize
/1024), sz
*(pagesize
/1024));
595 /* labels only for v1 */
599 /* use version 1 as default, if possible */
600 if (linux_version_code() < MAKE_VERSION(2,1,117))
602 else if (pagesize
< 2048)
607 if (version
!= 0 && version
!= 1) {
608 fprintf(stderr
, _("%s: error: unknown version %d\n"),
609 program_name
, version
);
615 _("%s: error: swap area needs to be at least %ldkB\n"),
616 program_name
, (long)(10 * pagesize
/ 1000));
621 maxpages
= V0_MAX_PAGES
;
622 else if (linux_version_code() >= MAKE_VERSION(2,3,4))
624 else if (linux_version_code() >= MAKE_VERSION(2,2,1))
625 maxpages
= V1_MAX_PAGES
;
627 maxpages
= V1_OLD_MAX_PAGES
;
629 if (PAGES
> maxpages
) {
632 _("%s: warning: truncating swap area to %ldkB\n"),
633 program_name
, PAGES
* pagesize
/ 1000);
636 if (opt_label
&& version
== 0) {
638 _("%s: error: label only with v1 swap area\n"),
643 if (stat(device_name
, &statbuf
) < 0) {
647 if (S_ISBLK(statbuf
.st_mode
))
648 DEV
= open(device_name
, O_RDWR
| O_EXCL
);
650 DEV
= open(device_name
, O_RDWR
);
657 /* Want a block device. Probably not /dev/hda or /dev/hdb. */
658 if (!S_ISBLK(statbuf
.st_mode
))
660 else if (statbuf
.st_rdev
== 0x0300 || statbuf
.st_rdev
== 0x0340) {
663 "will not try to make swapdevice on '%s'\n"),
664 program_name
, device_name
);
666 } else if (check_mount()) {
669 "%s is mounted; will not make swapspace.\n"),
670 program_name
, device_name
);
675 if (!force
&& version
== 0) {
676 /* Don't overwrite partition table unless forced */
677 unsigned char *buffer
= (unsigned char *)signature_page
;
678 unsigned short *q
, sum
;
680 if (read(DEV
, buffer
, 512) != 512)
681 die(_("fatal: first page unreadable"));
682 if (buffer
[508] == 0xDA && buffer
[509] == 0xBE) {
683 q
= (unsigned short *)(buffer
+ 510);
684 for (sum
= 0; q
>= (unsigned short *) buffer
;)
688 %s: Device '%s' contains a valid Sun disklabel.\n\
689 This probably means creating v0 swap would destroy your partition table.\n\
690 No swap was created. If you really want to create v0 swap on that device,\n\
691 use the -f option to force it.\n"),
692 program_name
, device_name
);
699 if (version
== 0 || check
)
701 if (version
== 0 && !bit_test_and_clear(signature_page
,0))
702 die(_("fatal: first page unreadable"));
704 p
->version
= version
;
705 p
->last_page
= PAGES
-1;
706 p
->nr_badpages
= badpages
;
709 goodpages
= PAGES
- badpages
- 1;
710 if ((long) goodpages
<= 0)
711 die(_("Unable to set up swap-space: unreadable"));
712 printf(_("Setting up swapspace version %d, size = %llu kB\n"),
713 version
, (unsigned long long)goodpages
* pagesize
/ 1000);
714 write_signature((version
== 0) ? "SWAP-SPACE" : "SWAPSPACE2");
717 write_uuid_and_label(uuid
, opt_label
);
719 offset
= ((version
== 0) ? 0 : 1024);
720 if (lseek(DEV
, offset
, SEEK_SET
) != offset
)
721 die(_("unable to rewind swap-device"));
722 if (write(DEV
,(char*)signature_page
+offset
, pagesize
-offset
)
724 die(_("unable to write signature page"));
727 * A subsequent swapon() will fail if the signature
728 * is not actually on disk. (This is a kernel bug.)
732 die(_("fsync failed"));
735 #ifdef HAVE_LIBSELINUX
736 if (S_ISREG(statbuf
.st_mode
) && is_selinux_enabled()) {
737 security_context_t context_string
;
738 security_context_t oldcontext
;
739 context_t newcontext
;
741 if (fgetfilecon(DEV
, &oldcontext
) < 0) {
742 if (errno
!= ENODATA
) {
743 fprintf(stderr
, _("%s: %s: unable to obtain selinux file label: %s\n"),
744 program_name
, device_name
,
748 if (matchpathcon(device_name
, statbuf
.st_mode
, &oldcontext
))
749 die(_("unable to matchpathcon()"));
751 if (!(newcontext
= context_new(oldcontext
)))
752 die(_("unable to create new selinux context"));
753 if (context_type_set(newcontext
, SELINUX_SWAPFILE_TYPE
))
754 die(_("couldn't compute selinux context"));
756 context_string
= context_str(newcontext
);
758 if (strcmp(context_string
, oldcontext
)!=0) {
759 if (fsetfilecon(DEV
, context_string
)) {
760 fprintf(stderr
, _("%s: unable to relabel %s to %s: %s\n"),
761 program_name
, device_name
,
767 context_free(newcontext
);