We are currently creating test partitions via ImageManager, which
unfortunately leads to a lot of hacks in my local tree to test
first-stage init. ImageManager devices look nothing like real partitions
in super, and it's a lot of work to massage it to act the same.
Instead, let's create an actual super partition. We can do this via
ImageManager, and give it its very own partition table. To make this
work, we need a special IPartitionOpener that will redirect requests for
"super" to our temporary device. A new .cpp file has been added to house
this. A few other tidbits have moved there as well.
This makes setup code a bit more complicated, but now our tests will
behave much closer to a real device.
Bug: 139204329
Test: libsnapshot_test gtest
Change-Id: I2f40109cd3c1d6343d6f52979789e25f9afd533a
Before ImageManager was introduced, gsid avoided using PartitionOpener
when writing to external media. PartitionOpener couldn't interact with
non-boot devices, because it prepends /dev/block/by-name. We hacked
around this in both gsid and in first-stage init, which manually detects
the problem and prepends /dev/block instead.
After the ImageManager refactoring, sdcard support broke in gsid,
because it started relying on PartitionOpener. Let's fix this by allowing
/dev/block for mmcblk* names in PartitionOpener.
Bug: 139204329
Test: fiemap_image_test gtest
Change-Id: Ic1cbdbe0a18fc09522ee38cc62b35fd8193ce250
The test suite is still quite buggy if interrupted. This fixes a number
of issues (such as bad ordering of setup calls), and refactors things to
add more ASSERTs.
Bug: 139204329
Test: libsnapshot_test gtest
Change-Id: I224608715c29f343b34512a9ac1143f0dde932e9
Convert the string field to an enum. We still write a string back to the
state file.
Bug: N/A
Test: libsnapshot_test gtest
Change-Id: I7cc1cb597dacd7d6faaaba05fb01c0a86bd54c8f
IPartitionOpener is useful for writing gtests, however, it can't easily
be used with CreateLogicalPartition. fs_mgr assumes the super partition
name will map to /dev/block/by-name/super whereas in tests we want to
redirect it to a different block device.
This CL makes two changes. First, it adds a new method to IPartitionOpener
to return a "device string" for a device name. The string must either be
an absolute path (for example /dev/block/by-name/super) or a major:minor
sequence, since device-mapper will accept either.
Second, CreateLogicalPartition now accepts an optional IPartitionOpener.
When converting block devices to paths, it uses the opener instead of
automatically prepending /dev/block/by-name.
Bug: 139204329
Test: liblp_test gtest
libsnapshot_test gtest
Change-Id: Id6b3120cc2ef5c0dd941b29ff96215ad3c8ec848
Beside using the 1% threshold for determining that a filesystem
should be an overlayfs candidate, do so also if the free space
is below 8MB. This will cover nearly empty filesystems that can
not be right-sized below the smallest ext4 filesystem size.
Adjust the test to cover the new cases.
Should test all system partitions, including new /system_ext and
any others that get added in the future.
Fix instance of dir that were supposed to be die. Using || die
does not work as expected within a function, so use if ! <cond>.
Test: adb-remount-test.sh
Bug: 139471424
Change-Id: If3e4cac5dce7bee998727052130eaf362e9e2fb5
For Virtual A/B devices, rename partitions / groups ending in
source slot to target slot, so that the metadata can later
be written to target metadata slot.
Test: liblp_test_static
Bug: 135752105
Change-Id: I6a7b25e8da2808b1831f317760f4345df6b22689
For Virtual A/B devices, we snapshot the partitions. Hence
there is no need to prioritize using the second half of super
partition for _b partitions.
Test: liblp_test_static
Bug: 135752105
Change-Id: I8bd669e6ffa0a4d114a1b386133179bd2819099b
Allow to retrieve name of a block device partition at
a certain index. If the index is out of range, return
empty string.
This is needed for an hypothetical edge case when an
intersection of two LinearExtent needs to be computed,
and the two metadata have a different list of block
device names. In reality, Virtual A/B devices are always
launched with dynamic partitions, so it will always return
"super" for index 0 and "" otherwise.
Test: liblp_test_static
Bug: 135752105
Change-Id: I9ea59edefdc41d0e69e3644aa2452676372938b4
Otherwise, DeleteDevice will just return false and it will
be stuck here.
Test: apply OTA after first boot, update_engine can unmap system_b
Bug: 135752105
Change-Id: If2b00336f4b948ba5f57a5e129fc070a739848fa
Converting all of them to string_view requires some
non-trivial amount of refactoring (because there is not
an implicit conversion from string_view to string), and
hence may be done later if necessary.
Test: builds
Bug: 135752105
Change-Id: I936ae7117500fadc7b34a5b91b279bc863d9919d
Introduce a parameter struct to eliminate parameter explosion, and refactor
existing callers to use the new helper.
Test: manual test
Bug: 135752105
Change-Id: I0c5ebe4e084ad7503c2ac6c65886a71505d50d00
The purpose of this is twofold. First, we need a way to detect whether
the device has booted into the new slot after an update. Second, we need
a quick-and-dirty test for first-stage init so it can avoid searching
for snapshots if it doesn't need to.
We can solve both of these problems by storing the source slot in
/metadata/ota/snapshot-boot. The existence of the file implies a more
complex check is needed, and the file stores the source slot.
Test: libsnapshot_test gtest
Bug: 139204329
Bug: 139089801
Change-Id: I919dd1c27a65734c61f3a9bdffefb32bdebd723b
It helps to fix a compilation issue with host libc:
core/fs_mgr/liblp/reader.cpp:252:9: error: use of undeclared identifier 'memcpy'; did you mean 'wmemcpy'?
memcpy(&partition, cursor, sizeof(partition));
^~~~~~
wmemcpy
Change-Id: I68f9c5b815b09f846aeba67bce0290f6829c80cf
For devices that do not have verity, or start the test with
verity disabled, but are using overlayfs, use a 'secret' surgical
technique to revert the device back to original state.
adb enable-verity will carry risk in that if the device did not
arrive with verity enabled, we can not guarantee it will boot
if we turn on verity.
Test: atest adb-remount-sh
Bug: 138649540
Change-Id: If6d55c57fb9daca9305c42a4df2c18c7f8c5eefa
Check for A/B /dev/block/by-name/system<slot> and also non-A/B
/dev/block/by-name/system to discover what /dev/root can be when
evaluating candidates for using overlayfs.
This is to handle a misconfigured (or legacy) system-as-root device.
It is recommended that the default fstab specifically mentions the
root mount's device node to prevent going down this path.
Test: adb-remount-test.sh
Bug: 138407617
Change-Id: I3853d203b9376d0f848cb490150ff00cc4ed3d5f
This implements InitiateMerge() and WaitForMerge(). InitiateMerge() is
meant to be called after an update has been marked successful.
WaitForMerge() is designed to be called either: immediately after
InitiateMerge, or during each subsequent boot where merging has not
completed.
InitiateMerge converts each snapshot device to a snapshot-merge device.
WaitForMerge polls each snapshot-merge device until no device reports a
"merging" state. One of the following states can result from this:
- MergeFailed. This will happen if any device failed to merge, or we
were unable to poll, or any other system-level failure occurred.
- MergeNeedsReboot. This will happen if a snapshot-merge device has
completed merging, but we were unable to clean it up due to something
holding a resource open.
- MergeCompleted. This indicates that all snapshots completed merging
and were cleaned up.
If WaitForMerge() returns MergeCompleted, then all snapshots have been
removed and a new update can begin. GetUpdateState() will return None.
MergeFailed and MergeNeedsReboot, on the other hand, are "sticky". They
indicate a merge is still pending. When called again, WaitForMerge()
will poll again to attempt to make more progress in the merge. For
NeedsReboot, a single reboot will ensure all resources are released and
the next WaitForMerge() will successfully finish cleanup. In the failure
case, it is unlikely the next WaitForMerge will succeed, but we always
retry anyway (there is no harm in doing so, and if we get lucky, the
device can take more OTAs).
Bug: 136678799
Test: libsnapshot_test gtests
Change-Id: I5e93fcbffee1973da5ff76363df12d6317a7a7c7
When we stopped unmapping snapshots in DeleteSnapshot, this also stopped
unmapping the COW device. Of course, the caller has no way to unmap this
since it's an implementation detail. Therefore unmap it in
DeleteSnapshot.
This scenario can arise after rewriting or removing a snapshot-merge
device.
Bug: 136678799
Test: manual test
Change-Id: I9d4c8bcfbb95b4454edd1cf0853d51b441e895fa
Per-snapshot locks don't solve any problems and add a great deal of
complexity. Instead, refactor the Read/WriteSnapshotStatus methods so
the caller just needs the snapshot name, and is not responsible for
opening a file.
As part of this change, callers of WriteSnapshotStatus must always take
an exclusive flock on the update state file. This is enforced by adding
a helper method to LockedFile to check the lock mode.
Bug: 136678799
Test: libsnapshot_test gtest
Change-Id: Icd580aaec7dfc916b3eed174d86b26688cd2291b
This CL fixes a bug where libsnapshot_test failed on the first run. It
also fixes bugs where it could not run if it died in the middle of a
test.
Previously, libsnapshot_test relied on CancelUpdate() to perform
cleanup, which cannot run in certain states. Instead, manually delete
dm devices and COW image files, and forcefully erase any lingering data.
Bug: 136678799
Test: libsnapshot_test gtest
Change-Id: I7b2399a403b387eb47184626e71dcf8674f6ab89
Move the logic for retrofit DAP to its new function. The new flow
in NewForUpdate is:
metadata = ReadMetadata();
if (retrofit dap) UpdateMetadataForOtherSuper(metadata)
return metadata;
Test: liblp_test_static
Change-Id: I6890fff3a7c44ebe2004de96b2ccbe1e8ce37546
kDefaultGroup is the 'default' group that is never deleted
and has no size constraints. During a virtual a/b update,
the following series of action happens:
- move partitions out of groups that will be shrunk / deleted
(into default)
- shrink / delete these groups
- grow / add other groups
- move those partitions to their destination group.
Otherwise, the metadata is inconsistent.
Bug: 138816109
Test: builds
Change-Id: I57cf4b44dda948377c6b3153756f469caa4652bc
It is hard to re-use this function in the merge code when it forcefully
unmaps the snapshot, because the snapshot may have been rewritten to be
a dm-linear device. Instead, leave the decision up to the caller.
Bug: 136678799
Test: libsnapshot_test gtest
Change-Id: I03c027c0781696885a5a5654d3049287cc16ecd0
Use dependency injection so that GetProperty / GetBoolProperty
can be mocked in tests.
Test: run liblp_test_static
Change-Id: I8efa85fbbd7aebce2541f748f840e512f3729c30
Change its type from std::string to constexpr char[] so that it does
not need to be constructed at runtime, which pollutes the bss page
unnecessarily.
Bug: 138856262
Test: Along with another fix for libbootloader_message.so, see that bss
section for libbootloader_message.so is now clean on cuttlefish
for several processes.
Change-Id: I1c8ff9cfeb25164a352cef89cfa7be889b3d3387
Changing the type of kDefaultGroup from std::string to std::string_view
allows us to make it a constexpr object. Since kDefaultGroup is the
only dirty object in liblp .bss at runtime, this change turns the .bss
page clean and thus saves 4KB per library load.
Bug: 138856262
Test: Boot cuttlefish and check liblp bss is clean for all 5 processes
that are using it.
Change-Id: I7d7c0992e0ab769f070807f24e1275ffed424b5b