Annotation of /trunk/mkinitrd-magellan/busybox/util-linux/mkswap.c
Parent Directory | Revision Log
Revision 984 -
(hide annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 3701 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years ago) by niro
File MIME type: text/plain
File size: 3701 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | niro | 532 | /* 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 GPL version 2, see file LICENSE in this tarball for details. | ||
7 | */ | ||
8 | niro | 816 | #include "libbb.h" |
9 | niro | 532 | |
10 | niro | 816 | #if ENABLE_SELINUX |
11 | static void mkswap_selinux_setcontext(int fd, const char *path) | ||
12 | niro | 532 | { |
13 | niro | 816 | struct stat stbuf; |
14 | |||
15 | if (!is_selinux_enabled()) | ||
16 | return; | ||
17 | |||
18 | if (fstat(fd, &stbuf) < 0) | ||
19 | bb_perror_msg_and_die("fstat failed"); | ||
20 | if (S_ISREG(stbuf.st_mode)) { | ||
21 | security_context_t newcon; | ||
22 | security_context_t oldcon = NULL; | ||
23 | context_t context; | ||
24 | |||
25 | if (fgetfilecon(fd, &oldcon) < 0) { | ||
26 | if (errno != ENODATA) | ||
27 | goto error; | ||
28 | if (matchpathcon(path, stbuf.st_mode, &oldcon) < 0) | ||
29 | goto error; | ||
30 | } | ||
31 | context = context_new(oldcon); | ||
32 | if (!context || context_type_set(context, "swapfile_t")) | ||
33 | goto error; | ||
34 | newcon = context_str(context); | ||
35 | if (!newcon) | ||
36 | goto error; | ||
37 | /* fsetfilecon_raw is hidden */ | ||
38 | if (strcmp(oldcon, newcon) != 0 && fsetfilecon(fd, newcon) < 0) | ||
39 | goto error; | ||
40 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
41 | context_free(context); | ||
42 | freecon(oldcon); | ||
43 | } | ||
44 | } | ||
45 | return; | ||
46 | error: | ||
47 | bb_perror_msg_and_die("SELinux relabeling failed"); | ||
48 | } | ||
49 | #else | ||
50 | niro | 984 | # define mkswap_selinux_setcontext(fd, path) ((void)0) |
51 | niro | 816 | #endif |
52 | |||
53 | niro | 984 | /* from Linux 2.6.23 */ |
54 | niro | 816 | /* |
55 | niro | 984 | * Magic header for a swap area. ... Note that the first |
56 | * kilobyte is reserved for boot loader or disk label stuff. | ||
57 | niro | 816 | */ |
58 | niro | 984 | struct swap_header_v1 { |
59 | /* char bootbits[1024]; Space for disklabel etc. */ | ||
60 | uint32_t version; /* second kbyte, word 0 */ | ||
61 | uint32_t last_page; /* 1 */ | ||
62 | uint32_t nr_badpages; /* 2 */ | ||
63 | char sws_uuid[16]; /* 3,4,5,6 */ | ||
64 | char sws_volume[16]; /* 7,8,9,10 */ | ||
65 | uint32_t padding[117]; /* 11..127 */ | ||
66 | uint32_t badpages[1]; /* 128 */ | ||
67 | /* total 129 32-bit words in 2nd kilobyte */ | ||
68 | niro | 816 | }; |
69 | |||
70 | #define NWORDS 129 | ||
71 | niro | 984 | #define hdr ((struct swap_header_v1*)bb_common_bufsiz1) |
72 | niro | 816 | |
73 | niro | 984 | struct BUG_sizes { |
74 | char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1]; | ||
75 | char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1]; | ||
76 | niro | 816 | }; |
77 | |||
78 | /* Stored without terminating NUL */ | ||
79 | static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2"; | ||
80 | |||
81 | int mkswap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
82 | niro | 984 | int mkswap_main(int argc UNUSED_PARAM, char **argv) |
83 | niro | 816 | { |
84 | niro | 984 | int fd; |
85 | unsigned pagesize; | ||
86 | niro | 532 | off_t len; |
87 | niro | 984 | const char *label = ""; |
88 | niro | 532 | |
89 | niro | 984 | opt_complementary = "=1"; |
90 | /* TODO: -p PAGESZ, -U UUID, | ||
91 | * optional SIZE_IN_KB 2nd param | ||
92 | */ | ||
93 | getopt32(argv, "L:", &label); | ||
94 | argv += optind; | ||
95 | niro | 532 | |
96 | niro | 984 | fd = xopen(argv[0], O_WRONLY); |
97 | niro | 532 | |
98 | niro | 984 | /* Figure out how big the device is and announce our intentions */ |
99 | niro | 816 | /* fdlength was reported to be unreliable - use seek */ |
100 | len = xlseek(fd, 0, SEEK_END); | ||
101 | niro | 984 | if (ENABLE_SELINUX) |
102 | xlseek(fd, 0, SEEK_SET); | ||
103 | |||
104 | niro | 532 | pagesize = getpagesize(); |
105 | niro | 984 | len -= pagesize; |
106 | printf("Setting up swapspace version 1, size = %"OFF_FMT"u bytes\n", len); | ||
107 | mkswap_selinux_setcontext(fd, argv[0]); | ||
108 | niro | 532 | |
109 | niro | 984 | /* Make a header. hdr is zero-filled so far... */ |
110 | hdr->version = 1; | ||
111 | hdr->last_page = (uoff_t)len / pagesize; | ||
112 | niro | 532 | |
113 | niro | 984 | if (ENABLE_FEATURE_MKSWAP_UUID) { |
114 | char uuid_string[32]; | ||
115 | generate_uuid((void*)hdr->sws_uuid); | ||
116 | bin2hex(uuid_string, hdr->sws_uuid, 16); | ||
117 | /* f.e. UUID=dfd9c173-be52-4d27-99a5-c34c6c2ff55f */ | ||
118 | printf("UUID=%.8s" "-%.4s-%.4s-%.4s-%.12s\n", | ||
119 | uuid_string, | ||
120 | uuid_string+8, | ||
121 | uuid_string+8+4, | ||
122 | uuid_string+8+4+4, | ||
123 | uuid_string+8+4+4+4 | ||
124 | ); | ||
125 | } | ||
126 | safe_strncpy(hdr->sws_volume, label, 16); | ||
127 | niro | 532 | |
128 | niro | 984 | /* Write the header. Sync to disk because some kernel versions check |
129 | * signature on disk (not in cache) during swapon. */ | ||
130 | niro | 532 | xlseek(fd, 1024, SEEK_SET); |
131 | niro | 816 | xwrite(fd, hdr, NWORDS * 4); |
132 | xlseek(fd, pagesize - 10, SEEK_SET); | ||
133 | xwrite(fd, SWAPSPACE2, 10); | ||
134 | niro | 532 | fsync(fd); |
135 | |||
136 | niro | 984 | if (ENABLE_FEATURE_CLEAN_UP) |
137 | close(fd); | ||
138 | niro | 532 | |
139 | return 0; | ||
140 | } |