source: trunk/minix/commands/simple/mkswap.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 5.0 KB
Line 
1/* mkswap 1.0 - Initialize a swap partition or file
2 * Author: Kees J. Bot
3 * 6 Jan 2001
4 */
5#define nil ((void*)0)
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <errno.h>
10#include <unistd.h>
11#include <dirent.h>
12#include <fcntl.h>
13#include <sys/stat.h>
14#include <sys/types.h>
15#include <sys/ioctl.h>
16#include <minix/config.h>
17#include <minix/const.h>
18#include <minix/type.h>
19#include <minix/u64.h>
20#include <minix/partition.h>
21#include <minix/swap.h>
22#include <servers/fs/const.h>
23#include <servers/fs/type.h>
24#include <servers/fs/super.h>
25
26static void usage(void)
27{
28 fprintf(stderr, "Usage: mkswap [-f] device-or-file [size[km]]\n");
29 exit(1);
30}
31
32int main(int argc, char **argv)
33{
34 int first;
35 int i;
36 char *file;
37 unsigned long offset, size, devsize;
38 int fd;
39 struct stat st;
40 ssize_t r;
41 struct super_block super;
42 swap_hdr_t swap_hdr;
43 static u8_t block[_MAX_BLOCK_SIZE];
44
45 first= 0;
46 i= 1;
47 while (i < argc && argv[i][0] == '-') {
48 char *opt= argv[i++]+1;
49
50 if (opt[0] == '-' && opt[1] == 0) break; /* -- */
51
52 while (*opt != 0) switch (*opt++) {
53 case 'f': first= 1; break;
54 default: usage();
55 }
56 }
57 if (i == argc) usage();
58 file= argv[i++];
59
60 size= 0;
61 if (i < argc) {
62 char *end;
63 unsigned long m;
64
65 size= strtoul(argv[i], &end, 10);
66 if (end == argv[i]) usage();
67 m= 1024;
68 if (*end != 0) {
69 switch (*end) {
70 case 'm': case 'M': m *= 1024; /*FALL THROUGH*/
71 case 'k': case 'K': end++; break;
72 }
73 }
74 if (*end != 0 || size == -1
75 || (size * m) / m != size || (size *= m) <= SWAP_OFFSET
76 ) {
77 fprintf(stderr, "mkswap: %s: Bad size\n", argv[i]);
78 exit(1);
79 }
80 i++;
81 }
82 if (i != argc) usage();
83
84 /* Open the device or file. */
85 if ((fd= open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
86 fprintf(stderr, "mkswap: Can't open %s: %s\n", file, strerror(errno));
87 exit(1);
88 }
89
90 /* File or device? */
91 (void) fstat(fd, &st);
92 if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
93 struct partition part;
94
95 /* How big is the partition? */
96 if (ioctl(fd, DIOCGETP, &part) < 0) {
97 fprintf(stderr, "mkswap: Can't determine the size of %s: %s\n",
98 file, strerror(errno));
99 exit(1);
100 }
101 devsize= cv64ul(part.size);
102 offset= 0;
103
104 if (!first) {
105 /* Is there a file system? */
106 r= -1;
107 if (lseek(fd, SUPER_BLOCK_BYTES, SEEK_SET) == -1
108 || (r= read(fd, block, _STATIC_BLOCK_SIZE)) < _STATIC_BLOCK_SIZE
109 ) {
110 fprintf(stderr, "mkswap: %s: %s\n",
111 file, r >= 0 ? "End of file" : strerror(errno));
112 exit(1);
113 }
114 memcpy(&super, block, sizeof(super));
115 if (super.s_magic == SUPER_MAGIC) {
116 offset= (unsigned long) super.s_nzones * _STATIC_BLOCK_SIZE;
117 } else
118 if (super.s_magic == SUPER_V2) {
119 offset= (unsigned long) super.s_zones * _STATIC_BLOCK_SIZE;
120 } else if (super.s_magic == SUPER_V3) {
121 offset= (unsigned long) super.s_zones * super.s_block_size;
122 } else {
123 first= 1;
124 }
125 }
126 if (size == 0) size= devsize - offset;
127 if (size == 0 || offset + size > devsize) {
128 fprintf(stderr, "mkswap: There is no room on %s for ", file);
129 if (size > 0) fprintf(stderr, "%lu kilobytes of ", size/1024);
130 fprintf(stderr, "swapspace\n");
131 if (offset > 0) {
132 fprintf(stderr, "(Use the -f flag to wipe the file system)\n");
133 }
134 exit(1);
135 }
136 } else
137 if (S_ISREG(st.st_mode)) {
138 /* Write to the swap file to guarantee space for MM. */
139 unsigned long n;
140
141 if (size == 0) {
142 fprintf(stderr, "mkswap: No size specified for %s\n", file);
143 usage();
144 }
145
146 memset(block, 0, sizeof(block));
147 for (n= 0; n < size; n += r) {
148 r= size > sizeof(block) ? sizeof(block) : size;
149 if ((r= write(fd, block, r)) <= 0) {
150 fprintf(stderr, "mkswap: %s: %s\n",
151 file, r == 0 ? "End of file" : strerror(errno));
152 exit(1);
153 }
154 }
155 first= 1;
156 } else {
157 fprintf(stderr, "mkswap: %s is not a device or a file\n", file);
158 exit(1);
159 }
160
161 if (offset < SWAP_OFFSET) {
162 offset += SWAP_OFFSET;
163 if (size < SWAP_OFFSET) size= 0; else size -= SWAP_OFFSET;
164 }
165 swap_hdr.sh_magic[0]= SWAP_MAGIC0;
166 swap_hdr.sh_magic[1]= SWAP_MAGIC1;
167 swap_hdr.sh_magic[2]= SWAP_MAGIC2;
168 swap_hdr.sh_magic[3]= SWAP_MAGIC3;
169 swap_hdr.sh_version= SH_VERSION;
170 swap_hdr.sh_priority= 0;
171 swap_hdr.sh_offset= offset;
172 swap_hdr.sh_swapsize= size;
173
174 r= -1;
175 if (lseek(fd, SWAP_BOOTOFF, SEEK_SET) == -1
176 || (r= read(fd, block, sizeof(block))) < sizeof(block)
177 ) {
178 fprintf(stderr, "mkswap: %s: %s\n", file,
179 file, r >= 0 ? "End of file" : strerror(errno));
180 exit(1);
181 }
182
183 r= (first ? SWAP_BOOTOFF : OPTSWAP_BOOTOFF) - SWAP_BOOTOFF;
184 memcpy(block + r, &swap_hdr, sizeof(swap_hdr));
185
186 r= -1;
187 if (lseek(fd, SWAP_BOOTOFF, SEEK_SET) == -1
188 || (r= write(fd, block, sizeof(block))) < sizeof(block)
189 ) {
190 fprintf(stderr, "mkswap: %s: %s\n", file,
191 file, r >= 0 ? "End of file" : strerror(errno));
192 exit(1);
193 }
194 printf("%s: swapspace at offset %lu, size %lu kilobytes\n",
195 file, offset / 1024, size / 1024);
196 return 0;
197}
Note: See TracBrowser for help on using the repository browser.