1/* See LICENSE file for copyright and license details. */
2
3#include <sys/stat.h>
4
5#include <fcntl.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10
11#include "util.h"
12
13#define SWAP_UUID_LENGTH 16
14#define SWAP_LABEL_LENGTH 16
15#define SWAP_MIN_PAGES 10
16
17struct swap_hdr {
18 char bootbits[1024];
19 unsigned int version;
20 unsigned int last_page;
21 unsigned int nr_badpages;
22 unsigned char uuid[SWAP_UUID_LENGTH];
23 char volume_name[SWAP_LABEL_LENGTH];
24 unsigned int padding[117];
25 unsigned int badpages[1];
26};
27
28static void
29usage(void)
30{
31 eprintf("usage: %s device\n", argv0);
32}
33
34// ?man mkswap: set up a swap area
35// ?man arguments: device
36// ?man initialize a linux swap area on a device or file
37int
38main(int argc, char *argv[])
39{
40 int fd;
41 unsigned int pages;
42 long pagesize;
43 struct stat sb;
44 char *buf;
45 struct swap_hdr *hdr;
46
47 ARGBEGIN
48 {
49 default:
50 usage();
51 }
52 ARGEND;
53
54 if (argc < 1)
55 usage();
56
57 pagesize = sysconf(_SC_PAGESIZE);
58 if (pagesize <= 0) {
59 pagesize = sysconf(_SC_PAGE_SIZE);
60 if (pagesize <= 0)
61 eprintf("can't determine pagesize\n");
62 }
63
64 fd = open(argv[0], O_RDWR);
65 if (fd < 0)
66 eprintf("open %s:", argv[0]);
67 if (fstat(fd, &sb) < 0)
68 eprintf("stat %s:", argv[0]);
69
70 buf = ecalloc(1, pagesize);
71
72 pages = sb.st_size / pagesize;
73 if (pages < SWAP_MIN_PAGES)
74 eprintf("swap space needs to be at least %ldKiB\n", SWAP_MIN_PAGES * pagesize / 1024);
75
76 /* Fill up the swap header */
77 hdr = (struct swap_hdr *)buf;
78 hdr->version = 1;
79 hdr->last_page = pages - 1;
80 memcpy(buf + pagesize - 10, "SWAPSPACE2", 10);
81
82 printf("Setting up swapspace version 1, size = %luKiB\n", (pages - 1) * pagesize / 1024);
83
84 /* Write out the signature page */
85 if (write(fd, buf, pagesize) != pagesize)
86 eprintf("unable to write signature page\n");
87
88 fsync(fd);
89 close(fd);
90 free(buf);
91
92 return 0;
93}