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>
diff --git a/Makefile b/Makefile
index 5f5132c..c4ebbdd 100644
--- a/Makefile
+++ b/Makefile
@@ -187,6 +187,12 @@
 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 @@
 	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 @@
 	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/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/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 @@
 	${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.
diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c
index 6f4bbae..8046aad 100644
--- a/cgpt/cgpt_find.c
+++ b/cgpt/cgpt_find.c
@@ -96,19 +96,6 @@
     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 @@
   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) {
@@ -255,48 +312,10 @@
   }
 
   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;
 }
 
diff --git a/cgpt/cgpt_nor.c b/cgpt/cgpt_nor.c
index 4030667..f7e65e8 100644
--- a/cgpt/cgpt_nor.c
+++ b/cgpt/cgpt_nor.c
@@ -49,7 +49,7 @@
   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 @@
 // 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 @@
   // 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 @@
 }
 
 // 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 @@
   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");