diff options
author | Julius Werner <jwerner@chromium.org> | 2016-04-19 16:55:36 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-25 15:15:32 -0700 |
commit | 39910d062dffcd16683e0626dac1e7064991c7e5 (patch) | |
tree | 0985bb84a411aaa6d46eb3d2a4f3dbbac76e8865 /cgpt | |
parent | 5de0000ece70bf419130db9bdbaf444ffc98bf30 (diff) | |
download | vboot-39910d062dffcd16683e0626dac1e7064991c7e5.tar.gz |
cgptlib: Add support for IGNOREME GPT signature
This patch makes cgpt aware of a special "IGNOREME" GPT header signature
string that may appear in either the primary or the secondary GPT and
cause cgpt (and other cgptlib clients) to completely ignore that GPT. It
will continue to function correctly for all other purposes (using the
data from the non-ignored GPT), but never write any data back to the
ignored GPT.
BRANCH=None
BUG=chrome-os-partner:52595
TEST=unit tests
Change-Id: I7e53542385ae9d8d24dc25b75e91f4ff4917f66f
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/340072
Reviewed-by: Nam Nguyen <namnguyen@google.com>
Diffstat (limited to 'cgpt')
-rw-r--r-- | cgpt/cgpt_common.c | 61 | ||||
-rw-r--r-- | cgpt/cgpt_show.c | 140 |
2 files changed, 112 insertions, 89 deletions
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 2c21cdc2..29fe524a 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -184,7 +184,11 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) { return -1; } } else { - Warning("Primary GPT header is invalid\n"); + Warning("Primary GPT header is %s\n", + memcmp(primary_header->signature, GPT_HEADER_SIGNATURE_IGNORED, + GPT_HEADER_SIGNATURE_SIZE) ? "invalid" : "being ignored"); + drive->gpt.primary_entries = calloc(MAX_NUMBER_OF_ENTRIES, + sizeof(GptEntry)); } GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header; if (CheckHeader(secondary_header, 1, drive->gpt.streaming_drive_sectors, @@ -198,41 +202,48 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) { return -1; } } else { - Warning("Secondary GPT header is invalid\n"); + Warning("Secondary GPT header is %s\n", + memcmp(primary_header->signature, GPT_HEADER_SIGNATURE_IGNORED, + GPT_HEADER_SIGNATURE_SIZE) ? "invalid" : "being ignored"); + drive->gpt.secondary_entries = calloc(MAX_NUMBER_OF_ENTRIES, + sizeof(GptEntry)); } return 0; } static int GptSave(struct drive *drive) { int errors = 0; - if (drive->gpt.modified & GPT_MODIFIED_HEADER1) { - if (CGPT_OK != Save(drive, drive->gpt.primary_header, - GPT_PMBR_SECTORS, - drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) { - errors++; - Error("Cannot write primary header: %s\n", strerror(errno)); + + if (!(drive->gpt.ignored & MASK_PRIMARY)) { + if (drive->gpt.modified & GPT_MODIFIED_HEADER1) { + if (CGPT_OK != Save(drive, drive->gpt.primary_header, + GPT_PMBR_SECTORS, + drive->gpt.sector_bytes, GPT_HEADER_SECTORS)) { + errors++; + Error("Cannot write primary header: %s\n", strerror(errno)); + } } - } - GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; - if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) { - if (CGPT_OK != Save(drive, drive->gpt.primary_entries, - primary_header->entries_lba, - drive->gpt.sector_bytes, - CalculateEntriesSectors(primary_header))) { - errors++; - Error("Cannot write primary entries: %s\n", strerror(errno)); + GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; + if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) { + if (CGPT_OK != Save(drive, drive->gpt.primary_entries, + primary_header->entries_lba, + drive->gpt.sector_bytes, + CalculateEntriesSectors(primary_header))) { + errors++; + Error("Cannot write primary entries: %s\n", strerror(errno)); + } } - } - // Sync primary GPT before touching secondary so one is always valid. - if (drive->gpt.modified & (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1)) - if (fsync(drive->fd) < 0 && errno == EIO) { - errors++; - Error("I/O error when trying to write primary GPT\n"); - } + // Sync primary GPT before touching secondary so one is always valid. + if (drive->gpt.modified & (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1)) + if (fsync(drive->fd) < 0 && errno == EIO) { + errors++; + Error("I/O error when trying to write primary GPT\n"); + } + } // Only start writing secondary GPT if primary was written correctly. - if (!errors) { + if (!errors && !(drive->gpt.ignored & MASK_SECONDARY)) { if (drive->gpt.modified & GPT_MODIFIED_HEADER2) { if(CGPT_OK != Save(drive, drive->gpt.secondary_header, drive->gpt.gpt_drive_sectors - GPT_PMBR_SECTORS, diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index 143b5fa1..638655bd 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -250,79 +250,91 @@ static int GptShow(struct drive *drive, CgptShowParams *params) { PMBRToStr(&drive->pmbr, buf, sizeof(buf)); // will exit if buf is too small printf(GPT_FMT, 0, GPT_PMBR_SECTORS, "", buf); - if (drive->gpt.valid_headers & MASK_PRIMARY) { + if (drive->gpt.ignored & MASK_PRIMARY) { printf(GPT_FMT, (int)GPT_PMBR_SECTORS, - (int)GPT_HEADER_SECTORS, "", "Pri GPT header"); + (int)GPT_HEADER_SECTORS, "IGNORED", "Pri GPT header"); } else { - printf(GPT_FMT, (int)GPT_PMBR_SECTORS, - (int)GPT_HEADER_SECTORS, "INVALID", "Pri GPT header"); - } - - if (params->debug || - ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) { - GptHeader *header; - char indent[64]; + if (drive->gpt.valid_headers & MASK_PRIMARY) { + printf(GPT_FMT, (int)GPT_PMBR_SECTORS, + (int)GPT_HEADER_SECTORS, "", "Pri GPT header"); + } else { + printf(GPT_FMT, (int)GPT_PMBR_SECTORS, + (int)GPT_HEADER_SECTORS, "INVALID", "Pri GPT header"); + } - require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); - header = (GptHeader*)drive->gpt.primary_header; - entries = (GptEntry*)drive->gpt.primary_entries; - HeaderDetails(header, entries, indent, params->numeric); - } + if (params->debug || + ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) { + GptHeader *header; + char indent[64]; - GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; - printf(GPT_FMT, (int)primary_header->entries_lba, - (int)CalculateEntriesSectors(primary_header), - drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID", - "Pri GPT table"); + require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); + header = (GptHeader*)drive->gpt.primary_header; + entries = (GptEntry*)drive->gpt.primary_entries; + HeaderDetails(header, entries, indent, params->numeric); + } - if (params->debug || - (drive->gpt.valid_entries & MASK_PRIMARY)) - EntriesDetails(drive, PRIMARY, params->numeric); + GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; + printf(GPT_FMT, (int)primary_header->entries_lba, + (int)CalculateEntriesSectors(primary_header), + drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID", + "Pri GPT table"); - /****************************** Secondary *************************/ - GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header; - printf(GPT_FMT, (int)secondary_header->entries_lba, - (int)CalculateEntriesSectors(secondary_header), - drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID", - "Sec GPT table"); - /* We show secondary table details if any of following is true. - * 1. in debug mode. - * 2. only secondary is valid. - * 3. secondary is not identical to promary. - */ - if (params->debug || - ((drive->gpt.valid_entries & MASK_SECONDARY) && - (!(drive->gpt.valid_entries & MASK_PRIMARY) || - memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries, - secondary_header->number_of_entries * - secondary_header->size_of_entry)))) { - EntriesDetails(drive, SECONDARY, params->numeric); + if (params->debug || + (drive->gpt.valid_entries & MASK_PRIMARY)) + EntriesDetails(drive, PRIMARY, params->numeric); } - if (drive->gpt.valid_headers & MASK_SECONDARY) + /****************************** Secondary *************************/ + if (drive->gpt.ignored & MASK_SECONDARY) { printf(GPT_FMT, (int)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS), - (int)GPT_HEADER_SECTORS, "", "Sec GPT header"); - else - printf(GPT_FMT, (int)GPT_PMBR_SECTORS, - (int)GPT_HEADER_SECTORS, "INVALID", "Sec GPT header"); - /* We show secondary header if any of following is true: - * 1. in debug mode. - * 2. only secondary is valid. - * 3. secondary is not synonymous to primary. - */ - if (params->debug || - ((drive->gpt.valid_headers & MASK_SECONDARY) && - (!(drive->gpt.valid_headers & MASK_PRIMARY) || - !IsSynonymous((GptHeader*)drive->gpt.primary_header, - (GptHeader*)drive->gpt.secondary_header)) && - params->verbose)) { - GptHeader *header; - char indent[64]; - - require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); - header = (GptHeader*)drive->gpt.secondary_header; - entries = (GptEntry*)drive->gpt.secondary_entries; - HeaderDetails(header, entries, indent, params->numeric); + (int)GPT_HEADER_SECTORS, "IGNORED", "Sec GPT header"); + } else { + GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header; + printf(GPT_FMT, (int)secondary_header->entries_lba, + (int)CalculateEntriesSectors(secondary_header), + drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID", + "Sec GPT table"); + /* We show secondary table details if any of following is true. + * 1. in debug mode. + * 2. primary table is being ignored + * 3. only secondary is valid. + * 4. secondary is not identical to promary. + */ + if (params->debug || (drive->gpt.ignored & MASK_PRIMARY) || + ((drive->gpt.valid_entries & MASK_SECONDARY) && + (!(drive->gpt.valid_entries & MASK_PRIMARY) || + memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries, + secondary_header->number_of_entries * + secondary_header->size_of_entry)))) { + EntriesDetails(drive, SECONDARY, params->numeric); + } + + if (drive->gpt.valid_headers & MASK_SECONDARY) { + printf(GPT_FMT, (int)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS), + (int)GPT_HEADER_SECTORS, "", "Sec GPT header"); + } else { + printf(GPT_FMT, (int)GPT_PMBR_SECTORS, + (int)GPT_HEADER_SECTORS, "INVALID", "Sec GPT header"); + } + /* We show secondary header if any of following is true: + * 1. in debug mode. + * 2. only secondary is valid. + * 3. secondary is not synonymous to primary and not ignored. + */ + if (params->debug || + ((drive->gpt.valid_headers & MASK_SECONDARY) && + (!(drive->gpt.valid_headers & MASK_PRIMARY) || + !IsSynonymous((GptHeader*)drive->gpt.primary_header, + (GptHeader*)drive->gpt.secondary_header)) && + params->verbose)) { + GptHeader *header; + char indent[64]; + + require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); + header = (GptHeader*)drive->gpt.secondary_header; + entries = (GptEntry*)drive->gpt.secondary_entries; + HeaderDetails(header, entries, indent, params->numeric); + } } } |