]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - disk-utils/mkswap.c
2 * mkswap.c - set up a linux swap device
4 * (C) 1991 Linus Torvalds. This file may be redistributed as per
9 * 20.12.91 - time began. Got VM working yesterday by doing this by hand.
11 * Usuage: mkswap [-c] device [size-in-blocks]
13 * -c for readablility checking (use it unless you are SURE!)
15 * The device may be a block device or a image of one, but this isn't
16 * enforced (but it's not much fun on a character device :-).
18 * Patches from jaggy@purplet.demon.co.uk (Mike Jagdis) to make the
19 * size-in-blocks parameter optional added Wed Feb 8 10:33:43 1995.
27 #include <sys/ioctl.h>
31 #define BLKGETSIZE 0x1260
37 #define TEST_BUFFER_PAGES 8
39 static char * program_name
= "mkswap";
40 static char * device_name
= NULL
;
42 static long PAGES
= 0;
44 static int badpages
= 0;
46 static int signature_page
[PAGE_SIZE
/sizeof(int)];
48 static void bit_set (unsigned int *addr
, unsigned int nr
)
52 addr
+= nr
/ (8 * sizeof(int));
54 m
= 1 << (nr
& (8 * sizeof(int) - 1));
58 static int bit_test_and_clear (unsigned int *addr
, unsigned int nr
)
62 addr
+= nr
/ (8 * sizeof(int));
64 m
= 1 << (nr
& (8 * sizeof(int) - 1));
70 * Volatile to let gcc know that this doesn't return. When trying
71 * to compile this under minix, volatile gives a warning, as
72 * exit() isn't defined as volatile under minix.
74 volatile void fatal_error(const char * fmt_string
)
76 fprintf(stderr
,fmt_string
,program_name
,device_name
);
80 #define usage() fatal_error("Usage: %s [-c] /dev/name [blocks]\n")
81 #define die(str) fatal_error("%s: " str "\n")
83 void check_blocks(void)
85 unsigned int current_page
;
87 static char buffer
[PAGE_SIZE
];
90 while (current_page
< PAGES
) {
92 bit_set(signature_page
,current_page
++);
95 if (do_seek
&& lseek(DEV
,current_page
*PAGE_SIZE
,SEEK_SET
) !=
96 current_page
*PAGE_SIZE
)
97 die("seek failed in check_blocks");
98 if ((do_seek
= (PAGE_SIZE
!= read(DEV
, buffer
, PAGE_SIZE
)))) {
99 bit_test_and_clear(signature_page
,current_page
++);
103 bit_set(signature_page
,current_page
++);
106 printf("%d bad page%s\n",badpages
,(badpages
>1)?"s":"");
109 static long valid_offset (int fd
, int offset
)
113 if (lseek (fd
, offset
, 0) < 0)
115 if (read (fd
, &ch
, 1) < 1)
120 static int count_blocks (int fd
)
125 for (high
= 1; valid_offset (fd
, high
); high
*= 2)
127 while (low
< high
- 1)
129 const int mid
= (low
+ high
) / 2;
131 if (valid_offset (fd
, mid
))
136 valid_offset (fd
, 0);
140 static int get_size(const char *file
)
145 fd
= open(file
, O_RDWR
);
150 if (ioctl(fd
, BLKGETSIZE
, &size
) >= 0) {
155 size
= count_blocks(fd
);
160 int main(int argc
, char ** argv
)
166 memset(signature_page
,0,PAGE_SIZE
);
168 program_name
= *argv
;
171 if (argv
[0][0] != '-')
173 PAGES
= strtol(argv
[0],&tmp
,0)>>(PAGE_SHIFT
-10);
177 device_name
= argv
[0];
178 else while (*++argv
[0])
179 switch (argv
[0][0]) {
180 case 'c': check
=1; break;
184 if (device_name
&& !PAGES
) {
185 PAGES
= get_size(device_name
) / PAGE_SIZE
;
189 "%s: error: Nowhere to set up swap on?\n",
195 "%s: error: swap area needs to be at least %ldkB\n",
196 program_name
, (long)(10 * PAGE_SIZE
/ 1024));
199 if (PAGES
> 8 * (PAGE_SIZE
- 10)) {
200 PAGES
= 8 * (PAGE_SIZE
- 10);
201 fprintf(stderr
, "%s: warning: truncating swap area to %ldkB\n",
202 program_name
, PAGES
* PAGE_SIZE
/ 1024);
204 DEV
= open(device_name
,O_RDWR
);
205 if (DEV
< 0 || fstat(DEV
, &statbuf
) < 0) {
209 if (!S_ISBLK(statbuf
.st_mode
))
211 else if (statbuf
.st_rdev
== 0x0300 || statbuf
.st_rdev
== 0x0340)
212 die("Will not try to make swapdevice on '%s'");
214 if (!bit_test_and_clear(signature_page
,0))
215 die("fatal: first page unreadable");
216 goodpages
= PAGES
- badpages
- 1;
218 die("Unable to set up swap-space: unreadable");
219 printf("Setting up swapspace, size = %ld bytes\n",
220 (long)(goodpages
*PAGE_SIZE
));
221 strncpy((char*)signature_page
+PAGE_SIZE
-10, "SWAP-SPACE", 10);
222 if (lseek(DEV
, 0, SEEK_SET
))
223 die("unable to rewind swap-device");
224 if (PAGE_SIZE
!= write(DEV
, signature_page
, PAGE_SIZE
))
225 die("unable to write signature page");
227 * A subsequent swapon() will fail if the signature
228 * is not actually on disk. (This is a kernel bug.)