Merge changes I169b52cf,Ieb0e4e24
* changes:
init: Add test for gentle_kill
init: Add gentle_kill service property
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index 610eebf..a4b9307 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -191,16 +191,30 @@
// Iterate over the endpoints for this interface and see if there
// are any that do bulk in/out.
- for (UInt8 endpoint = 1; endpoint <= interfaceNumEndpoints; endpoint++) {
+ for (UInt8 endpoint = 1; endpoint <= interfaceNumEndpoints; ++endpoint) {
UInt8 transferType;
- UInt16 maxPacketSize;
+ UInt16 endPointMaxPacketSize = 0;
UInt8 interval;
+
+ // Attempt to retrieve the 'true' packet-size from supported interface.
+ kr = (*interface)
+ ->GetEndpointProperties(interface, 0, endpoint,
+ kUSBOut,
+ &transferType,
+ &endPointMaxPacketSize, &interval);
+ if (kr == kIOReturnSuccess && !endPointMaxPacketSize) {
+ ERR("GetEndpointProperties() returned zero len packet-size");
+ }
+
+ UInt16 pipePropMaxPacketSize;
UInt8 number;
UInt8 direction;
+ // Proceed with extracting the transfer direction, so we can fill in the
+ // appropriate fields (bulkIn or bulkOut).
kr = (*interface)->GetPipeProperties(interface, endpoint,
&direction,
- &number, &transferType, &maxPacketSize, &interval);
+ &number, &transferType, &pipePropMaxPacketSize, &interval);
if (kr == 0) {
if (transferType != kUSBBulk) {
@@ -216,7 +230,8 @@
}
if (handle->info.ifc_protocol == 0x01) {
- handle->zero_mask = maxPacketSize - 1;
+ handle->zero_mask = (endPointMaxPacketSize == 0) ?
+ pipePropMaxPacketSize - 1 : endPointMaxPacketSize - 1;
}
} else {
ERR("could not get pipe properties for endpoint %u (%08x)\n", endpoint, kr);
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index cdff06e..9eb89b6 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -395,6 +395,10 @@
// first-stage to decide whether to launch snapuserd.
bool IsSnapuserdRequired();
+ // This is primarily used to device reboot. If OTA update is in progress,
+ // init will avoid killing processes
+ bool IsUserspaceSnapshotUpdateInProgress();
+
enum class SnapshotDriver {
DM_SNAPSHOT,
DM_USER,
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 6fed09c..10d2f18 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -4349,5 +4349,16 @@
return status.source_build_fingerprint();
}
+bool SnapshotManager::IsUserspaceSnapshotUpdateInProgress() {
+ auto slot = GetCurrentSlot();
+ if (slot == Slot::Target) {
+ if (IsSnapuserdRequired()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
} // namespace snapshot
} // namespace android
diff --git a/healthd/Android.bp b/healthd/Android.bp
index a090b74..76b6ad0 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -2,17 +2,8 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-cc_library_headers {
- name: "libhealthd_headers",
- vendor_available: true,
- recovery_available: true,
- export_include_dirs: ["include"],
- header_libs: ["libbatteryservice_headers"],
- export_header_lib_headers: ["libbatteryservice_headers"],
-}
-
-cc_library_static {
- name: "libbatterymonitor",
+cc_defaults {
+ name: "libbatterymonitor_defaults",
srcs: ["BatteryMonitor.cpp"],
cflags: ["-Wall", "-Werror"],
vendor_available: true,
@@ -25,6 +16,66 @@
// Need HealthInfo definition from headers of these shared
// libraries. Clients don't need to link to these.
"android.hardware.health@2.1",
+ ],
+ header_libs: ["libhealthd_headers"],
+ export_header_lib_headers: ["libhealthd_headers"],
+}
+
+cc_defaults {
+ name: "libhealthd_charger_ui_defaults",
+ vendor_available: true,
+ export_include_dirs: [
+ "include",
+ "include_charger",
+ ],
+
+ static_libs: [
+ "libcharger_sysprop",
+ "libhealthd_draw",
+ "libhealthloop",
+ "libminui",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libpng",
+ "libsuspend",
+ "libutils",
+ ],
+
+ header_libs: [
+ "libhealthd_headers",
+ ],
+
+ srcs: [
+ "healthd_mode_charger.cpp",
+ "AnimationParser.cpp",
+ ],
+
+ target: {
+ vendor: {
+ exclude_static_libs: [
+ "libcharger_sysprop",
+ ],
+ },
+ },
+}
+
+cc_library_headers {
+ name: "libhealthd_headers",
+ vendor_available: true,
+ recovery_available: true,
+ export_include_dirs: ["include"],
+ header_libs: ["libbatteryservice_headers"],
+ export_header_lib_headers: ["libbatteryservice_headers"],
+}
+
+cc_library_static {
+ name: "libbatterymonitor",
+ defaults: ["libbatterymonitor_defaults"],
+ static_libs: [
"android.hardware.health-V1-ndk",
],
whole_static_libs: [
@@ -32,8 +83,20 @@
// BatteryMonitor.
"android.hardware.health-translate-ndk",
],
- header_libs: ["libhealthd_headers"],
- export_header_lib_headers: ["libhealthd_headers"],
+}
+
+// TODO(b/251425963): remove when android.hardware.health is upgraded to V2.
+cc_library_static {
+ name: "libbatterymonitor-V1",
+ defaults: ["libbatterymonitor_defaults"],
+ static_libs: [
+ "android.hardware.health-V1-ndk",
+ ],
+ whole_static_libs: [
+ // Need to translate HIDL to AIDL to support legacy APIs in
+ // BatteryMonitor.
+ "android.hardware.health-translate-V1-ndk",
+ ],
}
cc_defaults {
@@ -136,50 +199,31 @@
cc_library_static {
name: "libhealthd_charger_ui",
- vendor_available: true,
- export_include_dirs: [
- "include",
- "include_charger",
- ],
+ defaults: ["libhealthd_charger_ui_defaults"],
static_libs: [
"android.hardware.health-V1-ndk",
"android.hardware.health-translate-ndk",
- "libcharger_sysprop",
- "libhealthd_draw",
- "libhealthloop",
- "libminui",
- ],
-
- shared_libs: [
- "libbase",
- "libcutils",
- "liblog",
- "libpng",
- "libsuspend",
- "libutils",
- ],
-
- header_libs: [
- "libhealthd_headers",
],
export_static_lib_headers: [
"android.hardware.health-V1-ndk",
],
+}
- srcs: [
- "healthd_mode_charger.cpp",
- "AnimationParser.cpp",
+// TODO(b/251425963): remove when android.hardware.health is upgraded to V2.
+cc_library_static {
+ name: "libhealthd_charger_ui-V1",
+ defaults: ["libhealthd_charger_ui_defaults"],
+
+ static_libs: [
+ "android.hardware.health-V1-ndk",
+ "android.hardware.health-translate-V1-ndk",
],
- target: {
- vendor: {
- exclude_static_libs: [
- "libcharger_sysprop",
- ],
- },
- },
+ export_static_lib_headers: [
+ "android.hardware.health-V1-ndk",
+ ],
}
cc_library_static {
diff --git a/init/apex_init_util.cpp b/init/apex_init_util.cpp
index d618a6e..c818f8f 100644
--- a/init/apex_init_util.cpp
+++ b/init/apex_init_util.cpp
@@ -18,7 +18,6 @@
#include <glob.h>
-#include <map>
#include <vector>
#include <android-base/logging.h>
@@ -66,18 +65,20 @@
}
static Result<void> ParseConfigs(const std::vector<std::string>& configs) {
- Parser parser = CreateApexConfigParser(ActionManager::GetInstance(),
- ServiceList::GetInstance());
- bool success = true;
+ Parser parser =
+ CreateApexConfigParser(ActionManager::GetInstance(), ServiceList::GetInstance());
+ std::vector<std::string> errors;
for (const auto& c : configs) {
- success &= parser.ParseConfigFile(c);
+ auto result = parser.ParseConfigFile(c);
+ // We should handle other config files even when there's an error.
+ if (!result.ok()) {
+ errors.push_back(result.error().message());
+ }
}
-
- if (success) {
- return {};
- } else {
- return Error() << "Unable to parse apex configs";
+ if (!errors.empty()) {
+ return Error() << "Unable to parse apex configs: " << base::Join(errors, "|");
}
+ return {};
}
Result<void> ParseApexConfigs(const std::string& apex_name) {
diff --git a/init/parser.cpp b/init/parser.cpp
index 0a388db..adb41ad 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -141,19 +141,19 @@
return true;
}
-bool Parser::ParseConfigFile(const std::string& path) {
+Result<void> Parser::ParseConfigFile(const std::string& path) {
LOG(INFO) << "Parsing file " << path << "...";
android::base::Timer t;
auto config_contents = ReadFile(path);
if (!config_contents.ok()) {
- LOG(INFO) << "Unable to read config file '" << path << "': " << config_contents.error();
- return false;
+ return Error() << "Unable to read config file '" << path
+ << "': " << config_contents.error();
}
ParseData(path, &config_contents.value());
LOG(VERBOSE) << "(Parsing " << path << " took " << t << ".)";
- return true;
+ return {};
}
bool Parser::ParseConfigDir(const std::string& path) {
@@ -176,8 +176,8 @@
// Sort first so we load files in a consistent order (bug 31996208)
std::sort(files.begin(), files.end());
for (const auto& file : files) {
- if (!ParseConfigFile(file)) {
- LOG(ERROR) << "could not import file '" << file << "'";
+ if (auto result = ParseConfigFile(file); !result.ok()) {
+ LOG(ERROR) << "could not import file '" << file << "': " << result.error();
}
}
return true;
@@ -187,7 +187,11 @@
if (is_dir(path.c_str())) {
return ParseConfigDir(path);
}
- return ParseConfigFile(path);
+ auto result = ParseConfigFile(path);
+ if (!result.ok()) {
+ LOG(INFO) << result.error();
+ }
+ return result.ok();
}
} // namespace init
diff --git a/init/parser.h b/init/parser.h
index 95b0cd7..980ae0c 100644
--- a/init/parser.h
+++ b/init/parser.h
@@ -72,7 +72,7 @@
Parser();
bool ParseConfig(const std::string& path);
- bool ParseConfigFile(const std::string& path);
+ Result<void> ParseConfigFile(const std::string& path);
void AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser);
void AddSingleLineParser(const std::string& prefix, LineCallback callback);
diff --git a/init/reboot.cpp b/init/reboot.cpp
index a3fc534..27a7876 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -51,6 +51,7 @@
#include <bootloader_message/bootloader_message.h>
#include <cutils/android_reboot.h>
#include <fs_mgr.h>
+#include <libsnapshot/snapshot.h>
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
#include <selinux/selinux.h>
@@ -422,11 +423,31 @@
if (run_fsck && !FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
return UMOUNT_STAT_ERROR;
}
-
+ auto sm = snapshot::SnapshotManager::New();
+ bool ota_update_in_progress = false;
+ if (sm->IsUserspaceSnapshotUpdateInProgress()) {
+ LOG(INFO) << "OTA update in progress";
+ ota_update_in_progress = true;
+ }
UmountStat stat = UmountPartitions(timeout - t.duration());
if (stat != UMOUNT_STAT_SUCCESS) {
LOG(INFO) << "umount timeout, last resort, kill all and try";
if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
+ // Since umount timedout, we will try to kill all processes
+ // and do one more attempt to umount the partitions.
+ //
+ // However, if OTA update is in progress, we don't want
+ // to kill the snapuserd daemon as the daemon will
+ // be serving I/O requests. Killing the daemon will
+ // end up with I/O failures. If the update is in progress,
+ // we will just return the umount failure status immediately.
+ // This is ok, given the fact that killing the processes
+ // and doing an umount is just a last effort. We are
+ // still not doing fsck when all processes are killed.
+ //
+ if (ota_update_in_progress) {
+ return stat;
+ }
KillAllProcesses();
// even if it succeeds, still it is timeout and do not run fsck with all processes killed
UmountStat st = UmountPartitions(0ms);
diff --git a/init/test_upgrade_mte/mte_upgrade_test_helper.cpp b/init/test_upgrade_mte/mte_upgrade_test_helper.cpp
index 3188337..6728cc6 100644
--- a/init/test_upgrade_mte/mte_upgrade_test_helper.cpp
+++ b/init/test_upgrade_mte/mte_upgrade_test_helper.cpp
@@ -60,6 +60,10 @@
if (prctl(PR_SET_TAGGED_ADDR_CTRL, res & ~PR_MTE_TCF_SYNC, 0, 0, 0) == -1) abort();
}
std::unique_ptr<volatile char[]> f(new char[1]);
+ // This out-of-bounds is on purpose: we are testing MTE, which is designed to turn
+ // out-of-bound errors into segfaults.
+ // This binary gets run by src/com/android/tests/init/MteUpgradeTest.java, which
+ // asserts that it crashes as expected.
f[17] = 'x';
char buf[1];
read(1, buf, 1);