android_system_core/fs_mgr/libsnapshot/utility.h

117 lines
4.0 KiB
C
Raw Normal View History

// 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 <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>
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::DeviceMapper* dm, const std::string& name)
: AutoDevice(name), dm_(dm) {}
AutoUnmapDevice(AutoUnmapDevice&& other) = default;
~AutoUnmapDevice();
private:
DISALLOW_COPY_AND_ASSIGN(AutoUnmapDevice);
android::dm::DeviceMapper* 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);
libsnapshot: Also use empty space in super for COW The super partition usually has some empty space even after the target partitions are created, especially for retrofit Virtual A/B devices. Use that empty space for COW before taking up userdata space. - PartitionCowCreator computes free regions in super partition metadata and use that space until it is used up. It returns a pair of numbers (cow_partition_size, cow_file_size) and let SnapshotManager to create the partition / images with proper sizes. - A region is considered free iff it is used by NEITHER target NOR source partitions - The list is in PartitionCowCreator's return value so that SnapshotManager can use it as a guide when creating partitions. - These partitions are created under the group named "cow". - Avoid mapping COW partitions directly during init first stage mount. Init only maps them when they are needed by the top-level device. - CreateCowImage no longer zero-fills the first 4 bytes of the image. (See below) - CreateUpdatePartitions: after creating the snapshot, also maps the COW devices (via MapCowDevices()) and zero-fills the first 4 bytes of the top-level COW device. - Add a new SnapshotManager::MapCowDevices() function, which maps both the COW partition (in super) and the COW image (through IImageManager) (if necessary). Then, create a dm-linear target that concatenates them (if necessary). - Add a new SnapshotManager::UnmapCowDevices() functions that does the reverse MapCowDevices(). - DeleteSnapshot also unmaps the top-level COW device and COW partition before unmapping the COW images (before deleting them). Test: libsnapshot_test Change-Id: I0098b7e842ab48b0b4dd2a59142098b098d23d34
2019-08-27 21:25:31 +00:00
// Initialize a device before using it as the COW device for a dm-snapshot device.
bool InitializeCow(const std::string& device);
} // namespace snapshot
} // namespace android