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

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

Issue 2374001: cgpt supports dev and add/delete/modify commands. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Created 10 years, 6 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 * Update GPT attribute bits.
6 */
7 #include <getopt.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "cgpt.h"
11 #include "cgptlib_internal.h"
12 #include "utility.h"
13
14 static struct number_range
15 range_127_0 = {127, 0};
16
17 /* Integers to store parsed argument. */
18 static int help, partition, begin_lba, size_lba;
19 static char type[128], unique[128], name[128];
20
21 /* The structure for getopt_long(). When you add/delete any line, please refine
22 * attribute_comments[] and third parameter of getopt_long() too. */
23 static struct option adm_options[] = {
24 {.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'},
25 {.name = "partition", .has_arg = required_argument, .flag = 0, .val = 'i'},
26 #if 0//FIXME
27 {.name = "bad", .has_arg = required_argument, .flag = 0, .val = 'b'},
28 {.name = "successful", .has_arg = required_argument, .flag = 0, .val = 's'},
29 {.name = "tries", .has_arg = required_argument, .flag = 0, .val = 't'},
30 {.name = "priority", .has_arg = required_argument, .flag = 0, .val = 'p'},
31 #endif
32 {.name = "type", .has_arg = required_argument, .flag = 0, .val = 't'},
33 {.name = "unique", .has_arg = required_argument, .flag = 0, .val = 'u'},
34 {.name = "begin", .has_arg = required_argument, .flag = 0, .val = 'b'},
35 {.name = "size", .has_arg = required_argument, .flag = 0, .val = 's'},
36 {.name = "name", .has_arg = required_argument, .flag = 0, .val = 'n'},
37 { /* last element, which should be zero. */ }
38 };
39
40 /* Extra information than struct option, please update this structure if you
41 * add/remove any line in attribute_options[]. */
42 static struct option_details adm_options_details[] = {
43 /* help */
44 { .comment = "print this help",
45 .validator = AssignTrue,
46 .valid_range = 0,
47 .parsed = &help},
48 /* partition */
49 { .comment = "partition number (MUST HAVE)",
50 .validator = InNumberRange,
51 .valid_range = &range_127_0,
52 .parsed = &partition},
53 #if 0//FIXME
54 /* bad */
55 { .comment = "mark partition bad",
56 .validator = InNumberRange,
57 .valid_range = &range_1_0,
58 .parsed = &bad},
59 /* successful */
60 { .comment = "mark partition successful",
61 .validator = InNumberRange,
62 .valid_range = &range_1_0,
63 .parsed = &successful},
64 /* tries */
65 { .comment = "tries",
66 .validator = InNumberRange,
67 .valid_range = &range_15_0,
68 .parsed = &tries},
69 /* priority */
70 { .comment = "priority to boot",
71 .validator = InNumberRange,
72 .valid_range = &range_15_0,
73 .parsed = &priority},
74 #endif
75 /* type */
76 { .comment = "Partition Type (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)",
77 .validator = CopyString,
78 .valid_range = (void*)sizeof(type),
79 .parsed = &type},
80 /* uuid */
81 { .comment = "Partition UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)",
82 .validator = CopyString,
83 .valid_range = (void*)sizeof(unique),
84 .parsed = &unique},
85 /* start */
86 { .comment = "starting LBA",
87 .validator = InNumberRange,
88 .valid_range = 0,
89 .parsed = &begin_lba},
90 /* end */
91 { .comment = "ending LBA",
92 .validator = InNumberRange,
93 .valid_range = 0,
94 .parsed = &size_lba},
95 /* name */
96 { .comment = "Partition name",
97 .validator = CopyString,
98 .valid_range = (void*)sizeof(name),
99 .parsed = &name},
100 { /* last element, which should be zero. */ }
101 };
102
103 void AdmHelp() {
104 printf("\nUsage: %s {add|delete|modify} [OPTIONS] device_name\n\n", progname);
105 ShowOptions(adm_options, adm_options_details, ARRAY_COUNT(adm_options));
106 PrintTypes();
107 printf("\n");
108 }
109
110 enum {
111 ADD,
112 DELETE,
113 MODIFY,
114 } command;
115
116 /* Parses all options (and validates them), then opens the drive and sets
117 * corresponding bits in GPT entry. */
118 int CgptAdm(int argc, char *argv[]) {
119 struct drive drive;
120 char *cmd;
121 GptEntry *entry;
122 Guid type_guid, unique_guid;
123 int dirty = 0;
124
125 /* I know this is NOT the perfect place to put code to make options[] and
126 * details[] are synced. But this is the best place we have right now since C
127 * preprocessor doesn't know sizeof() for #if directive. */
128 assert(ARRAY_COUNT(adm_options) ==
129 ARRAY_COUNT(adm_options_details));
130
131 cmd = argv[optind - 1];
132 if (!strcmp("add", cmd)) command = ADD;
133 else if (!strcmp("delete", cmd)) command = DELETE;
134 else if (!strcmp("modify", cmd)) command = MODIFY;
135
136 #if 0//FIXME
137 help = partition = bad = successful = tries = priority =
138 #endif
139 help = partition = begin_lba = size_lba = NOT_INITED;
140 type[0] = '\0';
141 unique[0] = '\0';
142 name[0] = '\0';
143
144 if (CGPT_OK != HandleOptions(argc, argv,
145 "hi:t:u:b:s:n:",
146 ARRAY_COUNT(adm_options),
147 adm_options,
148 adm_options_details))
149 return CGPT_FAILED;
150 if (help != NOT_INITED) {
151 AdmHelp();
152 return CGPT_FAILED;
153 }
154
155 if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive))
156 return CGPT_FAILED;
157
158 if (CheckValid(&drive) != CGPT_OK) goto error_close;
159
160 if (partition == NOT_INITED) {
161 printf("[ERROR] Please provide partition number with --partition or -i.\n");
162 goto error_close;
163 }
164
165 entry = GetEntry(&drive.gpt, PRIMARY, partition);
166 /* check before really doing something. */
167 switch (command) {
168 case ADD:
169 if (NonZeroGuid(&entry->type)) {
170 printf("[ERROR] partition %d is not free, use '%s modify' instead.\n",
171 partition, progname);
172 goto error_close;
173 }
174 if (type[0] == '\0') {
175 printf("* You must give a type with '--type' or '-t'.\n");
176 PrintTypes();
177 goto error_close;
178 }
179 if (begin_lba == NOT_INITED) {
180 printf("* You didn't give the begin LBA, use '--begin' to specify.\n");
181 goto error_close;
182 }
183 if (size_lba == NOT_INITED) {
184 printf("* You didn't give size, use '--size' to specify.\n");
185 goto error_close;
186 }
187 break;
188 case DELETE:
189 if (!NonZeroGuid(&entry->type)) {
190 printf("[ERROR] partition %d is free already.\n", partition);
191 goto error_close;
192 }
193 break;
194 case MODIFY:
195 if (!NonZeroGuid(&entry->type)) {
196 printf("[ERROR] partition %d is free, use '%s add' first.\n",
197 partition, progname);
198 goto error_close;
199 }
200 break;
201 }
202
203 #if 0 //FIXME
204 if (bad != NOT_INITED)
205 SetBad(&drive.gpt, PRIMARY, partition, bad);
206 if (successful != NOT_INITED)
207 SetSuccessful(&drive.gpt, PRIMARY, partition, successful);
208 if (tries != NOT_INITED)
209 SetTries(&drive.gpt, PRIMARY, partition, tries);
210 if (priority != NOT_INITED)
211 SetPriority(&drive.gpt, PRIMARY, partition, priority);
212 #endif
213 if (type[0]) {
214 if (CGPT_OK != SupportedType(type, &type_guid) &&
215 CGPT_OK != StrToGuid(type, &type_guid)) {
216 printf("[ERROR] You didn't give a valid type [%s]\n", type);
217 goto error_close;
218 }
219 Memcpy(&entry->type, &type_guid, sizeof(Guid));
220 ++dirty;
221 }
222 if (unique[0]) {
223 if (CGPT_OK != StrToGuid(unique, &unique_guid)) {
224 printf("[ERROR] You didn't give a valid UUID [%s]\n", unique);
225 goto error_close;
226 }
227 Memcpy(&entry->unique, &unique_guid, sizeof(Guid));
228 ++dirty;
229 }
230 if (begin_lba != NOT_INITED) {
231 entry->starting_lba = begin_lba;
232 ++dirty;
233 }
234 if (size_lba != NOT_INITED) {
235 entry->ending_lba = entry->starting_lba + size_lba - 1;
236 ++dirty;
237 }
238 if (name[0]) {
239 UTF8ToUTF16((uint8_t*)name, entry->name);
240 ++dirty;
241 }
242
243 if (command == DELETE) {
244 Guid unused = GPT_ENT_TYPE_UNUSED;
245 Memcpy(&entry->type, &unused, sizeof(Guid));
246 }
247
248 if (dirty) {
249 uint32_t valid_entries;
250
251 valid_entries = drive.gpt.valid_entries;
252 if ((valid_entries != CheckValidEntries(&drive.gpt)) ||
253 (valid_entries != CheckOverlappedPartition(&drive.gpt))) {
254 printf("\n[ERROR] Your change makes GPT invalid (or worse). "
255 "Please check your arguments.\n\n");
256 drive.gpt.modified = 0; /* DriveClose() won't update hard drive. */
257 goto error_close;
258 }
259
260 /* Claims primary is good, then secondary will be overwritten. */
261 RepairEntries(&drive.gpt, MASK_PRIMARY);
262 RepairHeader(&drive.gpt, MASK_PRIMARY);
263
264 /* Forces headers and entries are modified so that CRC32 will be
265 * re-calculated and headers and entries will be updated to drive. */
266 drive.gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
267 GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
268 UpdateCrc(&drive.gpt);
269 }
270 DriveClose(&drive);
271 return CGPT_OK;
272
273 error_close:
274 DriveClose(&drive);
275 return CGPT_FAILED;
276 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utility/cgpt/cgpt.c ('k') | src/platform/vboot_reference/utility/cgpt/cgpt_attribute.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698