master xplshn/aruu / cmd / linux / mkswap.c
 1/* See LICENSE file for copyright and license details. */
 2
 3
 4#include <sys/stat.h>
 5
 6#include <fcntl.h>
 7#include <stdio.h>
 8#include <stdlib.h>
 9#include <string.h>
10#include <unistd.h>
11
12#include "util.h"
13
14#define SWAP_UUID_LENGTH 16
15#define SWAP_LABEL_LENGTH 16
16#define SWAP_MIN_PAGES 10
17
18struct swap_hdr {
19	char	      bootbits[1024];
20	unsigned int  version;
21	unsigned int  last_page;
22	unsigned int  nr_badpages;
23	unsigned char uuid[SWAP_UUID_LENGTH];
24	char	      volume_name[SWAP_LABEL_LENGTH];
25	unsigned int  padding[117];
26	unsigned int  badpages[1];
27};
28
29static void
30usage(void)
31{
32	eprintf("usage: %s device\n", argv0);
33}
34
35// ?man mkswap: set up a swap area
36// ?man arguments: device
37// ?man initialize a linux swap area on a device or file
38int
39main(int argc, char *argv[])
40{
41	int fd;
42	unsigned int pages;
43	long pagesize;
44	struct stat sb;
45	char *buf;
46	struct swap_hdr *hdr;
47
48	ARGBEGIN {
49	default:
50		usage();
51	} ARGEND;
52
53	if (argc < 1)
54		usage();
55
56	pagesize = sysconf(_SC_PAGESIZE);
57	if (pagesize <= 0) {
58		pagesize = sysconf(_SC_PAGE_SIZE);
59		if (pagesize <= 0)
60			eprintf("can't determine pagesize\n");
61	}
62
63	fd = open(argv[0], O_RDWR);
64	if (fd < 0)
65		eprintf("open %s:", argv[0]);
66	if (fstat(fd, &sb) < 0)
67		eprintf("stat %s:", argv[0]);
68
69	buf = ecalloc(1, pagesize);
70
71	pages = sb.st_size / pagesize;
72	if (pages < SWAP_MIN_PAGES)
73		eprintf("swap space needs to be at least %ldKiB\n",
74			SWAP_MIN_PAGES * pagesize / 1024);
75
76	/* Fill up the swap header */
77	hdr = (struct swap_hdr *)buf;
78	hdr->version = 1;
79	hdr->last_page = pages - 1;
80	memcpy(buf + pagesize - 10, "SWAPSPACE2", 10);
81
82	printf("Setting up swapspace version 1, size = %luKiB\n",
83	       (pages - 1) * pagesize / 1024);
84
85	/* Write out the signature page */
86	if (write(fd, buf, pagesize) != pagesize)
87		eprintf("unable to write signature page\n");
88
89	fsync(fd);
90	close(fd);
91	free(buf);
92
93	return 0;
94}