Merge UP1A.230309.002

Change-Id: I0c898c65b8be0b0f1928c01d14ee8c240b5b0a45
This commit is contained in:
Erik Sanders 2023-03-16 20:34:54 +00:00
commit 62fc3ba439
8 changed files with 69 additions and 47 deletions

View File

@ -159,7 +159,8 @@ noinline void sigsegv_non_null() {
}
noinline void fprintf_null() {
fprintf(nullptr, "oops");
FILE* sneaky_null = nullptr;
fprintf(sneaky_null, "oops");
}
noinline void readdir_null() {

View File

@ -3216,6 +3216,8 @@ Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manife
vabc_disable_reason = "recovery";
} else if (!cow_format_support) {
vabc_disable_reason = "cow format not supported";
} else if (!KernelSupportsCompressedSnapshots()) {
vabc_disable_reason = "kernel missing userspace block device support";
}
if (!vabc_disable_reason.empty()) {

View File

@ -124,6 +124,10 @@ class SnapshotTest : public ::testing::Test {
SKIP_IF_NON_VIRTUAL_AB();
SetupProperties();
if (!DeviceSupportsMode()) {
GTEST_SKIP() << "Mode not supported on this device";
}
InitializeState();
CleanupTestArtifacts();
FormatFakeSuper();
@ -159,7 +163,13 @@ class SnapshotTest : public ::testing::Test {
IPropertyFetcher::OverrideForTesting(std::move(fetcher));
if (GetLegacyCompressionEnabledProperty() || CanUseUserspaceSnapshots()) {
snapuserd_required_ = true;
// If we're asked to test the device's actual configuration, then it
// may be misconfigured, so check for kernel support as libsnapshot does.
if (FLAGS_force_mode.empty()) {
snapuserd_required_ = KernelSupportsCompressedSnapshots();
} else {
snapuserd_required_ = true;
}
}
}
@ -176,6 +186,16 @@ class SnapshotTest : public ::testing::Test {
LOG(INFO) << "Teardown complete for test: " << test_name_;
}
bool DeviceSupportsMode() {
if (FLAGS_force_mode.empty()) {
return true;
}
if (snapuserd_required_ && !KernelSupportsCompressedSnapshots()) {
return false;
}
return true;
}
void InitializeState() {
ASSERT_TRUE(sm->EnsureImageManager());
image_manager_ = sm->image_manager();
@ -193,6 +213,11 @@ class SnapshotTest : public ::testing::Test {
// get an accurate list to remove.
lock_ = nullptr;
// If there is no image manager, the test was skipped.
if (!image_manager_) {
return;
}
std::vector<std::string> snapshots = {"test-snapshot", "test_partition_a",
"test_partition_b"};
for (const auto& snapshot : snapshots) {
@ -946,6 +971,11 @@ class SnapshotUpdateTest : public SnapshotTest {
SKIP_IF_NON_VIRTUAL_AB();
SnapshotTest::SetUp();
if (!image_manager_) {
// Test was skipped.
return;
}
Cleanup();
// Cleanup() changes slot suffix, so initialize it again.
@ -2680,6 +2710,9 @@ class ImageManagerTest : public SnapshotTest {
CleanUp();
}
void CleanUp() {
if (!image_manager_) {
return;
}
EXPECT_TRUE(!image_manager_->BackingImageExists(kImageName) ||
image_manager_->DeleteBackingImage(kImageName));
}

View File

@ -29,6 +29,7 @@
#include <fs_mgr/roots.h>
#include <liblp/property_fetcher.h>
using android::dm::DeviceMapper;
using android::dm::kSectorSize;
using android::fiemap::FiemapStatus;
using android::fs_mgr::EnsurePathMounted;
@ -251,7 +252,10 @@ bool CanUseUserspaceSnapshots() {
LOG(INFO) << "Userspace snapshots disabled for testing";
return false;
}
if (!KernelSupportsCompressedSnapshots()) {
LOG(ERROR) << "Userspace snapshots requested, but no kernel support is available.";
return false;
}
return true;
}
@ -278,5 +282,10 @@ bool IsDmSnapshotTestingEnabled() {
return fetcher->GetBoolProperty("snapuserd.test.dm.snapshots", false);
}
bool KernelSupportsCompressedSnapshots() {
auto& dm = DeviceMapper::Instance();
return dm.GetTargetByName("user", nullptr);
}
} // namespace snapshot
} // namespace android

View File

@ -127,6 +127,8 @@ std::ostream& operator<<(std::ostream& os, const Now&);
void AppendExtent(google::protobuf::RepeatedPtrField<chromeos_update_engine::Extent>* extents,
uint64_t start_block, uint64_t num_blocks);
bool KernelSupportsCompressedSnapshots();
bool GetLegacyCompressionEnabledProperty();
bool GetUserspaceSnapshotsEnabledProperty();
bool GetIouringEnabledProperty();

View File

@ -261,48 +261,21 @@ static class ShutdownState {
WakeMainInitThread();
}
std::optional<std::string> CheckShutdown() {
std::optional<std::string> CheckShutdown() __attribute__((warn_unused_result)) {
auto lock = std::lock_guard{shutdown_command_lock_};
if (do_shutdown_ && !IsShuttingDown()) {
do_shutdown_ = false;
return shutdown_command_;
}
return {};
}
bool do_shutdown() const { return do_shutdown_; }
void set_do_shutdown(bool value) { do_shutdown_ = value; }
private:
std::mutex shutdown_command_lock_;
std::string shutdown_command_ GUARDED_BY(shutdown_command_lock_);
bool do_shutdown_ = false;
} shutdown_state;
static void UnwindMainThreadStack() {
unwindstack::AndroidLocalUnwinder unwinder;
unwindstack::AndroidUnwinderData data;
if (!unwinder.Unwind(data)) {
LOG(ERROR) << __FUNCTION__
<< "sys.powerctl: Failed to unwind callstack: " << data.GetErrorString();
}
for (const auto& frame : data.frames) {
LOG(ERROR) << "sys.powerctl: " << unwinder.FormatFrame(frame);
}
}
void DebugRebootLogging() {
LOG(INFO) << "sys.powerctl: do_shutdown: " << shutdown_state.do_shutdown()
<< " IsShuttingDown: " << IsShuttingDown();
if (shutdown_state.do_shutdown()) {
LOG(ERROR) << "sys.powerctl set while a previous shutdown command has not been handled";
UnwindMainThreadStack();
}
if (IsShuttingDown()) {
LOG(ERROR) << "sys.powerctl set while init is already shutting down";
UnwindMainThreadStack();
}
}
void DumpState() {
ServiceList::GetInstance().DumpState();
ActionManager::GetInstance().DumpState();
@ -1138,36 +1111,43 @@ int SecondStageMain(int argc, char** argv) {
// Restore prio before main loop
setpriority(PRIO_PROCESS, 0, 0);
while (true) {
// By default, sleep until something happens.
std::optional<std::chrono::milliseconds> epoll_timeout;
// By default, sleep until something happens. Do not convert far_future into
// std::chrono::milliseconds because that would trigger an overflow. The unit of boot_clock
// is 1ns.
const boot_clock::time_point far_future = boot_clock::time_point::max();
boot_clock::time_point next_action_time = far_future;
auto shutdown_command = shutdown_state.CheckShutdown();
if (shutdown_command) {
LOG(INFO) << "Got shutdown_command '" << *shutdown_command
<< "' Calling HandlePowerctlMessage()";
HandlePowerctlMessage(*shutdown_command);
shutdown_state.set_do_shutdown(false);
}
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) {
next_action_time = boot_clock::now();
}
}
// Since the above code examined pending actions, no new actions must be
// queued by the code between this line and the Epoll::Wait() call below
// without calling WakeMainInitThread().
if (!IsShuttingDown()) {
auto next_process_action_time = HandleProcessActions();
// If there's a process that needs restarting, wake up in time for that.
if (next_process_action_time) {
epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
*next_process_action_time - boot_clock::now());
if (epoll_timeout < 0ms) epoll_timeout = 0ms;
next_action_time = std::min(next_action_time, *next_process_action_time);
}
}
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout = 0ms;
std::optional<std::chrono::milliseconds> epoll_timeout;
if (next_action_time != far_future) {
epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
std::max(next_action_time - boot_clock::now(), 0ns));
}
auto epoll_result = epoll.Wait(epoll_timeout);
if (!epoll_result.ok()) {
LOG(ERROR) << epoll_result.error();

View File

@ -42,8 +42,6 @@ void SendLoadPersistentPropertiesMessage();
void PropertyChanged(const std::string& name, const std::string& value);
bool QueueControlMessage(const std::string& message, const std::string& name, pid_t pid, int fd);
void DebugRebootLogging();
int SecondStageMain(int argc, char** argv);
int StopServicesFromApex(const std::string& apex_name);

View File

@ -552,9 +552,6 @@ std::optional<uint32_t> HandlePropertySet(const std::string& name, const std::st
}
LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid
<< process_log_string;
if (!value.empty()) {
DebugRebootLogging();
}
if (value == "reboot,userspace" && !is_userspace_reboot_supported().value_or(false)) {
*error = "Userspace reboot is not supported by this device";
return {PROP_ERROR_INVALID_VALUE};