Skip to content

Commit 633e46f

Browse files
committed
scripts: add portable mkswap.c extracted from BusyBox
Signed-off-by: Park Ju Hyung <[email protected]>
1 parent 446feae commit 633e46f

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

Diff for: scripts/mkswap.c

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* mkswap.c - format swap device (Linux v1 only)
3+
*
4+
* Copyright 2006 Rob Landley <[email protected]>
5+
*
6+
* Licensed under GPLv2
7+
*/
8+
9+
#include <stdio.h>
10+
#include <stdint.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
#include <unistd.h>
14+
#include <sys/types.h>
15+
#include <sys/stat.h>
16+
#include <fcntl.h>
17+
18+
/* from Linux 2.6.23 */
19+
/*
20+
* Magic header for a swap area. ... Note that the first
21+
* kilobyte is reserved for boot loader or disk label stuff.
22+
*/
23+
struct swap_header_v1 {
24+
/* char bootbits[1024]; Space for disklabel etc. */
25+
uint32_t version; /* second kbyte, word 0 */
26+
uint32_t last_page; /* 1 */
27+
uint32_t nr_badpages; /* 2 */
28+
char sws_uuid[16]; /* 3,4,5,6 */
29+
char sws_volume[16]; /* 7,8,9,10 */
30+
uint32_t padding[117]; /* 11..127 */
31+
uint32_t badpages[1]; /* 128 */
32+
/* total 129 32-bit words in 2nd kilobyte */
33+
} __attribute__((__may_alias__));
34+
35+
#define NWORDS 129
36+
#define COMMON_BUFSIZE 1024
37+
38+
static struct swap_header_v1 *hdr;
39+
40+
struct BUG_sizes {
41+
char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1];
42+
char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1];
43+
};
44+
45+
/* Stored without terminating NUL */
46+
static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] __attribute__((aligned(1))) = "SWAPSPACE2";
47+
48+
static loff_t get_volume_size_in_bytes(int fd)
49+
{
50+
loff_t result;
51+
52+
/* more portable than BLKGETSIZE[64] */
53+
result = lseek(fd, 0, SEEK_END);
54+
55+
lseek(fd, 0, SEEK_SET);
56+
57+
/* Prevent things like this:
58+
* $ dd if=/dev/zero of=foo count=1 bs=1024
59+
* $ mkswap foo
60+
* Setting up swapspace version 1, size = 18446744073709548544 bytes
61+
*
62+
* Picked 16k arbitrarily: */
63+
if (result < 16*1024) {
64+
fprintf(stderr, "image is too small\n");
65+
exit(1);
66+
}
67+
68+
return result;
69+
}
70+
71+
int main(int argc, char **argv)
72+
{
73+
int fd;
74+
int pagesize;
75+
off_t len;
76+
const char *label = "";
77+
78+
if (argc < 2) {
79+
fprintf(stderr, "Usage: %s /path/to/swapfile\n", argv[0]);
80+
exit(1);
81+
}
82+
83+
fd = open(argv[1], O_WRONLY);
84+
if (fd == -1) {
85+
perror("Failed to open file");
86+
exit(1);
87+
}
88+
89+
/* Figure out how big the device is */
90+
len = get_volume_size_in_bytes(fd);
91+
pagesize = getpagesize();
92+
len -= pagesize;
93+
94+
hdr = (struct swap_header_v1*)calloc(1, 1024);
95+
96+
/* Announce our intentions */
97+
printf("Setting up swapspace version 1, size = %jd bytes\n", (intmax_t)len);
98+
99+
/* hdr is zero-filled so far. Clear the first kbyte, or else
100+
* mkswap-ing former FAT partition does NOT erase its signature.
101+
*
102+
* util-linux-ng 2.17.2 claims to erase it only if it does not see
103+
* a partition table and is not run on whole disk. -f forces it.
104+
*/
105+
write(fd, hdr, 1024);
106+
107+
/* Fill the header. */
108+
hdr->version = 1;
109+
hdr->last_page = (uint32_t)(len / pagesize);
110+
111+
strncpy(hdr->sws_volume, label, 16);
112+
113+
/* Write the header. Sync to disk because some kernel versions check
114+
* signature on disk (not in cache) during swapon. */
115+
write(fd, hdr, NWORDS * 4);
116+
lseek(fd, pagesize - 10, SEEK_SET);
117+
write(fd, SWAPSPACE2, 10);
118+
fsync(fd);
119+
120+
close(fd);
121+
122+
return 0;
123+
}

0 commit comments

Comments
 (0)