Set retry count partition flag to 0 for slot B's kernel partition

When we create an image, we set the retry count for kernel partitions
of both slots A and B to 15 as a result, both are treated as
"bootable". Even though slot B doesn't have a valid data in the image,
after running chromeos-install, the content of slot A is copied to
both A & B, so we should maintain the slot B as bootable.

Having slot B bootable when booting from USB however (where slot B
doesn't have valid partition content) outright fools rollback
mechanism, since the partition is presented as bootable, but
the boot attempt will later fail.

The solution is to make sure we mark the secondary partion as not
bootable when creating the 'non-base' disk image.

BUG=chromium:365628, chromium:368844
TEST=Created a test image, inspected the partition table flags.
     Booted from USB and chromeos-install-ed it and verified the
     boot operation and partition flags.

Change-Id: I06ae062d39618d7dc72c0ff2b133d28b84eb0266
Reviewed-on: https://chromium-review.googlesource.com/198011
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/build_library/cgpt.py b/build_library/cgpt.py
index 908f878..8ce55b6 100755
--- a/build_library/cgpt.py
+++ b/build_library/cgpt.py
@@ -441,13 +441,15 @@
   return script_shell
 
 
-def WriteLayoutFunction(options, sfile, func_name, image_type, config):
+def WriteLayoutFunction(options, sfile, func, image_type, config):
   """Writes a shell script function to write out a given partition table.
 
   Args:
     options: Flags passed to the script
     sfile: File handle we're writing to
-    func_name: Function name to write out for specified layout
+    func: function of the layout:
+       for removable storage device: 'partition',
+       for the fixed storage device: 'base'
     image_type: Type of image eg base/test/dev/factory_install
     config: Partition configuration file object
   """
@@ -456,7 +458,7 @@
   partition_totals = GetTableTotals(config, partitions)
 
   lines = [
-    '%s() {' % func_name,
+    'write_%s_table() {' % func,
     'create_image $1 %d %s' % (
         partition_totals['min_disk_size'],
         config['metadata']['block_size']),
@@ -500,15 +502,27 @@
         ': $(( curr += %s ))' % partition['var'],
       ]
 
-  # Set default priorities on kernel partitions.
+  # Set default priorities and retry counter on kernel partitions.
+  tries = 15
   prio = 15
+  # The order of partition numbers in this loop matters.
+  # Make sure partition #2 is the first one, since it will be marked as
+  # default bootable partition.
   for n in (2, 4, 6):
     partition = GetPartitionByNumber(partitions, n)
     if partition['type'] != 'blank':
       lines += [
-        '${GPT} add -i %s -S 0 -T 15 -P %i $1' % (n, prio)
+        '${GPT} add -i %s -S 0 -T %i -P %i $1' % (n, tries, prio)
       ]
       prio = 0
+      # When not writing 'base' function, make sure the other partitions are
+      # marked as non-bootable (retry count == 0), since the USB layout
+      # doesn't have any valid data in slots B & C. But with base function,
+      # called by chromeos-install script, the KERNEL A partition is replicated
+      # into both slots A & B, so we should leave both bootable for error
+      # recovery in this case.
+      if func != 'base':
+        tries = 0
 
   lines += ['${GPT} boot -p -b $2 -i 12 $1']
   if config.get('hybrid_mbr'):
@@ -608,7 +622,7 @@
     f.write(script_shell)
 
     for func, layout in (('base', BASE_LAYOUT), ('partition', image_type)):
-      WriteLayoutFunction(options, f, 'write_%s_table' % func, layout, config)
+      WriteLayoutFunction(options, f, func, layout, config)
       WritePartitionSizesFunction(options, f, func, layout, config)
 
     # TODO: Backwards compat.  Should be killed off once we update