1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <map> 19 #include <memory> 20 #include <mutex> 21 #include <sstream> 22 #include <string> 23 #include <vector> 24 25 #include <android-base/unique_fd.h> 26 #include <android/gsi/BnGsiService.h> 27 #include <binder/BinderService.h> 28 #include <libfiemap_writer/split_fiemap_writer.h> 29 #include <liblp/builder.h> 30 #include "libgsi/libgsi.h" 31 32 namespace android { 33 namespace gsi { 34 35 class GsiService : public BinderService<GsiService>, public BnGsiService { 36 public: 37 static void Register(); 38 39 GsiService(); 40 ~GsiService() override; 41 42 binder::Status startGsiInstall(int64_t gsiSize, int64_t userdataSize, bool wipeUserdata, 43 int* _aidl_return) override; 44 binder::Status beginGsiInstall(const GsiInstallParams& params, int* _aidl_return) override; 45 binder::Status commitGsiChunkFromStream(const ::android::os::ParcelFileDescriptor& stream, 46 int64_t bytes, bool* _aidl_return) override; 47 binder::Status getInstallProgress(::android::gsi::GsiProgress* _aidl_return) override; 48 binder::Status commitGsiChunkFromMemory(const ::std::vector<uint8_t>& bytes, 49 bool* _aidl_return) override; 50 binder::Status cancelGsiInstall(bool* _aidl_return) override; 51 binder::Status setGsiBootable(bool oneShot, int* _aidl_return) override; 52 binder::Status isGsiEnabled(bool* _aidl_return) override; 53 binder::Status removeGsiInstall(bool* _aidl_return) override; 54 binder::Status disableGsiInstall(bool* _aidl_return) override; 55 binder::Status isGsiRunning(bool* _aidl_return) override; 56 binder::Status isGsiInstalled(bool* _aidl_return) override; 57 binder::Status isGsiInstallInProgress(bool* _aidl_return) override; 58 binder::Status getUserdataImageSize(int64_t* _aidl_return) override; 59 binder::Status getGsiBootStatus(int* _aidl_return) override; 60 binder::Status getInstalledGsiImageDir(std::string* _aidl_return) override; 61 binder::Status wipeGsiUserdata(int* _aidl_return) override; 62 getServiceName()63 static char const* getServiceName() { return kGsiServiceName; } 64 65 static void RunStartupTasks(); 66 67 // This helper class will redirect writes to either a SplitFiemap or 68 // device-mapper. 69 class WriteHelper { 70 public: ~WriteHelper()71 virtual ~WriteHelper() {}; 72 virtual bool Write(const void* data, uint64_t bytes) = 0; 73 virtual bool Flush() = 0; 74 virtual uint64_t Size() = 0; 75 76 WriteHelper() = default; 77 WriteHelper(const WriteHelper&) = delete; 78 WriteHelper& operator=(const WriteHelper&) = delete; 79 WriteHelper& operator=(WriteHelper&&) = delete; 80 WriteHelper(WriteHelper&&) = delete; 81 }; 82 83 private: 84 using LpMetadata = android::fs_mgr::LpMetadata; 85 using MetadataBuilder = android::fs_mgr::MetadataBuilder; 86 using SplitFiemap = android::fiemap_writer::SplitFiemap; 87 88 struct Image { 89 std::unique_ptr<SplitFiemap> writer; 90 uint64_t actual_size; 91 }; 92 93 int ValidateInstallParams(GsiInstallParams* params); 94 int StartInstall(const GsiInstallParams& params); 95 int PerformSanityChecks(); 96 int PreallocateFiles(); 97 int PreallocateUserdata(); 98 int PreallocateSystem(); 99 int DetermineReadWriteMethod(); 100 bool FormatUserdata(); 101 bool CommitGsiChunk(int stream_fd, int64_t bytes); 102 bool CommitGsiChunk(const void* data, size_t bytes); 103 int SetGsiBootable(bool one_shot); 104 int ReenableGsi(bool one_shot); 105 int WipeUserdata(); 106 bool DisableGsiInstall(); 107 bool AddPartitionFiemap(android::fs_mgr::MetadataBuilder* builder, 108 android::fs_mgr::Partition* partition, const Image& image, 109 const std::string& block_device); 110 std::unique_ptr<LpMetadata> CreateMetadata(); 111 std::unique_ptr<SplitFiemap> CreateFiemapWriter(const std::string& path, uint64_t size, 112 int* error); 113 bool CreateInstallStatusFile(); 114 bool CreateMetadataFile(); 115 bool SetBootMode(bool one_shot); 116 void PostInstallCleanup(); 117 118 void StartAsyncOperation(const std::string& step, int64_t total_bytes); 119 void UpdateProgress(int status, int64_t bytes_processed); 120 int GetExistingImage(const LpMetadata& metadata, const std::string& name, Image* image); 121 std::unique_ptr<WriteHelper> OpenPartition(const std::string& name); 122 123 enum class AccessLevel { 124 System, 125 SystemOrShell 126 }; 127 binder::Status CheckUid(AccessLevel level = AccessLevel::System); 128 129 static bool RemoveGsiFiles(const std::string& install_dir, bool wipeUserdata); 130 static std::string GetImagePath(const std::string& image_dir, const std::string& name); 131 static std::string GetInstalledImagePath(const std::string& name); 132 static std::string GetInstalledImageDir(); 133 134 std::mutex main_lock_; 135 136 // Set before installation starts, to determine whether or not to delete 137 // the userdata image if installation fails. 138 bool wipe_userdata_on_failure_; 139 140 // These are initialized or set in StartInstall(). 141 bool installing_ = false; 142 std::atomic<bool> should_abort_ = false; 143 std::string install_dir_; 144 std::string userdata_gsi_path_; 145 std::string system_gsi_path_; 146 uint64_t userdata_block_size_; 147 uint64_t system_block_size_; 148 uint64_t gsi_size_; 149 uint64_t userdata_size_; 150 bool can_use_devicemapper_; 151 bool wipe_userdata_; 152 // Remaining data we're waiting to receive for the GSI image. 153 uint64_t gsi_bytes_written_; 154 155 // Progress bar state. 156 std::mutex progress_lock_; 157 GsiProgress progress_; 158 159 std::unique_ptr<WriteHelper> system_writer_; 160 161 // This is used to track which GSI partitions have been created. 162 std::map<std::string, Image> partitions_; 163 std::unique_ptr<LpMetadata> metadata_; 164 }; 165 166 } // namespace gsi 167 } // namespace android 168