source: MondoRescue/branches/3.3/mindi-busybox/util-linux/mkswap.c@ 3625

Last change on this file since 3625 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 4.0 KB
Line 
1/* vi: set sw=4 ts=4: */
2/* mkswap.c - format swap device (Linux v1 only)
3 *
4 * Copyright 2006 Rob Landley <rob@landley.net>
5 *
6 * Licensed under GPLv2, see file LICENSE in this source tree.
7 */
8
9//usage:#define mkswap_trivial_usage
10//usage: "[-L LBL] BLOCKDEV [KBYTES]"
11//usage:#define mkswap_full_usage "\n\n"
12//usage: "Prepare BLOCKDEV to be used as swap partition\n"
13//usage: "\n -L LBL Label"
14
15#include "libbb.h"
16#include "common_bufsiz.h"
17
18#if ENABLE_SELINUX
19static void mkswap_selinux_setcontext(int fd, const char *path)
20{
21 struct stat stbuf;
22
23 if (!is_selinux_enabled())
24 return;
25
26 xfstat(fd, &stbuf, path);
27 if (S_ISREG(stbuf.st_mode)) {
28 security_context_t newcon;
29 security_context_t oldcon = NULL;
30 context_t context;
31
32 if (fgetfilecon(fd, &oldcon) < 0) {
33 if (errno != ENODATA)
34 goto error;
35 if (matchpathcon(path, stbuf.st_mode, &oldcon) < 0)
36 goto error;
37 }
38 context = context_new(oldcon);
39 if (!context || context_type_set(context, "swapfile_t"))
40 goto error;
41 newcon = context_str(context);
42 if (!newcon)
43 goto error;
44 /* fsetfilecon_raw is hidden */
45 if (strcmp(oldcon, newcon) != 0 && fsetfilecon(fd, newcon) < 0)
46 goto error;
47 if (ENABLE_FEATURE_CLEAN_UP) {
48 context_free(context);
49 freecon(oldcon);
50 }
51 }
52 return;
53 error:
54 bb_perror_msg_and_die("SELinux relabeling failed");
55}
56#else
57# define mkswap_selinux_setcontext(fd, path) ((void)0)
58#endif
59
60/* from Linux 2.6.23 */
61/*
62 * Magic header for a swap area. ... Note that the first
63 * kilobyte is reserved for boot loader or disk label stuff.
64 */
65struct swap_header_v1 {
66/* char bootbits[1024]; Space for disklabel etc. */
67 uint32_t version; /* second kbyte, word 0 */
68 uint32_t last_page; /* 1 */
69 uint32_t nr_badpages; /* 2 */
70 char sws_uuid[16]; /* 3,4,5,6 */
71 char sws_volume[16]; /* 7,8,9,10 */
72 uint32_t padding[117]; /* 11..127 */
73 uint32_t badpages[1]; /* 128 */
74 /* total 129 32-bit words in 2nd kilobyte */
75} FIX_ALIASING;
76
77#define NWORDS 129
78#define hdr ((struct swap_header_v1*)bb_common_bufsiz1)
79#define INIT_G() do { setup_common_bufsiz(); } while (0)
80
81struct BUG_sizes {
82 char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1];
83 char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1];
84};
85
86/* Stored without terminating NUL */
87static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2";
88
89int mkswap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
90int mkswap_main(int argc UNUSED_PARAM, char **argv)
91{
92 int fd;
93 unsigned pagesize;
94 off_t len;
95 const char *label = "";
96
97 INIT_G();
98
99 opt_complementary = "-1"; /* at least one param */
100 /* TODO: -p PAGESZ, -U UUID */
101 getopt32(argv, "L:", &label);
102 argv += optind;
103
104 fd = xopen(argv[0], O_WRONLY);
105
106 /* Figure out how big the device is */
107 len = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ 1);
108 pagesize = getpagesize();
109 len -= pagesize;
110
111 /* Announce our intentions */
112 printf("Setting up swapspace version 1, size = %"OFF_FMT"u bytes\n", len);
113 mkswap_selinux_setcontext(fd, argv[0]);
114
115 /* hdr is zero-filled so far. Clear the first kbyte, or else
116 * mkswap-ing former FAT partition does NOT erase its signature.
117 *
118 * util-linux-ng 2.17.2 claims to erase it only if it does not see
119 * a partition table and is not run on whole disk. -f forces it.
120 */
121 xwrite(fd, hdr, 1024);
122
123 /* Fill the header. */
124 hdr->version = 1;
125 hdr->last_page = (uoff_t)len / pagesize;
126
127 if (ENABLE_FEATURE_MKSWAP_UUID) {
128 char uuid_string[32];
129 generate_uuid((void*)hdr->sws_uuid);
130 bin2hex(uuid_string, hdr->sws_uuid, 16);
131 /* f.e. UUID=dfd9c173-be52-4d27-99a5-c34c6c2ff55f */
132 printf("UUID=%.8s" "-%.4s-%.4s-%.4s-%.12s\n",
133 uuid_string,
134 uuid_string+8,
135 uuid_string+8+4,
136 uuid_string+8+4+4,
137 uuid_string+8+4+4+4
138 );
139 }
140 safe_strncpy(hdr->sws_volume, label, 16);
141
142 /* Write the header. Sync to disk because some kernel versions check
143 * signature on disk (not in cache) during swapon. */
144 xwrite(fd, hdr, NWORDS * 4);
145 xlseek(fd, pagesize - 10, SEEK_SET);
146 xwrite(fd, SWAPSPACE2, 10);
147 fsync(fd);
148
149 if (ENABLE_FEATURE_CLEAN_UP)
150 close(fd);
151
152 return 0;
153}
Note: See TracBrowser for help on using the repository browser.