Merge "libsnapshot: Prototype the new API for mapping writable snapshots." am: 32771b2aa3
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1430217 Change-Id: Ic96666a7c2e1cf7840b7f7bd778cce13327a56b8
This commit is contained in:
commit
4d620fc341
6 changed files with 90 additions and 1 deletions
|
|
@ -30,6 +30,7 @@ cc_defaults {
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"libdm",
|
"libdm",
|
||||||
"libfstab",
|
"libfstab",
|
||||||
|
"libsnapshot_cow",
|
||||||
"update_metadata-protos",
|
"update_metadata-protos",
|
||||||
],
|
],
|
||||||
whole_static_libs: [
|
whole_static_libs: [
|
||||||
|
|
@ -38,7 +39,9 @@ cc_defaults {
|
||||||
"libfstab",
|
"libfstab",
|
||||||
],
|
],
|
||||||
header_libs: [
|
header_libs: [
|
||||||
|
"libchrome",
|
||||||
"libfiemap_headers",
|
"libfiemap_headers",
|
||||||
|
"libupdate_engine_headers",
|
||||||
],
|
],
|
||||||
export_static_lib_headers: [
|
export_static_lib_headers: [
|
||||||
"update_metadata-protos",
|
"update_metadata-protos",
|
||||||
|
|
@ -313,8 +316,10 @@ cc_defaults {
|
||||||
"libprotobuf-mutator",
|
"libprotobuf-mutator",
|
||||||
],
|
],
|
||||||
header_libs: [
|
header_libs: [
|
||||||
|
"libchrome",
|
||||||
"libfiemap_headers",
|
"libfiemap_headers",
|
||||||
"libstorage_literals_headers",
|
"libstorage_literals_headers",
|
||||||
|
"libupdate_engine_headers",
|
||||||
],
|
],
|
||||||
proto: {
|
proto: {
|
||||||
type: "full",
|
type: "full",
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libsnapshot/snapshot.h>
|
#include <libsnapshot/snapshot.h>
|
||||||
|
#include <payload_consumer/file_descriptor.h>
|
||||||
|
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
|
@ -37,6 +38,12 @@ class MockSnapshotManager : public ISnapshotManager {
|
||||||
(const android::fs_mgr::CreateLogicalPartitionParams& params,
|
(const android::fs_mgr::CreateLogicalPartitionParams& params,
|
||||||
std::string* snapshot_path),
|
std::string* snapshot_path),
|
||||||
(override));
|
(override));
|
||||||
|
MOCK_METHOD(std::unique_ptr<ICowWriter>, OpenSnapshotWriter,
|
||||||
|
(const std::string& partition_name, std::chrono::milliseconds timeout_ms),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(std::unique_ptr<FileDescriptor>, OpenSnapshotReader,
|
||||||
|
(const std::string& partition_name, std::chrono::milliseconds timeout_ms),
|
||||||
|
(override));
|
||||||
MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override));
|
MOCK_METHOD(bool, UnmapUpdateSnapshot, (const std::string& target_partition_name), (override));
|
||||||
MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override));
|
MOCK_METHOD(bool, NeedSnapshotsInFirstStageMount, (), (override));
|
||||||
MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions,
|
MOCK_METHOD(bool, CreateLogicalAndSnapshotPartitions,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include <update_engine/update_metadata.pb.h>
|
#include <update_engine/update_metadata.pb.h>
|
||||||
|
|
||||||
#include <libsnapshot/auto_device.h>
|
#include <libsnapshot/auto_device.h>
|
||||||
|
#include <libsnapshot/cow_writer.h>
|
||||||
#include <libsnapshot/return.h>
|
#include <libsnapshot/return.h>
|
||||||
|
|
||||||
#ifndef FRIEND_TEST
|
#ifndef FRIEND_TEST
|
||||||
|
|
@ -43,6 +44,10 @@
|
||||||
#define DEFINED_FRIEND_TEST
|
#define DEFINED_FRIEND_TEST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace chromeos_update_engine {
|
||||||
|
class FileDescriptor;
|
||||||
|
} // namespace chromeos_update_engine
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
namespace fiemap {
|
namespace fiemap {
|
||||||
|
|
@ -105,6 +110,8 @@ class ISnapshotManager {
|
||||||
};
|
};
|
||||||
virtual ~ISnapshotManager() = default;
|
virtual ~ISnapshotManager() = default;
|
||||||
|
|
||||||
|
using FileDescriptor = chromeos_update_engine::FileDescriptor;
|
||||||
|
|
||||||
// Begin an update. This must be called before creating any snapshots. It
|
// Begin an update. This must be called before creating any snapshots. It
|
||||||
// will fail if GetUpdateState() != None.
|
// will fail if GetUpdateState() != None.
|
||||||
virtual bool BeginUpdate() = 0;
|
virtual bool BeginUpdate() = 0;
|
||||||
|
|
@ -173,11 +180,25 @@ class ISnapshotManager {
|
||||||
|
|
||||||
// Map a snapshotted partition for OTA clients to write to. Write-protected regions are
|
// Map a snapshotted partition for OTA clients to write to. Write-protected regions are
|
||||||
// determined previously in CreateSnapshots.
|
// determined previously in CreateSnapshots.
|
||||||
|
//
|
||||||
// |snapshot_path| must not be nullptr.
|
// |snapshot_path| must not be nullptr.
|
||||||
|
//
|
||||||
|
// This method will return false if ro.virtual_ab.compression.enabled is true.
|
||||||
virtual bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
|
virtual bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
|
||||||
std::string* snapshot_path) = 0;
|
std::string* snapshot_path) = 0;
|
||||||
|
|
||||||
// Unmap a snapshot device that's previously mapped with MapUpdateSnapshot.
|
// Create an ICowWriter to build a snapshot against a target partition.
|
||||||
|
virtual std::unique_ptr<ICowWriter> OpenSnapshotWriter(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms = {}) = 0;
|
||||||
|
|
||||||
|
// Open a snapshot for reading. A file-like interface is provided through the FileDescriptor.
|
||||||
|
// In this mode, writes are not supported.
|
||||||
|
virtual std::unique_ptr<FileDescriptor> OpenSnapshotReader(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms = {}) = 0;
|
||||||
|
|
||||||
|
// Unmap a snapshot device or CowWriter that was previously opened with MapUpdateSnapshot,
|
||||||
|
// OpenSnapshotWriter, or OpenSnapshotReader. All outstanding open descriptors, writers,
|
||||||
|
// or readers must be deleted before this is called.
|
||||||
virtual bool UnmapUpdateSnapshot(const std::string& target_partition_name) = 0;
|
virtual bool UnmapUpdateSnapshot(const std::string& target_partition_name) = 0;
|
||||||
|
|
||||||
// If this returns true, first-stage mount must call
|
// If this returns true, first-stage mount must call
|
||||||
|
|
@ -288,6 +309,10 @@ class SnapshotManager final : public ISnapshotManager {
|
||||||
Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override;
|
Return CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) override;
|
||||||
bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
|
bool MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
|
||||||
std::string* snapshot_path) override;
|
std::string* snapshot_path) override;
|
||||||
|
std::unique_ptr<ICowWriter> OpenSnapshotWriter(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms = {}) override;
|
||||||
|
std::unique_ptr<FileDescriptor> OpenSnapshotReader(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms = {}) override;
|
||||||
bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
|
bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
|
||||||
bool NeedSnapshotsInFirstStageMount() override;
|
bool NeedSnapshotsInFirstStageMount() override;
|
||||||
bool CreateLogicalAndSnapshotPartitions(
|
bool CreateLogicalAndSnapshotPartitions(
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libsnapshot/snapshot.h>
|
#include <libsnapshot/snapshot.h>
|
||||||
|
#include <payload_consumer/file_descriptor.h>
|
||||||
|
|
||||||
namespace android::snapshot {
|
namespace android::snapshot {
|
||||||
|
|
||||||
|
|
@ -35,6 +36,10 @@ class SnapshotManagerStub : public ISnapshotManager {
|
||||||
const chromeos_update_engine::DeltaArchiveManifest& manifest) override;
|
const chromeos_update_engine::DeltaArchiveManifest& manifest) override;
|
||||||
bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
|
bool MapUpdateSnapshot(const android::fs_mgr::CreateLogicalPartitionParams& params,
|
||||||
std::string* snapshot_path) override;
|
std::string* snapshot_path) override;
|
||||||
|
std::unique_ptr<ICowWriter> OpenSnapshotWriter(const std::string& partition_name,
|
||||||
|
std::chrono::milliseconds timeout_ms) override;
|
||||||
|
std::unique_ptr<FileDescriptor> OpenSnapshotReader(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms = {}) override;
|
||||||
bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
|
bool UnmapUpdateSnapshot(const std::string& target_partition_name) override;
|
||||||
bool NeedSnapshotsInFirstStageMount() override;
|
bool NeedSnapshotsInFirstStageMount() override;
|
||||||
bool CreateLogicalAndSnapshotPartitions(
|
bool CreateLogicalAndSnapshotPartitions(
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/parseint.h>
|
#include <android-base/parseint.h>
|
||||||
|
#include <android-base/properties.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
#include <android-base/unique_fd.h>
|
#include <android-base/unique_fd.h>
|
||||||
#include <ext4_utils/ext4_utils.h>
|
#include <ext4_utils/ext4_utils.h>
|
||||||
|
|
@ -68,6 +69,7 @@ using android::fs_mgr::SlotNumberForSlotSuffix;
|
||||||
using android::hardware::boot::V1_1::MergeStatus;
|
using android::hardware::boot::V1_1::MergeStatus;
|
||||||
using chromeos_update_engine::DeltaArchiveManifest;
|
using chromeos_update_engine::DeltaArchiveManifest;
|
||||||
using chromeos_update_engine::Extent;
|
using chromeos_update_engine::Extent;
|
||||||
|
using chromeos_update_engine::FileDescriptor;
|
||||||
using chromeos_update_engine::InstallOperation;
|
using chromeos_update_engine::InstallOperation;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>;
|
using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>;
|
||||||
|
|
@ -103,6 +105,10 @@ SnapshotManager::SnapshotManager(IDeviceInfo* device) : device_(device) {
|
||||||
metadata_dir_ = device_->GetMetadataDir();
|
metadata_dir_ = device_->GetMetadataDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool IsCompressionEnabled() {
|
||||||
|
return android::base::GetBoolProperty("ro.virtual_ab.compression.enabled", false);
|
||||||
|
}
|
||||||
|
|
||||||
static std::string GetCowName(const std::string& snapshot_name) {
|
static std::string GetCowName(const std::string& snapshot_name) {
|
||||||
return snapshot_name + "-cow";
|
return snapshot_name + "-cow";
|
||||||
}
|
}
|
||||||
|
|
@ -2420,6 +2426,11 @@ Return SnapshotManager::InitializeUpdateSnapshots(
|
||||||
|
|
||||||
bool SnapshotManager::MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
|
bool SnapshotManager::MapUpdateSnapshot(const CreateLogicalPartitionParams& params,
|
||||||
std::string* snapshot_path) {
|
std::string* snapshot_path) {
|
||||||
|
if (IsCompressionEnabled()) {
|
||||||
|
LOG(ERROR) << "MapUpdateSnapshot cannot be used in compression mode.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto lock = LockShared();
|
auto lock = LockShared();
|
||||||
if (!lock) return false;
|
if (!lock) return false;
|
||||||
if (!UnmapPartitionWithSnapshot(lock.get(), params.GetPartitionName())) {
|
if (!UnmapPartitionWithSnapshot(lock.get(), params.GetPartitionName())) {
|
||||||
|
|
@ -2430,6 +2441,29 @@ bool SnapshotManager::MapUpdateSnapshot(const CreateLogicalPartitionParams& para
|
||||||
return MapPartitionWithSnapshot(lock.get(), params, snapshot_path);
|
return MapPartitionWithSnapshot(lock.get(), params, snapshot_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ICowWriter> SnapshotManager::OpenSnapshotWriter(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms) {
|
||||||
|
if (!IsCompressionEnabled()) {
|
||||||
|
LOG(ERROR) << "OpenSnapshotWriter can only be called in compression mode.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)partition_name;
|
||||||
|
(void)timeout_ms;
|
||||||
|
|
||||||
|
// Not yet implemented.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<FileDescriptor> SnapshotManager::OpenSnapshotReader(
|
||||||
|
const std::string& partition_name, std::chrono::milliseconds timeout_ms) {
|
||||||
|
(void)partition_name;
|
||||||
|
(void)timeout_ms;
|
||||||
|
|
||||||
|
// Not yet implemented.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool SnapshotManager::UnmapUpdateSnapshot(const std::string& target_partition_name) {
|
bool SnapshotManager::UnmapUpdateSnapshot(const std::string& target_partition_name) {
|
||||||
auto lock = LockShared();
|
auto lock = LockShared();
|
||||||
if (!lock) return false;
|
if (!lock) return false;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
using android::fs_mgr::CreateLogicalPartitionParams;
|
using android::fs_mgr::CreateLogicalPartitionParams;
|
||||||
using chromeos_update_engine::DeltaArchiveManifest;
|
using chromeos_update_engine::DeltaArchiveManifest;
|
||||||
|
using chromeos_update_engine::FileDescriptor;
|
||||||
|
|
||||||
namespace android::snapshot {
|
namespace android::snapshot {
|
||||||
|
|
||||||
|
|
@ -129,4 +130,16 @@ ISnapshotMergeStats* SnapshotManagerStub::GetSnapshotMergeStatsInstance() {
|
||||||
return &snapshot_merge_stats;
|
return &snapshot_merge_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ICowWriter> SnapshotManagerStub::OpenSnapshotWriter(const std::string&,
|
||||||
|
std::chrono::milliseconds) {
|
||||||
|
LOG(ERROR) << __FUNCTION__ << " should never be called.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<FileDescriptor> SnapshotManagerStub::OpenSnapshotReader(const std::string&,
|
||||||
|
std::chrono::milliseconds) {
|
||||||
|
LOG(ERROR) << __FUNCTION__ << " should never be called.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android::snapshot
|
} // namespace android::snapshot
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue