Home | History | Annotate | Download | only in toolbox
      1 #include <stdio.h>
      2 #include <unistd.h>
      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 }
     94