Right now there are two bootconfig parsers that gets linked into `init`.
One is from libinit itself and the other is from libfs_mgr.
The one in libinit removes all space characters between list elements,
so `key = "val1", "val2"` gets unquoted and squeezed into:
`key=val1,val2`
The one in libfs_mgr doesn't remove spaces, it only unquotes:
`key=val1, val2`
The libinit behavior is due to existing systems (such as sysprop)
expect the config value to be in the same format as kernel cmdline.
(aosp/1757971)
THe libfs_mgr behavior is due to the `androidboot.boot_device[s]`
format explicitly allows quoted comma appear in its list value, thus
relies on space, not comma, as the list value delimeter.
This commit merges the two parsers into libfs_mgr. Since all usages in
libfs_mgr besides `boot_device[s]` do not care about how list value are
delimited, and most usages in init expects the bootconfig value format
to be the same format as cmdline. We just special case the
`boot_device` scenario.
Also harden the test cases to cover all the different config value
format and expected result.
Note:
The format of kernel bootconfig is described here
https://docs.kernel.org/admin-guide/bootconfig.html
Bug: 293695109
Test: CtsFsMgrTestCases
Change-Id: I42b9bf626e8de38a60e8e09fac0693126b7efd91
VFIO nodes, both the container (`vfio`) node and group (numbered)
nodes, should be located in `/dev/vfio`. This change prevents
ueventd from flattening that structure.
Test: Bind a device to VFIO driver to create a VFIO group
Change-Id: I635e9febe6bb52718df263e735479f361eacad4c
We've had flake in libdm_test for a long time, with no clear cause.
Lately however it has become particularly reproducible when running
the UeventAfterLoadTable test in isolation, and thus we've identified
the root cause.
uevents for device-mapper are fired when the sysfs node is added, but at
that time, the "dm" subnode has not yet been added. The root node and dm
node are added very close together, so usually it works, but sometimes
ueventd is too fast.
Instead of relying on sysfs, query the uuid/name node directly from
device-mapper.
Bug: 270183812
Test: libdm_test
Change-Id: I258de5de05d813c3cb7f129e82e56dbfe8bf3117
Since we cannot create a gpt table on zoned LU, we cannot make a generic symlink
from it. Instead, let's make it by uevent, "/dev/block/by-name/zoned_device".
Note that, we support only one zoned device in the system.
Bug: 265180564
Change-Id: Ie62b0fd68b77e3e43cf0f5c5cad9503150174271
Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
DM_DEV_CREATE no longer creates sysfs nodes. Note this in ueventd and
add some helper APIs to libdm, so devices can be created with a
placeholder table.
This also fixes a bug in dmctl where the detailed info on suspended
devices was wrong.
Bug: 259328366
Test: dmctl with "uevents" tool
Change-Id: I822f8010e48d32841aa0ee508822f76d03a3dd85
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
The chown() call will fix the uid for pre-existing nodes, but not the
gid. This fix ensures the correct gid is set if needed.
Bug: 187738549
Test: manual test modifying ueventd.rc
Change-Id: I0fadd745a7c57a089fed9afc2572ace597a05396
If a `*` appears within (but not at the end) of a /dev or /sys path in
a ueventd.rc file, then that path is matched with fnmatch() using the
FNM_PATHNAME, which means `*` will not match `/`. That is not always
the intended behavior and this change creates the no_fnm_pathname
option, which will not use the FNM_PATHNAME flag and will have `*`
match `/`.
Bug: 172880724
Test: these unit tests
Change-Id: I85b813d89237dbf3af47564e5cbf6806df5d412f
Current implementation updates the permissions of sysfs
nodes of a device upon the following actions: "add",
"change" and "online".
But certain sysfs nodes (ex: wakeup capabilities under
power management) of devices are not present when the
device is added, but these are generally dependent on
the device driver and are added once the driver is bound.
This is particularly common in USB host stack.
If the bind action events are not parsed the ueventd
will not update the permissions of these nodes.
Hence, add the support for updating permissions on
bind action as well.
Bug: 174215510
Test: Verified permissions updated on bind action
Change-Id: Ic1a147e3993ef78dd6c539bbae652e8107207b87
Dynamically creating /dev/dm-user makes it difficult to set an inotify
watch for child devices to appear. It requires having an additional
watch on /dev, and more complicated sepolicy as a result.
Bug: 168554689
Test: full OTA with VABC enabled
Change-Id: I0cdef3d5a953a372446ff4e539a25a7b5314500d
When a device-mapper table contains a "user" entry, a corresponding
dm-user misc control device is created. The devices are put into a
separate folder by default, which currently confuses ueventd, and we
wind up with paths like:
/dev/dm-user!blah
Special case these devices so they wind up as:
/dev/dm-user/blah
Test: dmctl create blah user 0 100 test-device
/dev/dm-user/test-device exists
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
Change-Id: I313db07c3400f14f3ed0ffa20fdac2ac3e34b6d3
AMBA specification from Arm is a freely available open
standard for the connection and management of functional
blocks in a system-on-chip.
AMBA devices create a device kernel object in /sys/devices/platform
and a kernel object of the bus for the respective device in
/sys/bus/amba. For e.g. for pl180 mmc:
device: /sys/devices/platform/1c050000.mmci
bus: /sys/bus/amba/devices/1c050000.mmci
In first stage init, android creates a symlink from /sys/devices/platform/...
to /dev/block/platform/... for all partitions and then to
/dev/block/by-name for the boot_device used. However this is only done
for devices that "attach" to bus/platform. This patch adds support for
platform devices that attach to bus/amba.
Signed-off-by: Usama Arif <usama.arif@arm.com>
Change-Id: I9da7456407c4f62335c959502d8b2d16026fddfc
We want ashmem to only be used via libcutils API, with long-term goal
being deprecation of ashmem with memfd. To do that we route libcutils to
a new source of ashmem fds. We then phase out uses of /dev/ashmem that
doesn't go through libcutils using SELinux.
In Q, we introduced ashmemd as the source of ashmem fds to libcutils.
However, having a separate process and, consequently, binder hops to
handle /dev/ashmem results in performance/memory overhead.
To address the overhead, replace ashmemd with a duplicate of
/dev/ashmem. Name it /dev/ashmem<boot_id>, where boot_id is a random
number generated on each boot. This way we make sure that developers
don't accidentally depend on /dev/ashmem<boot_id>, as that name can't be
hardcoded.
Bug: 139855428
Test: writing "add"/"remove" to /sys/class/misc/ashmem/uevent correctly
adds/removes /dev/ashmem and /dev/ashmem/boot_id
Change-Id: I36d23116048bfcd99903ba46cc133161835a2cfa
This fixes a race condition where WaitForFile() after
GetDmDevicePathByName appears to succeed, but a subsequent operation on
the path fails. This can happen when CreateDevice() is called
immediately after a call to DeleteDevice (from any process), and the
path is re-used, enqueuing udev events to remove and re-add the block
device.
The fix for this is to introduce a new variant of CreateDevice() that
has a timeout parameter. When the timeout is positive, CreateDevice()
will wait for a /dev/block/mapper/by-uuid symlink to be created, which
signals that ueventd has finished processing the operation.
ueventd will now create these by-uuid symlinks for device-mapper nodes.
Unfortunately, the uuid is only available during "change" events, so we
have to special case device-mapper symlink creation. And since the uuid
is not available during "remove" events, we simply find matching links
to remove them.
This ensures that callers of CreateDevice() can use the device path
knowing that no asynchronous removals are pending. Code that uses the
old CreateDevice+WaitForFile pattern will be transitioned to the new
method.
Note that it is safe to ignore the timeout, or to use the "unsafe"
CreateDevice, if the caller ensures the path by other means. For example
first-stage init has no device removal, and regenerates uevents until
it has acquired all the paths it needs.
Finally, since libdm now inspects sysfs unconditionally, libdm consumers
need r_dir_file perms for sysfs_dm in their sepolicy. Additionally
linking to libdm now requires linking to libext2_uuid.
Bug: 135771280
Test: libdm_test
device flashes, boots
Change-Id: If5a7383ea38f32a7fbbcf24842dce6a668050a70
By moving it into builtins.cpp..., but that's less bad than it is
now, especially since this is defunct in code targeting Q+. Remove
the guards that init.h isn't being included by other files too as it's
not useful anymore.
Test: build
Change-Id: Ic564fcff9e8716ec924098b07a8c9d94ca25f960
This change factors out functions that handle selabels from
selinux.h/cpp into selabel.h/cpp. This allows util.cpp to be used by
the upcoming native zygote without a bunch of define flags that are
required for selinux.cpp.
Bug: 133443795
Test: Build and boot cuttlefish.
Change-Id: Ie238a96c6407c6698a605dd8803c1727abfaae7b
Since DM_NAME= is not sent (delete bug) or interpreted with ueventd
message, instead probe /sys/devices/virtual/block/dm-X/dm/name when
instantiating. Cache the value for later delete.
By creating the /dev/block/mapper/<name> nodes, this will give
selabel_lookup_best_match an alias to hang its hat on so that the
associated /dev/block/dm-X nodes will be suitably labelled and
differentiated.
NB: For Android, the deletion of the nodes will only happen in the
context of fastbootd, update_engine and gsid; otherwise the links
and properties created can be considered set-once and persistent.
Test: manual inspect /dev/block/mapper/ links
Bug: 124072565
Change-Id: I6d9e467970dfdad7b67754ad61084964251eb05f
Create /dev/block/by-name/<device> symlink for block devices that are
boot devices but do not have a partition name given.
Test: boot normally
Change-Id: I8c100b0d30dce02a2dd31aebcfea538b8eed9b19
We need to do restorecon after the cold boot, otherwise the newly
created sysfs nodes won't be labelled.
Bug: 118861992
Test: manual - do insmod, check sysfs nodes are properly labelled
Change-Id: I4bdfb4a68206724a568d8cbb6c644ba8764b5fa7
We're moving past a world where static executables are needed,
including watchdogd, so treat this like any other executable and place
it in /system/bin.
Bug: 73660730
Test: watchdogd still runs
Change-Id: I1f7508fd55dce6e9ee72a6ab7a085011a76c0053
Some devices have modules.alias and modules.dep for modprobe and other
purposes but do not want to opt into ueventd auto loading their
modules. Therefore we add a flag that can be added to ueventd
configuration files to opt into this behavior.
Bug: 111916071
Bug: 112048758
Test: check that modules are loaded with this opt-in
Test: check that modules are not loaded without this opt-in
Change-Id: Ifb281b273059b4671eea1ca5bc726c9e79f3adfb
During uevent processing, some "by-name" symlinks will be created.
/dev/block/<type>/<device>/by-name/<partition>
<type> can be: platform, pci or vbd.
<device> might be: soc.0/f9824900.sdhci, soc.0/f9824900.sdhci, etc.
<partition> might be: system, vendor, system_a, system_b, etc.
e.g., on a non-A/B device:
/dev/block/platform/soc.0/f9824900.sdhci/by-name/system
/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor
On a A/B device:
/dev/block/platform/soc/1da4000.ufshc/by-name/system_a
/dev/block/platform/soc/1da4000.ufshc/by-name/system_b
/dev/block/platform/soc/1da4000.ufshc/by-name/vendor_a
/dev/block/platform/soc/1da4000.ufshc/by-name/vendor_b
However, those symlinks are "device-specific".
This change adds the "generic" symlinks in ueventd, in addition to
the existing symlinks, when the possible "boot devices" are specified
in device tree. e.g.,
&firmware_android {
compatible = "android,firmware";
boot_devices ="soc/1da4000.ufshc,soc.0/f9824900.sdhci";
}
The following symlinks will then be created on the aforementioned non-A/B
and A/B devices, respectively.
/dev/block/by-name/system
/dev/block/by-name/vendor
/dev/block/by-name/system_a
/dev/block/by-name/system_b
/dev/block/by-name/vendor_a
/dev/block/by-name/vendor_b
Note that both <type> and <device> are skipped in the newly create symlinks.
It assumes there is no more than one devices with the same <partition>,
which is the assumption of current first stage mount flow.
Finally, when 'boot_devices' in DT is absent, it fallbacks to extract
'boot_devices' from fstab settings. e.g., using 'soc/1da4000.ufshc',
'soc.0/f9824900.sdhci' for a fstab with the following content:
/dev/block/platform/soc/1da4000.ufshc/by-name/system
/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor
Bug: 78613232
Test: adb shell ls /dev/block/by-name
Change-Id: Iec920b5a72409b6a2bdbeeb290f0a3acd2046b5d
The uevent.partition_num easily collides between partitions, for
example:
Both /dev/block/sda3 and /dev/block/sdd3 will generate the same symlink:
/dev/block/platform/soc/1da4000.ufshc/by-num/p3
This change remove those by-num symlinks as there seems no effective
user of it.
Bug: 78613232
Test: m init_tests && \
adb push $OUT/data/nativetest64/init_tests/init_tests /data/. && \
adb shell /data/init_tests
Change-Id: I8dfa8dc1a2f9fc9296aa30f33e905bf158b501de
We should have done this from the beginning. Thanks to Windows, we're not
going to be able to switch libbase over to std::string_view any time soon.
Bug: N/A
Test: ran tests
Change-Id: Iff2f56986e39de53f3ac484415378af17dacf26b
1) Check subsystems list before doing usb subsystem logic. This allows
developers to handle usb* subsystems in ueventd.rc files.
2) Fix a bug where each subsystem_ instance is not reinitialized, but
rather only the name_ member was set.
Test: boot bullhead
Test: check that multiple uevent_devname subsystems work when
specified in ueventd.rc
Change-Id: Ifcac04763afcaf72a3b14ef5f3a6cb89981b51a1
This change splits out the selinux initialization and supporting
functionality into selinux.cpp and splits the security related
initialization of the rng, etc to security.cpp. It also provides
additional documentation for SEPolicy loading as this has been
requested by some teams.
It additionally cleans up sehandle and sehandle_prop. The former is
static within selinux.cpp and new wrapper functions are created around
selabel_lookup*() to better serve the users. The latter is moved to
property_service.cpp as it is isolated to that file for its usage.
Test: boot bullhead
Merged-In: Idc95d493cebc681fbe686b5160502f36af149f60
Change-Id: Idc95d493cebc681fbe686b5160502f36af149f60
While refactoring ueventd, I was looking for code the character device
symlinks (/dev/usb/*) that ueventd creates, such that I could test it
on a real device. I found none in our tree, and history showing Xoom,
which was last supported years ago, was the last user. If this code
is in fact obsolete, let's remove it.
Test: boot bullhead
Test: init unit tests
Change-Id: I601f7165eb06d36b31b6dcf69ee9e0a449d81a96
In order to create symlinks for USB and block devices, the path for
their parent platform device must be known.
Previously, ueventd would save each platform device that it encounters
to a list and query this list when creating the symlinks. That,
however, is racy because the uevent socket does not differentiate
uevents from RegenerateUevents() and uevents sent by the kernel when
probing a device first the first time. The below scenario is the
faulty case:
1) Kernel probes parent platform device for a block device
2) ueventd calls RegenerateUevents() and starts processing uevents
3) Kernel probes block device and sends its uevents
4) ueventd picks up the block device uevent during its uevent processing,
without yet regenerating the platform device uevent, causing improper
symlinks to be created.
This change stops storing the platform devices in a list, and instead
traverses up the directory structure for each USB or block device
until it reaches a platform device, defined as one whose subsystem is
the platform bus. This fixes the race and simplifies the ueventd
code.
Bug: 62436493
Bug: 62681642
Test: Boot bullhead
Test: Boot sailfish
Test: Init unit tests
Test: Boot hikey + hotplug/unplug sdcard
Change-Id: I21636355d8e434f30e0cba568598a6cf139e67f9
fork() subprocesses to handle uevents in parallel.
This reduces coldboot time on bullhead from ~446ms to ~230ms.
This reduces coldboot time on sailfish from ~690ms to ~360ms.
This reduces coldboot time on ryu from ~187ms to ~122ms.
Bug: 33785894
Test: boot bullhead x40, observe no major differences in /dev and /sys
Test: boot sailfish x40, observe no major differences in /dev and /sys
Test: boot ryu x40, observe no major differences in /dev and /sys
Test: boottime tests on bullhead and sailfish
Test: init unit tests
Change-Id: Ie2f63e000b8af78d187477d31fe109f20304d749
devices.cpp handles too many things for creating one class. This
change breaks it up into various files and classes.
* Parsing is moved to ueventd_parser.cpp
* Reading from the uevent socket and Cold booting is moved to a
UeventListener class, in uevent_listener.cpp
* Firmware handling is moved to firmware_handler.cpp
* The remaining contents form a DeviceHandler class within devices.cpp
Bug: 33785894
Test: boot bullhead x40, observe no major differences in /dev and /sys
Test: boot sailfish x40, observe no major differences in /dev and /sys
Test: init unit tests
Change-Id: I846a2e5995fbb344c7a8e349065c18a934fa6aba
restorecon() has become nothing more than a small wrapper around
selinux_android_restore(). This itself isn't super problematic, but
it is an obstacle for compiling util.cpp on the host as that function
is not available on the host.
Bug: 36970783
Test: Boot bullhead
Merged-In: I7e209ece6898f9a0d5eb9e5d5d8155c2f1ba9faf
Change-Id: I7e209ece6898f9a0d5eb9e5d5d8155c2f1ba9faf
Init exposes a global 'sehandle' that ueventd references as part of
devices.cpp and util.cpp. This is particularly dangerous in
device_init() in which both uevent and init write to this global.
This change creates a separate local copy for devices.cpp and puts
restrictions on where init.h can be included to make sure the global
used by init is not reference by non-init code. Future changes to
init should remove this global.
Test: Boot bullhead
Change-Id: Ifefa9e1932e9d647d06cca2618f5c8e5a7a85460
Reloading sepolicy has been removed from the system, so this support
code can also now be removed.
Bug: 26544104
Test: Boot bullhead
Change-Id: If9dbc9d540d9a69340c1dd6a483c1f8fe5feb287
Previously init_parser.cpp was made generic and capable of parsing any
number of differently named 'sections' or prefixed lines. We now use
these capabilities to do the parsing for ueventd.
Bug: 36250207
Bug: 33785894
Test: boot bullhead and ensure the right /dev nodes exist
with the right permissions set
Test: verify no boot time difference
Change-Id: I698ca962d414f8135af32f6c9cd778841b2b8b53
Create classes for dev and sys permissions and store these permissions
in std::vector instead of the C list.
Test: boot bullhead
Test: init unit tests
Change-Id: I874039a3db29b4c70149506da8e407123ab7eca2
Also simplify this code a bit.
There's only one consumer that removes the /devices/platform prefix,
so have them handle it instead of storing two copies of the string.
Remove an unneeded search for '/' in get_character_device_symlinks()
as a / will always be the next character after a parent path, by
nature of FindPlatformDevice().
Test: boot bullhead
Test: init unit tests
Change-Id: I9d0482d137b1342ae7509ae993ff99198be814f0