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