| // Copyright (C) 2019 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. |
| |
| #pragma once |
| |
| #include <functional> |
| #include <iostream> |
| #include <string> |
| |
| #include <android-base/macros.h> |
| #include <fstab/fstab.h> |
| #include <libdm/dm.h> |
| #include <libfiemap/image_manager.h> |
| #include <liblp/builder.h> |
| #include <libsnapshot/snapshot.h> |
| #include <update_engine/update_metadata.pb.h> |
| |
| #include <libsnapshot/auto_device.h> |
| #include <libsnapshot/snapshot.h> |
| |
| namespace android { |
| namespace snapshot { |
| |
| // Unit is sectors, this is a 4K chunk. |
| static constexpr uint32_t kSnapshotChunkSize = 8; |
| |
| // A list of devices we created along the way. |
| // - Whenever a device is created that is subject to GC'ed at the end of |
| // this function, add it to this list. |
| // - If any error has occurred, the list is destroyed, and all these devices |
| // are cleaned up. |
| // - Upon success, Release() should be called so that the created devices |
| // are kept. |
| struct AutoDeviceList { |
| ~AutoDeviceList(); |
| template <typename T, typename... Args> |
| void EmplaceBack(Args&&... args) { |
| devices_.emplace_back(std::make_unique<T>(std::forward<Args>(args)...)); |
| } |
| void Release(); |
| |
| private: |
| std::vector<std::unique_ptr<AutoDevice>> devices_; |
| }; |
| |
| // Automatically unmap a device upon deletion. |
| struct AutoUnmapDevice : AutoDevice { |
| // On destruct, delete |name| from device mapper. |
| AutoUnmapDevice(android::dm::IDeviceMapper* dm, const std::string& name) |
| : AutoDevice(name), dm_(dm) {} |
| AutoUnmapDevice(AutoUnmapDevice&& other) = default; |
| ~AutoUnmapDevice(); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AutoUnmapDevice); |
| android::dm::IDeviceMapper* dm_ = nullptr; |
| }; |
| |
| // Automatically unmap an image upon deletion. |
| struct AutoUnmapImage : AutoDevice { |
| // On destruct, delete |name| from image manager. |
| AutoUnmapImage(android::fiemap::IImageManager* images, const std::string& name) |
| : AutoDevice(name), images_(images) {} |
| AutoUnmapImage(AutoUnmapImage&& other) = default; |
| ~AutoUnmapImage(); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AutoUnmapImage); |
| android::fiemap::IImageManager* images_ = nullptr; |
| }; |
| |
| // Automatically deletes a snapshot. |name| should be the name of the partition, e.g. "system_a". |
| // Client is responsible for maintaining the lifetime of |manager| and |lock|. |
| struct AutoDeleteSnapshot : AutoDevice { |
| AutoDeleteSnapshot(SnapshotManager* manager, SnapshotManager::LockedFile* lock, |
| const std::string& name) |
| : AutoDevice(name), manager_(manager), lock_(lock) {} |
| AutoDeleteSnapshot(AutoDeleteSnapshot&& other); |
| ~AutoDeleteSnapshot(); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AutoDeleteSnapshot); |
| SnapshotManager* manager_ = nullptr; |
| SnapshotManager::LockedFile* lock_ = nullptr; |
| }; |
| |
| struct AutoUnmountDevice : AutoDevice { |
| // Empty object that does nothing. |
| AutoUnmountDevice() : AutoDevice("") {} |
| static std::unique_ptr<AutoUnmountDevice> New(const std::string& path); |
| ~AutoUnmountDevice(); |
| |
| private: |
| AutoUnmountDevice(const std::string& path, android::fs_mgr::Fstab&& fstab) |
| : AutoDevice(path), fstab_(std::move(fstab)) {} |
| android::fs_mgr::Fstab fstab_; |
| }; |
| |
| // Return a list of partitions in |builder| with the name ending in |suffix|. |
| std::vector<android::fs_mgr::Partition*> ListPartitionsWithSuffix( |
| android::fs_mgr::MetadataBuilder* builder, const std::string& suffix); |
| |
| // Initialize a device before using it as the COW device for a dm-snapshot device. |
| Return InitializeKernelCow(const std::string& device); |
| |
| // "Atomically" write string to file. This is done by a series of actions: |
| // 1. Write to path + ".tmp" |
| // 2. Move temporary file to path using rename() |
| // Note that rename() is an atomic operation. This function may not work properly if there |
| // is an open fd to |path|, because that fd has an old view of the file. |
| bool WriteStringToFileAtomic(const std::string& content, const std::string& path); |
| |
| // Writes current time to a given stream. |
| struct Now {}; |
| std::ostream& operator<<(std::ostream& os, const Now&); |
| |
| // Append to |extents|. Merged into the last element if possible. |
| void AppendExtent(google::protobuf::RepeatedPtrField<chromeos_update_engine::Extent>* extents, |
| uint64_t start_block, uint64_t num_blocks); |
| |
| bool IsCompressionEnabled(); |
| |
| bool IsUserspaceSnapshotsEnabled(); |
| |
| bool IsDmSnapshotTestingEnabled(); |
| |
| bool IsIouringEnabled(); |
| |
| // Swap the suffix of a partition name. |
| std::string GetOtherPartitionName(const std::string& name); |
| } // namespace snapshot |
| } // namespace android |