cgpt: Move all GPT on SPI-NOR infra behind a flag

This piece of code caused serious issues in b/184559695, and it
seems like we have no active users at the moment.

We can punt the decision to remove the code entirely, but for now,
let's stop building and executing it, leaving it to potential
users to fix it up, and refactor/cleanup/test the code.

BRANCH=none
BUG=b:184812319
TEST=`make` does not build `cgpt_wrapper` or any SPI-NOR code.
TEST=`make GPT_SPI_NOR=1` does build it.
TEST=`emerge-$BOARD -v vboot_reference && \
      cros deploy $IP vboot_reference`
     `cgpt find -t kernel` does not print any RW_GPT-related errors
     anymore.

Change-Id: Ie081f372964807caa1b121059288ae761f2f8e43
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2814132
Commit-Queue: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
This commit is contained in:
Nicolas Boichat 2021-04-09 11:45:39 +08:00 committed by Commit Bot
parent 70838cc1a1
commit 57c0c5be50
3 changed files with 91 additions and 64 deletions

View File

@ -187,6 +187,12 @@ ifneq (${TPM2_MODE},)
CFLAGS += -DTPM2_MODE
endif
# Support devices with GPT in SPI-NOR (for nand device)
# TODO(b:184812319): Consider removing this code if nobody uses it.
ifneq (${GPT_SPI_NOR},)
CFLAGS += -DGPT_SPI_NOR
endif
# Enable boot from external disk when switching to dev mode
ifneq ($(filter-out 0,${BOOT_EXTERNAL_ON_DEV}),)
CFLAGS += -DBOOT_EXTERNAL_ON_DEV=1
@ -498,7 +504,6 @@ HOSTLIB_SRCS = \
cgpt/cgpt_create.c \
cgpt/cgpt_edit.c \
cgpt/cgpt_find.c \
cgpt/cgpt_nor.c \
cgpt/cgpt_prioritize.c \
cgpt/cgpt_show.c \
firmware/2lib/2common.c \
@ -535,6 +540,10 @@ HOSTLIB_SRCS = \
host/lib21/host_misc.c \
${TLCL_SRCS}
ifneq (${GPT_SPI_NOR},)
HOSTLIB_SRCS += cgpt/cgpt_nor.c
endif
HOSTLIB_OBJS = ${HOSTLIB_SRCS:%.c=${BUILD}/%.o}
ALL_OBJS += ${HOSTLIB_OBJS}
@ -552,7 +561,6 @@ CGPT_SRCS = \
cgpt/cgpt_edit.c \
cgpt/cgpt_find.c \
cgpt/cgpt_legacy.c \
cgpt/cgpt_nor.c \
cgpt/cgpt_prioritize.c \
cgpt/cgpt_repair.c \
cgpt/cgpt_show.c \
@ -566,6 +574,10 @@ CGPT_SRCS = \
cgpt/cmd_repair.c \
cgpt/cmd_show.c
ifneq (${GPT_SPI_NOR},)
CGPT_SRCS += cgpt/cgpt_nor.c
endif
CGPT_OBJS = ${CGPT_SRCS:%.c=${BUILD}/%.o}
ALL_OBJS += ${CGPT_OBJS}
@ -948,7 +960,7 @@ ${CGPT_WRAPPER}: ${CGPT_WRAPPER_OBJS} ${UTILLIB}
${Q}${LD} -o ${CGPT_WRAPPER} ${LDFLAGS} $^ ${LDLIBS}
.PHONY: cgpt
cgpt: ${CGPT} ${CGPT_WRAPPER}
cgpt: ${CGPT} $(if ${GPT_SPI_NOR},cgpt_wrapper)
# on FreeBSD: install misc/e2fsprogs-libuuid from ports,
# or e2fsprogs-libuuid from its binary package system.

View File

@ -96,19 +96,6 @@ static void showmatch(CgptFindParams *params, const char *filename,
EntryDetails(entry, partnum - 1, params->numeric);
}
// This handles the MTD devices. ChromeOS uses /dev/mtdX for kernel partitions,
// /dev/ubiblockX_0 for root partitions, and /dev/ubiX for stateful partition.
static void chromeos_mtd_show(CgptFindParams *params, const char *filename,
int partnum, GptEntry *entry) {
if (GuidEqual(&guid_chromeos_kernel, &entry->type)) {
printf("/dev/mtd%d\n", partnum);
} else if (GuidEqual(&guid_chromeos_rootfs, &entry->type)) {
printf("/dev/ubiblock%d_0\n", partnum);
} else {
printf("/dev/ubi%d_0\n", partnum);
}
}
// This returns true if a GPT partition matches the search criteria. If a match
// isn't found (or if the file doesn't contain a GPT), it returns false. The
// filename and partition number that matched is left in a global, since we
@ -214,6 +201,76 @@ static char *is_wholedev(const char *basename) {
return 0;
}
#ifdef GPT_SPI_NOR
// This handles the MTD devices. ChromeOS uses /dev/mtdX for kernel partitions,
// /dev/ubiblockX_0 for root partitions, and /dev/ubiX for stateful partition.
static void chromeos_mtd_show(CgptFindParams *params, const char *filename,
int partnum, GptEntry *entry) {
if (GuidEqual(&guid_chromeos_kernel, &entry->type)) {
printf("/dev/mtd%d\n", partnum);
} else if (GuidEqual(&guid_chromeos_rootfs, &entry->type)) {
printf("/dev/ubiblock%d_0\n", partnum);
} else {
printf("/dev/ubi%d_0\n", partnum);
}
}
static int scan_spi_gpt(CgptFindParams *params) {
int found = 0;
char partname[MAX_PARTITION_NAME_LEN];
FILE *fp;
size_t line_length = 0;
char *line = NULL;
fp = fopen(PROC_MTD, "re");
if (!fp) {
return found;
}
while (getline(&line, &line_length, fp) != -1) {
uint64_t sz;
uint32_t erasesz;
char name[128];
// dev: size erasesize name
if (sscanf(line, "%64[^:]: %" PRIx64 " %x \"%127[^\"]\"",
partname, &sz, &erasesz, name) != 4)
continue;
if (strcmp(partname, "mtd0") == 0) {
char temp_dir[] = "/tmp/cgpt_find.XXXXXX";
if (params->drive_size == 0) {
if (GetMtdSize("/dev/mtd0", &params->drive_size) != 0) {
perror("GetMtdSize");
goto cleanup;
}
}
if (ReadNorFlash(temp_dir) != 0) {
perror("ReadNorFlash");
goto cleanup;
}
char nor_file[64];
if (snprintf(nor_file, sizeof(nor_file), "%s/rw_gpt", temp_dir) > 0) {
params->show_fn = chromeos_mtd_show;
if (do_search(params, nor_file)) {
found++;
}
params->show_fn = NULL;
}
RemoveDir(temp_dir);
break;
}
}
cleanup:
fclose(fp);
free(line);
return found;
}
#else
// Stub
static int scan_spi_gpt(CgptFindParams *params) {
return 0;
}
#endif
// This scans all the physical devices it can find, looking for a match. It
// returns true if any matches were found, false otherwise.
static int scan_real_devs(CgptFindParams *params) {
@ -254,49 +311,11 @@ static int scan_real_devs(CgptFindParams *params) {
strcpy(partname_prev, partname);
}
fclose(fp);
fp = fopen(PROC_MTD, "re");
if (!fp) {
free(line);
return found;
}
while (getline(&line, &line_length, fp) != -1) {
uint64_t sz;
uint32_t erasesz;
char name[128];
// dev: size erasesize name
if (sscanf(line, "%64[^:]: %" PRIx64 " %x \"%127[^\"]\"",
partname, &sz, &erasesz, name) != 4)
continue;
if (strcmp(partname, "mtd0") == 0) {
char temp_dir[] = "/tmp/cgpt_find.XXXXXX";
if (params->drive_size == 0) {
if (GetMtdSize("/dev/mtd0", &params->drive_size) != 0) {
perror("GetMtdSize");
goto cleanup;
}
}
if (ReadNorFlash(temp_dir) != 0) {
perror("ReadNorFlash");
goto cleanup;
}
char nor_file[64];
if (snprintf(nor_file, sizeof(nor_file), "%s/rw_gpt", temp_dir) > 0) {
params->show_fn = chromeos_mtd_show;
if (do_search(params, nor_file)) {
found++;
}
params->show_fn = NULL;
}
RemoveDir(temp_dir);
break;
}
}
cleanup:
fclose(fp);
free(line);
found += scan_spi_gpt(params);
return found;
}

View File

@ -49,7 +49,7 @@ int GetMtdSize(const char *mtd_device, uint64_t *size) {
return ret;
}
// TODO(b:184559695): Remove these functions and use subprocess_run everywhere.
// TODO(b:184812319): Remove these functions and use subprocess_run everywhere.
int ForkExecV(const char *cwd, const char *const argv[]) {
pid_t pid = fork();
if (pid == -1) {
@ -202,6 +202,7 @@ int RemoveDir(const char *dir) {
// Read RW_GPT from NOR flash to "rw_gpt" in a temp dir |temp_dir_template|.
// |temp_dir_template| is passed to mkdtemp() so it must satisfy all
// requirements by mkdtemp.
// TODO(b:184812319): Replace this function with flashrom_read.
int ReadNorFlash(char *temp_dir_template) {
int ret = 0;
@ -215,9 +216,6 @@ int ReadNorFlash(char *temp_dir_template) {
// Read RW_GPT section from NOR flash to "rw_gpt".
ret++;
// TODO(b:184559695): Add parameter to subprocess_run to change directory
// before exec. Also, NULL parameter is a glibc extension that _might_
// break FreeBSD.
char *cwd = getcwd(NULL, 0);
if (!cwd) {
Error("Cannot get current directory.\n");
@ -247,6 +245,7 @@ out_free:
}
// Write "rw_gpt" back to NOR flash. We write the file in two parts for safety.
// TODO(b:184812319): Replace this function with flashrom_write.
int WriteNorFlash(const char *dir) {
int ret = 0;
@ -258,9 +257,6 @@ int WriteNorFlash(const char *dir) {
ret++;
int nr_fails = 0;
// TODO(b:184559695): Add parameter to subprocess_run to change directory
// before exec. Also, NULL parameter is a glibc extension that _might_
// break FreeBSD.
char *cwd = getcwd(NULL, 0);
if (!cwd) {
Error("Cannot get current directory.\n");