1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <functional>
18 #include <iostream>
19 #include <string>
20 
21 #include <android-base/macros.h>
22 #include <fstab/fstab.h>
23 #include <libdm/dm.h>
24 #include <libfiemap/image_manager.h>
25 #include <liblp/builder.h>
26 #include <libsnapshot/snapshot.h>
27 #include <update_engine/update_metadata.pb.h>
28 
29 #include <libsnapshot/auto_device.h>
30 #include <libsnapshot/snapshot.h>
31 
32 namespace android {
33 namespace snapshot {
34 
35 // Unit is sectors, this is a 4K chunk.
36 static constexpr uint32_t kSnapshotChunkSize = 8;
37 
38 // A list of devices we created along the way.
39 // - Whenever a device is created that is subject to GC'ed at the end of
40 //   this function, add it to this list.
41 // - If any error has occurred, the list is destroyed, and all these devices
42 //   are cleaned up.
43 // - Upon success, Release() should be called so that the created devices
44 //   are kept.
45 struct AutoDeviceList {
46     ~AutoDeviceList();
47     template <typename T, typename... Args>
EmplaceBackAutoDeviceList48     void EmplaceBack(Args&&... args) {
49         devices_.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
50     }
51     void Release();
52 
53   private:
54     std::vector<std::unique_ptr<AutoDevice>> devices_;
55 };
56 
57 // Automatically unmap a device upon deletion.
58 struct AutoUnmapDevice : AutoDevice {
59     // On destruct, delete |name| from device mapper.
AutoUnmapDeviceAutoUnmapDevice60     AutoUnmapDevice(android::dm::IDeviceMapper* dm, const std::string& name)
61         : AutoDevice(name), dm_(dm) {}
62     ~AutoUnmapDevice();
63 
64   private:
65     DISALLOW_COPY_AND_ASSIGN(AutoUnmapDevice);
66     android::dm::IDeviceMapper* dm_ = nullptr;
67 };
68 
69 // Automatically unmap an image upon deletion.
70 struct AutoUnmapImage : AutoDevice {
71     // On destruct, delete |name| from image manager.
AutoUnmapImageAutoUnmapImage72     AutoUnmapImage(android::fiemap::IImageManager* images, const std::string& name)
73         : AutoDevice(name), images_(images) {}
74     ~AutoUnmapImage();
75 
76   private:
77     DISALLOW_COPY_AND_ASSIGN(AutoUnmapImage);
78     android::fiemap::IImageManager* images_ = nullptr;
79 };
80 
81 // Automatically deletes a snapshot. |name| should be the name of the partition, e.g. "system_a".
82 // Client is responsible for maintaining the lifetime of |manager| and |lock|.
83 struct AutoDeleteSnapshot : AutoDevice {
AutoDeleteSnapshotAutoDeleteSnapshot84     AutoDeleteSnapshot(SnapshotManager* manager, SnapshotManager::LockedFile* lock,
85                        const std::string& name)
86         : AutoDevice(name), manager_(manager), lock_(lock) {}
87     ~AutoDeleteSnapshot();
88 
89   private:
90     DISALLOW_COPY_AND_ASSIGN(AutoDeleteSnapshot);
91     SnapshotManager* manager_ = nullptr;
92     SnapshotManager::LockedFile* lock_ = nullptr;
93 };
94 
95 struct AutoUnmountDevice : AutoDevice {
96     // Empty object that does nothing.
AutoUnmountDeviceAutoUnmountDevice97     AutoUnmountDevice() : AutoDevice("") {}
98     static std::unique_ptr<AutoUnmountDevice> New(const std::string& path);
99     ~AutoUnmountDevice();
100 
101   private:
AutoUnmountDeviceAutoUnmountDevice102     AutoUnmountDevice(const std::string& path, android::fs_mgr::Fstab&& fstab)
103         : AutoDevice(path), fstab_(std::move(fstab)) {}
104     android::fs_mgr::Fstab fstab_;
105 };
106 
107 // Return a list of partitions in |builder| with the name ending in |suffix|.
108 std::vector<android::fs_mgr::Partition*> ListPartitionsWithSuffix(
109         android::fs_mgr::MetadataBuilder* builder, const std::string& suffix);
110 
111 // Initialize a device before using it as the COW device for a dm-snapshot device.
112 Return InitializeKernelCow(const std::string& device);
113 
114 // "Atomically" write string to file. This is done by a series of actions:
115 // 1. Write to path + ".tmp"
116 // 2. Move temporary file to path using rename()
117 // Note that rename() is an atomic operation. This function may not work properly if there
118 // is an open fd to |path|, because that fd has an old view of the file.
119 bool WriteStringToFileAtomic(const std::string& content, const std::string& path);
120 bool FsyncDirectory(const char* dirname);
121 
122 // Writes current time to a given stream.
123 struct Now {};
124 std::ostream& operator<<(std::ostream& os, const Now&);
125 
126 // Append to |extents|. Merged into the last element if possible.
127 void AppendExtent(google::protobuf::RepeatedPtrField<chromeos_update_engine::Extent>* extents,
128                   uint64_t start_block, uint64_t num_blocks);
129 
130 bool KernelSupportsCompressedSnapshots();
131 
132 bool GetLegacyCompressionEnabledProperty();
133 bool GetUserspaceSnapshotsEnabledProperty();
134 bool GetIouringEnabledProperty();
135 bool GetXorCompressionEnabledProperty();
136 bool GetODirectEnabledProperty();
137 
138 bool CanUseUserspaceSnapshots();
139 bool IsDmSnapshotTestingEnabled();
140 bool IsVendorFromAndroid12();
141 
142 // Swap the suffix of a partition name.
143 std::string GetOtherPartitionName(const std::string& name);
144 
145 }  // namespace snapshot
146 }  // namespace android
147