Home | History | Annotate | Download | only in ota
      1 <html devsite>
      2   <head>
      3     <title>A/B (Seamless) System Updates</title>
      4     <meta name="project_path" value="/_project.yaml" />
      5     <meta name="book_path" value="/_book.yaml" />
      6   </head>
      7   <body>
      8   <!--
      9       Copyright 2017 The Android Open Source Project
     10 
     11       Licensed under the Apache License, Version 2.0 (the "License");
     12       you may not use this file except in compliance with the License.
     13       You may obtain a copy of the License at
     14 
     15           http://www.apache.org/licenses/LICENSE-2.0
     16 
     17       Unless required by applicable law or agreed to in writing, software
     18       distributed under the License is distributed on an "AS IS" BASIS,
     19       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     20       See the License for the specific language governing permissions and
     21       limitations under the License.
     22   -->
     23 
     24 
     25 
     26 <p>
     27   A/B system updates, also known as seamless updates, ensure a workable booting
     28   system remains on the disk during an <a href="/devices/tech/ota/index.html"
     29   >over-the-air (OTA) update</a>. This reduces the likelihood of an inactive
     30   device afterward, which means less device replacements and device reflashes at
     31   repair/warranty centers.
     32 </p>
     33 
     34 <p>
     35   Customers can continue to use their devices during an OTA. The only downtime
     36   during an update is when the device reboots into the updated disk partition. If
     37   the OTA fails, the device is still useable since it will boot into the pre-OTA
     38   disk partition. The download of the OTA can be attempted again. A/B system
     39   updates implemented through OTA are recommended for new devices only.
     40 </p>
     41 
     42 <p>
     43   A/B system updates affect:
     44 </p>
     45 
     46 <ul>
     47   <li>Interactions with the bootloader</li>
     48   <li>Partition selection</li>
     49   <li>The build process</li>
     50   <li>OTA update package generation</li>
     51 </ul>
     52 
     53 <p>
     54   The existing <a href="/security/verifiedboot/dm-verity.html"
     55   >dm-verity</a> feature guarantees the device will boot an uncorrupted image. If
     56   a device doesn't boot, because of a bad OTA or dm-verity issue, the device can
     57   reboot into an old image.
     58 </p>
     59 
     60 <p>
     61   The A/B system is robust because any errors (such as I/O errors) affect only
     62   the <strong>unused</strong> partition set and can be retried. Such errors also
     63   become less likely because the I/O load is deliberately low to avoid degrading
     64   the user experience.
     65 </p>
     66 
     67 <p>
     68   OTA updates can occur while the system is running, without interrupting the
     69   user. This includes the app optimizations that occur after a reboot.
     70   Additionally, the cache partition is no longer used to store OTA update
     71   packages; there is no need for sizing the cache partition.
     72 </p>
     73 
     74 <h2 id="overview">Overview</h2>
     75 
     76 <p>
     77   A/B system updates use a background daemon called <code>update_engine</code>
     78   and two sets of partitions. The two sets of partitions are referred to as
     79   <em>slots</em>, normally as slot A and slot B. The system runs from one slot,
     80   the <em>current</em> slot, while the partitions in the <em>unused</em> slot are
     81   not accessed by the running system (for normal operation).
     82 </p>
     83 
     84 <p>
     85   The goal of this feature is to make updates fault resistant by keeping the
     86   unused slot as a fallback. If there is an error during an update or immediately
     87   after an update, the system can rollback to the old slot and continue to have a
     88   working system. To achieve this goal, none of the partitions used by the
     89   <em>current</em> slot should be updated as part of the OTA update (including
     90   partitions for which there is only one copy).
     91 </p>
     92 
     93 <p>
     94   Each slot has a <em>bootable</em> attribute, which states whether the slot
     95   contains a correct system from which the device can boot. The current slot is
     96   clearly bootable when the system is running, but the other slot may have an old
     97   (still correct) version of the system, a newer version, or invalid data.
     98   Regardless of what the <em>current</em> slot is, there is one slot which is the
     99   <em>active</em> or preferred slot. The active slot is the one the bootloader
    100   will boot from on the next boot. Finally, each slot has a <em>successful</em>
    101   attribute set by the user space, which is only relevant if the slot is also
    102   bootable.
    103 </p>
    104 
    105 <p>
    106   A successful slot should be able to boot, run, and update itself. A bootable
    107   slot that was not marked as successful (after several attempts were made to
    108   boot from it) should be marked as unbootable by the bootloader, including
    109   changing the active slot to another bootable slot (normally to the slot running
    110   right before the attempt to boot into the new, active one). The specific
    111   details of the interface are defined in
    112   <code><a class="external-link" target="_blank"
    113            href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h"
    114         >boot_control.h</a></code>.
    115 </p>
    116 
    117 <h3 id="bootloader-state-examples">Bootloader state examples</h3>
    118 
    119 <p>
    120   The <code>boot_control</code> HAL is used by <code>update_engine</code> (and
    121   possibly other daemons) to instruct the bootloader what to boot from. These
    122   are common example scenarios and their associated states:
    123 </p>
    124 
    125 <ul>
    126   <li>
    127     <strong>Normal case</strong>: The system is running from its current slot,
    128     either slot A or B. No updates have been applied so far. The system's current
    129     slot is bootable, successful, and the active slot.
    130   </li>
    131   <li>
    132     <strong>Update in progress</strong>: The system is running from slot B, so
    133     slot B is the bootable, successful, and active slot. Slot A was marked as
    134     unbootable since the contents of slot A are being updated but not yet
    135     completed. A reboot in this state should continue booting from slot B.
    136   </li>
    137   <li>
    138     <strong>Update applied, reboot pending</strong>: The system is running from
    139     slot B, slot B is bootable and successful, but slot A was marked as active
    140     (and therefore is marked as bootable). Slot A is not yet marked as successful
    141     and some number of attempts to boot from slot A should be made by the
    142     bootloader.
    143   </li>
    144   <li>
    145     <strong>System rebooted into new update</strong>: The system is running from
    146     slot A for the first time, slot B is still bootable and successful while slot
    147     A is only bootable, and still active but not successful. A user space daemon
    148     should mark slot A as successful after some checks are made.
    149   </li>
    150 </ul>
    151 
    152 <h3 id="update-engine-features">Update Engine features</h3>
    153 
    154 <p>
    155   The <code>update_engine</code> daemon runs in the background and prepares the
    156   system to boot into a new, updated version. The <code>update_engine</code>
    157   daemon is not involved in the boot process itself and is limited in what it can
    158   do during an update. The <code>update_engine</code> daemon can do the
    159   following:
    160 </p>
    161 
    162 <ul>
    163   <li>
    164     Read from the current slot A/B partitions and write any data to the unused
    165     slot A/B partitions as instructed by the OTA package
    166   </li>
    167   <li>
    168     Call the <code>boot_control</code> interface in a pre-defined workflow
    169   </li>
    170   <li>
    171     Run a <em>post-install</em> program from the <em>new</em> partition after
    172     writing all the unused slot partitions, as instructed by the OTA package
    173   </li>
    174 </ul>
    175 
    176 <p>
    177   The post-install step is described in detail below. Note that the
    178   <code>update_engine</code> daemon is limited by the
    179   <a href="/security/selinux/">SELinux</a> policies and features in the
    180   <em>current</em> slot; those policies and features can't be updated until the
    181   system boots into a new version. To achieve a robustness goal, the update
    182   process should not:
    183 </p>
    184 
    185 <ul>
    186   <li>Modify the partition table</li>
    187   <li>Modify the contents of partitions in the current slot</li>
    188   <li>
    189     Modify the contents of non-A/B partitions that can't be wiped with a
    190     factory reset
    191   </li>
    192 </ul>
    193 
    194 <h2 id="life-of-an-a-b-update">Life of an A/B update</h2>
    195 
    196 <p>
    197   The update process starts when an OTA package, referred to in code as a
    198   <em>payload</em>, is available for downloading. Policies in the device may
    199   defer the payload download and application based on battery level, user
    200   activity, whether it is connected to a charger, or other policies. But since
    201   the update runs in the background, the user might not know that an update is
    202   in progress and the process can be interrupted at any point due to policies or
    203   unexpected reboots.
    204 </p>
    205 
    206 <p>
    207   The steps in the update process after a payload is available are as follows:
    208 </p>
    209 
    210 <p>
    211   <strong>Step 1:</strong> The current slot (or "source slot") is marked as
    212   successful (if not already marked) with <code>markBootSuccessful()</code>.
    213 </p>
    214 
    215 <p>
    216   <strong>Step 2:</strong> The unused slot (or "target slot") is marked as
    217   unbootable by calling the function <code>setSlotAsUnbootable()</code>.
    218 </p>
    219 
    220 <p>
    221   The current slot is always marked as successful at the beginning of the update
    222   to prevent the bootloader from falling back to the unused slot, which will soon
    223   have invalid data. If the system has reached the point where it can start
    224   applying an update, the current slot is marked as successful even if other
    225   major components are broken (such as the UI in a crash loop) since it's
    226   possible to push new software to fix these major problems.
    227 </p>
    228 
    229 <p>
    230   The update payload is an opaque blob with the instructions to update to the
    231   new version. The update payload consists of basically two parts: the metadata
    232   and the extra data associated with the instructions. The metadata is
    233   relatively small and contains a list of operations to produce and verify the
    234   new version on the target slot. For example, an operation could decompress a
    235   certain blob and write it to certain blocks in a target partition, or read from
    236   a source partition, apply a binary patch, and write to certain blocks in a
    237   target partition. The extra data associated to the operations, not included in
    238   the metadata, is the bulk of the update payload and would consist of the
    239   compressed blob or binary patch in these examples.
    240 </p>
    241 
    242 <p>
    243   <strong>Step 3:</strong> The payload metadata is downloaded.
    244 </p>
    245 
    246 <p>
    247   <strong>Step 4:</strong> For each operation defined in the metadata, in order,
    248   the associated data (if any) is downloaded to memory, the operation is applied,
    249   and the associated memory is discarded.
    250 </p>
    251 
    252 <p>
    253   These two steps take most of the update time, as they involve writing and
    254   downloading large amounts of data, and are likely to be interrupted for reasons
    255   of policy or reboot.
    256 </p>
    257 
    258 <p>
    259   <strong>Step 5:</strong> The whole partitions are re-read and verified against
    260   the expected hash.
    261 </p>
    262 
    263 <p>
    264   <strong>Step 6:</strong> The post-install step (if any) is run.
    265 </p>
    266 
    267 <p>
    268   In the case of an error during the execution of any step, the update fails and
    269   is re-attempted with possibly a different payload. If all the steps so far have
    270   succeeded, the update succeeds and the last step is executed.
    271 </p>
    272 
    273 <p>
    274   <strong>Step 7:</strong> The <em>unused slot</em> is marked as active by
    275   calling <code>setActiveBootSlot()</code>.
    276 </p>
    277 
    278 <p>
    279   Marking the unused slot as active doesn't mean it will finish booting. The
    280   bootloaderor system itselfcan switch the active slot back if it doesn't
    281   read a successful state.
    282 </p>
    283 
    284 <h3 id="post-install-step">Post-install step</h3>
    285 
    286 <p>
    287   The post-install step consists of running a program from the "new update"
    288   version while still running in the old version. If defined in the OTA package,
    289   this step is mandatory and the program must return with exit code
    290   <code>0</code>; otherwise, the update fails.
    291 </p>
    292 
    293 <p>
    294   For every partition where a post-install step is defined,
    295   <code>update_engine</code> mounts the new partition into a specific location
    296   and executes the program specified in the OTA relative to the mounted
    297   partition. For example, if the post-install program is defined as
    298   <code>usr/bin/postinstall</code> in the system partition, this partition from
    299   the unused slot will be mounted in a fixed location (for example, in
    300   <code>/postinstall_mount</code>) and the
    301   <code>/postinstall_mount/usr/bin/postinstall</code> command will be executed.
    302   Note that for this step to work, the following are required:
    303 </p>
    304 
    305 <ul>
    306   <li>
    307     The old kernel needs to be able to mount the new filesystem format. The
    308     filesystem type cannot change unless there's support for it in the old
    309     kernel (which includes details such as the compression algorithm used if
    310     using a compressed filesystem like SquashFS).
    311   </li>
    312   <li>
    313     The old kernel needs to understand the new partition's post-install program
    314     format. If using an ELF binary, it should be compatible with the old
    315     kernel (e.g. a 64-bit new program running on an old 32-bit kernel if the
    316     architecture switched from 32- to 64-bit builds). Also, the libraries
    317     will be loaded from the old system image, not the new one, unless the loader
    318     (<code>ld</code>) is instructed to use other paths or build a static binary.
    319   </li>
    320   <li>
    321     The new post-install program will be limited by the SELinux policies defined
    322     in the old system.
    323   </li>
    324 </ul>
    325 
    326 <p>
    327   An example case is to use a shell script as a post-install program (interpreted
    328   by the old system's shell binary with a <code>#!</code> marker at the top) and
    329   then set up library paths from the new environment for executing a more complex
    330   binary post-install program.
    331 </p>
    332 
    333 <p>
    334   Another example case is to run the post-install step from a dedicated smaller
    335   partition, so the filesystem format in the main system partition can be updated
    336   without incurring backward compatibility issues or stepping-stone updates,
    337   allowing users to update straight to the latest version from a factory image.
    338 </p>
    339 
    340 <p>
    341   Due to the SELinux policies, the post-install step is suitable for
    342   performing tasks required by design on a given device or other best-effort
    343   tasks: update the A/B-capable firmware or bootloader, prepare copies of some
    344   databases for the new version, etc. This step is not suitable for one-off bug
    345   fixes before reboot that require unforeseen permissions.
    346 </p>
    347 
    348 <p>
    349   The selected post-install program runs in the <code>postinstall</code> SELinux
    350   context. All the files in the new mounted partition will be tagged with
    351   <code>postinstall_file</code>, regardless of what their attributes are after
    352   rebooting into that new system. Changes to the SELinux attributes in the new
    353   system won't impact the post-install step. If the post-install program needs
    354   extra permissions, those must be added to the post-install context.
    355 </p>
    356 
    357 <h2 id="implementation">Implementation</h2>
    358 
    359 <p>
    360   OEMs and SoC vendors who wish to implement the feature must add the following
    361   support to their bootloaders:
    362 </p>
    363 
    364 <ul>
    365   <li>
    366     Pass the <a href="#kernel-command-line-arguments">correct parameters</a>
    367     to the kernel
    368   </li>
    369   <li>
    370     Implement the <code>boot_control</code> HAL
    371     (<a class="external-link nowrap" target="_blank"
    372         href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h"
    373     >https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h</a>)
    374   </li>
    375   <li>Implement the state machine as shown in Figure 1:</li>
    376 </ul>
    377 
    378 <img src="/devices/tech/ota/images/ab-updates-state-machine.png">
    379 
    380 <p class="img-caption"><strong>Figure 1.</strong> Bootloader state machine</p>
    381 
    382 <p>
    383   The boot control HAL can be tested using the
    384   <a class="external-link" target="_blank"
    385      href="https://android.googlesource.com/platform/system/extras/+/master/bootctl/"
    386   ><code>bootctl</code></a> utility.
    387 </p>
    388 
    389 <p>Some tests have been implemented for Brillo:</p>
    390 
    391 <ul>
    392   <li>
    393     <a class="external-link nowrap" target="_blank"
    394        href="https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/"
    395     >https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/</a>
    396   </li>
    397   <li>
    398     <a class="external-link nowrap" target="_blank"
    399        href="https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py"
    400     >https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py</a>
    401   </li>
    402 </ul>
    403 
    404 <h3 id="kernel-patches">Kernel patches</h3>
    405 
    406 <ul>
    407   <li>
    408     <a class="external-link nowrap" target="_blank"
    409        href="https://android-review.googlesource.com/#/c/158491/"
    410     >https://android-review.googlesource.com/#/c/158491/</a>
    411   </li>
    412   <li>
    413     <a class="external-link nowrap" target="_blank"
    414        href="https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18"
    415     >https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18</a>
    416   </li>
    417 </ul>
    418 
    419 <h3 id="kernel-command-line-arguments">Kernel command line arguments</h3>
    420 
    421 <p>
    422   The kernel command line arguments <strong>must</strong> contain the following
    423   extra arguments:
    424 </p>
    425 
    426 <pre class="devsite-click-to-copy">
    427 <code class="devsite-terminal">skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 \
    428   android-verity &lt;public-key-id&gt; &lt;path-to-system-partition&gt;"</code>
    429 </pre>
    430 
    431 <p>
    432   The <code>&lt;public-key-id&gt;</code> value is the ID of the public key used
    433   to verify the verity table signature (see
    434   <a href="/security/verifiedboot/dm-verity.html">dm-verity</a>).
    435 </p>
    436 
    437 <h4>
    438   To add the .X509 certificate containing the public key to the system keyring:
    439 </h4>
    440 
    441 <ol>
    442   <li>
    443     Copy the .X509 certificate formatted in the <code>.der</code>
    444     format to the root of the <code>kernel</code> directory. Use the following
    445     <code>openssl</code> command to convert from <code>.pem</code> to
    446     <code>.der</code> format (if the .X509 certificate is formatted in
    447     <code>.pem</code> format):
    448 <pre class="devsite-terminal devsite-click-to-copy">
    449 openssl x509 -in &lt;x509-pem-certificate&gt; -outform der -out &lt;x509-der-certificate&gt;
    450 </pre>
    451   </li>
    452   <li>
    453     Once copied to the kernel build root, build the <code>zImage</code> to
    454     include the certificate as part of the system keyring. This can be verified
    455     from the following <code>procfs</code> entry (requires
    456     <code>KEYS_CONFIG_DEBUG_PROC_KEYS</code> to be enabled):
    457 <pre class="devsite-click-to-copy">
    458 angler:/# cat /proc/keys
    459 
    460 1c8a217e I------     1 perm 1f010000     0     0 asymmetri
    461 Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
    462 2d454e3e I------     1 perm 1f030000     0     0 keyring
    463 .system_keyring: 1/4
    464 </pre>
    465   </li>
    466 </ol>
    467 
    468 <p>
    469   Successful inclusion of the .X509 certificate indicates the presence of the
    470   public key in the system keyring. The highlighted portion denotes the public
    471   key ID.
    472 </p>
    473 
    474 <p>
    475   As the next step, replace the space with # and pass it as
    476   <code>&lt;public-key-id&gt;</code> in the kernel command line. For example, in the
    477   above case, the following is passed in the place of
    478   <code>&lt;public-key-id&gt;</code>:
    479   <code>Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f</code>
    480 </p>
    481 
    482 <h3 id="recovery">Recovery</h3>
    483 
    484 <p>
    485   The recovery RAM disk is now contained in the <code>boot.img</code> file. When
    486   going into recovery, the bootloader <strong>cannot</strong> put the
    487   <code>skip_initramfs</code> option on the kernel command line.
    488 </p>
    489 
    490 <h3 id="build-variables">Build variables</h3>
    491 
    492 <h5>Must define for the A/B target:</h5>
    493 
    494 <ul>
    495   <li><code>AB_OTA_UPDATER := true</code></li>
    496   <li>
    497     <code>AB_OTA_PARTITIONS := \</code><br/>
    498     <code>&nbsp; boot \</code><br/>
    499     <code>&nbsp; system \</code><br/>
    500     <code>&nbsp; vendor</code><br/>
    501     and other partitions updated through <code>update_engine</code> (radio,
    502     bootloader, etc.)
    503   </li>
    504   <li>
    505     <code>BOARD_BUILD_SYSTEM_ROOT_IMAGE := true</code>
    506   </li>
    507   <li><code>TARGET_NO_RECOVERY := true</code></li>
    508   <li>
    509     <code>BOARD_USES_RECOVERY_AS_BOOT := true</code>
    510   </li>
    511   <li>
    512     <code>PRODUCT_PACKAGES += \</code><br/>
    513     <code>&nbsp; update_engine \</code><br/>
    514     <code>&nbsp; update_verifier</code>
    515   </li>
    516 </ul>
    517 
    518 <h5>Optionally define for debug builds:</h5>
    519 
    520 <ul>
    521   <li>
    522     <code>PRODUCT_PACKAGES_DEBUG += update_engine_client</code>
    523   </li>
    524 </ul>
    525 
    526 <h5>Cannot define for the A/B target:</h5>
    527 
    528 <ul>
    529   <li><code>BOARD_RECOVERYIMAGE_PARTITION_SIZE</code></li>
    530   <li><code>BOARD_CACHEIMAGE_PARTITION_SIZE</code></li>
    531   <li><code>BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE</code></li>
    532 </ul>
    533 
    534 <h3 id="partitions">Partitions</h3>
    535 
    536 <ul>
    537   <li>
    538     A/B devices do not need a recovery partition or cache partition because
    539     Android no longer uses these partitions. The data partition is now used for
    540     the downloaded OTA package, and the recovery image code is on the boot
    541     partition.
    542   </li>
    543   <li>
    544     All partitions that are A/B-ed should be named as follows (slots are always
    545     named <code>a</code>, <code>b</code>, etc.): <code>boot_a</code>,
    546     <code>boot_b</code>, <code>system_a</code>, <code>system_b</code>,
    547     <code>vendor_a</code>, <code>vendor_b</code>.
    548   </li>
    549 </ul>
    550 
    551 <h3 id="fstab">Fstab</h3>
    552 
    553 <p>
    554   The <code>slotselect</code> argument <strong>must</strong> be on the line for
    555   the A/B-ed partitions. For example:
    556 </p>
    557 
    558 <pre class="devsite-click-to-copy">
    559 &lt;path-to-block-device&gt;/vendor  /vendor  ext4  ro
    560 wait,verify=&lt;path-to-block-device&gt;/metadata,slotselect
    561 </pre>
    562 
    563 <p>
    564   Please note that there should be no partition named <code>vendor</code> but
    565   instead the partition <code>vendor_a</code> or <code>vendor_b</code> will be
    566   selected and mounted on the <code>/vendor</code> mount point.
    567 </p>
    568 
    569 <h3 id="kernel-slot-arguments">Kernel slot arguments</h3>
    570 
    571 <p>
    572   The current slot suffix should be passed either through a specific DT node
    573   (<code>/firmware/android/slot_suffix</code>) or through the
    574   <code>androidboot.slot_suffix</code> command line argument.
    575 </p>
    576 
    577 <p>
    578   Optionally, if the bootloader implements fastboot, the following commands and
    579   variables should be supported:
    580 </p>
    581 
    582 <h4>Commands</h4>
    583 <ul>
    584   <li>
    585     <code>set_active &lt;slot&gt;</code> Sets the current active slot to
    586     the given slot. This must also clear the unbootable flag for that slot, and
    587     reset the retry count to default values.
    588   </li>
    589 </ul>
    590 
    591 <h4>Variables</h4>
    592 <ul>
    593   <li>
    594     <code>has-slot:&lt;partition-base-name-without-suffix&gt;</code>
    595       Returns yes if the given partition supports slots, no otherwise.
    596   </li>
    597   <li>
    598     <code>current-slot</code> Returns the slot suffix that will be booted from
    599     next.
    600   </li>
    601   <li>
    602     <code>slot-count</code> Returns an integer representing the number of
    603     available slots. Currently, two slots are supported so this value is
    604     <code>2</code>.
    605   </li>
    606   <li>
    607     <code>slot-successful:&lt;slot-suffix&gt;</code> Returns "yes" if the given
    608     slot has been marked as successfully booting, "no" otherwise.
    609   </li>
    610   <li>
    611     <code>slot-unbootable:&lt;slot-suffix&gt;</code> Returns yes if the given
    612     slot is marked as unbootable, "no" otherwise.
    613   </li>
    614   <li>
    615     <code>slot-retry-count:<slot suffix></code> Number of retries remaining to
    616     attempt to boot the given slot.
    617   </li>
    618   <li>
    619     These variables should all appear under the following:
    620     <code>fastboot getvar all</code>
    621   </li>
    622 </ul>
    623 
    624 <h3 id="ota-package-generation">OTA package generation</h3>
    625 
    626 <p>
    627   The <a href="/devices/tech/ota/tools.html">OTA package tools</a>
    628   follow the same commands as the commands for non-A/B devices. The
    629   <code>target_files.zip</code> file must be generated by defining the build
    630   variables for the A/B target. The OTA package tools automatically identify and
    631   generate packages in the format for the A/B updater.
    632 </p>
    633 
    634 <p>
    635   For example, use the following to generate a full OTA:
    636 </p>
    637 
    638 <pre class="devsite-terminal devsite-click-to-copy">
    639 ./build/tools/releasetools/ota_from_target_files \
    640   dist_output/tardis-target_files.zip ota_update.zip
    641 </pre>
    642 
    643 <p>
    644   Or, generate an incremental OTA:
    645 </p>
    646 
    647 <pre class="devsite-terminal devsite-click-to-copy">
    648 ./build/tools/releasetools/ota_from_target_files \
    649   -i PREVIOUS-tardis-target_files.zip \
    650   dist_output/tardis-target_files.zip incremental_ota_update.zip
    651 </pre>
    652 
    653 <h2 id="configuration">Configuration</h2>
    654 
    655 <h3 id="config-partitions">Partitions</h3>
    656 
    657 <p>
    658   The Update Engine can update any pair of A/B partitions defined in the same
    659   disk.
    660 </p>
    661 
    662 <p>
    663   A pair of partitions has a common prefix (such as <code>system</code> or
    664   <code>boot</code>) and per-slot suffix (such as <code>_a</code>). The list of
    665   partitions for which the payload generator defines an update is configured by
    666   the <code>AB_OTA_PARTITIONS</code> make variable. For example, if a pair of
    667   partitions <code>bootloader_a</code> and <code>booloader_b</code> are included
    668   (<code>_a</code> and <code>_b</code> are the slot suffixes), these partitions
    669   can be updated by specifying the following on the product or board
    670   configuration:
    671 </p>
    672 
    673 <pre class="devsite-click-to-copy">
    674 AB_OTA_PARTITIONS := \
    675   boot \
    676   system \
    677   bootloader
    678 </pre>
    679 
    680 <p>
    681   All the partitions updated by the Update Engine must not be modified by the
    682   rest of the system. During incremental or <em>delta</em> updates, the binary
    683   data from the current slot is used to generate the data in the new slot. Any
    684   modification may cause the new slot data to fail verification during the
    685   update process, and therefore fail the update.
    686 </p>
    687 
    688 <h3 id="post-install">Post-install</h3>
    689 
    690 <p>
    691   The post-install step can be configured differently for each updated partition
    692   using a set of key-value pairs.
    693 </p>
    694 
    695 <p>
    696   To run a program located at <code>/system/usr/bin/postinst</code> in a
    697   new image, specify the path relative to the root of the filesystem in the
    698   system partition. For example, <code>usr/bin/postinst</code> is
    699   <code>system/usr/bin/postinst</code> (if not using a RAM disk). Additionally,
    700   specify the filesystem type to pass to the <code>mount(2)</code> system call.
    701   Add the following to the product or device <code>.mk</code> files (if
    702   applicable):
    703 </p>
    704 
    705 <pre class="devsite-click-to-copy">
    706 AB_OTA_POSTINSTALL_CONFIG += \
    707   RUN_POSTINSTALL_system=true \
    708   POSTINSTALL_PATH_system=usr/bin/postinst \
    709   FILESYSTEM_TYPE_system=ext4
    710 </pre>
    711 
    712 <h3 id="compilation">App compilation in background</h3>
    713 
    714 <p>Compiling apps in the background for A/B updates requires the following two
    715 additions to the product's device configuration (in the product's device.mk):</p>
    716 
    717 <ol>
    718   <li>Include the native components in the build. This ensures the compilation
    719   script and binaries are compiled and included in the system image.
    720 <pre class="devsite-click-to-copy">
    721   # A/B OTA dexopt package
    722   PRODUCT_PACKAGES += otapreopt_script
    723 </pre>
    724   </li>
    725   <li>Connect the compilation script to <code>update_engine</code> such that it
    726   is run as a post-install step.
    727 <pre class="devsite-click-to-copy">
    728   # A/B OTA dexopt update_engine hookup
    729   AB_OTA_POSTINSTALL_CONFIG += \
    730     RUN_POSTINSTALL_system=true \
    731     POSTINSTALL_PATH_system=system/bin/otapreopt_script \
    732     FILESYSTEM_TYPE_system=ext4 \
    733     POSTINSTALL_OPTIONAL_system=true
    734   </pre>
    735   </li>
    736 </ol>
    737 
    738 <p>See <a href="/devices/tech/dalvik/configure.html#other_odex">First
    739 boot installation of DEX_PREOPT files</a> to install the preopted files in the
    740 unused second system partition.</p>
    741 
    742   </body>
    743 </html>
    744