From 23429d3d782f7506fb4747356974294cce08ac47 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Mon, 30 Apr 2012 11:33:13 -0700 Subject: Let cgpt open devices in read-only mode when possible. BUG=chromium-os:12430 TEST=manual Running "make; make runtests" in src/platform/vboot_refererence will test this change. Tests for use on a Chromebook are described in the bug report, but will require a USB or SD card that has a physical write-protect switch. Change-Id: I16a67bad3b59bec0981f4064f51fb1a29da65a90 Reviewed-on: https://gerrit.chromium.org/gerrit/21474 Tested-by: Bill Richardson Commit-Ready: Bill Richardson Reviewed-by: Richard Barnette Reviewed-by: Che-Liang Chiou --- cgpt/cgpt.h | 4 +++- cgpt/cgpt_add.c | 6 +++--- cgpt/cgpt_boot.c | 13 +++++++++---- cgpt/cgpt_common.c | 5 +++-- cgpt/cgpt_create.c | 2 +- cgpt/cgpt_find.c | 2 +- cgpt/cgpt_prioritize.c | 2 +- cgpt/cgpt_repair.c | 2 +- cgpt/cgpt_show.c | 4 ++-- 9 files changed, 24 insertions(+), 16 deletions(-) (limited to 'cgpt') diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index 1c809161..6851ded7 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -10,6 +10,7 @@ #endif #define _FILE_OFFSET_BITS 64 +#include #include #include #include @@ -61,7 +62,8 @@ struct drive { }; -int DriveOpen(const char *drive_path, struct drive *drive); +/* mode should be O_RDONLY or O_RDWR */ +int DriveOpen(const char *drive_path, struct drive *drive, int mode); int DriveClose(struct drive *drive, int update_as_needed); int CheckValid(const struct drive *drive); diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index e3e1a483..a3d0fb99 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -39,7 +39,7 @@ int cgpt_set_attributes(CgptAddParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { @@ -101,7 +101,7 @@ int cgpt_get_partition_details(CgptAddParams *params) { if (params == NULL) return result; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) { + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) { Error("Unable to open drive: %s\n", params->drive_name); return result; } @@ -183,7 +183,7 @@ int cgpt_add(CgptAddParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { diff --git a/cgpt/cgpt_boot.c b/cgpt/cgpt_boot.c index 33c5471c..f8e712d6 100644 --- a/cgpt/cgpt_boot.c +++ b/cgpt/cgpt_boot.c @@ -21,7 +21,7 @@ int cgpt_get_boot_partition_number(CgptBootParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { @@ -65,12 +65,17 @@ int cgpt_boot(CgptBootParams *params) { struct drive drive; int retval = 1; int gpt_retval= 0; + int mode = O_RDONLY; if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (params->create_pmbr || params->partition || params->bootfile) + mode = O_RDWR; + + if (CGPT_OK != DriveOpen(params->drive_name, &drive, mode)) { return CGPT_FAILED; + } if (CGPT_OK != ReadPMBR(&drive)) { Error("Unable to read PMBR\n"); @@ -135,8 +140,8 @@ int cgpt_boot(CgptBootParams *params) { GuidToStr(&drive.pmbr.boot_guid, buf, sizeof(buf)); printf("%s\n", buf); - // Write it all out - if (CGPT_OK == WritePMBR(&drive)) + // Write it all out, if needed. + if (mode == O_RDONLY || CGPT_OK == WritePMBR(&drive)) retval = 0; done: diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index a5a509b1..d69eb670 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -153,10 +153,11 @@ static int Save(const int fd, const uint8_t *buf, // Opens a block device or file, loads raw GPT data from it. +// mode should be O_RDONLY or O_RDWR // // Returns CGPT_FAILED if any error happens. // Returns CGPT_OK if success and information are stored in 'drive'. */ -int DriveOpen(const char *drive_path, struct drive *drive) { +int DriveOpen(const char *drive_path, struct drive *drive, int mode) { struct stat stat; require(drive_path); @@ -165,7 +166,7 @@ int DriveOpen(const char *drive_path, struct drive *drive) { // Clear struct for proper error handling. memset(drive, 0, sizeof(struct drive)); - drive->fd = open(drive_path, O_RDWR | O_LARGEFILE | O_NOFOLLOW); + drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW); if (drive->fd == -1) { Error("Can't open %s: %s\n", drive_path, strerror(errno)); return CGPT_FAILED; diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c index dc25d8fa..8c899d19 100644 --- a/cgpt/cgpt_create.c +++ b/cgpt/cgpt_create.c @@ -15,7 +15,7 @@ int cgpt_create(CgptCreateParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; // Erase the data diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c index 20070209..345c8310 100644 --- a/cgpt/cgpt_find.c +++ b/cgpt/cgpt_find.c @@ -94,7 +94,7 @@ static int do_search(CgptFindParams *params, char *fileName) { GptEntry *entry; char partlabel[GPT_PARTNAME_LEN]; - if (CGPT_OK != DriveOpen(fileName, &drive)) + if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY)) return 0; if (GPT_SUCCESS != GptSanityCheck(&drive.gpt)) { diff --git a/cgpt/cgpt_prioritize.c b/cgpt/cgpt_prioritize.c index 107c00a9..2b3feb06 100644 --- a/cgpt/cgpt_prioritize.c +++ b/cgpt/cgpt_prioritize.c @@ -108,7 +108,7 @@ int cgpt_prioritize(CgptPrioritizeParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { diff --git a/cgpt/cgpt_repair.c b/cgpt/cgpt_repair.c index 96d3fb1c..97beef84 100644 --- a/cgpt/cgpt_repair.c +++ b/cgpt/cgpt_repair.c @@ -15,7 +15,7 @@ int cgpt_repair(CgptRepairParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; int gpt_retval = GptSanityCheck(&drive.gpt); diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index d4170b1c..f0022a9d 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -186,7 +186,7 @@ int cgpt_get_num_non_empty_partitions(CgptShowParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { @@ -221,7 +221,7 @@ int cgpt_show(CgptShowParams *params) { if (params == NULL) return CGPT_FAILED; - if (CGPT_OK != DriveOpen(params->drive_name, &drive)) + if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { -- cgit v1.2.1