Commit graph

12 commits

Author SHA1 Message Date
Douglas Anderson
eb3d280f1e init: Look for partition only on a boot device if using boot_part_uuid
The current code waits for boot partitions to show up by waiting to
see a uevent with the right partition name. However, nothing in the
waiting code validates that the partition that showed up is actually
on the boot device. That means that the current code can be confused
if there is another block device in the system (possibly connected via
USB) that has a partition name matching one of the system ones.

It can be noted that the problem is specifically just that the
"waiting" part returns too early. Later parts of the system,
specifically the parts of the system that create the
"/dev/block/by-name" symlinks, do properly look at the list of "boot
devices". This means that the problem we're fixing is that later code,
which assumes that the boot partitions have already initialized, can
fail to find an initialized partition.

To make it concrete, imagine that you have two block devices in your
system: the builtin emmc and an external USB disk. Let's say you're
booting over USB and "boot_devices" properly lists only USB. Both the
"emmc" and "USB" block devices are properly formatted Android disks
and have the full slew of partitions. At boot time, you can see:
1. We get to the point where we need to wait for the "boot" source
   (USB) to show up.
2. We see the eMMC show up.
3. The eMMC has all the needed partitions, so we consider our wait
   done. ...but eMMC isn't in the list of "boot devices" so we don't
   create the "/dev/block/by-name" symlinks.
4. Later code assumes that the "/dev/block/by-name" symlinks are
   already setup and fails.
5. The device fails to boot.

Fix it so that the wait makes sure that the partitions are on the boot
device.

Unfortunately, it appears that in some cases products (especially
emulators) aren't setting the "boot devices" and/or are not making
sure all boot partitions are on the same device. Limit the fix to only
devices using the new "boot_part_uuid" to make sure we don't break old
code.

NOTE: this is effectively the same change as a previous one ("init:
Look for super partition only on a boot device") but with the added
fix to only enable the check when using "boot_part_uuid".

Bug: 309244873
Bug: 349144493
Bug: 316324155
Test: Boot isn't confused when two boot devices are present
Change-Id: Iaae453ed661307f485cdf4dde86294105cae9b2d
2024-11-06 13:03:15 -08:00
Douglas Anderson
e9de310061 init: Add the ability to find the boot device by partition UUID
The current mechanism for specifying boot devices on Android systems
involves passing a set of "boot_devices" though command line,
bootconfig, or device tree.

The bootdevices are specified as strings and, in general, need to
match a sysfs path but without the "/sys/devices" or
"/sys/devices/platform" prefix. The sysfs path is generally the path
to the closest parent of the block device that is a "platform" device.

As an example, if the sysfs path of the expected boot device is:
  /sys/devices/platform/soc@0/7c4000.mmc/mmc_host/mmc1/mmc1:0001/block/mmcblk1

The bootloader would specify it as "soc@0/7c4000.mmc" since:
* We strip off "/sys/devices/platform/"
* As we move up directories, we don't find one whose subsystem is
  "platform" until we get up to
  "/sys/devices/platform/soc@0/7c4000.mmc".

The current mechanism is a bit brittle. Specifically:
* The sysfs path isn't _really_ stable and can change across kernel
  upgrades. For instance, during one kernel upgrade the device tree
  for a product changed so that the root node changed from "soc" to
  "soc@0" and this changed all sysfs paths. In the past device tree
  folks have asserted that we shouldn't rely on dts node names to stay
  consistent, yet those node names are used to construct sysfs paths.
* For some devices, like USB, the path of the closest "platform"
  device tends to be the path of the USB controller. This means that
  if two USB disks are plugged in we can't guarantee which one will be
  identified as the boot device.

Add a new method of finding the boot device by passing the partition
UUID that we loaded the kernel from. Using the partition UUID to
identify the boot device is standard on Linux. You can see this
because when you're not using an initramfs you can use the syntax
"root=PARTUUID=<valid-uuid-id>[/PARTNROFF=n]" to specify the root.
Using the same idea for Android's boot code makes sense.

With this new method for finding the boot device, we can make the code
much more specific about matching sysfs paths. Once we find the sysfs
path for the kernel we can make sure that all of the other boot
partition share the same "scsi" or "mmc" parent instead of going all
the way to the closest platform device. In the above example, this
means that we'd make sure that all boot devices are found under this
sysfs node:
  /sys/devices/platform/soc@0/7c4000.mmc/mmc_host/mmc1/mmc1:0001/block/mmcblk1
...instead of just making sure they are under:
  /sys/devices/platform/soc@0/7c4000.mmc

There is the question of what we should do if the bootloader passes
_both_ an old style "boot_devices" and also a partition UUID. In this
case, we'll issue a warning and then ignore the old "boot_devices".
Considering it a warning rather than an error could allow switching to
the "boot_part_uuid" method even if an old bootloader is still
hardcoding some old "boot_devices".

NOTE: Using partition UUID won't cause any security problems even
though someone _could_ plug in an external device crafted to have the
same UUID as the normal boot device's kernel partition. We already
have "verity" in the system making sure our filesystems are not
tampered with and this would also protect us from booting a tampered
disk. That means that the worst someone could do in this case would be
to confuse the system and make the device non-bootable. Chromebooks
have been using the partition UUID to find the root filesystems for
years and this has never been a problem.

NOTE: this new method relies on the commit ("init: Add partition_uuid
to Uevent") which in turn relies upstream kernel commit 74f4a8dc0dd8
("block: add partition uuid into uevent as "PARTUUID"").

Bug: 316324155
Test: Use partition UUID to boot

Change-Id: If824cb700ca3696a442a28e6ad02d7c522c3b495
2024-11-06 13:03:15 -08:00
Konrad Adamczyk
5cc1ca1762 Revert^3 "init: Look for super partition only on a boot device"
This reverts commit 5bfb93678f.

Reason for revert: b/376468452 and trusty boot up on arm64. This CL is causing a lot of troubles (now only on emulator, but may affect more devices in field) and shall be reverted. Desktop team will handle support for selecting single boot source (while having more than one) as part of boot_part_uuid support (at aosp/3318438).  

Change-Id: I2804c119631f592d0862f3472ffe18dbb23b17e5
2024-10-31 08:25:54 +00:00
Konrad Adamczyk
5bfb93678f Revert^2 "init: Look for super partition only on a boot device"
This reverts commit 8d71220df2.

Reason for revert: Fix for gcar emulator (basically all QEMU-based emulators) landed at aosp/3315253 and aosp/3160116.

Change-Id: If4eddd3f7e224c31019ad3bd752e2375c7567780
2024-10-24 07:28:25 +00:00
Jusik Chung
8d71220df2 Revert "init: Look for super partition only on a boot device"
This reverts commit 6f0ebcb526.

Reason for revert: b/371393845 boot up failure of gcar emulator

Change-Id: I15e5bea609938cf5a1e347666b9a2abb287cb086
2024-10-04 02:21:37 +00:00
Jan Dabros
6f0ebcb526 init: Look for super partition only on a boot device
Init code is bailing out as soon as `super` partition was
found in the system, ignoring rest of uevents.

In case given device contains multiple boot sources, `super`
partition as well as all other partitions shall be taken
from the same boot source, instead of relying on
`which uevent came first`.

Bug: 309244873, 349144493
Test: Plug secondary USB boot device to device that supports multiple
      boot sources. Select boot from USB. Device boots properly.

Signed-off-by: Jan Dabros <dabros@google.com>
Signed-off-by: Konrad Adamczyk <konrada@google.com>

Change-Id: I70eb7d4223258ec273faa523cb67ddab0b7c32a0
2024-09-27 06:43:00 +00:00
Tiffany Yang
0fb39f6e69 init: Support for initializing virtio-console devices
This change allows init to ensure that a specified virtio-console
device file (`/dev/hvc*`) is available before `ueventd` coldboot.
Times out if device path is not encountered within 10 seconds.

Bug: 325538592
Test: build bertha_x86_64 and bertha_arm64
Change-Id: Ia1512e69ea607bf4d235595caa53668e2dac500c
2024-07-10 18:59:44 -07:00
Nikita Ioffe
1e114e677b Add a step to derive microdroid vendor dice node
The derivation happens in the derive_microdroid_vendor_dice_node binary
which first_stage_init forks and execvs.

Since the derivation requires talking to the dice driver, its
initialisation is also moved to the first stage init.

The derivation happens before the microdroid vendor partition is
verified & mounted. This should be safe because the first_stage_init
will fail the boot if the verification of the microdroid vendor
partition fails.

Bug: 287593065
Test: run microdroid with and without vendor partition
Test: atest MicrodroidTests
Change-Id: I0d83772eb98a56c315617e66ec64bd03639cfde6
2024-03-13 15:24:44 +00:00
Tom Cherry
96e5f9b5b8 Allow mapping of raw block devices to partition names
Allow mapping of raw block devices (those without a partition table)
to partition names for first stage mount and ueventd.  For example, a
block device `vdb` that contains only an ext4 metadata partition could
be mapped to `metadata` such that /dev/block/by-name/metadata is
created.

The mapping is provided by the `androidboot.partition_map` bootconfig
or kernel command line parameter.

Bug: 159943320
Test: boot with raw vdb,metadata;vdc,userdata partitions
Change-Id: Ib6a939d6fb88b85c46c81d613425a127627a734b
2021-07-30 10:35:58 -07:00
David Anderson
32f281d77a init: Pass a uevent regen callback to libsnapshot.
In first-stage init, libsnapshot needs to know how to wait for device
paths, since ueventd isn't running yet. We do this by passing a callback
wrapping BlockDevInitializer.

Bug: 173476209
Test: device boots into first-stage init after full VABC ota
Change-Id: I9a87f98824e65a9379cb0b99c001e28cccd9d205
2020-11-22 13:51:03 -08:00
David Anderson
67cd9f09ca init: Initiate other misc devices from BlockDevInitializer.
This allows init to easily ensure misc devices other than device-mapper
are present.

Bug: 154536437
Test: manual test
Change-Id: I49495684edee322f9787ce7ab7f79d0e8060171d
2020-07-08 15:46:28 -07:00
David Anderson
4117559746 init: Factor out first-stage uevent handling into a separate class.
This will make it possible to re-use in second-stage init.

Bug: 150315914
Test: first-stage init boots
Change-Id: I6a0f13d5c71ab5529a76751f68ac0f15834323d1
2020-03-23 18:49:51 -07:00