Merge "Snap for 7562097 from a2aba786fefb62f14bf3e6d4b6552dda78857445 to sdk-release" into sdk-release
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 8314ec5..541f254 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -684,13 +684,9 @@
TEST(libdm, CreateEmptyDevice) {
DeviceMapper& dm = DeviceMapper::Instance();
ASSERT_TRUE(dm.CreateEmptyDevice("empty-device"));
- auto guard = android::base::make_scope_guard([&]() { dm.DeleteDevice("empty-device", 5s); });
+ auto guard =
+ android::base::make_scope_guard([&]() { dm.DeleteDeviceIfExists("empty-device", 5s); });
// Empty device should be in suspended state.
ASSERT_EQ(DmDeviceState::SUSPENDED, dm.GetState("empty-device"));
-
- std::string path;
- ASSERT_TRUE(dm.WaitForDevice("empty-device", 5s, &path));
- // Path should exist.
- ASSERT_EQ(0, access(path.c_str(), F_OK));
}
diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp
index b3198a0..af49c7d 100644
--- a/fs_mgr/libsnapshot/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/cow_reader.cpp
@@ -381,10 +381,10 @@
std::set<int, std::greater<int>> other_ops;
auto seq_ops_set = std::unordered_set<uint32_t>();
auto block_map = std::make_shared<std::unordered_map<uint32_t, int>>();
- int num_seqs = 0;
+ size_t num_seqs = 0;
size_t read;
- for (int i = 0; i < ops_->size(); i++) {
+ for (size_t i = 0; i < ops_->size(); i++) {
auto& current_op = ops_->data()[i];
if (current_op.type == kCowSequenceOp) {
@@ -396,7 +396,7 @@
PLOG(ERROR) << "Failed to read sequence op!";
return false;
}
- for (int j = num_seqs; j < num_seqs + seq_len; j++) {
+ for (size_t j = num_seqs; j < num_seqs + seq_len; j++) {
seq_ops_set.insert(merge_op_blocks->data()[j]);
}
num_seqs += seq_len;
@@ -413,10 +413,11 @@
}
block_map->insert({current_op.new_block, i});
}
- if (merge_op_blocks->size() > header_.num_merge_ops)
+ if (merge_op_blocks->size() > header_.num_merge_ops) {
num_ordered_ops_to_merge_ = merge_op_blocks->size() - header_.num_merge_ops;
- else
+ } else {
num_ordered_ops_to_merge_ = 0;
+ }
merge_op_blocks->reserve(merge_op_blocks->size() + other_ops.size());
for (auto block : other_ops) {
merge_op_blocks->emplace_back(block);
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 05f7066..6c3059c 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -126,6 +126,10 @@
bool GetRawBytes(uint64_t offset, void* buffer, size_t len, size_t* read);
+ // Returns the total number of data ops that should be merged. This is the
+ // count of the merge sequence before removing already-merged operations.
+ // It may be different than the actual data op count, for example, if there
+ // are duplicate ops in the stream.
uint64_t get_num_total_data_ops() { return num_total_data_ops_; }
uint64_t get_num_ordered_ops_to_merge() { return num_ordered_ops_to_merge_; }
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 0e36da1..bed5f56 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -1193,11 +1193,7 @@
return MergeFailureCode::ParseCowConsistencyCheck;
}
- for (auto iter = reader.GetOpIter(); !iter->Done(); iter->Next()) {
- if (!IsMetadataOp(iter->Get())) {
- num_ops++;
- }
- }
+ num_ops = reader.get_num_total_data_ops();
}
// Second pass, try as hard as we can to get the actual number of blocks
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 6018643..b2203fe 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -1184,6 +1184,53 @@
}
}
+TEST_F(SnapshotUpdateTest, DuplicateOps) {
+ if (!IsCompressionEnabled()) {
+ GTEST_SKIP() << "Compression-only test";
+ }
+
+ // OTA client blindly unmaps all partitions that are possibly mapped.
+ for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
+ ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
+ }
+
+ // Execute the update.
+ ASSERT_TRUE(sm->BeginUpdate());
+ ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
+
+ // Write some data to target partitions.
+ for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
+ ASSERT_TRUE(WriteSnapshotAndHash(name));
+ }
+
+ std::vector<PartitionUpdate*> partitions = {sys_, vnd_, prd_};
+ for (auto* partition : partitions) {
+ AddOperation(partition);
+
+ std::unique_ptr<ISnapshotWriter> writer;
+ auto res = MapUpdateSnapshot(partition->partition_name() + "_b", &writer);
+ ASSERT_TRUE(res);
+ ASSERT_TRUE(writer->AddZeroBlocks(0, 1));
+ ASSERT_TRUE(writer->AddZeroBlocks(0, 1));
+ ASSERT_TRUE(writer->Finalize());
+ }
+
+ ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
+
+ // Simulate shutting down the device.
+ ASSERT_TRUE(UnmapAll());
+
+ // After reboot, init does first stage mount.
+ auto init = NewManagerForFirstStageMount("_b");
+ ASSERT_NE(init, nullptr);
+ ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
+ ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
+
+ // Initiate the merge and wait for it to be completed.
+ ASSERT_TRUE(init->InitiateMerge());
+ ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
+}
+
// Test that shrinking and growing partitions at the same time is handled
// correctly in VABC.
TEST_F(SnapshotUpdateTest, SpaceSwapUpdate) {
diff --git a/fs_mgr/libsnapshot/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp
index e578a76..a09b111 100644
--- a/fs_mgr/libsnapshot/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd.cpp
@@ -64,7 +64,7 @@
int ret = msync(mapped_addr_, BLOCK_SZ, MS_SYNC);
if (ret < 0) {
- PLOG(ERROR) << "msync header failed: " << ret;
+ SNAP_PLOG(ERROR) << "msync header failed: " << ret;
return false;
}
diff --git a/init/Android.bp b/init/Android.bp
index 46fa1f6..3e8d4e3 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -257,7 +257,7 @@
name: "init_first_stage_cc_defaults",
module_type: "cc_defaults",
config_namespace: "ANDROID",
- bool_variables: ["BOARD_BUILD_SYSTEM_ROOT_IMAGE"],
+ bool_variables: ["BOARD_BUILD_SYSTEM_ROOT_IMAGE", "BOARD_USES_RECOVERY_AS_BOOT"],
properties: ["installable"],
}
@@ -269,6 +269,9 @@
BOARD_BUILD_SYSTEM_ROOT_IMAGE: {
installable: false,
},
+ BOARD_USES_RECOVERY_AS_BOOT: {
+ installable: false,
+ },
},
}
diff --git a/init/Android.mk b/init/Android.mk
index c1b0cf9..c08fe03 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -9,8 +9,10 @@
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
LOCAL_REQUIRED_MODULES := \
init_first_stage \
+endif # BOARD_USES_RECOVERY_AS_BOOT
endif # BOARD_BUILD_SYSTEM_ROOT_IMAGE
include $(BUILD_PHONY_PACKAGE)
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 8511da9..195e122 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -429,17 +429,24 @@
// ---------------------------------------------------------------------------
// Path functions
-static void setPathName(String8& s, const char* name) {
- size_t len = strlen(name);
- char* buf = s.lockBuffer(len);
+void String8::setPathName(const char* name)
+{
+ setPathName(name, strlen(name));
+}
+
+void String8::setPathName(const char* name, size_t len)
+{
+ char* buf = lockBuffer(len);
memcpy(buf, name, len);
// remove trailing path separator, if present
- if (len > 0 && buf[len - 1] == OS_PATH_SEPARATOR) len--;
+ if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
+ len--;
+
buf[len] = '\0';
- s.unlockBuffer(len);
+ unlockBuffer(len);
}
String8 String8::getPathLeaf(void) const
@@ -552,7 +559,7 @@
size_t len = length();
if (len == 0) {
// no existing filename, just use the new one
- setPathName(*this, name);
+ setPathName(name);
return *this;
}
@@ -572,7 +579,7 @@
return *this;
} else {
- setPathName(*this, name);
+ setPathName(name);
return *this;
}
}
diff --git a/libutils/String8_fuzz.cpp b/libutils/String8_fuzz.cpp
index faf49b6..a45d675 100644
--- a/libutils/String8_fuzz.cpp
+++ b/libutils/String8_fuzz.cpp
@@ -91,6 +91,10 @@
},
[](FuzzedDataProvider* dataProvider, android::String8* str1,
android::String8*) -> void {
+ str1->setPathName(dataProvider->ConsumeBytesWithTerminator<char>(5).data());
+ },
+ [](FuzzedDataProvider* dataProvider, android::String8* str1,
+ android::String8*) -> void {
str1->appendPath(dataProvider->ConsumeBytesWithTerminator<char>(5).data());
},
};
diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h
index 8b2dcf9..cee5dc6 100644
--- a/libutils/include/utils/String8.h
+++ b/libutils/include/utils/String8.h
@@ -137,6 +137,14 @@
*/
/*
+ * Set the filename field to a specific value.
+ *
+ * Normalizes the filename, removing a trailing '/' if present.
+ */
+ void setPathName(const char* name);
+ void setPathName(const char* name, size_t numChars);
+
+ /*
* Get just the filename component.
*
* "/tmp/foo/bar.c" --> "bar.c"
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index aa610e7..ff6460d 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -129,6 +129,27 @@
src: "set_attestation_key/keymaster_soft_attestation_keys.xml",
}
+cc_library {
+ name: "libtrusty_ipc",
+ vendor: true,
+ srcs: ["ipc/trusty_keymaster_ipc.cpp"],
+ local_include_dirs: ["include"],
+ shared_libs: [
+ "libc",
+ "libcrypto",
+ "liblog",
+ "libtrusty",
+ "libhardware",
+ "libkeymaster_messages",
+ "libxml2",
+ ],
+ export_include_dirs: ["include"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
+
cc_binary {
name: "trusty_keymaster_set_attestation_key",
vendor: true,
diff --git a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
index 6f4713b..17fee15 100644
--- a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
+++ b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
@@ -71,6 +71,7 @@
KM_SET_PRODUCT_ID = (0x9000 << KEYMASTER_REQ_SHIFT),
KM_CLEAR_ATTESTATION_CERT_CHAIN = (0xa000 << KEYMASTER_REQ_SHIFT),
KM_SET_WRAPPED_ATTESTATION_KEY = (0xb000 << KEYMASTER_REQ_SHIFT),
+ KM_SET_ATTESTATION_IDS = (0xc000 << KEYMASTER_REQ_SHIFT)
};
#ifdef __ANDROID__
diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp
index a471435..d67089f 100644
--- a/trusty/storage/proxy/Android.bp
+++ b/trusty/storage/proxy/Android.bp
@@ -29,7 +29,10 @@
"proxy.c",
],
- shared_libs: ["liblog"],
+ shared_libs: [
+ "liblog",
+ "libhardware_legacy",
+ ],
header_libs: ["libcutils_headers"],
static_libs: [
diff --git a/trusty/storage/proxy/rpmb.c b/trusty/storage/proxy/rpmb.c
index d1ed649..b59fb67 100644
--- a/trusty/storage/proxy/rpmb.c
+++ b/trusty/storage/proxy/rpmb.c
@@ -29,6 +29,8 @@
#include <linux/major.h>
#include <linux/mmc/ioctl.h>
+#include <hardware_legacy/power.h>
+
#include "ipc.h"
#include "log.h"
#include "rpmb.h"
@@ -100,6 +102,8 @@
static uint8_t read_buf[4096];
static enum dev_type dev_type = UNKNOWN_RPMB;
+static const char* UFS_WAKE_LOCK_NAME = "ufs_seq_wakelock";
+
#ifdef RPMB_DEBUG
static void print_buf(const char* prefix, const uint8_t* buf, size_t size) {
@@ -194,6 +198,7 @@
static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req) {
int rc;
+ int wl_rc;
const uint8_t* write_buf = req->payload;
/*
* Meaning of member values are stated on the definition of struct sec_proto_cdb.
@@ -202,6 +207,12 @@
struct sec_proto_cdb out_cdb = {0xB5, 0xEC, 0x00, 0x01, 0x00, 0x00, 0, 0x00, 0x00};
unsigned char sense_buffer[32];
+ wl_rc = acquire_wake_lock(PARTIAL_WAKE_LOCK, UFS_WAKE_LOCK_NAME);
+ if (wl_rc < 0) {
+ ALOGE("%s: failed to acquire wakelock: %d, %s\n", __func__, wl_rc, strerror(errno));
+ return wl_rc;
+ }
+
if (req->reliable_write_size) {
/* Prepare SECURITY PROTOCOL OUT command. */
out_cdb.length = __builtin_bswap32(req->reliable_write_size);
@@ -212,6 +223,7 @@
rc = ioctl(sg_fd, SG_IO, &io_hdr);
if (rc < 0) {
ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
+ goto err_op;
}
write_buf += req->reliable_write_size;
}
@@ -225,6 +237,7 @@
rc = ioctl(sg_fd, SG_IO, &io_hdr);
if (rc < 0) {
ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
+ goto err_op;
}
write_buf += req->write_size;
}
@@ -240,6 +253,13 @@
ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
}
}
+
+err_op:
+ wl_rc = release_wake_lock(UFS_WAKE_LOCK_NAME);
+ if (wl_rc < 0) {
+ ALOGE("%s: failed to release wakelock: %d, %s\n", __func__, wl_rc, strerror(errno));
+ }
+
return rc;
}