| OLD | NEW | 
|---|
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 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 | 2  * Use of this source code is governed by a BSD-style license that can be | 
| 3  * found in the LICENSE file. | 3  * found in the LICENSE file. | 
| 4  * | 4  * | 
| 5  * Update GPT attribute bits. | 5  * Update GPT attribute bits. | 
| 6  */ | 6  */ | 
| 7 #include <getopt.h> | 7 #include <getopt.h> | 
| 8 #include <stdio.h> | 8 #include <stdio.h> | 
| 9 #include <stdlib.h> | 9 #include <stdlib.h> | 
| 10 #include "cgpt.h" | 10 #include "cgpt.h" | 
| 11 #include "cgptlib_internal.h" | 11 #include "cgptlib_internal.h" | 
| 12 #include "cgpt_tofix.h" | 12 #include "cgpt_tofix.h" | 
| 13 #include "utility.h" | 13 #include "utility.h" | 
| 14 | 14 | 
| 15 static struct number_range | 15 static struct number_range range_1_0 = {1, 0}; | 
| 16     range_1_0 = {1, 0}, | 16 static struct number_range range_15_0 = {15, 0}; | 
| 17     range_15_0 = {15, 0}; | 17 static struct number_range range_16_1 = {16, 1}; | 
| 18 | 18 | 
| 19 /* Integers to store parsed argument. */ | 19 /* Integers to store parsed argument. */ | 
| 20 static int help, partition, bad, successful, tries, priority; | 20 static int help, partition, successful, tries, priority; | 
| 21 | 21 | 
| 22 /* The structure for getopt_long(). When you add/delete any line, please refine | 22 /* The structure for getopt_long(). When you add/delete any line, please refine | 
| 23  * attribute_comments[] and third parameter of getopt_long() too.  */ | 23  * attribute_comments[] and third parameter of getopt_long() too.  */ | 
| 24 static struct option attribute_options[] = { | 24 static struct option attribute_options[] = { | 
| 25   {.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'}, | 25   {.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'}, | 
| 26   {.name = "partition", .has_arg = required_argument, .flag = 0, .val = 'i'}, | 26   {.name = "partition", .has_arg = required_argument, .flag = 0, .val = 'i'}, | 
| 27   {.name = "bad", .has_arg = required_argument, .flag = 0, .val = 'b'}, |  | 
| 28   {.name = "successful", .has_arg = required_argument, .flag = 0, .val = 's'}, | 27   {.name = "successful", .has_arg = required_argument, .flag = 0, .val = 's'}, | 
| 29   {.name = "tries", .has_arg = required_argument, .flag = 0, .val = 't'}, | 28   {.name = "tries", .has_arg = required_argument, .flag = 0, .val = 't'}, | 
| 30   {.name = "priority", .has_arg = required_argument, .flag = 0, .val = 'p'}, | 29   {.name = "priority", .has_arg = required_argument, .flag = 0, .val = 'p'}, | 
| 31   { /* last element, which should be zero. */ } | 30   { /* last element, which should be zero. */ } | 
| 32 }; | 31 }; | 
| 33 | 32 | 
| 34 /* Extra information than struct option, please update this structure if you | 33 /* Extra information than struct option, please update this structure if you | 
| 35  * add/remove any line in attribute_options[]. */ | 34  * add/remove any line in attribute_options[]. */ | 
| 36 static struct option_details attribute_options_details[] = { | 35 static struct option_details attribute_options_details[] = { | 
| 37   /* help */ | 36   /* help */ | 
| 38   { .comment = "print this help", | 37   { .comment = "print this help", | 
| 39     .validator = AssignTrue, | 38     .validator = AssignTrue, | 
| 40     .valid_range = 0, | 39     .valid_range = 0, | 
| 41     .parsed = &help}, | 40     .parsed = &help}, | 
| 42   /* partition */ | 41   /* partition */ | 
| 43   { .comment = "partition number " | 42   { .comment = "partition number " | 
| 44               "(defualt: first ChromeOS kernel)", | 43               "(default: first ChromeOS kernel)", | 
| 45     .validator = InNumberRange, | 44     .validator = InNumberRange, | 
| 46     .valid_range = &range_15_0, | 45     .valid_range = &range_16_1, | 
| 47     .parsed = &partition}, | 46     .parsed = &partition}, | 
| 48   /* bad */ |  | 
| 49   { .comment = "mark partition bad", |  | 
| 50     .validator = InNumberRange, |  | 
| 51     .valid_range = &range_1_0, |  | 
| 52     .parsed = &bad}, |  | 
| 53   /* successful */ | 47   /* successful */ | 
| 54   { .comment = "mark partition successful", | 48   { .comment = "mark partition successful", | 
| 55     .validator = InNumberRange, | 49     .validator = InNumberRange, | 
| 56     .valid_range = &range_1_0, | 50     .valid_range = &range_1_0, | 
| 57     .parsed = &successful}, | 51     .parsed = &successful}, | 
| 58   /* tries */ | 52   /* tries */ | 
| 59   { .comment = "tries", | 53   { .comment = "tries", | 
| 60     .validator = InNumberRange, | 54     .validator = InNumberRange, | 
| 61     .valid_range = &range_15_0, | 55     .valid_range = &range_15_0, | 
| 62     .parsed = &tries}, | 56     .parsed = &tries}, | 
| 63   /* priority */ | 57   /* priority */ | 
| 64   { .comment = "priority to boot", | 58   { .comment = "priority to boot", | 
| 65     .validator = InNumberRange, | 59     .validator = InNumberRange, | 
| 66     .valid_range = &range_15_0, | 60     .valid_range = &range_15_0, | 
| 67     .parsed = &priority}, | 61     .parsed = &priority}, | 
| 68   { /* last element, which should be zero. */ } | 62   { /* last element, which should be zero. */ } | 
| 69 }; | 63 }; | 
| 70 | 64 | 
| 71 void AttributeHelp() { | 65 void AttributeHelp() { | 
| 72   printf("\nUsage: %s attribute [OPTIONS] device_name\n\n", progname); | 66   printf("\nUsage: %s attribute [OPTIONS] device_name\n\n", progname); | 
| 73   ShowOptions(attribute_options, attribute_options_details, | 67   ShowOptions(attribute_options, attribute_options_details, | 
| 74               ARRAY_COUNT(attribute_options)); | 68               ARRAY_COUNT(attribute_options)); | 
| 75   printf("\n* Attribute command only applies on ChromeOS kernel entry.\n\n"); |  | 
| 76 } | 69 } | 
| 77 | 70 | 
| 78 /* Parses all options (and validates them), then opens the drive and sets | 71 /* Parses all options (and validates them), then opens the drive and sets | 
| 79  * corresponding bits in GPT entry. */ | 72  * corresponding bits in GPT entry. */ | 
| 80 int CgptAttribute(int argc, char *argv[]) { | 73 int CgptAttribute(int argc, char *argv[]) { | 
| 81   struct drive drive; | 74   struct drive drive; | 
|  | 75   GptEntry *entry; | 
| 82 | 76 | 
| 83   /* I know this is NOT the perfect place to put code to make options[] and | 77   /* I know this is NOT the perfect place to put code to make options[] and | 
| 84    * details[] are synced. But this is the best place we have right now since C | 78    * details[] are synced. But this is the best place we have right now since C | 
| 85    * preprocessor doesn't know sizeof() for #if directive. */ | 79    * preprocessor doesn't know sizeof() for #if directive. */ | 
| 86   assert(ARRAY_COUNT(attribute_options) == | 80   assert(ARRAY_COUNT(attribute_options) == | 
| 87          ARRAY_COUNT(attribute_options_details)); | 81          ARRAY_COUNT(attribute_options_details)); | 
| 88 | 82 | 
| 89   help = partition = bad = successful = tries = priority = NOT_INITED; | 83   help = partition = successful = tries = priority = NOT_INITED; | 
| 90 | 84 | 
| 91   if (CGPT_OK != HandleOptions(argc, argv, | 85   if (CGPT_OK != HandleOptions(argc, argv, | 
| 92                      "hi:b:s:t:p:", | 86                      "hi:b:s:t:p:", | 
| 93                      ARRAY_COUNT(attribute_options), | 87                      ARRAY_COUNT(attribute_options), | 
| 94                      attribute_options, | 88                      attribute_options, | 
| 95                      attribute_options_details)) | 89                      attribute_options_details)) | 
| 96     return CGPT_FAILED; | 90     return CGPT_FAILED; | 
| 97   if (help != NOT_INITED) { | 91   if (help != NOT_INITED) { | 
| 98     AttributeHelp(); | 92     AttributeHelp(); | 
| 99     return CGPT_FAILED; | 93     return CGPT_FAILED; | 
| 100   } | 94   } | 
| 101 | 95 | 
| 102   if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive)) | 96   if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive)) | 
| 103     return CGPT_FAILED; | 97     return CGPT_FAILED; | 
| 104 | 98 | 
| 105   if (CheckValid(&drive) != CGPT_OK) return CGPT_FAILED; | 99   if (CheckValid(&drive) != CGPT_OK) return CGPT_FAILED; | 
| 106 | 100 | 
| 107   /* partition is not specified, search for the first Chromeos kernel. */ | 101   /* partition is not specified, search for the first Chromeos kernel. */ | 
| 108   if (partition == NOT_INITED) { | 102   if (partition == NOT_INITED) { | 
| 109     int i; | 103     int i; | 
| 110     for (i = 0; i < GetNumberOfEntries(&drive.gpt); ++i) { | 104     for (i = 0; i < GetNumberOfEntries(&drive.gpt); ++i) { | 
| 111       static Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; |  | 
| 112       GptEntry *entry; |  | 
| 113       entry = GetEntry(&drive.gpt, PRIMARY, i); | 105       entry = GetEntry(&drive.gpt, PRIMARY, i); | 
| 114       if (!Memcmp(&chromeos_kernel, &entry->type, sizeof(Guid))) { | 106       if (!Memcmp(&guid_chromeos_kernel, &entry->type, sizeof(Guid))) { | 
| 115         partition = i; | 107         partition = i+1; | 
| 116         break; | 108         break; | 
| 117       } | 109       } | 
| 118     } | 110     } | 
| 119     if (partition == NOT_INITED) { | 111     if (partition == NOT_INITED) { | 
| 120       printf("[ERROR] No ChromeOS kernel is found. " | 112       printf("[ERROR] No ChromeOS kernel partition found. " | 
| 121              "Please use --partition to specify.\n"); | 113              "Please use --partition to specify.\n"); | 
| 122       return CGPT_FAILED; | 114       return CGPT_FAILED; | 
| 123     } else { | 115     } else { | 
| 124       debug("No --partition is specified. " | 116       debug("No --partition is specified. " | 
| 125             "Found the first ChromeOS kernel at index [%d].\n", | 117             "Found the first ChromeOS kernel in partition [%d].\n", | 
| 126             partition); | 118             partition); | 
| 127     } | 119     } | 
| 128   } | 120   } | 
|  | 121   int index = partition - 1; | 
| 129 | 122 | 
| 130   if (successful != NOT_INITED) | 123   if (successful != NOT_INITED) | 
| 131     SetSuccessful(&drive.gpt, PRIMARY, partition, successful); | 124     SetSuccessful(&drive.gpt, PRIMARY, index, successful); | 
| 132   if (tries != NOT_INITED) | 125   if (tries != NOT_INITED) | 
| 133     SetTries(&drive.gpt, PRIMARY, partition, tries); | 126     SetTries(&drive.gpt, PRIMARY, index, tries); | 
| 134   if (priority != NOT_INITED) | 127   if (priority != NOT_INITED) | 
| 135     SetPriority(&drive.gpt, PRIMARY, partition, priority); | 128     SetPriority(&drive.gpt, PRIMARY, index, priority); | 
|  | 129 | 
|  | 130   /* Display state */ | 
|  | 131   entry = GetEntry(&drive.gpt, PRIMARY, index); | 
|  | 132   EntryDetails(entry, index, NOT_INITED); | 
| 136 | 133 | 
| 137   /* Claims primary is good, then secondary will be overwritten. */ | 134   /* Claims primary is good, then secondary will be overwritten. */ | 
| 138   /* TODO: rspangler broke this during cgptlib refactoring; need to | 135   /* TODO: rspangler broke this during cgptlib refactoring; need to | 
| 139    * update this to match new internal APIs. */ | 136    * update this to match new internal APIs. */ | 
| 140   RepairEntries(&drive.gpt, MASK_PRIMARY); | 137   RepairEntries(&drive.gpt, MASK_PRIMARY); | 
| 141   RepairHeader(&drive.gpt, MASK_PRIMARY); | 138   RepairHeader(&drive.gpt, MASK_PRIMARY); | 
| 142 | 139 | 
| 143   /* Forces headers and entries are modified so that CRC32 will be re-calculated | 140   /* Forces headers and entries are modified so that CRC32 will be re-calculated | 
| 144    * and headers and entries will be updated to drive. */ | 141    * and headers and entries will be updated to drive. */ | 
| 145   drive.gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | | 142   drive.gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | | 
| 146                          GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); | 143                          GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); | 
| 147   UpdateCrc(&drive.gpt); | 144   UpdateCrc(&drive.gpt); | 
| 148   DriveClose(&drive); | 145   DriveClose(&drive); | 
| 149 | 146 | 
| 150   return CGPT_OK; | 147   return CGPT_OK; | 
| 151 } | 148 } | 
| OLD | NEW | 
|---|