| Rom Lemarchand | 367297c | 2013-06-05 13:25:12 -0700 | [diff] [blame] | 1 | #include <stdio.h> | 
|  | 2 | #include <unistd.h> | 
| Rom Lemarchand | 367297c | 2013-06-05 13:25:12 -0700 | [diff] [blame] | 3 | #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 */ | 
|  | 9 | struct 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 |  | 
|  | 24 | int 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 | } | 
|  | 90 | err: | 
|  | 91 | close(fd); | 
|  | 92 | return err; | 
|  | 93 | } |