Merge "Ignore functionfs mounts."
diff --git a/adb/Android.bp b/adb/Android.bp
index a557090..12d9a14 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -317,8 +317,8 @@
static_libs: [
"libadb_crypto",
"libadb_host",
- "libadb_pairing_auth",
- "libadb_pairing_connection",
+ "libadb_pairing_auth",
+ "libadb_pairing_connection",
"libadb_protos",
"libadb_tls_connection",
"libandroidfw",
diff --git a/adb/client/file_sync_client.cpp b/adb/client/file_sync_client.cpp
index 0844428..2ed58b2 100644
--- a/adb/client/file_sync_client.cpp
+++ b/adb/client/file_sync_client.cpp
@@ -42,7 +42,7 @@
#include "adb_client.h"
#include "adb_io.h"
#include "adb_utils.h"
-#include "brotli_utils.h"
+#include "compression_utils.h"
#include "file_sync_protocol.h"
#include "line_printer.h"
#include "sysdeps/errno.h"
@@ -580,8 +580,8 @@
while (true) {
Block output;
- BrotliEncodeResult result = encoder.Encode(&output);
- if (result == BrotliEncodeResult::Error) {
+ EncodeResult result = encoder.Encode(&output);
+ if (result == EncodeResult::Error) {
Error("compressing '%s' locally failed", lpath.c_str());
return false;
}
@@ -592,12 +592,12 @@
WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + output.size());
}
- if (result == BrotliEncodeResult::Done) {
+ if (result == EncodeResult::Done) {
sending = false;
break;
- } else if (result == BrotliEncodeResult::NeedInput) {
+ } else if (result == EncodeResult::NeedInput) {
break;
- } else if (result == BrotliEncodeResult::MoreOutput) {
+ } else if (result == EncodeResult::MoreOutput) {
continue;
}
}
@@ -1076,9 +1076,9 @@
while (true) {
std::span<char> output;
- BrotliDecodeResult result = decoder.Decode(&output);
+ DecodeResult result = decoder.Decode(&output);
- if (result == BrotliDecodeResult::Error) {
+ if (result == DecodeResult::Error) {
sc.Error("decompress failed");
adb_unlink(lpath);
return false;
@@ -1097,15 +1097,15 @@
sc.RecordBytesTransferred(msg.data.size);
sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, expected_size);
- if (result == BrotliDecodeResult::NeedInput) {
+ if (result == DecodeResult::NeedInput) {
break;
- } else if (result == BrotliDecodeResult::MoreOutput) {
+ } else if (result == DecodeResult::MoreOutput) {
continue;
- } else if (result == BrotliDecodeResult::Done) {
+ } else if (result == DecodeResult::Done) {
reading = false;
break;
} else {
- LOG(FATAL) << "invalid BrotliDecodeResult: " << static_cast<int>(result);
+ LOG(FATAL) << "invalid DecodeResult: " << static_cast<int>(result);
}
}
}
diff --git a/adb/brotli_utils.h b/adb/compression_utils.h
similarity index 88%
rename from adb/brotli_utils.h
rename to adb/compression_utils.h
index c5be73d..c445095 100644
--- a/adb/brotli_utils.h
+++ b/adb/compression_utils.h
@@ -23,7 +23,14 @@
#include "types.h"
-enum class BrotliDecodeResult {
+enum class DecodeResult {
+ Error,
+ Done,
+ NeedInput,
+ MoreOutput,
+};
+
+enum class EncodeResult {
Error,
Done,
NeedInput,
@@ -38,7 +45,7 @@
void Append(Block&& block) { input_buffer_.append(std::move(block)); }
- BrotliDecodeResult Decode(std::span<char>* output) {
+ DecodeResult Decode(std::span<char>* output) {
size_t available_in = input_buffer_.front_size();
const uint8_t* next_in = reinterpret_cast<const uint8_t*>(input_buffer_.front_data());
@@ -56,16 +63,16 @@
switch (r) {
case BROTLI_DECODER_RESULT_SUCCESS:
- return BrotliDecodeResult::Done;
+ return DecodeResult::Done;
case BROTLI_DECODER_RESULT_ERROR:
- return BrotliDecodeResult::Error;
+ return DecodeResult::Error;
case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
// Brotli guarantees as one of its invariants that if it returns NEEDS_MORE_INPUT,
// it will consume the entire input buffer passed in, so we don't have to worry
// about bytes left over in the front block with more input remaining.
- return BrotliDecodeResult::NeedInput;
+ return DecodeResult::NeedInput;
case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:
- return BrotliDecodeResult::MoreOutput;
+ return DecodeResult::MoreOutput;
}
}
@@ -75,13 +82,6 @@
std::unique_ptr<BrotliDecoderState, void (*)(BrotliDecoderState*)> decoder_;
};
-enum class BrotliEncodeResult {
- Error,
- Done,
- NeedInput,
- MoreOutput,
-};
-
template <size_t OutputBlockSize>
struct BrotliEncoder {
explicit BrotliEncoder()
@@ -95,7 +95,7 @@
void Append(Block input) { input_buffer_.append(std::move(input)); }
void Finish() { finished_ = true; }
- BrotliEncodeResult Encode(Block* output) {
+ EncodeResult Encode(Block* output) {
output->clear();
while (true) {
size_t available_in = input_buffer_.front_size();
@@ -112,7 +112,7 @@
if (!BrotliEncoderCompressStream(encoder_.get(), op, &available_in, &next_in,
&available_out, &next_out, nullptr)) {
- return BrotliEncodeResult::Error;
+ return EncodeResult::Error;
}
size_t bytes_consumed = input_buffer_.front_size() - available_in;
@@ -123,14 +123,14 @@
if (BrotliEncoderIsFinished(encoder_.get())) {
output_block_.resize(OutputBlockSize - output_bytes_left_);
*output = std::move(output_block_);
- return BrotliEncodeResult::Done;
+ return EncodeResult::Done;
} else if (output_bytes_left_ == 0) {
*output = std::move(output_block_);
output_block_.resize(OutputBlockSize);
output_bytes_left_ = OutputBlockSize;
- return BrotliEncodeResult::MoreOutput;
+ return EncodeResult::MoreOutput;
} else if (input_buffer_.empty()) {
- return BrotliEncodeResult::NeedInput;
+ return EncodeResult::NeedInput;
}
}
}
diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp
index 07f6e65..5ccddea 100644
--- a/adb/daemon/file_sync_service.cpp
+++ b/adb/daemon/file_sync_service.cpp
@@ -57,7 +57,7 @@
#include "adb_io.h"
#include "adb_trace.h"
#include "adb_utils.h"
-#include "brotli_utils.h"
+#include "compression_utils.h"
#include "file_sync_protocol.h"
#include "security_log_tags.h"
#include "sysdeps/errno.h"
@@ -288,8 +288,8 @@
while (true) {
std::span<char> output;
- BrotliDecodeResult result = decoder.Decode(&output);
- if (result == BrotliDecodeResult::Error) {
+ DecodeResult result = decoder.Decode(&output);
+ if (result == DecodeResult::Error) {
SendSyncFailErrno(s, "decompress failed");
return false;
}
@@ -299,14 +299,14 @@
return false;
}
- if (result == BrotliDecodeResult::NeedInput) {
+ if (result == DecodeResult::NeedInput) {
break;
- } else if (result == BrotliDecodeResult::MoreOutput) {
+ } else if (result == DecodeResult::MoreOutput) {
continue;
- } else if (result == BrotliDecodeResult::Done) {
+ } else if (result == DecodeResult::Done) {
break;
} else {
- LOG(FATAL) << "invalid BrotliDecodeResult: " << static_cast<int>(result);
+ LOG(FATAL) << "invalid DecodeResult: " << static_cast<int>(result);
}
}
}
@@ -591,7 +591,6 @@
static bool recv_uncompressed(borrowed_fd s, unique_fd fd, std::vector<char>& buffer) {
syncmsg msg;
msg.data.id = ID_DATA;
- std::optional<BrotliEncoder<SYNC_DATA_MAX>> encoder;
while (true) {
int r = adb_read(fd.get(), &buffer[0], buffer.size() - sizeof(msg.data));
if (r <= 0) {
@@ -633,8 +632,8 @@
while (true) {
Block output;
- BrotliEncodeResult result = encoder.Encode(&output);
- if (result == BrotliEncodeResult::Error) {
+ EncodeResult result = encoder.Encode(&output);
+ if (result == EncodeResult::Error) {
SendSyncFailErrno(s, "compress failed");
return false;
}
@@ -647,12 +646,12 @@
}
}
- if (result == BrotliEncodeResult::Done) {
+ if (result == EncodeResult::Done) {
sending = false;
break;
- } else if (result == BrotliEncodeResult::NeedInput) {
+ } else if (result == EncodeResult::NeedInput) {
break;
- } else if (result == BrotliEncodeResult::MoreOutput) {
+ } else if (result == EncodeResult::MoreOutput) {
continue;
}
}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index a9c1676..5d6cee4 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -1238,16 +1238,26 @@
// Shift last_reboot_reason_property to last_last_reboot_reason_property
std::string last_boot_reason;
if (!android::base::ReadFileToString(last_reboot_reason_file, &last_boot_reason)) {
+ PLOG(ERROR) << "Failed to read " << last_reboot_reason_file;
last_boot_reason = android::base::GetProperty(last_reboot_reason_property, "");
+ LOG(INFO) << "Value of " << last_reboot_reason_property << " : " << last_boot_reason;
+ } else {
+ LOG(INFO) << "Last reboot reason read from " << last_reboot_reason_file << " : "
+ << last_boot_reason << ". Last reboot reason read from "
+ << last_reboot_reason_property << " : "
+ << android::base::GetProperty(last_reboot_reason_property, "");
}
if (last_boot_reason.empty() || isKernelRebootReason(system_boot_reason)) {
last_boot_reason = system_boot_reason;
} else {
transformReason(last_boot_reason);
}
+ LOG(INFO) << "Normalized last reboot reason : " << last_boot_reason;
android::base::SetProperty(last_last_reboot_reason_property, last_boot_reason);
android::base::SetProperty(last_reboot_reason_property, "");
- unlink(last_reboot_reason_file);
+ if (unlink(last_reboot_reason_file) != 0) {
+ PLOG(ERROR) << "Failed to unlink " << last_reboot_reason_file;
+ }
}
// Gets the boot time offset. This is useful when Android is running in a
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index a836d3b..b218f21 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -829,6 +829,20 @@
return std::set<std::string>(boot_devices.begin(), boot_devices.end());
}
+ std::string cmdline;
+ if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
+ std::set<std::string> boot_devices;
+ const std::string cmdline_key = "androidboot.boot_device";
+ for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) {
+ if (key == cmdline_key) {
+ boot_devices.emplace(value);
+ }
+ }
+ if (!boot_devices.empty()) {
+ return boot_devices;
+ }
+ }
+
// Fallback to extract boot devices from fstab.
Fstab fstab;
if (!ReadDefaultFstab(&fstab)) {
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 655b8de..842b2e5 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -47,6 +47,7 @@
#include <thread>
#include <vector>
+#include <InitProperties.sysprop.h>
#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -85,6 +86,7 @@
using android::properties::ParsePropertyInfoFile;
using android::properties::PropertyInfoAreaFile;
using android::properties::PropertyInfoEntry;
+using android::sysprop::InitProperties::is_userspace_reboot_supported;
namespace android {
namespace init {
@@ -492,6 +494,10 @@
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;
+ }
}
// If a process other than init is writing a non-empty value, it means that process is
diff --git a/init/property_service_test.cpp b/init/property_service_test.cpp
index 0f4cd0d..c6dcfa2 100644
--- a/init/property_service_test.cpp
+++ b/init/property_service_test.cpp
@@ -22,8 +22,10 @@
#include <sys/_system_properties.h>
#include <android-base/properties.h>
+#include <android-base/scopeguard.h>
#include <gtest/gtest.h>
+using android::base::GetProperty;
using android::base::SetProperty;
namespace android {
@@ -74,5 +76,19 @@
EXPECT_TRUE(SetProperty("property_service_utf8_test", "\xF0\x90\x80\x80"));
}
+TEST(property_service, userspace_reboot_not_supported) {
+ if (getuid() != 0) {
+ GTEST_SKIP() << "Skipping test, must be run as root.";
+ return;
+ }
+ const std::string original_value = GetProperty("init.userspace_reboot.is_supported", "");
+ auto guard = android::base::make_scope_guard([&original_value]() {
+ SetProperty("init.userspace_reboot.is_supported", original_value);
+ });
+
+ ASSERT_TRUE(SetProperty("init.userspace_reboot.is_supported", "false"));
+ EXPECT_FALSE(SetProperty("sys.powerctl", "reboot,userspace"));
+}
+
} // namespace init
} // namespace android
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 2351afa..5efe03f 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -529,6 +529,10 @@
free(buf);
} else if (opthdr->nd_opt_type == ND_OPT_DNSSL) {
// TODO: support DNSSL.
+ } else if (opthdr->nd_opt_type == ND_OPT_CAPTIVE_PORTAL) {
+ // TODO: support CAPTIVE PORTAL.
+ } else if (opthdr->nd_opt_type == ND_OPT_PREF64) {
+ // TODO: support PREF64.
} else {
SLOGD("Unknown ND option type %d\n", opthdr->nd_opt_type);
return false;