Merge changes from topic "logcatd-shell"
* changes:
logcat: fix logpersist.stop and logpersist.clear
logcat: fix logcatd / logpersist
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index f452a64..02a887e 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -122,6 +122,7 @@
shared_libs: [
"android.hardware.boot@1.0",
+ "android.hardware.boot@1.1",
"android.hardware.fastboot@1.0",
"android.hardware.health@2.0",
"libadbd",
diff --git a/fastboot/constants.h b/fastboot/constants.h
index 8a72627..7fba67c 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -34,6 +34,7 @@
#define FB_CMD_UPDATE_SUPER "update-super"
#define FB_CMD_OEM "oem"
#define FB_CMD_GSI "gsi"
+#define FB_CMD_SNAPSHOT_UPDATE "snapshot-update"
#define RESPONSE_OKAY "OKAY"
#define RESPONSE_FAIL "FAIL"
@@ -66,3 +67,4 @@
#define FB_VAR_BATTERY_VOLTAGE "battery-voltage"
#define FB_VAR_BATTERY_SOC_OK "battery-soc-ok"
#define FB_VAR_SUPER_PARTITION_NAME "super-partition-name"
+#define FB_VAR_SNAPSHOT_UPDATE_STATUS "snapshot-update-status"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 4c77c75..dfd5690 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -25,6 +25,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
#include <cutils/android_reboot.h>
#include <ext4_utils/wipe.h>
#include <fs_mgr.h>
@@ -44,8 +45,10 @@
using ::android::hardware::boot::V1_0::BoolResult;
using ::android::hardware::boot::V1_0::CommandResult;
using ::android::hardware::boot::V1_0::Slot;
+using ::android::hardware::boot::V1_1::MergeStatus;
using ::android::hardware::fastboot::V1_0::Result;
using ::android::hardware::fastboot::V1_0::Status;
+using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
struct VariableHandlers {
// Callback to retrieve the value of a single variable.
@@ -101,7 +104,8 @@
{FB_VAR_BATTERY_VOLTAGE, {GetBatteryVoltage, nullptr}},
{FB_VAR_BATTERY_SOC_OK, {GetBatterySoCOk, nullptr}},
{FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}},
- {FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}}};
+ {FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}},
+ {FB_VAR_SNAPSHOT_UPDATE_STATUS, {GetSnapshotUpdateStatus, nullptr}}};
if (args.size() < 2) {
return device->WriteFail("Missing argument");
@@ -547,3 +551,40 @@
}
return device->WriteStatus(FastbootResult::OKAY, "Success");
}
+
+bool SnapshotUpdateHandler(FastbootDevice* device, const std::vector<std::string>& args) {
+ // Note that we use the HAL rather than mounting /metadata, since we want
+ // our results to match the bootloader.
+ auto hal = device->boot_control_hal();
+ if (!hal) return device->WriteFail("Not supported");
+
+ android::sp<IBootControl1_1> hal11 = IBootControl1_1::castFrom(hal);
+ if (!hal11) return device->WriteFail("Not supported");
+
+ // If no arguments, return the same thing as a getvar. Note that we get the
+ // HAL first so we can return "not supported" before we return the less
+ // specific error message below.
+ if (args.size() < 2 || args[1].empty()) {
+ std::string message;
+ if (!GetSnapshotUpdateStatus(device, {}, &message)) {
+ return device->WriteFail("Could not determine update status");
+ }
+ device->WriteInfo(message);
+ return device->WriteOkay("");
+ }
+
+ if (args.size() != 2 || args[1] != "cancel") {
+ return device->WriteFail("Invalid arguments");
+ }
+
+ MergeStatus status = hal11->getSnapshotMergeStatus();
+ switch (status) {
+ case MergeStatus::SNAPSHOTTED:
+ case MergeStatus::MERGING:
+ hal11->setSnapshotMergeStatus(MergeStatus::CANCELLED);
+ break;
+ default:
+ break;
+ }
+ return device->WriteStatus(FastbootResult::OKAY, "Success");
+}
diff --git a/fastboot/device/commands.h b/fastboot/device/commands.h
index 9b6e7b6..c1324bc 100644
--- a/fastboot/device/commands.h
+++ b/fastboot/device/commands.h
@@ -49,3 +49,4 @@
bool UpdateSuperHandler(FastbootDevice* device, const std::vector<std::string>& args);
bool OemCmdHandler(FastbootDevice* device, const std::vector<std::string>& args);
bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args);
+bool SnapshotUpdateHandler(FastbootDevice* device, const std::vector<std::string>& args);
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 56fafab..d3c2bda 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -54,6 +54,7 @@
{FB_CMD_UPDATE_SUPER, UpdateSuperHandler},
{FB_CMD_OEM, OemCmdHandler},
{FB_CMD_GSI, GsiHandler},
+ {FB_CMD_SNAPSHOT_UPDATE, SnapshotUpdateHandler},
}),
transport_(std::make_unique<ClientUsbTransport>()),
boot_control_hal_(IBootControl::getService()),
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index 130a3cf..6e613d6 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -23,6 +23,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
#include <ext4_utils/ext4_utils.h>
#include <fs_mgr.h>
#include <healthhalutils/HealthHalUtils.h>
@@ -34,9 +35,11 @@
using ::android::hardware::boot::V1_0::BoolResult;
using ::android::hardware::boot::V1_0::Slot;
+using ::android::hardware::boot::V1_1::MergeStatus;
using ::android::hardware::fastboot::V1_0::FileSystemType;
using ::android::hardware::fastboot::V1_0::Result;
using ::android::hardware::fastboot::V1_0::Status;
+using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
using namespace android::fs_mgr;
constexpr char kFastbootProtocolVersion[] = "0.4";
@@ -424,3 +427,34 @@
*message = fs_mgr_get_super_partition_name(slot_number);
return true;
}
+
+bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& /* args */,
+ std::string* message) {
+ // Note that we use the HAL rather than mounting /metadata, since we want
+ // our results to match the bootloader.
+ auto hal = device->boot_control_hal();
+ if (!hal) {
+ *message = "not supported";
+ return false;
+ }
+
+ android::sp<IBootControl1_1> hal11 = IBootControl1_1::castFrom(hal);
+ if (!hal11) {
+ *message = "not supported";
+ return false;
+ }
+
+ MergeStatus status = hal11->getSnapshotMergeStatus();
+ switch (status) {
+ case MergeStatus::SNAPSHOTTED:
+ *message = "snapshotted";
+ break;
+ case MergeStatus::MERGING:
+ *message = "merging";
+ break;
+ default:
+ *message = "none";
+ break;
+ }
+ return true;
+}
diff --git a/fastboot/device/variables.h b/fastboot/device/variables.h
index 015a4c5..4dec10f 100644
--- a/fastboot/device/variables.h
+++ b/fastboot/device/variables.h
@@ -61,6 +61,8 @@
std::string* message);
bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& args,
std::string* message);
+bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& args,
+ std::string* message);
// Helpers for getvar all.
std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device);
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 2fe3b1a..7ce7c7c 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -396,6 +396,9 @@
" gsi wipe|disable Wipe or disable a GSI installation (fastbootd only).\n"
" wipe-super [SUPER_EMPTY] Wipe the super partition. This will reset it to\n"
" contain an empty set of default dynamic partitions.\n"
+ " snapshot-update cancel On devices that support snapshot-based updates, cancel\n"
+ " an in-progress update. This may make the device\n"
+ " unbootable until it is reflashed.\n"
"\n"
"boot image:\n"
" boot KERNEL [RAMDISK [SECOND]]\n"
@@ -1216,6 +1219,14 @@
target_sparse_limit = -1;
}
+static void CancelSnapshotIfNeeded() {
+ std::string merge_status = "none";
+ if (fb->GetVar(FB_VAR_SNAPSHOT_UPDATE_STATUS, &merge_status) == fastboot::SUCCESS &&
+ merge_status != "none") {
+ fb->SnapshotUpdateCommand("Cancel");
+ }
+}
+
class ImageSource {
public:
virtual bool ReadFile(const std::string& name, std::vector<char>* out) const = 0;
@@ -1268,6 +1279,8 @@
DetermineSecondarySlot();
CollectImages();
+ CancelSnapshotIfNeeded();
+
// First flash boot partitions. We allow this to happen either in userspace
// or in bootloader fastboot.
FlashImages(boot_images_);
@@ -2071,12 +2084,24 @@
image = next_arg(&args);
}
do_wipe_super(image, slot_override);
+ } else if (command == "snapshot-update") {
+ std::string arg;
+ if (!args.empty()) {
+ arg = next_arg(&args);
+ }
+ if (!arg.empty() && arg != "cancel") {
+ syntax_error("expected: snapshot-update [cancel]");
+ }
+ fb->SnapshotUpdateCommand(arg);
} else {
syntax_error("unknown command %s", command.c_str());
}
}
if (wants_wipe) {
+ if (force_flash) {
+ CancelSnapshotIfNeeded();
+ }
std::vector<std::string> partitions = { "userdata", "cache", "metadata" };
for (const auto& partition : partitions) {
std::string partition_type;
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index b897182..6a5ad20 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -122,6 +122,12 @@
response, info);
}
+RetCode FastBootDriver::SnapshotUpdateCommand(const std::string& command, std::string* response,
+ std::vector<std::string>* info) {
+ std::string raw = FB_CMD_SNAPSHOT_UPDATE ":" + command;
+ return RawCommand(raw, response, info);
+}
+
RetCode FastBootDriver::FlashPartition(const std::string& partition,
const std::vector<char>& data) {
RetCode ret;
diff --git a/fastboot/fastboot_driver.h b/fastboot/fastboot_driver.h
index af02637..7265632 100644
--- a/fastboot/fastboot_driver.h
+++ b/fastboot/fastboot_driver.h
@@ -104,6 +104,8 @@
std::vector<std::string>* info = nullptr);
RetCode Upload(const std::string& outfile, std::string* response = nullptr,
std::vector<std::string>* info = nullptr);
+ RetCode SnapshotUpdateCommand(const std::string& command, std::string* response = nullptr,
+ std::vector<std::string>* info = nullptr);
/* HIGHER LEVEL COMMANDS -- Composed of the commands above */
RetCode FlashPartition(const std::string& partition, const std::vector<char>& data);
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 65f0eff..eb737bb 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -74,6 +74,7 @@
"liblogwrap",
"libdm",
"libext2_uuid",
+ "libfscrypt",
"libfstab",
],
cppflags: [
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 6faead0..a8059b7 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -58,6 +58,7 @@
#include <fs_avb/fs_avb.h>
#include <fs_mgr/file_wait.h>
#include <fs_mgr_overlayfs.h>
+#include <fscrypt/fscrypt.h>
#include <libdm/dm.h>
#include <liblp/metadata_format.h>
#include <linux/fs.h>
@@ -84,6 +85,9 @@
#define SYSFS_EXT4_VERITY "/sys/fs/ext4/features/verity"
+// FIXME: this should be in system/extras
+#define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800
+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
using android::base::Basename;
@@ -412,25 +416,43 @@
// Enable file-based encryption if needed.
static void tune_encrypt(const std::string& blk_device, const FstabEntry& entry,
const struct ext4_super_block* sb, int* fs_stat) {
- bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0;
- bool want_encrypt = entry.fs_mgr_flags.file_encryption;
-
- if (has_encrypt || !want_encrypt) {
+ if (!entry.fs_mgr_flags.file_encryption) {
+ return; // Nothing needs done.
+ }
+ std::vector<std::string> features_needed;
+ if ((sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) == 0) {
+ features_needed.emplace_back("encrypt");
+ }
+ android::fscrypt::EncryptionOptions options;
+ if (!android::fscrypt::ParseOptions(entry.encryption_options, &options)) {
+ LERROR << "Unable to parse encryption options on " << blk_device << ": "
+ << entry.encryption_options;
return;
}
-
+ if ((options.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) != 0) {
+ // We can only use this policy on ext4 if the "stable_inodes" feature
+ // is set on the filesystem, otherwise shrinking will break encrypted files.
+ if ((sb->s_feature_compat & cpu_to_le32(EXT4_FEATURE_COMPAT_STABLE_INODES)) == 0) {
+ features_needed.emplace_back("stable_inodes");
+ }
+ }
+ if (features_needed.size() == 0) {
+ return;
+ }
if (!tune2fs_available()) {
LERROR << "Unable to enable ext4 encryption on " << blk_device
<< " because " TUNE2FS_BIN " is missing";
return;
}
- const char* argv[] = {TUNE2FS_BIN, "-Oencrypt", blk_device.c_str()};
+ auto flags = android::base::Join(features_needed, ',');
+ auto flag_arg = "-O"s + flags;
+ const char* argv[] = {TUNE2FS_BIN, flag_arg.c_str(), blk_device.c_str()};
- LINFO << "Enabling ext4 encryption on " << blk_device;
+ LINFO << "Enabling ext4 flags " << flags << " on " << blk_device;
if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
LERROR << "Failed to run " TUNE2FS_BIN " to enable "
- << "ext4 encryption on " << blk_device;
+ << "ext4 flags " << flags << " on " << blk_device;
*fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED;
}
}
diff --git a/fs_mgr/libsnapshot/utility.cpp b/fs_mgr/libsnapshot/utility.cpp
index 615cbca..1b2f528 100644
--- a/fs_mgr/libsnapshot/utility.cpp
+++ b/fs_mgr/libsnapshot/utility.cpp
@@ -19,6 +19,7 @@
#include <android-base/strings.h>
#include <fs_mgr/roots.h>
+using android::dm::kSectorSize;
using android::fs_mgr::EnsurePathMounted;
using android::fs_mgr::EnsurePathUnmounted;
using android::fs_mgr::Fstab;
@@ -94,13 +95,11 @@
// so it can be used to resume the last state of a snapshot device;
// - an _INVALID_ snapshot otherwise.
// To avoid zero-filling the whole CoW file when a new dm-snapshot is
- // created, here we zero-fill only the first 32 bits. This is a temporary
- // workaround that will be discussed again when the kernel API gets
- // consolidated.
- // TODO(b/139202197): Remove this hack once the kernel API is consolidated.
- constexpr ssize_t kDmSnapZeroFillSize = 4; // 32-bit
+ // created, here we zero-fill only the first chunk to be compliant with
+ // lvm.
+ constexpr ssize_t kDmSnapZeroFillSize = kSectorSize * kSnapshotChunkSize;
- char zeros[kDmSnapZeroFillSize] = {0};
+ std::vector<uint8_t> zeros(kDmSnapZeroFillSize, 0);
android::base::unique_fd fd(open(device.c_str(), O_WRONLY | O_BINARY));
if (fd < 0) {
PLOG(ERROR) << "Can't open COW device: " << device;
@@ -108,7 +107,7 @@
}
LOG(INFO) << "Zero-filling COW device: " << device;
- if (!android::base::WriteFully(fd, zeros, kDmSnapZeroFillSize)) {
+ if (!android::base::WriteFully(fd, zeros.data(), kDmSnapZeroFillSize)) {
PLOG(ERROR) << "Can't zero-fill COW device for " << device;
return false;
}
diff --git a/init/Android.bp b/init/Android.bp
index bd2d38c..776a3a6 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -79,7 +79,6 @@
"libdl",
"libext4_utils",
"libfs_mgr",
- "libfscrypt",
"libgsi",
"libhidl-gen-utils",
"libkeyutils",
diff --git a/init/Android.mk b/init/Android.mk
index 4e4c002..997b2bc 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -91,7 +91,6 @@
libsquashfs_utils \
liblogwrap \
libext4_utils \
- libfscrypt \
libcrypto_utils \
libsparse \
libavb \
diff --git a/libmodprobe/include/modprobe/modprobe.h b/libmodprobe/include/modprobe/modprobe.h
index dcb4ffb..421d826 100644
--- a/libmodprobe/include/modprobe/modprobe.h
+++ b/libmodprobe/include/modprobe/modprobe.h
@@ -19,6 +19,7 @@
#include <set>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
class Modprobe {
@@ -59,5 +60,6 @@
std::vector<std::string> module_load_;
std::unordered_map<std::string, std::string> module_options_;
std::set<std::string> module_blacklist_;
+ std::unordered_set<std::string> module_loaded_;
bool blacklist_enabled = false;
};
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index 73ae15b..3c78ec9 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -330,7 +330,12 @@
bool Modprobe::LoadWithAliases(const std::string& module_name, bool strict,
const std::string& parameters) {
- std::set<std::string> modules_to_load = {MakeCanonical(module_name)};
+ auto canonical_name = MakeCanonical(module_name);
+ if (module_loaded_.count(canonical_name)) {
+ return true;
+ }
+
+ std::set<std::string> modules_to_load = {canonical_name};
bool module_loaded = false;
// use aliases to expand list of modules to load (multiple modules
@@ -338,6 +343,7 @@
for (const auto& [alias, aliased_module] : module_aliases_) {
if (fnmatch(alias.c_str(), module_name.c_str(), 0) != 0) continue;
LOG(VERBOSE) << "Found alias for '" << module_name << "': '" << aliased_module;
+ if (module_loaded_.count(MakeCanonical(aliased_module))) continue;
modules_to_load.emplace(aliased_module);
}
diff --git a/libmodprobe/libmodprobe_ext.cpp b/libmodprobe/libmodprobe_ext.cpp
index 2efcac2..8bebe4c 100644
--- a/libmodprobe/libmodprobe_ext.cpp
+++ b/libmodprobe/libmodprobe_ext.cpp
@@ -30,8 +30,9 @@
return false;
}
+ auto canonical_name = MakeCanonical(path_name);
std::string options = "";
- auto options_iter = module_options_.find(MakeCanonical(path_name));
+ auto options_iter = module_options_.find(canonical_name);
if (options_iter != module_options_.end()) {
options = options_iter->second;
}
@@ -44,6 +45,7 @@
if (ret != 0) {
if (errno == EEXIST) {
// Module already loaded
+ module_loaded_.emplace(canonical_name);
return true;
}
LOG(ERROR) << "Failed to insmod '" << path_name << "' with args '" << options << "'";
@@ -51,15 +53,18 @@
}
LOG(INFO) << "Loaded kernel module " << path_name;
+ module_loaded_.emplace(canonical_name);
return true;
}
bool Modprobe::Rmmod(const std::string& module_name) {
- int ret = syscall(__NR_delete_module, MakeCanonical(module_name).c_str(), O_NONBLOCK);
+ auto canonical_name = MakeCanonical(module_name);
+ int ret = syscall(__NR_delete_module, canonical_name.c_str(), O_NONBLOCK);
if (ret != 0) {
PLOG(ERROR) << "Failed to remove module '" << module_name << "'";
return false;
}
+ module_loaded_.erase(canonical_name);
return true;
}
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index 6c2221e..af70f1d 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -435,6 +435,12 @@
};
if (role == kUnzip) {
+ // `unzip -Z` is "zipinfo mode", so in that case just restart...
+ if (argc > 1 && !strcmp(argv[1], "-Z")) {
+ argv[1] = const_cast<char*>("zipinfo");
+ return main(argc - 1, argv + 1);
+ }
+
int opt;
while ((opt = getopt_long(argc, argv, "-d:hlnopqvx", opts, nullptr)) != -1) {
switch (opt) {