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 "linux_version.h"
50 #include "swapheader.h"
56 #include <uuid/uuid.h>
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 SELINUX_SWAPFILE_TYPE "swapfile_t"
71 # define is_sparc64() 1
77 static int sparc64
= -1;
79 if (sparc64
!= -1) return sparc64
;
82 if (uname(&un
) < 0) return 0;
83 if (! strcmp(un
.machine
, "sparc64")) {
87 if (strcmp(un
.machine
, "sparc"))
88 return 0; /* Should not happen */
90 #ifdef HAVE_PERSONALITY
92 extern int personality(unsigned long);
94 #define PERS_LINUX 0x00000000
95 #define PERS_LINUX_32BIT 0x00800000
96 #define PERS_LINUX32 0x00000008
98 oldpers
= personality(PERS_LINUX_32BIT
);
100 if (personality(PERS_LINUX
) != -1) {
102 if (! strcmp(un
.machine
, "sparc64")) {
104 oldpers
= PERS_LINUX32
;
107 personality(oldpers
);
114 # define is_be64() is_sparc64()
115 # endif /* sparc32 */
121 * The definition of the union swap_header uses the kernel constant PAGE_SIZE.
122 * Unfortunately, on some architectures this depends on the hardware model, and
123 * can only be found at run time -- we use getpagesize(), so that we do not
124 * need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
126 * Even more unfortunately, getpagesize() does not always return the right
127 * information. For example, libc4, libc5 and glibc 2.0 do not use the system
128 * call but invent a value themselves (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC),
129 * and thus it may happen that e.g. on a sparc kernel PAGE_SIZE=4096 and
130 * getpagesize() returns 8192.
132 * What to do? Let us allow the user to specify the pagesize explicitly.
134 * Update 05-Feb-2007 (kzak):
135 * - use sysconf(_SC_PAGESIZE) to be consistent with the rest of
136 * util-linux code. It is the standardized and preferred way of
137 * querying page size.
139 static int user_pagesize
;
141 static unsigned long *signature_page
;
142 struct swap_header_v1
*p
;
145 init_signature_page(void) {
147 int kernel_pagesize
= pagesize
= (int) sysconf(_SC_PAGESIZE
);
150 if ((user_pagesize
& (user_pagesize
-1)) ||
151 user_pagesize
< 1024) {
152 fprintf(stderr
, _("Bad user-specified page size %d\n"),
156 pagesize
= user_pagesize
;
159 if (user_pagesize
&& user_pagesize
!= kernel_pagesize
)
160 fprintf(stderr
, _("Using user-specified page size %d, "
161 "instead of the system value %d\n"),
162 pagesize
, kernel_pagesize
);
164 signature_page
= (unsigned long *) malloc(pagesize
);
165 memset(signature_page
, 0, pagesize
);
166 p
= (struct swap_header_v1
*) signature_page
;
170 write_signature(char *sig
) {
171 char *sp
= (char *) signature_page
;
173 strncpy(sp
+pagesize
-10, sig
, 10);
177 write_uuid_and_label(unsigned char *uuid
, char *volume_name
) {
178 struct swap_header_v1_2
*h
;
181 if (sizeof(struct swap_header_v1
) !=
182 sizeof(struct swap_header_v1_2
)) {
184 _("Bad swap header size, no label written.\n"));
188 h
= (struct swap_header_v1_2
*) signature_page
;
190 memcpy(h
->uuid
, uuid
, sizeof(h
->uuid
));
192 xstrncpy(h
->volume_name
, volume_name
, sizeof(h
->volume_name
));
193 if (strlen(volume_name
) > strlen(h
->volume_name
))
194 fprintf(stderr
, _("Label was truncated.\n"));
196 if (uuid
|| volume_name
) {
198 printf("LABEL=%s, ", h
->volume_name
);
200 printf(_("no label, "));
203 char uuid_string
[37];
204 uuid_unparse(uuid
, uuid_string
);
205 printf("UUID=%s\n", uuid_string
);
208 printf(_("no uuid\n"));
213 * Find out what the maximum amount of swap space is that the kernel will
214 * handle. This wouldn't matter if the kernel just used as much of the
215 * swap space as it can handle, but until 2.3.4 it would return an error
216 * to swapon() if the swapspace was too large.
218 #define V0_MAX_PAGES (8 * (pagesize - 10))
219 /* Before 2.2.0pre9 */
220 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
221 /* Since 2.2.0pre9, before 2.3.4:
222 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
224 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
225 #define SWP_OFFSET(entry) ((entry) >> 8)
226 on the various architectures. Below the result - yuk.
228 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
229 i386 2^12 o<<8 e>>8 1<<24 1<<19
230 mips 2^12 o<<15 e>>15 1<<17 1<<19
231 alpha 2^13 o<<40 e>>40 1<<24 1<<18
232 m68k 2^12 o<<12 e>>12 1<<20 1<<19
233 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
234 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
235 ppc 2^12 o<<8 e>>8 1<<24 1<<19
236 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
237 armv 2^12 o<<9 e>>9 1<<23 1<<19
239 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
241 The bad part is that we need to know this since the kernel will
242 refuse a swap space if it is too large.
244 /* patch from jj - why does this differ from the above? */
245 /* 32bit kernels have a second limitation of 2GB, sparc64 is limited by
246 the size of virtual address space allocation for vmalloc */
247 #if defined(__alpha__)
248 #define V1_MAX_PAGES ((1 << 24) - 1)
249 #elif defined(__mips__)
250 #define V1_MAX_PAGES ((1 << 17) - 1)
251 #elif defined(__sparc__)
252 #define V1_MAX_PAGES (is_sparc64() ? ((3 << 29) - 1) : ((1 << 18) - 1))
253 #elif defined(__ia64__)
255 * The actual size will depend on the amount of virtual address space
256 * available to vmalloc the swap map.
258 #define V1_MAX_PAGES ((1UL << 54) - 1)
260 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
262 /* man page now says:
263 The maximum useful size of a swap area now depends on the architecture.
264 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
265 128GB on alpha and 3TB on sparc64.
268 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
271 * One more point of lossage - Linux swapspace really is a mess.
272 * The definition of the bitmap used is architecture dependent,
273 * and requires one to know whether the machine is bigendian,
274 * and if so, whether it will use 32-bit or 64-bit units in
276 * davem writes: "... is based upon an unsigned long type of
277 * the cpu and the native endianness".
278 * So, it seems we can write `unsigned long' below.
279 * However, sparc64 uses 64-bit units in the kernel, while
280 * mkswap may have been translated with 32-bit longs. Thus,
281 * we need an explicit test for version 0 swap on sparc64.
285 bit_set (unsigned long *addr
, unsigned int nr
) {
289 unsigned long long *bitmap
= (unsigned long long *) addr
;
290 unsigned long long bitnum
= (unsigned long long) nr
;
291 unsigned long long rl
, ml
;
293 bitmap
+= bitnum
/ (8 * sizeof(long long));
295 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
300 addr
+= nr
/ (8 * sizeof(unsigned long));
302 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
307 bit_test_and_clear (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));
319 return ((rl
& ml
) != 0ULL);
322 addr
+= nr
/ (8 * sizeof(unsigned long));
324 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
332 _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] [-L label] [-U UUID] /dev/name [blocks]\n"),
338 die(const char *str
) {
339 fprintf(stderr
, "%s: %s\n", program_name
, str
);
346 bit_set(signature_page
, page
);
352 bit_test_and_clear(signature_page
, page
);
354 if (badpages
== MAX_BADPAGES
)
355 die(_("too many bad pages"));
356 p
->badpages
[badpages
] = page
;
363 unsigned int current_page
;
367 buffer
= malloc(pagesize
);
369 die(_("Out of memory"));
371 while (current_page
< PAGES
) {
373 page_ok(current_page
++);
376 if (do_seek
&& lseek(DEV
,current_page
*pagesize
,SEEK_SET
) !=
377 current_page
*pagesize
)
378 die(_("seek failed in check_blocks"));
379 if ((do_seek
= (pagesize
!= read(DEV
, buffer
, pagesize
)))) {
380 page_bad(current_page
++);
383 page_ok(current_page
++);
386 printf(_("one bad page\n"));
387 else if (badpages
> 1)
388 printf(_("%lu bad pages\n"), badpages
);
392 valid_offset (int fd
, off_t offset
) {
395 if (lseek (fd
, offset
, 0) < 0)
397 if (read (fd
, &ch
, 1) < 1)
407 for (high
= 1; high
> 0 && valid_offset (fd
, high
); high
*= 2)
409 while (low
< high
- 1) {
410 const off_t mid
= (low
+ high
) / 2;
412 if (valid_offset (fd
, mid
))
420 /* return size in pages, to avoid integer overflow */
422 get_size(const char *file
) {
424 unsigned long long size
;
426 fd
= open(file
, O_RDONLY
);
431 if (blkdev_get_size(fd
, &size
) == 0)
434 size
= find_size(fd
) / pagesize
;
442 return (c
>= '1' && c
<= '9');
447 * Check to make certain that our new filesystem won't be created on
448 * an already mounted partition. Code adapted from mke2fs, Copyright
449 * (C) 1994 Theodore Ts'o. Also licensed under GPL.
450 * (C) 2006 Karel Zak -- port to mkswap
457 if ((f
= setmntent (MOUNTED
, "r")) == NULL
)
459 while ((mnt
= getmntent (f
)) != NULL
)
460 if (strcmp (device_name
, mnt
->mnt_fsname
) == 0)
470 write_all(int fd
, const void *buf
, size_t count
) {
475 tmp
= write(fd
, buf
, count
);
480 } else if (errno
!= EINTR
&& errno
!= EAGAIN
)
487 main(int argc
, char ** argv
) {
490 unsigned long maxpages
;
491 unsigned long goodpages
;
495 char *block_count
= 0;
497 char *opt_label
= NULL
;
498 unsigned char *uuid
= NULL
;
500 const char *opt_uuid
= NULL
;
504 program_name
= (argc
&& *argv
) ? argv
[0] : "mkswap";
505 if ((pp
= strrchr(program_name
, '/')) != NULL
)
508 setlocale(LC_ALL
, "");
509 bindtextdomain(PACKAGE
, LOCALEDIR
);
513 (!strcmp(argv
[1], "-V") || !strcmp(argv
[1], "--version"))) {
514 printf(_("%s (%s)\n"), program_name
, PACKAGE_STRING
);
518 for (i
=1; i
<argc
; i
++) {
519 if (argv
[i
][0] == '-') {
520 switch (argv
[i
][1]) {
529 if (!*pp
&& i
+1 < argc
)
532 user_pagesize
= atoi(pp
);
538 if (!*pp
&& i
+1 < argc
)
543 version
= atoi(argv
[i
]+2);
547 opt_uuid
= argv
[i
]+2;
548 if (!*opt_uuid
&& i
+1 < argc
)
549 opt_uuid
= argv
[++i
];
551 fprintf(stderr
, _("%1$s: warning: ignore -U (UUIDs are unsupported by %1$s)\n"),
558 } else if (!device_name
) {
559 device_name
= argv
[i
];
560 } else if (!block_count
) {
561 block_count
= argv
[i
];
568 if (uuid_parse(opt_uuid
, uuid_dat
) != 0)
569 die(_("error: UUID parsing failed"));
571 uuid_generate(uuid_dat
);
575 init_signature_page(); /* get pagesize */
579 _("%s: error: Nowhere to set up swap on?\n"),
584 /* this silly user specified the number of blocks
587 int blocks_per_page
= pagesize
/1024;
588 PAGES
= strtoul(block_count
,&tmp
,0)/blocks_per_page
;
592 sz
= get_size(device_name
);
595 } else if (PAGES
> sz
&& !force
) {
598 "size %lu KiB is larger than device size %lu KiB\n"),
600 PAGES
*(pagesize
/1024), sz
*(pagesize
/1024));
605 /* labels only for v1 */
609 /* use version 1 as default, if possible */
611 if (get_linux_version() < KERNEL_VERSION(2,1,117))
620 if (version
!= 0 && version
!= 1) {
621 fprintf(stderr
, _("%s: error: unknown version %d\n"),
622 program_name
, version
);
628 _("%s: error: swap area needs to be at least %ld KiB\n"),
629 program_name
, (long)(10 * pagesize
/1024));
634 maxpages
= V0_MAX_PAGES
;
636 else if (get_linux_version() >= KERNEL_VERSION(2,3,4))
638 else if (get_linux_version() >= KERNEL_VERSION(2,2,1))
639 maxpages
= V1_MAX_PAGES
;
642 maxpages
= V1_OLD_MAX_PAGES
;
644 if (PAGES
> maxpages
) {
647 _("%s: warning: truncating swap area to %ld KiB\n"),
648 program_name
, PAGES
* pagesize
/ 1024);
651 if (opt_label
&& version
== 0) {
653 _("%s: error: label only with v1 swap area\n"),
658 if (stat(device_name
, &statbuf
) < 0) {
662 if (S_ISBLK(statbuf
.st_mode
))
663 DEV
= open(device_name
, O_RDWR
| O_EXCL
);
665 DEV
= open(device_name
, O_RDWR
);
672 /* Want a block device. Probably not /dev/hda or /dev/hdb. */
673 if (!S_ISBLK(statbuf
.st_mode
))
675 else if (statbuf
.st_rdev
== 0x0300 || statbuf
.st_rdev
== 0x0340) {
678 "will not try to make swapdevice on '%s'\n"),
679 program_name
, device_name
);
681 } else if (check_mount()) {
684 "%s is mounted; will not make swapspace.\n"),
685 program_name
, device_name
);
690 if (!force
&& version
== 0) {
691 /* Don't overwrite partition table unless forced */
692 unsigned char *buffer
= (unsigned char *)signature_page
;
693 unsigned short *q
, sum
;
695 if (read(DEV
, buffer
, 512) != 512)
696 die(_("fatal: first page unreadable"));
697 if (buffer
[508] == 0xDA && buffer
[509] == 0xBE) {
698 q
= (unsigned short *)(buffer
+ 510);
699 for (sum
= 0; q
>= (unsigned short *) buffer
;)
703 %s: Device '%s' contains a valid Sun disklabel.\n\
704 This probably means creating v0 swap would destroy your partition table.\n\
705 No swap was created. If you really want to create v0 swap on that device,\n\
706 use the -f option to force it.\n"),
707 program_name
, device_name
);
714 if (version
== 0 || check
)
716 if (version
== 0 && !bit_test_and_clear(signature_page
,0))
717 die(_("fatal: first page unreadable"));
719 p
->version
= version
;
720 p
->last_page
= PAGES
-1;
721 p
->nr_badpages
= badpages
;
724 goodpages
= PAGES
- badpages
- 1;
725 if ((long) goodpages
<= 0)
726 die(_("Unable to set up swap-space: unreadable"));
727 printf(_("Setting up swapspace version %d, size = %llu KiB\n"),
728 version
, (unsigned long long)goodpages
* pagesize
/ 1024);
729 write_signature((version
== 0) ? "SWAP-SPACE" : "SWAPSPACE2");
732 write_uuid_and_label(uuid
, opt_label
);
734 offset
= ((version
== 0) ? 0 : 1024);
735 if (lseek(DEV
, offset
, SEEK_SET
) != offset
)
736 die(_("unable to rewind swap-device"));
737 if (write_all(DEV
, (char *) signature_page
+ offset
,
738 pagesize
- offset
) == -1) {
739 fprintf(stderr
, _("%s: %s: unable to write signature page: %s"),
740 program_name
, device_name
, strerror(errno
));
745 * A subsequent swapon() will fail if the signature
746 * is not actually on disk. (This is a kernel bug.)
750 die(_("fsync failed"));
753 #ifdef HAVE_LIBSELINUX
754 if (S_ISREG(statbuf
.st_mode
) && is_selinux_enabled() > 0) {
755 security_context_t context_string
;
756 security_context_t oldcontext
;
757 context_t newcontext
;
759 if (fgetfilecon(DEV
, &oldcontext
) < 0) {
760 if (errno
!= ENODATA
) {
761 fprintf(stderr
, _("%s: %s: unable to obtain selinux file label: %s\n"),
762 program_name
, device_name
,
766 if (matchpathcon(device_name
, statbuf
.st_mode
, &oldcontext
))
767 die(_("unable to matchpathcon()"));
769 if (!(newcontext
= context_new(oldcontext
)))
770 die(_("unable to create new selinux context"));
771 if (context_type_set(newcontext
, SELINUX_SWAPFILE_TYPE
))
772 die(_("couldn't compute selinux context"));
774 context_string
= context_str(newcontext
);
776 if (strcmp(context_string
, oldcontext
)!=0) {
777 if (fsetfilecon(DEV
, context_string
)) {
778 fprintf(stderr
, _("%s: unable to relabel %s to %s: %s\n"),
779 program_name
, device_name
,
785 context_free(newcontext
);