Home | History | Annotate | Download | only in toolbox
      1 #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 */
     10 struct 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 
     25 int 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     }
     91 err:
     92     close(fd);
     93     return err;
     94 }
     95