diff options
Diffstat (limited to 'fs_mgr/libsnapshot')
| -rw-r--r-- | fs_mgr/libsnapshot/Android.bp | 33 | ||||
| -rw-r--r-- | fs_mgr/libsnapshot/include/libsnapshot/snapshot.h | 5 | ||||
| -rw-r--r-- | fs_mgr/libsnapshot/snapshot.cpp | 7 | ||||
| -rw-r--r-- | fs_mgr/libsnapshot/snapshot_fuzz.cpp | 2 | ||||
| -rw-r--r-- | fs_mgr/libsnapshot/snapshot_fuzz_utils.h | 4 | ||||
| -rw-r--r-- | fs_mgr/libsnapshot/snapshot_metadata_updater.cpp | 9 | ||||
| -rw-r--r-- | fs_mgr/libsnapshot/snapuserd.cpp | 126 |
7 files changed, 172 insertions, 14 deletions
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp index 95301ff71a..eaef180377 100644 --- a/fs_mgr/libsnapshot/Android.bp +++ b/fs_mgr/libsnapshot/Android.bp @@ -310,3 +310,36 @@ cc_test { auto_gen_config: true, require_root: true, } + +cc_defaults { + name: "snapuserd_defaults", + srcs: [ + "snapuserd.cpp", + ], + + cflags: [ + "-Wall", + "-Werror" + ], + + static_libs: [ + "libbase", + "liblog", + "libdm", + ], +} + +cc_binary { + name: "snapuserd", + defaults: ["snapuserd_defaults"], +} + +cc_binary { + name: "snapuserd_ramdisk", + stem: "snapuserd", + defaults: ["snapuserd_defaults"], + + ramdisk: true, + static_executable: true, + system_shared_libs: [], +} diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h index 3c2c77683b..a4a31507ee 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h @@ -553,9 +553,8 @@ class SnapshotManager final : public ISnapshotManager { // This should only be called in recovery. bool UnmapAllPartitions(); - // Sanity check no snapshot overflows. Note that this returns false negatives if the snapshot - // overflows, then is remapped and not written afterwards. Hence, the function may only serve - // as a sanity check. + // Check no snapshot overflows. Note that this returns false negatives if the snapshot + // overflows, then is remapped and not written afterwards. bool EnsureNoOverflowSnapshot(LockedFile* lock); enum class Slot { Unknown, Source, Target }; diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 7488bdaca8..b49f99ea45 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -300,9 +300,9 @@ bool SnapshotManager::CreateSnapshot(LockedFile* lock, SnapshotStatus* status) { LOG(ERROR) << "SnapshotStatus has no name."; return false; } - // Sanity check these sizes. Like liblp, we guarantee the partition size - // is respected, which means it has to be sector-aligned. (This guarantee - // is useful for locating avb footers correctly). The COW file size, however, + // Check these sizes. Like liblp, we guarantee the partition size is + // respected, which means it has to be sector-aligned. (This guarantee is + // useful for locating avb footers correctly). The COW file size, however, // can be arbitrarily larger than specified, so we can safely round it up. if (status->device_size() % kSectorSize != 0) { LOG(ERROR) << "Snapshot " << status->name() @@ -351,7 +351,6 @@ Return SnapshotManager::CreateCowImage(LockedFile* lock, const std::string& name } // The COW file size should have been rounded up to the nearest sector in CreateSnapshot. - // Sanity check this. if (status.cow_file_size() % kSectorSize != 0) { LOG(ERROR) << "Snapshot " << name << " COW file size is not a multiple of the sector size: " << status.cow_file_size(); diff --git a/fs_mgr/libsnapshot/snapshot_fuzz.cpp b/fs_mgr/libsnapshot/snapshot_fuzz.cpp index 5b145c31f2..aced3edf58 100644 --- a/fs_mgr/libsnapshot/snapshot_fuzz.cpp +++ b/fs_mgr/libsnapshot/snapshot_fuzz.cpp @@ -141,7 +141,7 @@ SNAPSHOT_FUZZ_FUNCTION(RecoveryCreateSnapshotDevicesWithMetadata, CreateResult, const RecoveryCreateSnapshotDevicesArgs& args) { std::unique_ptr<AutoDevice> device; if (args.has_metadata_device_object()) { - device = std::make_unique<DummyAutoDevice>(args.metadata_mounted()); + device = std::make_unique<NoOpAutoDevice>(args.metadata_mounted()); } return snapshot->RecoveryCreateSnapshotDevices(device); } diff --git a/fs_mgr/libsnapshot/snapshot_fuzz_utils.h b/fs_mgr/libsnapshot/snapshot_fuzz_utils.h index fa327b8a74..5319e69de0 100644 --- a/fs_mgr/libsnapshot/snapshot_fuzz_utils.h +++ b/fs_mgr/libsnapshot/snapshot_fuzz_utils.h @@ -35,9 +35,9 @@ namespace android::snapshot { class AutoMemBasedDir; class SnapshotFuzzDeviceInfo; -class DummyAutoDevice : public AutoDevice { +class NoOpAutoDevice : public AutoDevice { public: - DummyAutoDevice(bool mounted) : AutoDevice(mounted ? "dummy" : "") {} + NoOpAutoDevice(bool mounted) : AutoDevice(mounted ? "no_op" : "") {} }; struct SnapshotTestModule { diff --git a/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp b/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp index 051584c341..17a0c96a89 100644 --- a/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp +++ b/fs_mgr/libsnapshot/snapshot_metadata_updater.cpp @@ -39,6 +39,8 @@ namespace snapshot { SnapshotMetadataUpdater::SnapshotMetadataUpdater(MetadataBuilder* builder, uint32_t target_slot, const DeltaArchiveManifest& manifest) : builder_(builder), target_suffix_(SlotSuffixForSlotNumber(target_slot)) { + partial_update_ = manifest.partial_update(); + if (!manifest.has_dynamic_partition_metadata()) { return; } @@ -63,7 +65,6 @@ SnapshotMetadataUpdater::SnapshotMetadataUpdater(MetadataBuilder* builder, uint3 } } - partial_update_ = manifest.partial_update(); } bool SnapshotMetadataUpdater::ShrinkPartitions() const { @@ -173,9 +174,9 @@ bool SnapshotMetadataUpdater::DeleteGroups() const { if (iter != groups_.end()) { continue; } - // Update package metadata doesn't have this group. Before deleting it, sanity check that it - // doesn't have any partitions left. Update metadata shouldn't assign any partitions to this - // group, so all partitions that originally belong to this group should be moved by + // Update package metadata doesn't have this group. Before deleting it, check that it + // doesn't have any partitions left. Update metadata shouldn't assign any partitions to + // this group, so all partitions that originally belong to this group should be moved by // MovePartitionsToDefault at this point. auto existing_partitions_in_group = builder_->ListPartitionsInGroup(existing_group_name); if (!existing_partitions_in_group.empty()) { diff --git a/fs_mgr/libsnapshot/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp new file mode 100644 index 0000000000..a6ff4fd046 --- /dev/null +++ b/fs_mgr/libsnapshot/snapuserd.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <linux/types.h> + +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/stringprintf.h> +#include <android-base/unique_fd.h> +#include <libdm/dm.h> + +using android::base::unique_fd; + +#define DM_USER_MAP_READ 0 +#define DM_USER_MAP_WRITE 1 + +struct dm_user_message { + __u64 seq; + __u64 type; + __u64 flags; + __u64 sector; + __u64 len; + __u8 buf[]; +}; + +using namespace android::dm; + +static int daemon_main(const std::string& device) { + unique_fd block_fd(open(device.c_str(), O_RDWR)); + if (block_fd < 0) { + PLOG(ERROR) << "Unable to open " << device; + return 1; + } + + unique_fd ctrl_fd(open("/dev/dm-user", O_RDWR)); + if (ctrl_fd < 0) { + PLOG(ERROR) << "Unable to open /dev/dm-user"; + return 1; + } + + size_t buf_size = 1UL << 16; + auto buf = std::make_unique<char>(buf_size); + + /* Just keeps pumping messages between userspace and the kernel. We won't + * actually be doing anything, but the sequence numbers line up so it'll at + * least make forward progress. */ + while (true) { + struct dm_user_message* msg = (struct dm_user_message*)buf.get(); + + memset(buf.get(), 0, buf_size); + + ssize_t readed = read(ctrl_fd.get(), buf.get(), buf_size); + if (readed < 0) { + PLOG(ERROR) << "Control read failed, trying with more space"; + buf_size *= 2; + buf = std::make_unique<char>(buf_size); + continue; + } + + LOG(DEBUG) << android::base::StringPrintf("read() from dm-user returned %d bytes:", + (int)readed); + LOG(DEBUG) << android::base::StringPrintf(" msg->seq: 0x%016llx", msg->seq); + LOG(DEBUG) << android::base::StringPrintf(" msg->type: 0x%016llx", msg->type); + LOG(DEBUG) << android::base::StringPrintf(" msg->flags: 0x%016llx", msg->flags); + LOG(DEBUG) << android::base::StringPrintf(" msg->sector: 0x%016llx", msg->sector); + LOG(DEBUG) << android::base::StringPrintf(" msg->len: 0x%016llx", msg->len); + + switch (msg->type) { + case DM_USER_MAP_READ: { + LOG(DEBUG) << android::base::StringPrintf( + "Responding to read of sector %lld with %lld bytes data", msg->sector, + msg->len); + + if ((sizeof(*msg) + msg->len) > buf_size) { + auto old_buf = std::move(buf); + buf_size = sizeof(*msg) + msg->len; + buf = std::make_unique<char>(buf_size); + memcpy(buf.get(), old_buf.get(), sizeof(*msg)); + msg = (struct dm_user_message*)buf.get(); + } + + if (lseek(block_fd.get(), msg->sector * 512, SEEK_SET) < 0) { + PLOG(ERROR) << "lseek failed: " << device; + return 7; + } + if (!android::base::ReadFully(block_fd.get(), msg->buf, msg->len)) { + PLOG(ERROR) << "read failed: " << device; + return 7; + } + + if (!android::base::WriteFully(ctrl_fd.get(), buf.get(), sizeof(*msg) + msg->len)) { + PLOG(ERROR) << "write control failed"; + return 3; + } + break; + } + + case DM_USER_MAP_WRITE: + abort(); + break; + } + + LOG(DEBUG) << "read() finished, next message"; + } + + return 0; +} + +int main([[maybe_unused]] int argc, char** argv) { + android::base::InitLogging(argv, &android::base::KernelLogger); + daemon_main(argv[1]); + return 0; +} |
