1 /* 2 * Copyright (C) 2018 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 17 #ifndef ANDROID_APEXD_APEXD_H_ 18 #define ANDROID_APEXD_APEXD_H_ 19 20 #include <android-base/macros.h> 21 #include <android-base/result.h> 22 23 #include <ostream> 24 #include <string> 25 #include <vector> 26 27 #include "apex_classpath.h" 28 #include "apex_constants.h" 29 #include "apex_database.h" 30 #include "apex_file.h" 31 #include "apex_file_repository.h" 32 #include "apexd_session.h" 33 34 namespace android { 35 namespace apex { 36 37 // A structure containing all the values that might need to be injected for 38 // testing (e.g. apexd status property, etc.) 39 // 40 // Ideally we want to introduce Apexd class and use dependency injection for 41 // such values, but that will require a sizeable refactoring. For the time being 42 // this config should do the trick. 43 struct ApexdConfig { 44 const char* apex_status_sysprop; 45 std::vector<std::string> apex_built_in_dirs; 46 const char* active_apex_data_dir; 47 const char* decompression_dir; 48 const char* ota_reserved_dir; 49 const char* apex_hash_tree_dir; 50 const char* staged_session_dir; 51 const char* metadata_sepolicy_staged_dir; 52 // Overrides the path to the "metadata" partition which is by default 53 // /dev/block/by-name/payload-metadata It should be a path pointing the first 54 // partition of the VM payload disk. So, realpath() of this path is checked if 55 // it has the suffix "1". For example, /test-dir/test-metadata-1 can be valid 56 // and the subsequent numbers should point APEX files. 57 const char* vm_payload_metadata_partition_prop; 58 const char* active_apex_selinux_ctx; 59 }; 60 61 static const ApexdConfig kDefaultConfig = { 62 kApexStatusSysprop, 63 kApexPackageBuiltinDirs, 64 kActiveApexPackagesDataDir, 65 kApexDecompressedDir, 66 kOtaReservedDir, 67 kApexHashTreeDir, 68 kStagedSessionsDir, 69 kMetadataSepolicyStagedDir, 70 kVmPayloadMetadataPartitionProp, 71 "u:object_r:staging_data_file", 72 }; 73 74 class CheckpointInterface; 75 76 void SetConfig(const ApexdConfig& config); 77 78 // Exposed only for testing. 79 android::base::Result<void> Unmount( 80 const MountedApexDatabase::MountedApexData& data, bool deferred); 81 82 android::base::Result<void> ResumeRevertIfNeeded(); 83 84 android::base::Result<void> PreinstallPackages( 85 const std::vector<std::string>& paths) WARN_UNUSED; 86 87 android::base::Result<void> StagePackages( 88 const std::vector<std::string>& tmpPaths) WARN_UNUSED; 89 android::base::Result<void> UnstagePackages( 90 const std::vector<std::string>& paths) WARN_UNUSED; 91 92 android::base::Result<std::vector<ApexFile>> SubmitStagedSession( 93 const int session_id, const std::vector<int>& child_session_ids, 94 const bool has_rollback_enabled, const bool is_rollback, 95 const int rollback_id) WARN_UNUSED; 96 android::base::Result<std::vector<ApexFile>> GetStagedApexFiles( 97 const int session_id, 98 const std::vector<int>& child_session_ids) WARN_UNUSED; 99 android::base::Result<ClassPath> MountAndDeriveClassPath( 100 const std::vector<ApexFile>&) WARN_UNUSED; 101 android::base::Result<void> MarkStagedSessionReady(const int session_id) 102 WARN_UNUSED; 103 android::base::Result<void> MarkStagedSessionSuccessful(const int session_id) 104 WARN_UNUSED; 105 // Only only of the parameters should be passed during revert 106 android::base::Result<void> RevertActiveSessions( 107 const std::string& crashing_native_process, 108 const std::string& error_message); 109 // Only only of the parameters should be passed during revert 110 android::base::Result<void> RevertActiveSessionsAndReboot( 111 const std::string& crashing_native_process, 112 const std::string& error_message); 113 114 android::base::Result<void> ActivatePackage(const std::string& full_path) 115 WARN_UNUSED; 116 android::base::Result<void> DeactivatePackage(const std::string& full_path) 117 WARN_UNUSED; 118 119 std::vector<ApexFile> GetActivePackages(); 120 android::base::Result<ApexFile> GetActivePackage( 121 const std::string& package_name); 122 123 std::vector<ApexFile> GetFactoryPackages(); 124 125 android::base::Result<void> AbortStagedSession(const int session_id); 126 127 android::base::Result<void> SnapshotCeData(const int user_id, 128 const int rollback_id, 129 const std::string& apex_name); 130 android::base::Result<void> RestoreCeData(const int user_id, 131 const int rollback_id, 132 const std::string& apex_name); 133 134 android::base::Result<void> DestroyDeSnapshots(const int rollback_id); 135 android::base::Result<void> DestroyCeSnapshots(const int user_id, 136 const int rollback_id); 137 android::base::Result<void> DestroyCeSnapshotsNotSpecified( 138 int user_id, const std::vector<int>& retain_rollback_ids); 139 140 int OnBootstrap(); 141 // Sets the values of gVoldService and gInFsCheckpointMode. 142 void InitializeVold(CheckpointInterface* checkpoint_service); 143 // Initializes in-memory state (e.g. pre-installed data, activated apexes). 144 // Must be called first before calling any other boot sequence related function. 145 void Initialize(CheckpointInterface* checkpoint_service); 146 // Initializes data apex as in-memory state. Should be called only if we are 147 // not booting, since initialization timing is different when booting 148 void InitializeDataApex(); 149 // Migrates sessions from /data/apex/session to /metadata/session.i 150 // Must only be called during boot (i.e apexd.status is not "ready" or 151 // "activated"). 152 android::base::Result<void> MigrateSessionsDirIfNeeded(); 153 // Apex activation logic. Scans staged apex sessions and activates apexes. 154 // Must only be called during boot (i.e apexd.status is not "ready" or 155 // "activated"). 156 void OnStart(); 157 // For every package X, there can be at most two APEX, pre-installed vs 158 // installed on data. We decide which ones should be activated and return them 159 // as a list 160 std::vector<ApexFileRef> SelectApexForActivation( 161 const std::unordered_map<std::string, std::vector<ApexFileRef>>& all_apex, 162 const ApexFileRepository& instance); 163 std::vector<ApexFile> ProcessCompressedApex( 164 const std::vector<ApexFileRef>& compressed_apex, bool is_ota_chroot); 165 // Validate |apex| is same as |capex| 166 android::base::Result<void> ValidateDecompressedApex(const ApexFile& capex, 167 const ApexFile& apex); 168 // Notifies system that apexes are activated by setting apexd.status property to 169 // "activated". 170 // Must only be called during boot (i.e. apexd.status is not "ready" or 171 // "activated"). 172 void OnAllPackagesActivated(bool is_bootstrap); 173 // Notifies system that apexes are ready by setting apexd.status property to 174 // "ready". 175 // Must only be called during boot (i.e. apexd.status is not "ready" or 176 // "activated"). 177 void OnAllPackagesReady(); 178 void OnBootCompleted(); 179 // Exposed for testing 180 void RemoveInactiveDataApex(); 181 void BootCompletedCleanup(); 182 int SnapshotOrRestoreDeUserData(); 183 184 int UnmountAll(); 185 186 android::base::Result<MountedApexDatabase::MountedApexData> 187 GetTempMountedApexData(const std::string& package); 188 189 // Optimistically tries to remount as many APEX packages as possible. 190 // For more documentation see corresponding binder call in IApexService.aidl. 191 android::base::Result<void> RemountPackages(); 192 193 // Exposed for unit tests 194 bool ShouldAllocateSpaceForDecompression(const std::string& new_apex_name, 195 int64_t new_apex_version, 196 const ApexFileRepository& instance); 197 198 int64_t CalculateSizeForCompressedApex( 199 const std::vector<std::tuple<std::string, int64_t, int64_t>>& 200 compressed_apexes, 201 const ApexFileRepository& instance); 202 203 void CollectApexInfoList(std::ostream& os, 204 const std::vector<ApexFile>& active_apexs, 205 const std::vector<ApexFile>& inactive_apexs); 206 207 // Reserve |size| bytes in |dest_dir| by creating a zero-filled file 208 android::base::Result<void> ReserveSpaceForCompressedApex( 209 int64_t size, const std::string& dest_dir); 210 211 // Entry point when running in the VM mode (with --vm arg) 212 int OnStartInVmMode(); 213 214 // Activates apexes in otapreot_chroot environment. 215 // TODO(b/172911822): support compressed apexes. 216 int OnOtaChrootBootstrap(); 217 218 // Activates flattened apexes 219 int ActivateFlattenedApex(); 220 int ActivateFlattenedApex(const std::vector<std::string>& multi_apex_prefixes); 221 222 android::apex::MountedApexDatabase& GetApexDatabaseForTesting(); 223 224 // Performs a non-staged install of an APEX specified by |package_path|. 225 // TODO(ioffe): add more documentation. 226 android::base::Result<ApexFile> InstallPackage(const std::string& package_path); 227 228 // Exposed for testing. 229 android::base::Result<int> AddBlockApex(ApexFileRepository& instance); 230 231 bool IsActiveApexChanged(const ApexFile& apex); 232 233 // Shouldn't be used outside of apexd_test.cpp 234 std::set<std::string>& GetChangedActiveApexesForTesting(); 235 236 } // namespace apex 237 } // namespace android 238 239 #endif // ANDROID_APEXD_APEXD_H_ 240