Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 673 lines (598 sloc) 17.468 kB
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
1 /*
2 * mkswap.c - set up a linux swap device
3 *
4 * (C) 1991 Linus Torvalds. This file may be redistributed as per
5 * the Linux copyright.
6 */
7
8 /*
9 * 20.12.91 - time began. Got VM working yesterday by doing this by hand.
10 *
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
11 * Usage: mkswap [-c] [-vN] [-f] device [size-in-blocks]
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
12 *
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
13 * -c for readability checking. (Use it unless you are SURE!)
14 * -vN for swap areas version N. (Only N=0,1 known today.)
15 * -f for forcing swap creation even if it would smash partition table.
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
16 *
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
17 * The device may be a block device or an image of one, but this isn't
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
18 * enforced (but it's not much fun on a character device :-).
19 *
20 * Patches from jaggy@purplet.demon.co.uk (Mike Jagdis) to make the
21 * size-in-blocks parameter optional added Wed Feb 8 10:33:43 1995.
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
22 *
23 * Version 1 swap area code (for kernel 2.1.117), aeb, 981010.
24 *
25 * Sparc fixes, jj@ultra.linux.cz (Jakub Jelinek), 981201 - mangled by aeb.
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
26 * V1_MAX_PAGES fixes, jj, 990325.
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
27 * sparc64 fixes, jj, 000219.
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
28 *
c07ebfa @karelzak Imported from util-linux-2.11b tarball.
authored
29 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
30 * - added Native Language Support
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
31 *
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
32 */
33
34 #include <stdio.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <fcntl.h>
38 #include <stdlib.h>
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
39 #include <limits.h>
8abb4c2 @karelzak mkswap: avoid mkswap usage on already mounted device
authored
40 #include <mntent.h>
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
41 #include <sys/utsname.h>
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
42 #include <sys/stat.h>
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
43 #include <errno.h>
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
44 #include <getopt.h>
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
45 #ifdef HAVE_LIBSELINUX
46 #include <selinux/selinux.h>
47 #include <selinux/context.h>
48 #endif
49
8023c83 @karelzak mkswap: linux_version() code consolidation
authored
50 #include "linux_version.h"
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
51 #include "swapheader.h"
8abcf29 lib: [strutils] general purpose string handling functions
Davidlohr Bueso authored
52 #include "strutils.h"
66ee815 @karelzak Imported from util-linux-2.10s tarball.
authored
53 #include "nls.h"
54e377b @karelzak mkswap: BLKGETSIZE cleanup
authored
54 #include "blkdev.h"
fc68cd4 @brainflux disk-utils: s/MOUNTED/_PATH_MOUNTED/
brainflux authored
55 #include "pathnames.h"
ff3bed8 @karelzak mkswap: zap bootbits
authored
56 #include "wholedisk.h"
e12c986 @knot include: rename writeall.h to all-io.h
knot authored
57 #include "all-io.h"
94a50e2 @kerolasa mkswap: use xalloc
kerolasa authored
58 #include "xalloc.h"
0867526 @brainflux mkswap: Use c.h
brainflux authored
59 #include "c.h"
45ca68e @kerolasa disk-utils: verify writing to streams was successful
kerolasa authored
60 #include "closestream.h"
def478c @knot mkswap: use is_mounted() instead of check_mount()
knot authored
61 #include "ismounted.h"
66ee815 @karelzak Imported from util-linux-2.10s tarball.
authored
62
766dd75 disk-utils: fix libuuid usage in mkswap
Matthias Koenig authored
63 #ifdef HAVE_LIBUUID
7ee9699 @karelzak build-sys: include <uuid.h> rather than <uuid/uuid.h>
authored
64 # include <uuid.h>
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
65 #endif
66
64d1547 @karelzak build-sys: don't use HAVE_LIBBLKID_INTERNAL macro
authored
67 #ifdef HAVE_LIBBLKID
566f35b @karelzak mkswap: use libblkid to detect PT
authored
68 # include <blkid.h>
69 #endif
70
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
71 static char *device_name = NULL;
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
72 static int DEV = -1;
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
73 static unsigned long long PAGES = 0;
d03dd60 @karelzak Imported from util-linux-2.12a tarball.
authored
74 static unsigned long badpages = 0;
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
75 static int check = 0;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
76
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
77 #define SELINUX_SWAPFILE_TYPE "swapfile_t"
78
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
79 #ifdef __sparc__
80 # ifdef __arch64__
81 # define is_sparc64() 1
82 # define is_be64() 1
83 # else /* sparc32 */
84 static int
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
85 is_sparc64(void)
86 {
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
87 struct utsname un;
88 static int sparc64 = -1;
89
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
90 if (sparc64 != -1)
91 return sparc64;
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
92 sparc64 = 0;
93
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
94 if (uname(&un) < 0)
95 return 0;
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
96 if (! strcmp(un.machine, "sparc64")) {
97 sparc64 = 1;
98 return 1;
99 }
100 if (strcmp(un.machine, "sparc"))
101 return 0; /* Should not happen */
102
48d7b13 @karelzak Imported from util-linux-2.13-pre1 tarball.
authored
103 #ifdef HAVE_PERSONALITY
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
104 {
105 extern int personality(unsigned long);
106 int oldpers;
107 #define PERS_LINUX 0x00000000
108 #define PERS_LINUX_32BIT 0x00800000
109 #define PERS_LINUX32 0x00000008
110
111 oldpers = personality(PERS_LINUX_32BIT);
112 if (oldpers != -1) {
113 if (personality(PERS_LINUX) != -1) {
114 uname(&un);
115 if (! strcmp(un.machine, "sparc64")) {
116 sparc64 = 1;
117 oldpers = PERS_LINUX32;
118 }
119 }
120 personality(oldpers);
121 }
122 }
123 #endif
124
125 return sparc64;
126 }
127 # define is_be64() is_sparc64()
128 # endif /* sparc32 */
129 #else /* !sparc */
130 # define is_be64() 0
131 #endif
132
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
133 /*
7ac3b5b @karelzak Clean up pagesize/PAGE_SIZE usage.
authored
134 * The definition of the union swap_header uses the kernel constant PAGE_SIZE.
135 * Unfortunately, on some architectures this depends on the hardware model, and
136 * can only be found at run time -- we use getpagesize(), so that we do not
137 * need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
138 *
139 * Even more unfortunately, getpagesize() does not always return the right
140 * information. For example, libc4, libc5 and glibc 2.0 do not use the system
141 * call but invent a value themselves (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC),
142 * and thus it may happen that e.g. on a sparc kernel PAGE_SIZE=4096 and
143 * getpagesize() returns 8192.
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
144 *
145 * What to do? Let us allow the user to specify the pagesize explicitly.
7ac3b5b @karelzak Clean up pagesize/PAGE_SIZE usage.
authored
146 *
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
147 */
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
148 static unsigned int user_pagesize;
149 static unsigned int pagesize;
3216beb @karelzak mkswap: fix memory leaks, cleanup check_blocks()
authored
150 static unsigned long *signature_page = NULL;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
151
152 static void
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
153 init_signature_page(void)
154 {
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
155
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
156 unsigned int kernel_pagesize = pagesize = getpagesize();
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
157
158 if (user_pagesize) {
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
159 if (!is_power_of_2(user_pagesize) ||
160 user_pagesize < sizeof(struct swap_header_v1_2) + 10)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
161 errx(EXIT_FAILURE,
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
162 _("Bad user-specified page size %u"),
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
163 user_pagesize);
164 pagesize = user_pagesize;
165 }
166
7ac3b5b @karelzak Clean up pagesize/PAGE_SIZE usage.
authored
167 if (user_pagesize && user_pagesize != kernel_pagesize)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
168 warnx(_("Using user-specified page size %d, "
169 "instead of the system value %d"),
7ac3b5b @karelzak Clean up pagesize/PAGE_SIZE usage.
authored
170 pagesize, kernel_pagesize);
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
171
94a50e2 @kerolasa mkswap: use xalloc
kerolasa authored
172 signature_page = (unsigned long *) xcalloc(1, pagesize);
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
173 }
174
175 static void
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
176 write_signature(char *sig)
177 {
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
178 char *sp = (char *) signature_page;
179
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
180 strncpy(sp + pagesize - 10, sig, 10);
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
181 }
182
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
183 static void
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
184 write_uuid_and_label(unsigned char *uuid, char *volume_name)
185 {
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
186 struct swap_header_v1_2 *h;
187
188 /* Sanity check */
189 if (sizeof(struct swap_header_v1) !=
190 sizeof(struct swap_header_v1_2)) {
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
191 warnx(_("Bad swap header size, no label written."));
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
192 return;
193 }
194
195 h = (struct swap_header_v1_2 *) signature_page;
196 if (uuid)
197 memcpy(h->uuid, uuid, sizeof(h->uuid));
198 if (volume_name) {
199 xstrncpy(h->volume_name, volume_name, sizeof(h->volume_name));
200 if (strlen(volume_name) > strlen(h->volume_name))
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
201 warnx(_("Label was truncated."));
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
202 }
203 if (uuid || volume_name) {
204 if (volume_name)
205 printf("LABEL=%s, ", h->volume_name);
206 else
207 printf(_("no label, "));
766dd75 disk-utils: fix libuuid usage in mkswap
Matthias Koenig authored
208 #ifdef HAVE_LIBUUID
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
209 if (uuid) {
210 char uuid_string[37];
211 uuid_unparse(uuid, uuid_string);
212 printf("UUID=%s\n", uuid_string);
213 } else
214 #endif
215 printf(_("no uuid\n"));
216 }
217 }
218
0e6f4a2 @karelzak Imported from util-linux-2.11v tarball.
authored
219 /*
220 * Find out what the maximum amount of swap space is that the kernel will
221 * handle. This wouldn't matter if the kernel just used as much of the
222 * swap space as it can handle, but until 2.3.4 it would return an error
223 * to swapon() if the swapspace was too large.
224 */
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
225 /* Before 2.2.0pre9 */
226 #define V1_OLD_MAX_PAGES ((0x7fffffff / pagesize) - 1)
0e6f4a2 @karelzak Imported from util-linux-2.11v tarball.
authored
227 /* Since 2.2.0pre9, before 2.3.4:
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
228 error if nr of pages >= SWP_OFFSET(SWP_ENTRY(0,~0UL))
229 with variations on
230 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
231 #define SWP_OFFSET(entry) ((entry) >> 8)
232 on the various architectures. Below the result - yuk.
233
234 Machine pagesize SWP_ENTRY SWP_OFFSET bound+1 oldbound+2
235 i386 2^12 o<<8 e>>8 1<<24 1<<19
236 mips 2^12 o<<15 e>>15 1<<17 1<<19
237 alpha 2^13 o<<40 e>>40 1<<24 1<<18
238 m68k 2^12 o<<12 e>>12 1<<20 1<<19
239 sparc 2^{12,13} (o&0x3ffff)<<9 (e>>9)&0x3ffff 1<<18 1<<{19,18}
240 sparc64 2^13 o<<13 e>>13 1<<51 1<<18
241 ppc 2^12 o<<8 e>>8 1<<24 1<<19
242 armo 2^{13,14,15} o<<8 e>>8 1<<24 1<<{18,17,16}
243 armv 2^12 o<<9 e>>9 1<<23 1<<19
244
245 assuming that longs have 64 bits on alpha and sparc64 and 32 bits elsewhere.
246
247 The bad part is that we need to know this since the kernel will
248 refuse a swap space if it is too large.
249 */
250 /* patch from jj - why does this differ from the above? */
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
251 /* 32bit kernels have a second limitation of 2GB, sparc64 is limited by
252 the size of virtual address space allocation for vmalloc */
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
253 #if defined(__alpha__)
254 #define V1_MAX_PAGES ((1 << 24) - 1)
255 #elif defined(__mips__)
256 #define V1_MAX_PAGES ((1 << 17) - 1)
257 #elif defined(__sparc__)
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
258 #define V1_MAX_PAGES (is_sparc64() ? ((3 << 29) - 1) : ((1 << 18) - 1))
1d4ad1d @karelzak Imported from util-linux-2.11q tarball.
authored
259 #elif defined(__ia64__)
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
260 /*
1d4ad1d @karelzak Imported from util-linux-2.11q tarball.
authored
261 * The actual size will depend on the amount of virtual address space
262 * available to vmalloc the swap map.
263 */
264 #define V1_MAX_PAGES ((1UL << 54) - 1)
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
265 #else
266 #define V1_MAX_PAGES V1_OLD_MAX_PAGES
267 #endif
268 /* man page now says:
269 The maximum useful size of a swap area now depends on the architecture.
270 It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
271 128GB on alpha and 3TB on sparc64.
272 */
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
273
274 #define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
275 #define MIN_GOODPAGES 10
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
276
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
277 static void __attribute__ ((__noreturn__)) usage(FILE *out)
278 {
279 fprintf(out,
280 _("\nUsage:\n"
281 " %s [options] device [size]\n"),
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
282 program_invocation_short_name);
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
283
284 fprintf(out, _(
285 "\nOptions:\n"
286 " -c, --check check bad blocks before creating the swap area\n"
287 " -f, --force allow swap size area be larger than device\n"
288 " -p, --pagesize SIZE specify page size in bytes\n"
289 " -L, --label LABEL specify label\n"
290 " -v, --swapversion NUM specify swap-space version number\n"
291 " -U, --uuid UUID specify the uuid to use\n"
292 " -V, --version output version information and exit\n"
293 " -h, --help display this help and exit\n\n"));
294
295 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
296 }
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
297
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
298 static void
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
299 page_bad(int page)
300 {
3e16599 @karelzak mkswap: use calloc(), remove obsolete v1 header usage
authored
301 struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) signature_page;
302
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
303 if (badpages == MAX_BADPAGES)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
304 errx(EXIT_FAILURE, _("too many bad pages"));
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
305 p->badpages[badpages] = page;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
306 badpages++;
307 }
308
22853e4 @karelzak Imported from util-linux-2.10m tarball.
authored
309 static void
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
310 check_blocks(void)
311 {
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
312 unsigned int current_page;
313 int do_seek = 1;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
314 char *buffer;
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
315
94a50e2 @kerolasa mkswap: use xalloc
kerolasa authored
316 buffer = xmalloc(pagesize);
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
317 current_page = 0;
318 while (current_page < PAGES) {
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
319 if (do_seek && lseek(DEV,current_page*pagesize,SEEK_SET) !=
320 current_page*pagesize)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
321 errx(EXIT_FAILURE, _("seek failed in check_blocks"));
3216beb @karelzak mkswap: fix memory leaks, cleanup check_blocks()
authored
322 if ((do_seek = (pagesize != read(DEV, buffer, pagesize))))
adda7f7 @pdewacht mkswap: unbreak -c ("check") option.
pdewacht authored
323 page_bad(current_page);
324 current_page++;
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
325 }
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
326 if (badpages == 1)
327 printf(_("one bad page\n"));
328 else if (badpages > 1)
d03dd60 @karelzak Imported from util-linux-2.12a tarball.
authored
329 printf(_("%lu bad pages\n"), badpages);
3216beb @karelzak mkswap: fix memory leaks, cleanup check_blocks()
authored
330 free(buffer);
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
331 }
332
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
333 /* return size in pages */
334 static unsigned long long
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
335 get_size(const char *file)
336 {
337 int fd;
54e377b @karelzak mkswap: BLKGETSIZE cleanup
authored
338 unsigned long long size;
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
339
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
340 fd = open(file, O_RDONLY);
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
341 if (fd < 0) {
342 perror(file);
a4d3e77 @kerolasa mkswap: use EXIT_ values
kerolasa authored
343 exit(EXIT_FAILURE);
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
344 }
54e377b @karelzak mkswap: BLKGETSIZE cleanup
authored
345 if (blkdev_get_size(fd, &size) == 0)
346 size /= pagesize;
347
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
348 close(fd);
349 return size;
350 }
351
979f1dd @karelzak mkswap: wipe all old signatures
authored
352 #ifdef HAVE_LIBBLKID
353 static blkid_probe
354 new_prober(int fd)
355 {
356 blkid_probe pr = blkid_new_probe();
357 if (!pr)
358 errx(EXIT_FAILURE, _("unable to alloc new libblkid probe"));
359 if (blkid_probe_set_device(pr, fd, 0, 0))
360 errx(EXIT_FAILURE, _("unable to assign device to libblkid probe"));
361 return pr;
362 }
363 #endif
364
ff3bed8 @karelzak mkswap: zap bootbits
authored
365 static void
d5ac5df @kerolasa mkswap: fix shadow declaration
kerolasa authored
366 wipe_device(int fd, const char *devname, int force, int is_blkdevice)
ff3bed8 @karelzak mkswap: zap bootbits
authored
367 {
566f35b @karelzak mkswap: use libblkid to detect PT
authored
368 char *type = NULL;
369 int whole = 0;
ff3bed8 @karelzak mkswap: zap bootbits
authored
370 int zap = 1;
9206b23 @karelzak test: refresh build-sys tests
authored
371 #ifdef HAVE_LIBBLKID
979f1dd @karelzak mkswap: wipe all old signatures
authored
372 blkid_probe pr = NULL;
9206b23 @karelzak test: refresh build-sys tests
authored
373 #endif
ff3bed8 @karelzak mkswap: zap bootbits
authored
374 if (!force) {
375 if (lseek(fd, 0, SEEK_SET) != 0)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
376 errx(EXIT_FAILURE, _("unable to rewind swap-device"));
ff3bed8 @karelzak mkswap: zap bootbits
authored
377
d5ac5df @kerolasa mkswap: fix shadow declaration
kerolasa authored
378 if (is_blkdevice && is_whole_disk_fd(fd, devname)) {
ff3bed8 @karelzak mkswap: zap bootbits
authored
379 /* don't zap bootbits on whole disk -- we know nothing
380 * about bootloaders on the device */
566f35b @karelzak mkswap: use libblkid to detect PT
authored
381 whole = 1;
ff3bed8 @karelzak mkswap: zap bootbits
authored
382 zap = 0;
566f35b @karelzak mkswap: use libblkid to detect PT
authored
383 } else {
64d1547 @karelzak build-sys: don't use HAVE_LIBBLKID_INTERNAL macro
authored
384 #ifdef HAVE_LIBBLKID
979f1dd @karelzak mkswap: wipe all old signatures
authored
385 pr = new_prober(fd);
566f35b @karelzak mkswap: use libblkid to detect PT
authored
386 blkid_probe_enable_partitions(pr, 1);
387 blkid_probe_enable_superblocks(pr, 0);
388
c596a05 @karelzak mkswap: check blkid_probe_lookup_values() return [coverity scan]
authored
389 if (blkid_do_fullprobe(pr) == 0 &&
390 blkid_probe_lookup_value(pr, "PTTYPE",
391 (const char **) &type, NULL) == 0 &&
392 type) {
94a50e2 @kerolasa mkswap: use xalloc
kerolasa authored
393 type = xstrdup(type);
566f35b @karelzak mkswap: use libblkid to detect PT
authored
394 zap = 0;
395 }
396 #else
397 /* don't zap if compiled without libblkid */
ff3bed8 @karelzak mkswap: zap bootbits
authored
398 zap = 0;
566f35b @karelzak mkswap: use libblkid to detect PT
authored
399 #endif
400 }
ff3bed8 @karelzak mkswap: zap bootbits
authored
401 }
402
403 if (zap) {
979f1dd @karelzak mkswap: wipe all old signatures
authored
404 /*
405 * Wipe boodbits
406 */
ff3bed8 @karelzak mkswap: zap bootbits
authored
407 char buf[1024];
408
409 if (lseek(fd, 0, SEEK_SET) != 0)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
410 errx(EXIT_FAILURE, _("unable to rewind swap-device"));
ff3bed8 @karelzak mkswap: zap bootbits
authored
411
412 memset(buf, 0, sizeof(buf));
413 if (write_all(fd, buf, sizeof(buf)))
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
414 errx(EXIT_FAILURE, _("unable to erase bootbits sectors"));
979f1dd @karelzak mkswap: wipe all old signatures
authored
415 #ifdef HAVE_LIBBLKID
416 /*
417 * Wipe rest of the device
418 */
419 if (!pr)
420 pr = new_prober(fd);
421
422 blkid_probe_enable_superblocks(pr, 1);
423 blkid_probe_enable_partitions(pr, 0);
424 blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
425
426 while (blkid_do_probe(pr) == 0)
427 blkid_do_wipe(pr, 0);
428 #endif
429 } else {
430 warnx(_("%s: warning: don't erase bootbits sectors"),
431 devname);
432 if (type)
433 fprintf(stderr, _(" (%s partition table detected). "), type);
434 else if (whole)
435 fprintf(stderr, _(" on whole disk. "));
436 else
437 fprintf(stderr, _(" (compiled without libblkid). "));
438 fprintf(stderr, "Use -f to force.\n");
ff3bed8 @karelzak mkswap: zap bootbits
authored
439 }
979f1dd @karelzak mkswap: wipe all old signatures
authored
440 #ifdef HAVE_LIBBLKID
441 blkid_free_probe(pr);
442 #endif
ff3bed8 @karelzak mkswap: zap bootbits
authored
443 }
444
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
445 int
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
446 main(int argc, char **argv) {
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
447 struct stat statbuf;
3e16599 @karelzak mkswap: use calloc(), remove obsolete v1 header usage
authored
448 struct swap_header_v1_2 *hdr;
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
449 int c;
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
450 unsigned long long maxpages;
451 unsigned long long goodpages;
452 unsigned long long sz;
1d4ad1d @karelzak Imported from util-linux-2.11q tarball.
authored
453 off_t offset;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
454 int force = 0;
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
455 int version = 1;
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
456 char *block_count = 0;
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
457 char *opt_label = NULL;
f88c89d @karelzak mkswap: fix signedness problems and remove obsolete code
authored
458 unsigned char *uuid = NULL;
766dd75 disk-utils: fix libuuid usage in mkswap
Matthias Koenig authored
459 #ifdef HAVE_LIBUUID
7b24180 @karelzak mkswap: fix compiler warnings
authored
460 const char *opt_uuid = NULL;
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
461 uuid_t uuid_dat;
462 #endif
6c7d5ae @karelzak move struct option to .rodata
authored
463 static const struct option longopts[] = {
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
464 { "check", no_argument, 0, 'c' },
465 { "force", no_argument, 0, 'f' },
466 { "pagesize", required_argument, 0, 'p' },
467 { "label", required_argument, 0, 'L' },
468 { "swapversion", required_argument, 0, 'v' },
469 { "uuid", required_argument, 0, 'U' },
470 { "version", no_argument, 0, 'V' },
471 { "help", no_argument, 0, 'h' },
472 { NULL, 0, 0, 0 }
473 };
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
474
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
475 setlocale(LC_ALL, "");
476 bindtextdomain(PACKAGE, LOCALEDIR);
477 textdomain(PACKAGE);
45ca68e @kerolasa disk-utils: verify writing to streams was successful
kerolasa authored
478 atexit(close_stdout);
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
479
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
480 while((c = getopt_long(argc, argv, "cfp:L:v:U:Vh", longopts, NULL)) != -1) {
481 switch (c) {
482 case 'c':
483 check=1;
484 break;
485 case 'f':
486 force=1;
487 break;
488 case 'p':
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
489 user_pagesize = strtou32_or_err(optarg, _("parse page size failed"));
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
490 break;
491 case 'L':
492 opt_label = optarg;
493 break;
494 case 'v':
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
495 version = strtos32_or_err(optarg, _("parse version number failed"));
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
496 break;
497 case 'U':
93bf0f2 mkswap: set UUID for swap space (add -U option)
Martin Schulze authored
498 #ifdef HAVE_LIBUUID
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
499 opt_uuid = optarg;
93bf0f2 mkswap: set UUID for swap space (add -U option)
Martin Schulze authored
500 #else
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
501 warnx(_("warning: ignore -U (UUIDs are unsupported by %s)"),
502 program_invocation_short_name);
93bf0f2 mkswap: set UUID for swap space (add -U option)
Martin Schulze authored
503 #endif
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
504 break;
505 case 'V':
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
506 printf(UTIL_LINUX_VERSION);
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
507 exit(EXIT_SUCCESS);
508 case 'h':
509 usage(stdout);
510 default:
511 usage(stderr);
512 }
513 }
514 if (optind < argc)
515 device_name = argv[optind++];
516 if (optind < argc)
517 block_count = argv[optind++];
518 if (optind != argc) {
519 warnx(("only one device as argument is currently supported."));
520 usage(stderr);
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
521 }
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
522
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
523 if (version != 1)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
524 errx(EXIT_FAILURE,
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
525 _("does not support swapspace version %d."), version);
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
526
766dd75 disk-utils: fix libuuid usage in mkswap
Matthias Koenig authored
527 #ifdef HAVE_LIBUUID
93bf0f2 mkswap: set UUID for swap space (add -U option)
Martin Schulze authored
528 if(opt_uuid) {
529 if (uuid_parse(opt_uuid, uuid_dat) != 0)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
530 errx(EXIT_FAILURE, _("error: UUID parsing failed"));
93bf0f2 mkswap: set UUID for swap space (add -U option)
Martin Schulze authored
531 } else
532 uuid_generate(uuid_dat);
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
533 uuid = uuid_dat;
534 #endif
535
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
536 init_signature_page(); /* get pagesize */
537
fd6b7a7 @karelzak Imported from util-linux-2.7.1 tarball.
authored
538 if (!device_name) {
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
539 warnx(_("error: Nowhere to set up swap on?"));
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
540 usage(stderr);
fd6b7a7 @karelzak Imported from util-linux-2.7.1 tarball.
authored
541 }
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
542 if (block_count) {
20543e6 @karelzak mkswap: more robust strtoull() usage
authored
543 /* this silly user specified the number of blocks explicitly */
33fb5cf @karelzak disk-utils: cleanup strtoxx_or_err()
authored
544 uint64_t blks = strtou64_or_err(block_count,
545 _("invalid block count argument"));
20543e6 @karelzak mkswap: more robust strtoull() usage
authored
546 PAGES = blks / (pagesize / 1024);
eb63b9b @karelzak Imported from util-linux-2.10f tarball.
authored
547 }
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
548 sz = get_size(device_name);
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
549 if (!PAGES)
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
550 PAGES = sz;
f270466 @kerolasa mkswap: coding style unification
kerolasa authored
551 else if (PAGES > sz && !force) {
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
552 errx(EXIT_FAILURE,
553 _("error: "
554 "size %llu KiB is larger than device size %llu KiB"),
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
555 PAGES*(pagesize/1024), sz*(pagesize/1024));
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
556 }
557
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
558 if (PAGES < MIN_GOODPAGES) {
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
559 warnx(_("error: swap area needs to be at least %ld KiB"),
560 (long)(MIN_GOODPAGES * pagesize/1024));
e079c4e @kerolasa mkswap: support long options and check user inputs
kerolasa authored
561 usage(stderr);
726f69e @karelzak Imported from util-linux-2.5 tarball.
authored
562 }
0e6f4a2 @karelzak Imported from util-linux-2.11v tarball.
authored
563
ff035f6 @sthibaul mkswap: non-linux support
sthibaul authored
564 #ifdef __linux__
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
565 if (get_linux_version() >= KERNEL_VERSION(2,3,4))
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
566 maxpages = UINT_MAX + 1ULL;
8023c83 @karelzak mkswap: linux_version() code consolidation
authored
567 else if (get_linux_version() >= KERNEL_VERSION(2,2,1))
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
568 maxpages = V1_MAX_PAGES;
0e6f4a2 @karelzak Imported from util-linux-2.11v tarball.
authored
569 else
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
570 #endif
7eda085 @karelzak Imported from util-linux-2.9v tarball.
authored
571 maxpages = V1_OLD_MAX_PAGES;
0e6f4a2 @karelzak Imported from util-linux-2.11v tarball.
authored
572
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
573 if (PAGES > maxpages) {
574 PAGES = maxpages;
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
575 warnx(_("warning: truncating swap area to %llu KiB"),
576 PAGES * pagesize / 1024);
726f69e @karelzak Imported from util-linux-2.5 tarball.
authored
577 }
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
578
dceb1f2 @knot mkswap: improve diagnostics message if the device is mounted
knot authored
579 if (is_mounted(device_name))
580 errx(EXIT_FAILURE, _("error: "
581 "%s is mounted; will not make swapspace."),
582 device_name);
583
2018629 disk-utils: let mkfs tools open with O_EXCL
Matthias Koenig authored
584 if (stat(device_name, &statbuf) < 0) {
585 perror(device_name);
a4d3e77 @kerolasa mkswap: use EXIT_ values
kerolasa authored
586 exit(EXIT_FAILURE);
2018629 disk-utils: let mkfs tools open with O_EXCL
Matthias Koenig authored
587 }
588 if (S_ISBLK(statbuf.st_mode))
589 DEV = open(device_name, O_RDWR | O_EXCL);
590 else
591 DEV = open(device_name, O_RDWR);
592
593 if (DEV < 0) {
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
594 perror(device_name);
a4d3e77 @kerolasa mkswap: use EXIT_ values
kerolasa authored
595 exit(EXIT_FAILURE);
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
596 }
95f1bde @karelzak Imported from util-linux-2.11x tarball.
authored
597
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
598 if (!S_ISBLK(statbuf.st_mode))
599 check=0;
95fa64d mkswap: add alignment check
Davidlohr Bueso authored
600 else if (blkdev_is_misaligned(DEV))
601 warnx(_("warning: %s is misaligned"), device_name);
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
602
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
603 if (check)
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
604 check_blocks();
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
605
979f1dd @karelzak mkswap: wipe all old signatures
authored
606 wipe_device(DEV, device_name, force, S_ISBLK(statbuf.st_mode));
ff3bed8 @karelzak mkswap: zap bootbits
authored
607
3e16599 @karelzak mkswap: use calloc(), remove obsolete v1 header usage
authored
608 hdr = (struct swap_header_v1_2 *) signature_page;
609 hdr->version = 1;
610 hdr->last_page = PAGES - 1;
611 hdr->nr_badpages = badpages;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
612
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
613 if (badpages > PAGES - MIN_GOODPAGES)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
614 errx(EXIT_FAILURE, _("Unable to set up swap-space: unreadable"));
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
615
99e6d52 mkswap: handle 2^32 pages
Hugh Dickins authored
616 goodpages = PAGES - badpages - 1;
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
617 printf(_("Setting up swapspace version 1, size = %llu KiB\n"),
618 goodpages * pagesize / 1024);
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
619
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
620 write_signature("SWAPSPACE2");
621 write_uuid_and_label(uuid, opt_label);
756bfd0 @karelzak Imported from util-linux-2.12o tarball.
authored
622
4c85aa3 @karelzak mkswap: remove v0 swap space support
authored
623 offset = 1024;
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
624 if (lseek(DEV, offset, SEEK_SET) != offset)
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
625 errx(EXIT_FAILURE, _("unable to rewind swap-device"));
db83e35 @karelzak mkswap: when writing the signature page, handle EINTR returns
authored
626 if (write_all(DEV, (char *) signature_page + offset,
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
627 pagesize - offset) == -1)
628 err(EXIT_FAILURE,
629 _("%s: unable to write signature page"),
630 device_name);
5c36a0e @karelzak Imported from util-linux-2.9i tarball.
authored
631
2b6fc90 @karelzak Imported from util-linux-2.8 tarball.
authored
632 /*
633 * A subsequent swapon() will fail if the signature
634 * is not actually on disk. (This is a kernel bug.)
635 */
48d7b13 @karelzak Imported from util-linux-2.13-pre1 tarball.
authored
636 #ifdef HAVE_FSYNC
2b6fc90 @karelzak Imported from util-linux-2.8 tarball.
authored
637 if (fsync(DEV))
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
638 errx(EXIT_FAILURE, _("fsync failed"));
66ee815 @karelzak Imported from util-linux-2.10s tarball.
authored
639 #endif
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
640
641 #ifdef HAVE_LIBSELINUX
4ba66ed @karelzak selinux: is_selinux_enabled() returns 0, 1 and -1
authored
642 if (S_ISREG(statbuf.st_mode) && is_selinux_enabled() > 0) {
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
643 security_context_t context_string;
644 security_context_t oldcontext;
645 context_t newcontext;
646
71bf788 @kaigai mkswap: possible to crash with SELinux relabeling support
kaigai authored
647 if (fgetfilecon(DEV, &oldcontext) < 0) {
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
648 if (errno != ENODATA)
649 err(EXIT_FAILURE,
8d1b0fe @karelzak mkswap: fix compiler warning
authored
650 _("%s: unable to obtain selinux file label"),
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
651 device_name);
71bf788 @kaigai mkswap: possible to crash with SELinux relabeling support
kaigai authored
652 if (matchpathcon(device_name, statbuf.st_mode, &oldcontext))
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
653 errx(EXIT_FAILURE, _("unable to matchpathcon()"));
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
654 }
655 if (!(newcontext = context_new(oldcontext)))
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
656 errx(EXIT_FAILURE, _("unable to create new selinux context"));
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
657 if (context_type_set(newcontext, SELINUX_SWAPFILE_TYPE))
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
658 errx(EXIT_FAILURE, _("couldn't compute selinux context"));
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
659
660 context_string = context_str(newcontext);
661
662 if (strcmp(context_string, oldcontext)!=0) {
00a7d0d @kerolasa mkswap: use libc error messaging facilities
kerolasa authored
663 if (fsetfilecon(DEV, context_string))
664 err(EXIT_FAILURE, _("unable to relabel %s to %s"),
665 device_name, context_string);
3e18b04 @karelzak mkswap: automatically add selinux label to swapfile
authored
666 }
667 context_free(newcontext);
668 freecon(oldcontext);
669 }
670 #endif
a4d3e77 @kerolasa mkswap: use EXIT_ values
kerolasa authored
671 return EXIT_SUCCESS;
6dbe3af @karelzak Imported from util-linux-2.2 tarball.
authored
672 }
Something went wrong with that request. Please try again.