blob: 0904152dfed5e8ea6bd4473b5a625b52f4c40993 [file] [log] [blame]
Rom Lemarchand367297c2013-06-05 13:25:12 -07001#include <stdio.h>
2#include <unistd.h>
Rom Lemarchand367297c2013-06-05 13:25:12 -07003#include <sys/swap.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7
8/* XXX This needs to be obtained from kernel headers. See b/9336527 */
9struct linux_swap_header {
10 char bootbits[1024]; /* Space for disklabel etc. */
11 uint32_t version;
12 uint32_t last_page;
13 uint32_t nr_badpages;
14 unsigned char sws_uuid[16];
15 unsigned char sws_volume[16];
16 uint32_t padding[117];
17 uint32_t badpages[1];
18};
19
20#define MAGIC_SWAP_HEADER "SWAPSPACE2"
21#define MAGIC_SWAP_HEADER_LEN 10
22#define MIN_PAGES 10
23
24int mkswap_main(int argc, char **argv)
25{
26 int err = 0;
27 int fd;
28 ssize_t len;
29 off_t swap_size;
30 int pagesize;
31 struct linux_swap_header sw_hdr;
32
33 if (argc != 2) {
34 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
35 return -EINVAL;
36 }
37
38 fd = open(argv[1], O_WRONLY);
39 if (fd < 0) {
40 err = errno;
41 fprintf(stderr, "Cannot open %s\n", argv[1]);
42 return err;
43 }
44
45 pagesize = getpagesize();
46 /* Determine the length of the swap file */
47 swap_size = lseek(fd, 0, SEEK_END);
48 if (swap_size < MIN_PAGES * pagesize) {
49 fprintf(stderr, "Swap file needs to be at least %dkB\n",
50 (MIN_PAGES * pagesize) >> 10);
51 err = -ENOSPC;
52 goto err;
53 }
54 if (lseek(fd, 0, SEEK_SET)) {
55 err = errno;
56 fprintf(stderr, "Can't seek to the beginning of the file\n");
57 goto err;
58 }
59
60 memset(&sw_hdr, 0, sizeof(sw_hdr));
61 sw_hdr.version = 1;
62 sw_hdr.last_page = (swap_size / pagesize) - 1;
63
64 len = write(fd, &sw_hdr, sizeof(sw_hdr));
65 if (len != sizeof(sw_hdr)) {
66 err = errno;
67 fprintf(stderr, "Failed to write swap header into %s\n", argv[1]);
68 goto err;
69 }
70
71 /* Write the magic header */
72 if (lseek(fd, pagesize - MAGIC_SWAP_HEADER_LEN, SEEK_SET) < 0) {
73 err = errno;
74 fprintf(stderr, "Failed to seek into %s\n", argv[1]);
75 goto err;
76 }
77
78 len = write(fd, MAGIC_SWAP_HEADER, MAGIC_SWAP_HEADER_LEN);
79 if (len != MAGIC_SWAP_HEADER_LEN) {
80 err = errno;
81 fprintf(stderr, "Failed to write magic swap header into %s\n", argv[1]);
82 goto err;
83 }
84
85 if (fsync(fd) < 0) {
86 err = errno;
87 fprintf(stderr, "Failed to sync %s\n", argv[1]);
88 goto err;
89 }
90err:
91 close(fd);
92 return err;
93}