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"
54 #include "pathnames.h"
57 #include <uuid/uuid.h>
60 static char * program_name
= "mkswap";
61 static char * device_name
= NULL
;
63 static unsigned long PAGES
= 0;
64 static unsigned long badpages
= 0;
66 static int version
= -1;
68 #define SELINUX_SWAPFILE_TYPE "swapfile_t"
72 # define is_sparc64() 1
78 static int sparc64
= -1;
80 if (sparc64
!= -1) return sparc64
;
83 if (uname(&un
) < 0) return 0;
84 if (! strcmp(un
.machine
, "sparc64")) {
88 if (strcmp(un
.machine
, "sparc"))
89 return 0; /* Should not happen */
91 #ifdef HAVE_PERSONALITY
93 extern int personality(unsigned long);
95 #define PERS_LINUX 0x00000000
96 #define PERS_LINUX_32BIT 0x00800000
97 #define PERS_LINUX32 0x00000008
99 oldpers
= personality(PERS_LINUX_32BIT
);
101 if (personality(PERS_LINUX
) != -1) {
103 if (! strcmp(un
.machine
, "sparc64")) {
105 oldpers
= PERS_LINUX32
;
108 personality(oldpers
);
115 # define is_be64() is_sparc64()
116 # endif /* sparc32 */
122 * The definition of the union swap_header uses the kernel constant PAGE_SIZE.
123 * Unfortunately, on some architectures this depends on the hardware model, and
124 * can only be found at run time -- we use getpagesize(), so that we do not
125 * need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
127 * Even more unfortunately, getpagesize() does not always return the right
128 * information. For example, libc4, libc5 and glibc 2.0 do not use the system
129 * call but invent a value themselves (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC),
130 * and thus it may happen that e.g. on a sparc kernel PAGE_SIZE=4096 and
131 * getpagesize() returns 8192.
133 * What to do? Let us allow the user to specify the pagesize explicitly.
135 * Update 05-Feb-2007 (kzak):
136 * - use sysconf(_SC_PAGESIZE) to be consistent with the rest of
137 * util-linux code. It is the standardized and preferred way of
138 * querying page size.
140 static int user_pagesize
;
142 static unsigned long *signature_page
;
143 struct swap_header_v1
*p
;
146 init_signature_page(void) {
148 int kernel_pagesize
= pagesize
= (int) sysconf(_SC_PAGESIZE
);
151 if ((user_pagesize
& (user_pagesize
-1)) ||
152 user_pagesize
< 1024) {
153 fprintf(stderr
, _("Bad user-specified page size %d\n"),
157 pagesize
= user_pagesize
;
160 if (user_pagesize
&& user_pagesize
!= kernel_pagesize
)
161 fprintf(stderr
, _("Using user-specified page size %d, "
162 "instead of the system value %d\n"),
163 pagesize
, kernel_pagesize
);
165 signature_page
= (unsigned long *) malloc(pagesize
);
166 memset(signature_page
, 0, pagesize
);
167 p
= (struct swap_header_v1
*) signature_page
;
171 write_signature(char *sig
) {
172 char *sp
= (char *) signature_page
;
174 strncpy(sp
+pagesize
-10, sig
, 10);
178 write_uuid_and_label(unsigned char *uuid
, char *volume_name
) {
179 struct swap_header_v1_2
*h
;
182 if (sizeof(struct swap_header_v1
) !=
183 sizeof(struct swap_header_v1_2
)) {
185 _("Bad swap header size, no label written.\n"));
189 h
= (struct swap_header_v1_2
*) signature_page
;
191 memcpy(h
->uuid
, uuid
, sizeof(h
->uuid
));
193 xstrncpy(h
->volume_name
, volume_name
, sizeof(h
->volume_name
));
194 if (strlen(volume_name
) > strlen(h
->volume_name
))
195 fprintf(stderr
, _("Label was truncated.\n"));
197 if (uuid
|| volume_name
) {
199 printf("LABEL=%s, ", h
->volume_name
);
201 printf(_("no label, "));
204 char uuid_string
[37];
205 uuid_unparse(uuid
, uuid_string
);
206 printf("UUID=%s\n", uuid_string
);
209 printf(_("no uuid\n"));
214 * Find out what the maximum amount of swap space is that the kernel will
215 * handle. This wouldn't matter if the kernel just used as much of the
216 * swap space as it can handle, but until 2.3.4 it would return an error
217 * to swapon() if the swapspace was too large.
219 #define V0_MAX_PAGES (8 * (pagesize - 10))
220 /* Before 2.2.0pre9 */
221 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
222 /* Since 2.2.0pre9, before 2.3.4:
223 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
225 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
226 #define SWP_OFFSET(entry) ((entry) >> 8)
227 on the various architectures. Below the result - yuk.
229 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
230 i386 2^12 o<<8 e>>8 1<<24 1<<19
231 mips 2^12 o<<15 e>>15 1<<17 1<<19
232 alpha 2^13 o<<40 e>>40 1<<24 1<<18
233 m68k 2^12 o<<12 e>>12 1<<20 1<<19
234 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
235 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
236 ppc 2^12 o<<8 e>>8 1<<24 1<<19
237 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
238 armv 2^12 o<<9 e>>9 1<<23 1<<19
240 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
242 The bad part is that we need to know this since the kernel will
243 refuse a swap space if it is too large.
245 /* patch from jj - why does this differ from the above? */
246 /* 32bit kernels have a second limitation of 2GB, sparc64 is limited by
247 the size of virtual address space allocation for vmalloc */
248 #if defined(__alpha__)
249 #define V1_MAX_PAGES ((1 << 24) - 1)
250 #elif defined(__mips__)
251 #define V1_MAX_PAGES ((1 << 17) - 1)
252 #elif defined(__sparc__)
253 #define V1_MAX_PAGES (is_sparc64() ? ((3 << 29) - 1) : ((1 << 18) - 1))
254 #elif defined(__ia64__)
256 * The actual size will depend on the amount of virtual address space
257 * available to vmalloc the swap map.
259 #define V1_MAX_PAGES ((1UL << 54) - 1)
261 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
263 /* man page now says:
264 The maximum useful size of a swap area now depends on the architecture.
265 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
266 128GB on alpha and 3TB on sparc64.
269 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
272 * One more point of lossage - Linux swapspace really is a mess.
273 * The definition of the bitmap used is architecture dependent,
274 * and requires one to know whether the machine is bigendian,
275 * and if so, whether it will use 32-bit or 64-bit units in
277 * davem writes: "... is based upon an unsigned long type of
278 * the cpu and the native endianness".
279 * So, it seems we can write `unsigned long' below.
280 * However, sparc64 uses 64-bit units in the kernel, while
281 * mkswap may have been translated with 32-bit longs. Thus,
282 * we need an explicit test for version 0 swap on sparc64.
286 bit_set (unsigned long *addr
, unsigned int nr
) {
290 unsigned long long *bitmap
= (unsigned long long *) addr
;
291 unsigned long long bitnum
= (unsigned long long) nr
;
292 unsigned long long rl
, ml
;
294 bitmap
+= bitnum
/ (8 * sizeof(long long));
296 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
301 addr
+= nr
/ (8 * sizeof(unsigned long));
303 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
308 bit_test_and_clear (unsigned long *addr
, unsigned int nr
) {
312 unsigned long long *bitmap
= (unsigned long long *) addr
;
313 unsigned long long bitnum
= (unsigned long long) nr
;
314 unsigned long long rl
, ml
;
316 bitmap
+= bitnum
/ (8 * sizeof(long long));
318 ml
= 1ULL << (bitnum
& (8ULL * sizeof(long long) - 1ULL));
320 return ((rl
& ml
) != 0ULL);
323 addr
+= nr
/ (8 * sizeof(unsigned long));
325 m
= 1 << (nr
& (8 * sizeof(unsigned long) - 1));
333 _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] [-L label] [-U UUID] /dev/name [blocks]\n"),
339 die(const char *str
) {
340 fprintf(stderr
, "%s: %s\n", program_name
, str
);
347 bit_set(signature_page
, page
);
353 bit_test_and_clear(signature_page
, page
);
355 if (badpages
== MAX_BADPAGES
)
356 die(_("too many bad pages"));
357 p
->badpages
[badpages
] = page
;
364 unsigned int current_page
;
368 buffer
= malloc(pagesize
);
370 die(_("Out of memory"));
372 while (current_page
< PAGES
) {
374 page_ok(current_page
++);
377 if (do_seek
&& lseek(DEV
,current_page
*pagesize
,SEEK_SET
) !=
378 current_page
*pagesize
)
379 die(_("seek failed in check_blocks"));
380 if ((do_seek
= (pagesize
!= read(DEV
, buffer
, pagesize
)))) {
381 page_bad(current_page
++);
384 page_ok(current_page
++);
387 printf(_("one bad page\n"));
388 else if (badpages
> 1)
389 printf(_("%lu bad pages\n"), badpages
);
392 /* return size in pages, to avoid integer overflow */
394 get_size(const char *file
) {
396 unsigned long long size
;
398 fd
= open(file
, O_RDONLY
);
403 if (blkdev_get_size(fd
, &size
) == 0)
406 size
= blkdev_find_size(fd
) / pagesize
;
414 return (c
>= '1' && c
<= '9');
419 * Check to make certain that our new filesystem won't be created on
420 * an already mounted partition. Code adapted from mke2fs, Copyright
421 * (C) 1994 Theodore Ts'o. Also licensed under GPL.
422 * (C) 2006 Karel Zak -- port to mkswap
429 if ((f
= setmntent (_PATH_MOUNTED
, "r")) == NULL
)
431 while ((mnt
= getmntent (f
)) != NULL
)
432 if (strcmp (device_name
, mnt
->mnt_fsname
) == 0)
442 write_all(int fd
, const void *buf
, size_t count
) {
447 tmp
= write(fd
, buf
, count
);
452 } else if (errno
!= EINTR
&& errno
!= EAGAIN
)
459 main(int argc
, char ** argv
) {
462 unsigned long maxpages
;
463 unsigned long goodpages
;
467 char *block_count
= 0;
469 char *opt_label
= NULL
;
470 unsigned char *uuid
= NULL
;
472 const char *opt_uuid
= NULL
;
476 program_name
= (argc
&& *argv
) ? argv
[0] : "mkswap";
477 if ((pp
= strrchr(program_name
, '/')) != NULL
)
480 setlocale(LC_ALL
, "");
481 bindtextdomain(PACKAGE
, LOCALEDIR
);
485 (!strcmp(argv
[1], "-V") || !strcmp(argv
[1], "--version"))) {
486 printf(_("%s (%s)\n"), program_name
, PACKAGE_STRING
);
490 for (i
=1; i
<argc
; i
++) {
491 if (argv
[i
][0] == '-') {
492 switch (argv
[i
][1]) {
501 if (!*pp
&& i
+1 < argc
)
504 user_pagesize
= atoi(pp
);
510 if (!*pp
&& i
+1 < argc
)
515 version
= atoi(argv
[i
]+2);
519 opt_uuid
= argv
[i
]+2;
520 if (!*opt_uuid
&& i
+1 < argc
)
521 opt_uuid
= argv
[++i
];
523 fprintf(stderr
, _("%1$s: warning: ignore -U (UUIDs are unsupported by %1$s)\n"),
530 } else if (!device_name
) {
531 device_name
= argv
[i
];
532 } else if (!block_count
) {
533 block_count
= argv
[i
];
540 if (uuid_parse(opt_uuid
, uuid_dat
) != 0)
541 die(_("error: UUID parsing failed"));
543 uuid_generate(uuid_dat
);
547 init_signature_page(); /* get pagesize */
551 _("%s: error: Nowhere to set up swap on?\n"),
556 /* this silly user specified the number of blocks
559 int blocks_per_page
= pagesize
/1024;
560 PAGES
= strtoul(block_count
,&tmp
,0)/blocks_per_page
;
564 sz
= get_size(device_name
);
567 } else if (PAGES
> sz
&& !force
) {
570 "size %lu KiB is larger than device size %lu KiB\n"),
572 PAGES
*(pagesize
/1024), sz
*(pagesize
/1024));
577 /* labels only for v1 */
581 /* use version 1 as default, if possible */
583 if (get_linux_version() < KERNEL_VERSION(2,1,117))
592 if (version
!= 0 && version
!= 1) {
593 fprintf(stderr
, _("%s: error: unknown version %d\n"),
594 program_name
, version
);
600 _("%s: error: swap area needs to be at least %ld KiB\n"),
601 program_name
, (long)(10 * pagesize
/1024));
606 maxpages
= V0_MAX_PAGES
;
608 else if (get_linux_version() >= KERNEL_VERSION(2,3,4))
610 else if (get_linux_version() >= KERNEL_VERSION(2,2,1))
611 maxpages
= V1_MAX_PAGES
;
614 maxpages
= V1_OLD_MAX_PAGES
;
616 if (PAGES
> maxpages
) {
619 _("%s: warning: truncating swap area to %ld KiB\n"),
620 program_name
, PAGES
* pagesize
/ 1024);
623 if (opt_label
&& version
== 0) {
625 _("%s: error: label only with v1 swap area\n"),
630 if (stat(device_name
, &statbuf
) < 0) {
634 if (S_ISBLK(statbuf
.st_mode
))
635 DEV
= open(device_name
, O_RDWR
| O_EXCL
);
637 DEV
= open(device_name
, O_RDWR
);
644 /* Want a block device. Probably not /dev/hda or /dev/hdb. */
645 if (!S_ISBLK(statbuf
.st_mode
))
647 else if (statbuf
.st_rdev
== 0x0300 || statbuf
.st_rdev
== 0x0340) {
650 "will not try to make swapdevice on '%s'\n"),
651 program_name
, device_name
);
653 } else if (check_mount()) {
656 "%s is mounted; will not make swapspace.\n"),
657 program_name
, device_name
);
662 if (!force
&& version
== 0) {
663 /* Don't overwrite partition table unless forced */
664 unsigned char *buffer
= (unsigned char *)signature_page
;
665 unsigned short *q
, sum
;
667 if (read(DEV
, buffer
, 512) != 512)
668 die(_("fatal: first page unreadable"));
669 if (buffer
[508] == 0xDA && buffer
[509] == 0xBE) {
670 q
= (unsigned short *)(buffer
+ 510);
671 for (sum
= 0; q
>= (unsigned short *) buffer
;)
675 %s: Device '%s' contains a valid Sun disklabel.\n\
676 This probably means creating v0 swap would destroy your partition table.\n\
677 No swap was created. If you really want to create v0 swap on that device,\n\
678 use the -f option to force it.\n"),
679 program_name
, device_name
);
686 if (version
== 0 || check
)
688 if (version
== 0 && !bit_test_and_clear(signature_page
,0))
689 die(_("fatal: first page unreadable"));
691 p
->version
= version
;
692 p
->last_page
= PAGES
-1;
693 p
->nr_badpages
= badpages
;
696 goodpages
= PAGES
- badpages
- 1;
697 if ((long) goodpages
<= 0)
698 die(_("Unable to set up swap-space: unreadable"));
699 printf(_("Setting up swapspace version %d, size = %llu KiB\n"),
700 version
, (unsigned long long)goodpages
* pagesize
/ 1024);
701 write_signature((version
== 0) ? "SWAP-SPACE" : "SWAPSPACE2");
704 write_uuid_and_label(uuid
, opt_label
);
706 offset
= ((version
== 0) ? 0 : 1024);
707 if (lseek(DEV
, offset
, SEEK_SET
) != offset
)
708 die(_("unable to rewind swap-device"));
709 if (write_all(DEV
, (char *) signature_page
+ offset
,
710 pagesize
- offset
) == -1) {
711 fprintf(stderr
, _("%s: %s: unable to write signature page: %s"),
712 program_name
, device_name
, strerror(errno
));
717 * A subsequent swapon() will fail if the signature
718 * is not actually on disk. (This is a kernel bug.)
722 die(_("fsync failed"));
725 #ifdef HAVE_LIBSELINUX
726 if (S_ISREG(statbuf
.st_mode
) && is_selinux_enabled() > 0) {
727 security_context_t context_string
;
728 security_context_t oldcontext
;
729 context_t newcontext
;
731 if (fgetfilecon(DEV
, &oldcontext
) < 0) {
732 if (errno
!= ENODATA
) {
733 fprintf(stderr
, _("%s: %s: unable to obtain selinux file label: %s\n"),
734 program_name
, device_name
,
738 if (matchpathcon(device_name
, statbuf
.st_mode
, &oldcontext
))
739 die(_("unable to matchpathcon()"));
741 if (!(newcontext
= context_new(oldcontext
)))
742 die(_("unable to create new selinux context"));
743 if (context_type_set(newcontext
, SELINUX_SWAPFILE_TYPE
))
744 die(_("couldn't compute selinux context"));
746 context_string
= context_str(newcontext
);
748 if (strcmp(context_string
, oldcontext
)!=0) {
749 if (fsetfilecon(DEV
, context_string
)) {
750 fprintf(stderr
, _("%s: unable to relabel %s to %s: %s\n"),
751 program_name
, device_name
,
757 context_free(newcontext
);