1 /* 2 * Copyright (C) 2021 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 ART_ODREFRESH_ODREFRESH_H_ 18 #define ART_ODREFRESH_ODREFRESH_H_ 19 20 #include <ctime> 21 #include <functional> 22 #include <memory> 23 #include <optional> 24 #include <set> 25 #include <string> 26 #include <unordered_set> 27 #include <vector> 28 29 #include "android-base/function_ref.h" 30 #include "android-base/result.h" 31 #include "base/os.h" 32 #include "com_android_apex.h" 33 #include "com_android_art.h" 34 #include "exec_utils.h" 35 #include "odr_artifacts.h" 36 #include "odr_config.h" 37 #include "odr_metrics.h" 38 #include "odrefresh/odrefresh.h" 39 #include "tools/cmdline_builder.h" 40 41 namespace art { 42 namespace odrefresh { 43 44 class OnDeviceRefresh; 45 46 struct BootImages { 47 static constexpr int kMaxCount = 2; 48 49 bool primary_boot_image : 1; 50 bool boot_image_mainline_extension : 1; 51 52 int Count() const; 53 54 OdrMetrics::BcpCompilationType GetTypeForMetrics() const; 55 }; 56 57 struct CompilationOptions { 58 // If not empty, generate the boot images for ISAs in the list. 59 std::vector<std::pair<InstructionSet, BootImages>> boot_images_to_generate_for_isas; 60 61 // If not empty, compile the system server jars in the list. 62 std::set<std::string> system_server_jars_to_compile; 63 64 static CompilationOptions CompileAll(const OnDeviceRefresh& odr); 65 66 int CompilationUnitCount() const; 67 }; 68 69 struct CompilationResult { 70 OdrMetrics::Status status = OdrMetrics::Status::kOK; 71 std::string error_msg; 72 int64_t elapsed_time_ms = 0; 73 std::optional<ExecResult> dex2oat_result; 74 OkCompilationResult75 static CompilationResult Ok() { return {}; } 76 Dex2oatOkCompilationResult77 static CompilationResult Dex2oatOk(int64_t elapsed_time_ms, const ExecResult& dex2oat_result) { 78 return {.elapsed_time_ms = elapsed_time_ms, .dex2oat_result = dex2oat_result}; 79 } 80 ErrorCompilationResult81 static CompilationResult Error(OdrMetrics::Status status, const std::string& error_msg) { 82 return {.status = status, .error_msg = error_msg}; 83 } 84 Dex2oatErrorCompilationResult85 static CompilationResult Dex2oatError(const std::string& error_msg, 86 int64_t elapsed_time_ms, 87 const ExecResult& dex2oat_result) { 88 return {.status = OdrMetrics::Status::kDex2OatError, 89 .error_msg = error_msg, 90 .elapsed_time_ms = elapsed_time_ms, 91 .dex2oat_result = dex2oat_result}; 92 } 93 IsOkCompilationResult94 bool IsOk() { return status == OdrMetrics::Status::kOK; } 95 MergeCompilationResult96 void Merge(const CompilationResult& other) { 97 // Accumulate the compilation time. 98 elapsed_time_ms += other.elapsed_time_ms; 99 100 // Only keep the first failure. 101 if (status == OdrMetrics::Status::kOK) { 102 status = other.status; 103 error_msg = other.error_msg; 104 dex2oat_result = other.dex2oat_result; 105 } 106 } 107 }; 108 109 class PreconditionCheckResult { 110 public: NoneOk(OdrMetrics::Trigger trigger)111 static PreconditionCheckResult NoneOk(OdrMetrics::Trigger trigger) { 112 return PreconditionCheckResult(trigger, 113 /*primary_boot_image_ok=*/false, 114 /*boot_image_mainline_extension_ok=*/false, 115 /*system_server_ok=*/false); 116 } BootImageMainlineExtensionNotOk(OdrMetrics::Trigger trigger)117 static PreconditionCheckResult BootImageMainlineExtensionNotOk(OdrMetrics::Trigger trigger) { 118 return PreconditionCheckResult(trigger, 119 /*primary_boot_image_ok=*/true, 120 /*boot_image_mainline_extension_ok=*/false, 121 /*system_server_ok=*/false); 122 } SystemServerNotOk(OdrMetrics::Trigger trigger)123 static PreconditionCheckResult SystemServerNotOk(OdrMetrics::Trigger trigger) { 124 return PreconditionCheckResult(trigger, 125 /*primary_boot_image_ok=*/true, 126 /*boot_image_mainline_extension_ok=*/true, 127 /*system_server_ok=*/false); 128 } AllOk()129 static PreconditionCheckResult AllOk() { 130 return PreconditionCheckResult(/*trigger=*/std::nullopt, 131 /*primary_boot_image_ok=*/true, 132 /*boot_image_mainline_extension_ok=*/true, 133 /*system_server_ok=*/true); 134 } IsAllOk()135 bool IsAllOk() const { return !trigger_.has_value(); } GetTrigger()136 OdrMetrics::Trigger GetTrigger() const { return trigger_.value(); } IsPrimaryBootImageOk()137 bool IsPrimaryBootImageOk() const { return primary_boot_image_ok_; } IsBootImageMainlineExtensionOk()138 bool IsBootImageMainlineExtensionOk() const { return boot_image_mainline_extension_ok_; } IsSystemServerOk()139 bool IsSystemServerOk() const { return system_server_ok_; } 140 141 private: 142 // Use static factory methods instead. PreconditionCheckResult(std::optional<OdrMetrics::Trigger> trigger,bool primary_boot_image_ok,bool boot_image_mainline_extension_ok,bool system_server_ok)143 PreconditionCheckResult(std::optional<OdrMetrics::Trigger> trigger, 144 bool primary_boot_image_ok, 145 bool boot_image_mainline_extension_ok, 146 bool system_server_ok) 147 : trigger_(trigger), 148 primary_boot_image_ok_(primary_boot_image_ok), 149 boot_image_mainline_extension_ok_(boot_image_mainline_extension_ok), 150 system_server_ok_(system_server_ok) {} 151 152 // Indicates why the precondition is not okay, or `std::nullopt` if it's okay. 153 std::optional<OdrMetrics::Trigger> trigger_; 154 bool primary_boot_image_ok_; 155 bool boot_image_mainline_extension_ok_; 156 bool system_server_ok_; 157 }; 158 159 class OnDeviceRefresh final { 160 public: 161 explicit OnDeviceRefresh(const OdrConfig& config); 162 163 // Constructor with injections. For testing and internal use only. 164 OnDeviceRefresh(const OdrConfig& config, 165 const std::string& cache_info_filename, 166 std::unique_ptr<ExecUtils> exec_utils, 167 android::base::function_ref<bool()> check_compilation_space, 168 android::base::function_ref<int(const char*, const char*)> setfilecon); 169 170 // Returns the exit code and specifies what should be compiled in `compilation_options`. 171 WARN_UNUSED ExitCode 172 CheckArtifactsAreUpToDate(OdrMetrics& metrics, 173 /*out*/ CompilationOptions* compilation_options) const; 174 175 WARN_UNUSED ExitCode Compile(OdrMetrics& metrics, CompilationOptions compilation_options) const; 176 177 WARN_UNUSED bool RemoveArtifactsDirectory() const; 178 179 // Returns a set of all system server jars. AllSystemServerJars()180 std::set<std::string> AllSystemServerJars() const { 181 return {all_systemserver_jars_.begin(), all_systemserver_jars_.end()}; 182 } 183 Config()184 const OdrConfig& Config() const { return config_; } 185 186 private: 187 time_t GetExecutionTimeUsed() const; 188 189 time_t GetExecutionTimeRemaining() const; 190 191 time_t GetSubprocessTimeout() const; 192 193 android::base::Result<std::string> CreateStagingDirectory() const; 194 195 // Gets the `ApexInfo` for active APEXes. 196 std::optional<std::vector<com::android::apex::ApexInfo>> GetApexInfoList() const; 197 198 // Reads the ART APEX cache information (if any) found in the output artifact directory. 199 android::base::Result<com::android::art::CacheInfo> ReadCacheInfo() const; 200 201 // Writes ART APEX cache information to `kOnDeviceRefreshOdrefreshArtifactDirectory`. 202 android::base::Result<void> WriteCacheInfo() const; 203 204 std::vector<com::android::art::Component> GenerateBootClasspathComponents() const; 205 206 std::vector<com::android::art::Component> GenerateDex2oatBootClasspathComponents() const; 207 208 std::vector<com::android::art::SystemServerComponent> GenerateSystemServerComponents() const; 209 210 // Returns the list of BCP jars in the ART module. 211 std::vector<std::string> GetArtBcpJars() const; 212 213 // Returns the list of BCP jars for the boot image framework extension. 214 std::vector<std::string> GetFrameworkBcpJars() const; 215 216 // Returns the list of BCP jars for the boot image mainline extension. 217 std::vector<std::string> GetMainlineBcpJars() const; 218 219 // Returns the symbolic primary boot image location (without ISA). If `minimal` is true, returns 220 // the symbolic location of the minimal boot image. 221 std::string GetPrimaryBootImage(bool on_system, bool minimal) const; 222 223 // Returns the real primary boot image location (with ISA). If `minimal` is true, returns the 224 // real location of the minimal boot image. 225 std::string GetPrimaryBootImagePath(bool on_system, bool minimal, InstructionSet isa) const; 226 227 // Returns the symbolic boot image framework extension location (without ISA). Note that this only 228 // applies to boot images on /system. 229 std::string GetSystemBootImageFrameworkExtension() const; 230 231 // Returns the real boot image framework extension location (with ISA). Note that this only 232 // applies to boot images on /system. 233 std::string GetSystemBootImageFrameworkExtensionPath(InstructionSet isa) const; 234 235 // Returns the symbolic boot image mainline extension location (without ISA). 236 std::string GetBootImageMainlineExtension(bool on_system) const; 237 238 // Returns the real boot image mainline extension location (with ISA). 239 std::string GetBootImageMainlineExtensionPath(bool on_system, InstructionSet isa) const; 240 241 // Returns the best combination of symbolic boot image locations (without ISA) based on file 242 // existence. 243 std::vector<std::string> GetBestBootImages(InstructionSet isa, 244 bool include_mainline_extension) const; 245 246 std::string GetSystemServerImagePath(bool on_system, const std::string& jar_path) const; 247 248 // Removes files that are not in the list. 249 android::base::Result<void> CleanupArtifactDirectory( 250 OdrMetrics& metrics, const std::vector<std::string>& artifacts_to_keep) const; 251 252 // Loads artifacts to memory and writes them back. This is a workaround for old versions of 253 // odsign, which encounters "file exists" error when it adds existing artifacts to fs-verity. This 254 // function essentially removes existing artifacts from fs-verity to avoid the error. 255 android::base::Result<void> RefreshExistingArtifacts() const; 256 257 // Returns whether the primary boot image is present. 258 // If `on_system` is true, checks both the primary boot image and the framework extension on 259 // /system. 260 // If `minimal` is true, checks the minimal boot image. 261 // If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`. 262 WARN_UNUSED bool PrimaryBootImageExist( 263 bool on_system, 264 bool minimal, 265 InstructionSet isa, 266 /*out*/ std::string* error_msg, 267 /*out*/ std::vector<std::string>* checked_artifacts = nullptr) const; 268 269 // Returns whether the boot image mainline extension exists. 270 WARN_UNUSED bool BootImageMainlineExtensionExist( 271 bool on_system, 272 InstructionSet isa, 273 /*out*/ std::string* error_msg, 274 /*out*/ std::vector<std::string>* checked_artifacts = nullptr) const; 275 276 // Checks whether all system_server artifacts are present. The artifacts are checked in their 277 // order of compilation. Returns true if all are present, false otherwise. 278 // Adds the paths to the jars that are missing artifacts in `jars_with_missing_artifacts`. 279 // If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`. 280 bool SystemServerArtifactsExist( 281 bool on_system, 282 /*out*/ std::string* error_msg, 283 /*out*/ std::set<std::string>* jars_missing_artifacts, 284 /*out*/ std::vector<std::string>* checked_artifacts = nullptr) const; 285 286 // Returns true if all of the system properties listed in `kSystemProperties` are set to the 287 // default values. This function is usually called when cache-info.xml does not exist (i.e., 288 // compilation has not been done before). 289 WARN_UNUSED bool CheckSystemPropertiesAreDefault() const; 290 291 // Returns true if none of the system properties listed in `kSystemProperties` has changed since 292 // the last compilation. This function is usually called when cache-info.xml exists. 293 WARN_UNUSED bool CheckSystemPropertiesHaveNotChanged( 294 const com::android::art::CacheInfo& cache_info) const; 295 296 // Returns true if the system image is built with the right userfaultfd GC flag. 297 WARN_UNUSED bool CheckBuildUserfaultFdGc() const; 298 299 // Returns whether the precondition for using artifacts on /system is met. Note that this function 300 // does not check the artifacts. 301 WARN_UNUSED PreconditionCheckResult 302 CheckPreconditionForSystem(const std::vector<com::android::apex::ApexInfo>& apex_info_list) const; 303 304 // Returns whether the precondition for using artifacts on /data is met. Note that this function 305 // does not check the artifacts. 306 WARN_UNUSED PreconditionCheckResult 307 CheckPreconditionForData(const std::vector<com::android::apex::ApexInfo>& apex_info_list) const; 308 309 // Checks whether all boot classpath artifacts are up to date. Returns the boot images that need 310 // to be (re-)generated. If `checked_artifacts` is present, adds checked artifacts to 311 // `checked_artifacts`. 312 WARN_UNUSED BootImages 313 CheckBootClasspathArtifactsAreUpToDate(OdrMetrics& metrics, 314 InstructionSet isa, 315 const PreconditionCheckResult& system_result, 316 const PreconditionCheckResult& data_result, 317 /*out*/ std::vector<std::string>* checked_artifacts) const; 318 319 // Checks whether all system_server artifacts are up to date. The artifacts are checked in their 320 // order of compilation. Returns the paths to the jars that need to be compiled. 321 // If `checked_artifacts` is present, adds checked artifacts to `checked_artifacts`. 322 WARN_UNUSED std::set<std::string> CheckSystemServerArtifactsAreUpToDate( 323 OdrMetrics& metrics, 324 const PreconditionCheckResult& system_result, 325 const PreconditionCheckResult& data_result, 326 /*out*/ std::vector<std::string>* checked_artifacts) const; 327 328 WARN_UNUSED CompilationResult 329 RunDex2oat(const std::string& staging_dir, 330 const std::string& debug_message, 331 InstructionSet isa, 332 const std::vector<std::string>& dex_files, 333 const std::vector<std::string>& boot_classpath, 334 const std::vector<std::string>& input_boot_images, 335 const OdrArtifacts& artifacts, 336 tools::CmdlineBuilder&& extra_args, 337 /*inout*/ std::vector<std::unique_ptr<File>>& readonly_files_raii) const; 338 339 WARN_UNUSED CompilationResult 340 RunDex2oatForBootClasspath(const std::string& staging_dir, 341 const std::string& debug_name, 342 InstructionSet isa, 343 const std::vector<std::string>& dex_files, 344 const std::vector<std::string>& boot_classpath, 345 const std::vector<std::string>& input_boot_images, 346 const std::string& output_path) const; 347 348 WARN_UNUSED CompilationResult 349 CompileBootClasspath(const std::string& staging_dir, 350 InstructionSet isa, 351 BootImages boot_images, 352 const std::function<void()>& on_dex2oat_success) const; 353 354 WARN_UNUSED CompilationResult 355 RunDex2oatForSystemServer(const std::string& staging_dir, 356 const std::string& dex_file, 357 const std::vector<std::string>& classloader_context) const; 358 359 WARN_UNUSED CompilationResult 360 CompileSystemServer(const std::string& staging_dir, 361 const std::set<std::string>& system_server_jars_to_compile, 362 const std::function<void()>& on_dex2oat_success) const; 363 364 // Configuration to use. 365 const OdrConfig& config_; 366 367 // Path to cache information file that is used to speed up artifact checking. 368 const std::string cache_info_filename_; 369 370 // The raw list from DEX2OATBOOTCLASSPATH. This is the list of jars that should be compiled into 371 // the primary boot image. 372 std::vector<std::string> dex2oat_boot_classpath_jars_; 373 374 // The raw list from BOOTCLASSPATH. This is the list of all BCP jars. 375 std::vector<std::string> boot_classpath_jars_; 376 377 // Set of system_server components in SYSTEMSERVERCLASSPATH that should be compiled. 378 std::unordered_set<std::string> systemserver_classpath_jars_; 379 380 // List of all system_server components, including those in SYSTEMSERVERCLASSPATH and those in 381 // STANDALONE_SYSTEMSERVER_JARS (jars that system_server loads dynamically using separate 382 // classloaders). 383 std::vector<std::string> all_systemserver_jars_; 384 385 const time_t start_time_; 386 387 std::unique_ptr<ExecUtils> exec_utils_; 388 389 android::base::function_ref<bool()> check_compilation_space_; 390 android::base::function_ref<int(const char*, const char*)> setfilecon_; 391 392 DISALLOW_COPY_AND_ASSIGN(OnDeviceRefresh); 393 }; 394 395 } // namespace odrefresh 396 } // namespace art 397 398 #endif // ART_ODREFRESH_ODREFRESH_H_ 399