Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(664)

Side by Side Diff: src/platform/vboot_reference/utility/cgpt/cgpt.c

Issue 2082015: add cgpt framework and attribute support. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c
6 * files for more details.
7 */
8 #include "cgpt.h"
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <getopt.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/ioctl.h>
17 #include <sys/mount.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include "utility.h"
22
23 /* For usage print */
24 const char* progname;
25
26 /* Lists all command here. */
27 struct {
28 const char *name;
29 int (*fp)(int argc, char *argv[]);
30 const char *comment;
31 } cmds[] = {
32 {"attribute", CgptAttribute, "Update GPT attribute bits "
33 "(for ChromeOS kernel entry only)"},
34 {"show", CgptShow, "Show partition details"},
35 };
36
37 /* Shows main menu. If 'message' is non-NULL, shows it as header. Then, this
38 * traverses cmds[] and shows supported commands and their comments. */
39 void Usage(const char *message) {
40 int i;
41
42 if (message) printf("%s\n", message);
43 printf("Usage: %s COMMAND [OPTIONS]\n\n"
44 "Supported commands:\n\n",
45 progname);
46 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
47 printf(" %-10s %s\n", cmds[i].name, cmds[i].comment);
48 }
49 printf("\nFor more detailed usage, use %s COMMAND --help.\n\n", progname);
50 }
51
52 /* Loads sectors from 'fd'.
53 * *buf is pointed to an allocated memory when returned, and should be
54 * freed by cgpt_close().
55 *
56 * fd -- file descriptot.
57 * buf -- pointer to buffer pointer
58 * sector -- offset of starting sector (in sectors)
59 * sector_bytes -- bytes per sector
60 * sector_count -- number of sectors to load
61 *
62 * Returns CGPT_OK for successful. Aborts if any error occurs.
63 */
64 int Load(const int fd, uint8_t **buf,
65 const uint64_t sector,
66 const uint64_t sector_bytes,
67 const uint64_t sector_count) {
68 int count; /* byte count to read */
69 int nread;
70
71 assert(buf);
72 count = sector_bytes * sector_count;
73 *buf = Malloc(count);
74 assert(*buf);
75
76 if (-1 == lseek(fd, sector * sector_bytes, SEEK_SET))
77 goto error_free;
78
79 nread = read(fd, *buf, count);
80 if (nread < count)
81 goto error_free;
82
83 return CGPT_OK;
84
85 error_free:
86 Free(*buf);
87 *buf = 0;
88 abort();
89 }
90
91 /* Saves sectors to 'fd'.
92 *
93 * fd -- file descriptot.
94 * buf -- pointer to buffer
95 * sector -- starting sector offset
96 * sector_bytes -- bytes per sector
97 * sector_count -- number of sector to save
98 *
99 * Returns CGPT_OK for successful, CGPT_FAILED for failed.
100 */
101 int Save(const int fd, const uint8_t *buf,
102 const uint64_t sector,
103 const uint64_t sector_bytes,
104 const uint64_t sector_count) {
105 int count; /* byte count to write */
106 int nwrote;
107
108 assert(buf);
109 count = sector_bytes * sector_count;
110
111 if (-1 == lseek(fd, sector * sector_bytes, SEEK_SET))
112 return CGPT_FAILED;
113
114 nwrote = write(fd, buf, count);
115 if (nwrote < count)
116 return CGPT_FAILED;
117
118 return CGPT_OK;
119 }
120
121 /* Opens a block device (a regular file works well too).
122 *
123 * Returns CGPT_FAILED if any error happens.
124 * Returns CGPT_OK if success and information are stored in 'drive'. */
125 int DriveOpen(const char *drive_path, struct drive *drive) {
126 struct stat stat;
127 int gpt_retval;
128
129 assert(drive_path);
130 assert(drive);
131
132 Memset(drive, 0, sizeof(struct drive));
133 drive->fd = open(drive_path, O_RDWR);
134 if (drive->fd == -1) {
135 printf("[ERROR] Cannot open drive file [%s]: %s\n",
136 drive_path, strerror(errno));
137 return CGPT_FAILED;
138 }
139
140 if (fstat(drive->fd, &stat) == -1) {
141 goto error_close;
142 }
143 if ((stat.st_mode & S_IFMT) != S_IFREG) {
144 if (ioctl(drive->fd, BLKGETSIZE64, &drive->size) < 0) {
145 printf("[ERROR] Cannot get sector size from drive file [%s]: %s\n",
146 drive_path, strerror(errno));
147 goto error_close;
148 }
149 if (ioctl(drive->fd, BLKSSZGET, &drive->gpt.sector_bytes) < 0) {
150 printf("[ERROR] Cannot get drive size from drive file [%s]: %s\n",
151 drive_path, strerror(errno));
152 goto error_close;
153 }
154 } else {
155 drive->gpt.sector_bytes = 512; /* bytes */
156 drive->size = stat.st_size;
157 }
158 if (drive->size % drive->gpt.sector_bytes) {
159 printf("[ERROR] Media size (%llu) is not the multiple of sector size(%d)\n",
160 (long long unsigned int)drive->size, drive->gpt.sector_bytes);
161 goto error_close;
162 }
163 drive->gpt.drive_sectors = drive->size / drive->gpt.sector_bytes;
164 debug("drive: size:%llu sector_size:%d num_sector:%llu\n",
165 (long long unsigned int)drive->size, drive->gpt.sector_bytes,
166 (long long unsigned int)drive->gpt.drive_sectors);
167
168 Load(drive->fd, &drive->gpt.primary_header, GPT_PMBR_SECTOR,
169 drive->gpt.sector_bytes, GPT_HEADER_SECTOR);
170 Load(drive->fd, &drive->gpt.secondary_header,
171 drive->gpt.drive_sectors - GPT_PMBR_SECTOR,
172 drive->gpt.sector_bytes, GPT_HEADER_SECTOR);
173 Load(drive->fd, &drive->gpt.primary_entries,
174 GPT_PMBR_SECTOR + GPT_HEADER_SECTOR,
175 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS);
176 Load(drive->fd, &drive->gpt.secondary_entries,
177 drive->gpt.drive_sectors - GPT_HEADER_SECTOR - GPT_ENTRIES_SECTORS,
178 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS);
179
180 if (GPT_SUCCESS != (gpt_retval = GptInit(&drive->gpt))) {
181 printf("[ERROR] GptInit(): %s\n", GptError(gpt_retval));
182 goto error_close;
183 }
184
185 drive->inited = 1;
186
187 return CGPT_OK;
188
189 error_close:
190 close(drive->fd);
191 return CGPT_FAILED;
192 }
193
194 int DriveClose(struct drive *drive) {
195 if (drive->inited) {
196 if (drive->gpt.modified & GPT_MODIFIED_HEADER1)
197 assert(CGPT_OK ==
198 Save(drive->fd, drive->gpt.primary_header, GPT_PMBR_SECTOR,
199 drive->gpt.sector_bytes, GPT_HEADER_SECTOR));
200 if (drive->gpt.modified & GPT_MODIFIED_HEADER2)
201 assert(CGPT_OK ==
202 Save(drive->fd, drive->gpt.secondary_header,
203 drive->gpt.drive_sectors - GPT_PMBR_SECTOR,
204 drive->gpt.sector_bytes, GPT_HEADER_SECTOR));
205 if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1)
206 assert(CGPT_OK ==
207 Save(drive->fd, drive->gpt.primary_entries,
208 GPT_PMBR_SECTOR + GPT_HEADER_SECTOR,
209 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS));
210 if (drive->gpt.modified & GPT_MODIFIED_ENTRIES2)
211 assert(CGPT_OK ==
212 Save(drive->fd, drive->gpt.secondary_entries,
213 drive->gpt.drive_sectors - GPT_HEADER_SECTOR -
214 GPT_ENTRIES_SECTORS,
215 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS));
216
217 close(drive->fd);
218 }
219
220 Free(drive->gpt.primary_header);
221 drive->gpt.primary_header = 0;
222 Free(drive->gpt.primary_entries);
223 drive->gpt.primary_entries = 0;
224 Free(drive->gpt.secondary_header);
225 drive->gpt.secondary_header = 0;
226 Free(drive->gpt.secondary_entries);
227 drive->gpt.secondary_entries = 0;
228
229 drive->inited = 0;
230 return CGPT_OK;
231 }
232
233 int main(int argc, char *argv[]) {
234 char *cmd;
235 int i;
236
237 progname = argv[0];
238 cmd = argv[optind++];
239 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
240 if (cmd && !strcmp(cmds[i].name, cmd))
241 return cmds[i].fp(argc, argv);
242 }
243
244 Usage(0);
245 return CGPT_FAILED;
246 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698