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
41 #include <sys/utsname.h>
45 #ifdef HAVE_LIBSELINUX
46 #include <selinux/selinux.h>
47 #include <selinux/context.h>
50 #include "linux_version.h"
51 #include "swapheader.h"
55 #include "pathnames.h"
56 #include "wholedisk.h"
61 # ifdef HAVE_UUID_UUID_H
62 # include <uuid/uuid.h>
68 #ifdef HAVE_LIBBLKID_INTERNAL
72 static char * device_name
= NULL
;
74 static unsigned long long PAGES
= 0;
75 static unsigned long badpages
= 0;
78 #define SELINUX_SWAPFILE_TYPE "swapfile_t"
82 # define is_sparc64() 1
88 static int sparc64
= -1;
90 if (sparc64
!= -1) return sparc64
;
93 if (uname(&un
) < 0) return 0;
94 if (! strcmp(un
.machine
, "sparc64")) {
98 if (strcmp(un
.machine
, "sparc"))
99 return 0; /* Should not happen */
101 #ifdef HAVE_PERSONALITY
103 extern int personality(unsigned long);
105 #define PERS_LINUX 0x00000000
106 #define PERS_LINUX_32BIT 0x00800000
107 #define PERS_LINUX32 0x00000008
109 oldpers
= personality(PERS_LINUX_32BIT
);
111 if (personality(PERS_LINUX
) != -1) {
113 if (! strcmp(un
.machine
, "sparc64")) {
115 oldpers
= PERS_LINUX32
;
118 personality(oldpers
);
125 # define is_be64() is_sparc64()
126 # endif /* sparc32 */
132 * The definition of the union swap_header uses the kernel constant PAGE_SIZE.
133 * Unfortunately, on some architectures this depends on the hardware model, and
134 * can only be found at run time -- we use getpagesize(), so that we do not
135 * need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
137 * Even more unfortunately, getpagesize() does not always return the right
138 * information. For example, libc4, libc5 and glibc 2.0 do not use the system
139 * call but invent a value themselves (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC),
140 * and thus it may happen that e.g. on a sparc kernel PAGE_SIZE=4096 and
141 * getpagesize() returns 8192.
143 * What to do? Let us allow the user to specify the pagesize explicitly.
146 static int user_pagesize
;
148 static unsigned long *signature_page
= NULL
;
151 init_signature_page(void) {
153 int kernel_pagesize
= pagesize
= getpagesize();
156 if ((user_pagesize
& (user_pagesize
-1)) ||
157 user_pagesize
< sizeof(struct swap_header_v1_2
) + 10)
159 _("Bad user-specified page size %d"),
161 pagesize
= user_pagesize
;
164 if (user_pagesize
&& user_pagesize
!= kernel_pagesize
)
165 warnx(_("Using user-specified page size %d, "
166 "instead of the system value %d"),
167 pagesize
, kernel_pagesize
);
169 signature_page
= (unsigned long *) xcalloc(1, pagesize
);
173 write_signature(char *sig
) {
174 char *sp
= (char *) signature_page
;
176 strncpy(sp
+pagesize
-10, sig
, 10);
180 write_uuid_and_label(unsigned char *uuid
, char *volume_name
) {
181 struct swap_header_v1_2
*h
;
184 if (sizeof(struct swap_header_v1
) !=
185 sizeof(struct swap_header_v1_2
)) {
186 warnx(_("Bad swap header size, no label written."));
190 h
= (struct swap_header_v1_2
*) signature_page
;
192 memcpy(h
->uuid
, uuid
, sizeof(h
->uuid
));
194 xstrncpy(h
->volume_name
, volume_name
, sizeof(h
->volume_name
));
195 if (strlen(volume_name
) > strlen(h
->volume_name
))
196 warnx(_("Label was truncated."));
198 if (uuid
|| volume_name
) {
200 printf("LABEL=%s, ", h
->volume_name
);
202 printf(_("no label, "));
205 char uuid_string
[37];
206 uuid_unparse(uuid
, uuid_string
);
207 printf("UUID=%s\n", uuid_string
);
210 printf(_("no uuid\n"));
215 * Find out what the maximum amount of swap space is that the kernel will
216 * handle. This wouldn't matter if the kernel just used as much of the
217 * swap space as it can handle, but until 2.3.4 it would return an error
218 * to swapon() if the swapspace was too large.
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))
270 #define MIN_GOODPAGES 10
275 _("Usage: %s [-c] [-pPAGESZ] [-L label] [-U UUID] /dev/name [blocks]\n"),
276 program_invocation_short_name
);
282 struct swap_header_v1_2
*p
= (struct swap_header_v1_2
*) signature_page
;
284 if (badpages
== MAX_BADPAGES
)
285 errx(EXIT_FAILURE
, _("too many bad pages"));
286 p
->badpages
[badpages
] = page
;
292 unsigned int current_page
;
296 buffer
= xmalloc(pagesize
);
298 while (current_page
< PAGES
) {
299 if (do_seek
&& lseek(DEV
,current_page
*pagesize
,SEEK_SET
) !=
300 current_page
*pagesize
)
301 errx(EXIT_FAILURE
, _("seek failed in check_blocks"));
302 if ((do_seek
= (pagesize
!= read(DEV
, buffer
, pagesize
))))
303 page_bad(current_page
);
307 printf(_("one bad page\n"));
308 else if (badpages
> 1)
309 printf(_("%lu bad pages\n"), badpages
);
313 /* return size in pages */
314 static unsigned long long
315 get_size(const char *file
) {
317 unsigned long long size
;
319 fd
= open(file
, O_RDONLY
);
324 if (blkdev_get_size(fd
, &size
) == 0)
333 return (c
>= '1' && c
<= '9');
338 * Check to make certain that our new filesystem won't be created on
339 * an already mounted partition. Code adapted from mke2fs, Copyright
340 * (C) 1994 Theodore Ts'o. Also licensed under GPL.
341 * (C) 2006 Karel Zak -- port to mkswap
348 if ((f
= setmntent (_PATH_MOUNTED
, "r")) == NULL
)
350 while ((mnt
= getmntent (f
)) != NULL
)
351 if (strcmp (device_name
, mnt
->mnt_fsname
) == 0)
360 zap_bootbits(int fd
, const char *devname
, int force
, int is_blkdev
)
367 if (lseek(fd
, 0, SEEK_SET
) != 0)
368 errx(EXIT_FAILURE
, _("unable to rewind swap-device"));
370 if (is_blkdev
&& is_whole_disk_fd(fd
, devname
)) {
371 /* don't zap bootbits on whole disk -- we know nothing
372 * about bootloaders on the device */
376 #ifdef HAVE_LIBBLKID_INTERNAL
377 blkid_probe pr
= blkid_new_probe();
379 errx(EXIT_FAILURE
, _("unable to alloc new libblkid probe"));
380 if (blkid_probe_set_device(pr
, fd
, 0, 0))
381 errx(EXIT_FAILURE
, _("unable to assign device to libblkid probe"));
383 blkid_probe_enable_partitions(pr
, 1);
384 blkid_probe_enable_superblocks(pr
, 0);
386 if (blkid_do_fullprobe(pr
) == 0)
387 blkid_probe_lookup_value(pr
, "PTTYPE",
388 (const char **) &type
, NULL
);
390 type
= xstrdup(type
);
393 blkid_free_probe(pr
);
395 /* don't zap if compiled without libblkid */
404 if (lseek(fd
, 0, SEEK_SET
) != 0)
405 errx(EXIT_FAILURE
, _("unable to rewind swap-device"));
407 memset(buf
, 0, sizeof(buf
));
408 if (write_all(fd
, buf
, sizeof(buf
)))
409 errx(EXIT_FAILURE
, _("unable to erase bootbits sectors"));
413 warnx(_("%s: warning: don't erase bootbits sectors"),
416 fprintf(stderr
, _(" (%s partition table detected). "), type
);
418 fprintf(stderr
, _(" on whole disk. "));
420 fprintf(stderr
, _(" (compiled without libblkid). "));
421 fprintf(stderr
, "Use -f to force.\n");
425 main(int argc
, char ** argv
) {
427 struct swap_header_v1_2
*hdr
;
429 unsigned long long maxpages
;
430 unsigned long long goodpages
;
431 unsigned long long sz
;
435 char *block_count
= 0;
437 char *opt_label
= NULL
;
438 unsigned char *uuid
= NULL
;
440 const char *opt_uuid
= NULL
;
444 setlocale(LC_ALL
, "");
445 bindtextdomain(PACKAGE
, LOCALEDIR
);
449 (!strcmp(argv
[1], "-V") || !strcmp(argv
[1], "--version"))) {
450 printf(_("%s from %s\n"), program_invocation_short_name
, PACKAGE_STRING
);
454 for (i
=1; i
<argc
; i
++) {
455 if (argv
[i
][0] == '-') {
456 switch (argv
[i
][1]) {
465 if (!*pp
&& i
+1 < argc
)
468 user_pagesize
= atoi(pp
);
474 if (!*pp
&& i
+1 < argc
)
479 version
= atoi(argv
[i
]+2);
483 opt_uuid
= argv
[i
]+2;
484 if (!*opt_uuid
&& i
+1 < argc
)
485 opt_uuid
= argv
[++i
];
487 warnx(_("warning: ignore -U (UUIDs are unsupported by %s)"),
488 program_invocation_short_name
);
494 } else if (!device_name
) {
495 device_name
= argv
[i
];
496 } else if (!block_count
) {
497 block_count
= argv
[i
];
504 _("does not support swapspace version %d."),
510 if (uuid_parse(opt_uuid
, uuid_dat
) != 0)
511 errx(EXIT_FAILURE
, _("error: UUID parsing failed"));
513 uuid_generate(uuid_dat
);
517 init_signature_page(); /* get pagesize */
520 warnx(_("error: Nowhere to set up swap on?"));
524 /* this silly user specified the number of blocks explicitly */
529 blks
= strtoll(block_count
, &tmp
, 0);
530 if ((tmp
== block_count
) ||
532 (errno
!= 0 && (blks
== LLONG_MAX
|| blks
== LLONG_MIN
)) ||
536 PAGES
= blks
/ (pagesize
/ 1024);
538 sz
= get_size(device_name
);
541 } else if (PAGES
> sz
&& !force
) {
544 "size %llu KiB is larger than device size %llu KiB"),
545 PAGES
*(pagesize
/1024), sz
*(pagesize
/1024));
548 if (PAGES
< MIN_GOODPAGES
) {
549 warnx(_("error: swap area needs to be at least %ld KiB"),
550 (long)(MIN_GOODPAGES
* pagesize
/1024));
555 if (get_linux_version() >= KERNEL_VERSION(2,3,4))
556 maxpages
= UINT_MAX
+ 1ULL;
557 else if (get_linux_version() >= KERNEL_VERSION(2,2,1))
558 maxpages
= V1_MAX_PAGES
;
561 maxpages
= V1_OLD_MAX_PAGES
;
563 if (PAGES
> maxpages
) {
565 warnx(_("warning: truncating swap area to %llu KiB"),
566 PAGES
* pagesize
/ 1024);
569 if (stat(device_name
, &statbuf
) < 0) {
573 if (S_ISBLK(statbuf
.st_mode
))
574 DEV
= open(device_name
, O_RDWR
| O_EXCL
);
576 DEV
= open(device_name
, O_RDWR
);
583 /* Want a block device. Probably not /dev/hda or /dev/hdb. */
584 if (!S_ISBLK(statbuf
.st_mode
))
586 else if (statbuf
.st_rdev
== 0x0300 || statbuf
.st_rdev
== 0x0340)
587 errx(EXIT_FAILURE
, _("error: "
588 "will not try to make swapdevice on '%s'"),
590 else if (check_mount())
591 errx(EXIT_FAILURE
, _("error: "
592 "%s is mounted; will not make swapspace."),
598 zap_bootbits(DEV
, device_name
, force
, S_ISBLK(statbuf
.st_mode
));
600 hdr
= (struct swap_header_v1_2
*) signature_page
;
602 hdr
->last_page
= PAGES
- 1;
603 hdr
->nr_badpages
= badpages
;
605 if (badpages
> PAGES
- MIN_GOODPAGES
)
606 errx(EXIT_FAILURE
, _("Unable to set up swap-space: unreadable"));
608 goodpages
= PAGES
- badpages
- 1;
609 printf(_("Setting up swapspace version 1, size = %llu KiB\n"),
610 goodpages
* pagesize
/ 1024);
612 write_signature("SWAPSPACE2");
613 write_uuid_and_label(uuid
, opt_label
);
616 if (lseek(DEV
, offset
, SEEK_SET
) != offset
)
617 errx(EXIT_FAILURE
, _("unable to rewind swap-device"));
618 if (write_all(DEV
, (char *) signature_page
+ offset
,
619 pagesize
- offset
) == -1)
621 _("%s: unable to write signature page"),
625 * A subsequent swapon() will fail if the signature
626 * is not actually on disk. (This is a kernel bug.)
630 errx(EXIT_FAILURE
, _("fsync failed"));
633 #ifdef HAVE_LIBSELINUX
634 if (S_ISREG(statbuf
.st_mode
) && is_selinux_enabled() > 0) {
635 security_context_t context_string
;
636 security_context_t oldcontext
;
637 context_t newcontext
;
639 if (fgetfilecon(DEV
, &oldcontext
) < 0) {
640 if (errno
!= ENODATA
)
642 _("%s: %s: unable to obtain selinux file label: %s"),
644 if (matchpathcon(device_name
, statbuf
.st_mode
, &oldcontext
))
645 errx(EXIT_FAILURE
, _("unable to matchpathcon()"));
647 if (!(newcontext
= context_new(oldcontext
)))
648 errx(EXIT_FAILURE
, _("unable to create new selinux context"));
649 if (context_type_set(newcontext
, SELINUX_SWAPFILE_TYPE
))
650 errx(EXIT_FAILURE
, _("couldn't compute selinux context"));
652 context_string
= context_str(newcontext
);
654 if (strcmp(context_string
, oldcontext
)!=0) {
655 if (fsetfilecon(DEV
, context_string
))
656 err(EXIT_FAILURE
, _("unable to relabel %s to %s"),
657 device_name
, context_string
);
659 context_free(newcontext
);