otapreopt.cpp revision 56f79f96207c9c0101a5ca0237a8da631d93d5c5
173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe/* 273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Copyright 2016, The Android Open Source Project 373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Licensed under the Apache License, Version 2.0 (the "License"); 573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** you may not use this file except in compliance with the License. 673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** You may obtain a copy of the License at 773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** http://www.apache.org/licenses/LICENSE-2.0 973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 1073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Unless required by applicable law or agreed to in writing, software 1173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** distributed under the License is distributed on an "AS IS" BASIS, 1273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** See the License for the specific language governing permissions and 1473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** limitations under the License. 1573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe */ 1673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 1773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <algorithm> 1873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <inttypes.h> 1973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <random> 201842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe#include <regex> 2173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/android.h> 2273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/avc.h> 2373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <stdlib.h> 2473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <string.h> 2573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/capability.h> 2673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/prctl.h> 2773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/stat.h> 2873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/wait.h> 2973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/logging.h> 3173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/macros.h> 3273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/stringprintf.h> 336db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe#include <android-base/strings.h> 3473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/fs.h> 3573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/log.h> 3673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/properties.h> 3773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <private/android_filesystem_config.h> 3873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <commands.h> 401842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe#include <file_parsing.h> 4173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <globals.h> 4273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <installd_deps.h> // Need to fill in requirements of commands. 4373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <system_properties.h> 4473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <utils.h> 4573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 4673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifndef LOG_TAG 4773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define LOG_TAG "otapreopt" 4873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 4973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define BUFFER_MAX 1024 /* input buffer for commands */ 5173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define TOKEN_MAX 16 /* max number of arguments in buffer */ 5273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define REPLY_MAX 256 /* largest reply allowed */ 5373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::EndsWith; 556db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Join; 566db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Split; 5756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::StartsWith; 5873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeusing android::base::StringPrintf; 5973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 6073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace android { 6173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace installd { 6273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 631842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampestatic constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH"; 641842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampestatic constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT"; 6573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr const char* kOTARootDirectory = "/system-b"; 6673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr size_t kISAIndex = 3; 6773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 6873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 6973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundDown(T x, typename std::decay<T>::type n) { 7073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); 7173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 7273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 7373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 7473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) { 7573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return RoundDown(x + n - 1, n); 7673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 7773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 7873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeclass OTAPreoptService { 7973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe public: 8073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static constexpr const char* kOTADataDirectory = "/data/ota"; 8173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 8273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Main driver. Performs the following steps. 8373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 1) Parse options (read system properties etc from B partition). 8573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 2) Read in package data. 8773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 3) Prepare environment variables. 8973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 9073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 4) Prepare(compile) boot image, if necessary. 9173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 9273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 5) Run update. 9373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int Main(int argc, char** argv) { 9473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadSystemProperties()) { 9573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR)<< "Failed reading system properties."; 9673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 1; 9773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 9873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 9973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadEnvironment()) { 10073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed reading environment properties."; 10173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 2; 10273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 10373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 10473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadPackage(argc, argv)) { 10573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed reading command line file."; 10673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 3; 10773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 10873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 10973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PrepareEnvironment(); 11073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 11173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!PrepareBootImage()) { 11273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed preparing boot image."; 11373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 4; 11473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 11573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 11673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_retcode = RunPreopt(); 11773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 11873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return dexopt_retcode; 11973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 12173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int GetProperty(const char* key, char* value, const char* default_value) { 12273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* prop_value = system_properties_.GetProperty(key); 12373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prop_value == nullptr) { 12473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (default_value == nullptr) { 12573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 12673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Copy in the default value. 12873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, default_value, kPropertyValueMax - 1); 12973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[kPropertyValueMax - 1] = 0; 13073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return strlen(default_value);// TODO: Need to truncate? 13173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 13273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); 13373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, prop_value->data(), size); 13473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[size] = 0; 13573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return static_cast<int>(size); 13673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 13773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeprivate: 13973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadSystemProperties() { 1401842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe static constexpr const char* kPropertyFiles[] = { 1411842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe "/default.prop", "/system/build.prop" 1421842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }; 1431842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1441842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { 1451842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!system_properties_.Load(kPropertyFiles[i])) { 1461842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return false; 1471842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1481842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1491842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1501842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 15173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 15273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 15373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadEnvironment() { 1541842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // Parse the environment variables from init.environ.rc, which have the form 1551842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // export NAME VALUE 1561842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // For simplicity, don't respect string quotation. The values we are interested in can be 1571842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // encoded without them. 1581842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); 1591842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { 1601842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::smatch export_match; 1611842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!std::regex_match(line, export_match, export_regex)) { 1621842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 1631842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1641842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1651842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (export_match.size() != 3) { 1661842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 1671842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1681842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1691842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string name = export_match[1].str(); 1701842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string value = export_match[2].str(); 1711842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1721842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe system_properties_.SetProperty(name, value); 1731842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1741842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 1751842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }); 1761842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!parse_result) { 17773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 17873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 17973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 1801842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // Check that we found important properties. 1811842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe constexpr const char* kRequiredProperties[] = { 1821842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe kBootClassPathPropertyName, kAndroidRootPathPropertyName 1831842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }; 1841842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe for (size_t i = 0; i < arraysize(kRequiredProperties); ++i) { 1851842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (system_properties_.GetProperty(kRequiredProperties[i]) == nullptr) { 1861842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return false; 1871842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 18873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 18973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 19073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 19173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 19273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 19373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadPackage(int argc ATTRIBUTE_UNUSED, char** argv) { 19473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t index = 0; 195548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe static_assert(DEXOPT_PARAM_COUNT == ARRAY_SIZE(package_parameters_), 196548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe "Unexpected dexopt param count"); 197548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe while (index < DEXOPT_PARAM_COUNT && 19873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[index + 1] != nullptr) { 19973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe package_parameters_[index] = argv[index + 1]; 20073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe index++; 20173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 202548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe if (index != ARRAY_SIZE(package_parameters_) || argv[index + 1] != nullptr) { 20373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Wrong number of parameters"; 20473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 20573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 20673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 20773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 20873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 20973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 21073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe void PrepareEnvironment() { 21173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK(system_properties_.GetProperty(kBootClassPathPropertyName) != nullptr); 21273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string& boot_cp = 21373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *system_properties_.GetProperty(kBootClassPathPropertyName); 21473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_cp.c_str())); 21573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe environ_.push_back(StringPrintf("ANDROID_DATA=%s", kOTADataDirectory)); 21673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK(system_properties_.GetProperty(kAndroidRootPathPropertyName) != nullptr); 21773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string& android_root = 21873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *system_properties_.GetProperty(kAndroidRootPathPropertyName); 21973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root.c_str())); 22073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 22173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (const std::string& e : environ_) { 22273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe putenv(const_cast<char*>(e.c_str())); 22373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 22473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 22573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 22673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Ensure that we have the right boot image. The first time any app is 22773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // compiled, we'll try to generate it. 22873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool PrepareBootImage() { 22973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (package_parameters_[kISAIndex] == nullptr) { 23073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Instruction set missing."; 23173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 23273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 23373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* isa = package_parameters_[kISAIndex]; 23473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 23573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Check whether the file exists where expected. 23673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string dalvik_cache = std::string(kOTADataDirectory) + "/" + DALVIK_CACHE; 23773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string isa_path = dalvik_cache + "/" + isa; 23873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string art_path = isa_path + "/system@framework@boot.art"; 23973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string oat_path = isa_path + "/system@framework@boot.oat"; 24073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(art_path.c_str(), F_OK) == 0 && 24173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe access(oat_path.c_str(), F_OK) == 0) { 24273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Files exist, assume everything is alright. 24373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 24473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 24573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 24673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Create the directories, if necessary. 24773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(dalvik_cache.c_str(), F_OK) != 0) { 24873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (mkdir(dalvik_cache.c_str(), 0711) != 0) { 24973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Could not create dalvik-cache dir"; 25073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 25173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 25273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 25373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(isa_path.c_str(), F_OK) != 0) { 25473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (mkdir(isa_path.c_str(), 0711) != 0) { 25573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Could not create dalvik-cache isa dir"; 25673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 25773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 25873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 25973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 2605709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // Prepare to create. 26173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Delete files, just for a blank slate. 26273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string& boot_cp = *system_properties_.GetProperty(kBootClassPathPropertyName); 26373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 2649fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa); 2655709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe if (access(preopted_boot_art_path.c_str(), F_OK) == 0) { 2665709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return PatchoatBootImage(art_path, isa); 2675709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } else { 2685709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // No preopted boot image. Try to compile. 2695709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return Dex2oatBootImage(boot_cp, art_path, oat_path, isa); 2705709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 2715709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 2725709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2735709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool PatchoatBootImage(const std::string& art_path, const char* isa) { 2745709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 2755709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2765709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe std::vector<std::string> cmd; 2779fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("/system/bin/patchoat"); 2785709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2795709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back("--input-image-location=/system/framework/boot.art"); 2805709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str())); 2815709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2825709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 2835709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2845709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 2855709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe ART_BASE_ADDRESS_MAX_DELTA); 286febf0bf33ca81edcdaab3625e2711fa58b398cc5Andreas Gampe cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset)); 2875709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2885709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe std::string error_msg; 2895709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool result = Exec(cmd, &error_msg); 2905709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe if (!result) { 2915709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe LOG(ERROR) << "Could not generate boot image: " << error_msg; 2925709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 2935709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return result; 2945709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 2955709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 2965709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool Dex2oatBootImage(const std::string& boot_cp, 2975709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const std::string& art_path, 2985709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const std::string& oat_path, 2995709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const char* isa) { 30073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 30173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string> cmd; 3029fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("/system/bin/dex2oat"); 30373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--image=%s", art_path.c_str())); 3046db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe for (const std::string& boot_part : Split(boot_cp, ":")) { 30573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str())); 30673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 30773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str())); 30873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 30973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 31073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ART_BASE_ADDRESS_MAX_DELTA); 31173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 31273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 31373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 31473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 31573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp. 31673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms", 31773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-Xms", 31873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe true, 31973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 32073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx", 32173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-Xmx", 32273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe true, 32373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 32473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter", 32573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--compiler-filter=", 32673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 32773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 3289fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("--image-classes=/system/etc/preloaded-classes"); 32973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Compiled-classes. 33073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* extra_opts = 33173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags"); 33273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (extra_opts != nullptr) { 3336db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe std::vector<std::string> extra_vals = Split(*extra_opts, " "); 33473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end()); 33573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 33673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Should we lower this? It's usually set close to max, because 33773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // normally there's not much else going on at boot. 33873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads", 33973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-j", 34073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 34173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 34273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty( 34373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(), 34473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--instruction-set-variant=", 34573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 34673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 34773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty( 34873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(), 34973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--instruction-set-features=", 35073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 35173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 35273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 35373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string error_msg; 35473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool result = Exec(cmd, &error_msg); 35573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!result) { 35673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Could not generate boot image: " << error_msg; 35773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 35873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return result; 35973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 36073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 36173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static const char* ParseNull(const char* arg) { 36273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return (strcmp(arg, "!") == 0) ? nullptr : arg; 36373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 36473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 36573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int RunPreopt() { 36656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // Run the preopt. 36756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 36856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // There's one thing we have to be careful about: we may/will be asked to compile an app 36956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // living in the system image. This may be a valid request - if the app wasn't compiled, 37056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // e.g., if the system image wasn't large enough to include preopted files. However, the 37156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // data we have is from the old system, so the driver (the OTA service) can't actually 37256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // know. Thus, we will get requests for apps that have preopted components. To avoid 37356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // duplication (we'd generate files that are not used and are *not* cleaned up), do two 37456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // simple checks: 37556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 37656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image) 37756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.) 37856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 37956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 2) If you replace the name in the apk_path with "oat," does the path exist? 38056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (=have a subdirectory for preopted files) 38156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 38256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // If the answer to both is yes, skip the dexopt. 38356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 38456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // Note: while one may think it's OK to call dexopt and it will fail (because APKs should 38556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // be stripped), that's not true for APKs signed outside the build system (so the 38656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // jar content must be exactly the same). 38756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe 38856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (This is ugly as it's the only thing where we need to understand the contents 38956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // of package_parameters_, but it beats postponing the decision or using the call- 39056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // backs to do weird things.) 39156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe constexpr size_t kApkPathIndex = 0; 39256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK_GT(DEXOPT_PARAM_COUNT, kApkPathIndex); 39356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK(package_parameters_[kApkPathIndex] != nullptr); 39456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK(system_properties_.GetProperty(kAndroidRootPathPropertyName) != nullptr); 39556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (StartsWith(package_parameters_[kApkPathIndex], 39656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe system_properties_.GetProperty(kAndroidRootPathPropertyName)->c_str())) { 39756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe const char* last_slash = strrchr(package_parameters_[kApkPathIndex], '/'); 39856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (last_slash != nullptr) { 39956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe std::string path(package_parameters_[kApkPathIndex], 40056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe last_slash - package_parameters_[kApkPathIndex] + 1); 40156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK(EndsWith(path, "/")); 40256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe path = path + "oat"; 40356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (access(path.c_str(), F_OK) == 0) { 40456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe return 0; 40556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 40656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 40756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 40856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe 409548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe return dexopt(package_parameters_); 41073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 41173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 41273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe //////////////////////////////////// 41373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Helpers, mostly taken from ART // 41473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe //////////////////////////////////// 41573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 41673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Wrapper on fork/execv to run a command in a subprocess. 41773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) { 4186db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe const std::string command_line = Join(arg_vector, ' '); 41973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 42073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_GE(arg_vector.size(), 1U) << command_line; 42173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 42273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Convert the args to char pointers. 42373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* program = arg_vector[0].c_str(); 42473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<char*> args; 42573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (size_t i = 0; i < arg_vector.size(); ++i) { 42673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string& arg = arg_vector[i]; 42773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe char* arg_str = const_cast<char*>(arg.c_str()); 42873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK(arg_str != nullptr) << i; 42973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe args.push_back(arg_str); 43073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 43173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe args.push_back(nullptr); 43273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 43373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Fork and exec. 43473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t pid = fork(); 43573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == 0) { 43673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // No allocation allowed between fork and exec. 43773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 43873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Change process groups, so we don't get reaped by ProcessManager. 43973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe setpgid(0, 0); 44073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 44173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe execv(program, &args[0]); 44273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 44373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Failed to execv(" << command_line << ")"; 44473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // _exit to avoid atexit handlers in child. 44573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe _exit(1); 44673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 44773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == -1) { 44873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", 44973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str(), strerror(errno)); 45073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 45173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 45273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 45373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // wait for subprocess to finish 45473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int status; 45573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); 45673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (got_pid != pid) { 45773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " 45873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "wanted %d, got %d: %s", 45973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str(), pid, got_pid, strerror(errno)); 46073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 46173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 46273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 46373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", 46473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str()); 46573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 46673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 46773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 46873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 46973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 47073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 47173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. 47273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 47373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe constexpr size_t kPageSize = PAGE_SIZE; 47473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(min_delta % kPageSize, 0u); 47573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(max_delta % kPageSize, 0u); 47673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LT(min_delta, max_delta); 47773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 47873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::default_random_engine generator; 47973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe generator.seed(GetSeed()); 48073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta); 48173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int32_t r = distribution(generator); 48273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (r % 2 == 0) { 48373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe r = RoundUp(r, kPageSize); 48473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 48573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe r = RoundDown(r, kPageSize); 48673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 48773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LE(min_delta, r); 48873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_GE(max_delta, r); 48973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(r % kPageSize, 0u); 49073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return r; 49173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 49273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 49373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static uint64_t GetSeed() { 49473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifdef __BIONIC__ 49573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Bionic exposes arc4random, use it. 49673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe uint64_t random_data; 49773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe arc4random_buf(&random_data, sizeof(random_data)); 49873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return random_data; 49973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#else 50073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#error "This is only supposed to run with bionic. Otherwise, implement..." 50173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 50273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 50373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 50473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe void AddCompilerOptionFromSystemProperty(const char* system_property, 50573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* prefix, 50673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool runtime, 50773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string>& out) { 50873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* value = 50973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe system_properties_.GetProperty(system_property); 51073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (value != nullptr) { 51173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (runtime) { 51273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back("--runtime-arg"); 51373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 51473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prefix != nullptr) { 51573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back(StringPrintf("%s%s", prefix, value->c_str())); 51673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 51773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back(*value); 51873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 51973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 52073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 52173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 52273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Stores the system properties read out of the B partition. We need to use these properties 52373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // to compile, instead of the A properties we could get from init/get_property. 52473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe SystemProperties system_properties_; 52573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 526548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe const char* package_parameters_[DEXOPT_PARAM_COUNT]; 52773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 52873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Store environment values we need to set. 52973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string> environ_; 53073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe}; 53173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 53273dae11162aa61396c06cbdb05b954764e944e02Andreas GampeOTAPreoptService gOps; 53373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 53473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe//////////////////////// 53573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe// Plug-in functions. // 53673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe//////////////////////// 53773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 53873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeint get_property(const char *key, char *value, const char *default_value) { 53973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return gOps.GetProperty(key, value, default_value); 54073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 54173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 54273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe// Compute the output path of 54373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, 54473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *apk_path, 54573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 5469c8f93a2a6ed6a764de7a617fe7a01657d0f4479Dan Austin const char *file_name_start; 5479c8f93a2a6ed6a764de7a617fe7a01657d0f4479Dan Austin const char *file_name_end; 54873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 54973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_start = strrchr(apk_path, '/'); 55073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (file_name_start == nullptr) { 55173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 55273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 55373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 55473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_end = strrchr(file_name_start, '.'); 55573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (file_name_end == nullptr) { 55673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no extension\n", apk_path); 55773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 55873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 55973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 56073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Calculate file_name 56173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_start++; // Move past '/', is valid as file_name_end is valid. 56273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t file_name_len = file_name_end - file_name_start; 56373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string file_name(file_name_start, file_name_len); 56473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 56573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b 56673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe snprintf(path, PKG_PATH_MAX, "%s/%s/%s.odex.b", oat_dir, instruction_set, 56773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name.c_str()); 56873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 56973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 57073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 57173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe/* 57273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * Computes the odex file for the given apk_path and instruction_set. 57373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 57473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * 57573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * Returns false if it failed to determine the odex file path. 57673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe */ 57773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, 57873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 57973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (StringPrintf("%soat/%s/odex.b", apk_path, instruction_set).length() + 1 > PKG_PATH_MAX) { 58073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' may be too long to form odex file path.\n", apk_path); 58173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 58273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 58373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 58473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *path_end = strrchr(apk_path, '/'); 58573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (path_end == nullptr) { 58673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 58773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 58873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 58973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string path_component(apk_path, path_end - apk_path); 59073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 59173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *name_begin = path_end + 1; 59273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *extension_start = strrchr(name_begin, '.'); 59373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (extension_start == nullptr) { 59473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no extension.\n", apk_path); 59573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 59673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 59773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string name_component(name_begin, extension_start - name_begin); 59873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 59973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string new_path = StringPrintf("%s/oat/%s/%s.odex.b", 60073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe path_component.c_str(), 60173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe instruction_set, 60273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe name_component.c_str()); 60373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LT(new_path.length(), PKG_PATH_MAX); 60473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strcpy(path, new_path.c_str()); 60573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 60673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 60773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 60873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool create_cache_path(char path[PKG_PATH_MAX], 60973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *src, 61073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 61173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t srclen = strlen(src); 61273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 61373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe /* demand that we are an absolute path */ 61473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 61573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 61673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 61773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 61873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 61973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 62073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 62173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 62273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string from_src = std::string(src + 1); 62373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::replace(from_src.begin(), from_src.end(), '/', '@'); 62473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 62573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string assembled_path = StringPrintf("%s/%s/%s/%s%s", 62673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe OTAPreoptService::kOTADataDirectory, 62773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe DALVIK_CACHE, 62873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe instruction_set, 62973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe from_src.c_str(), 63073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe DALVIK_CACHE_POSTFIX2); 63173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 63273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (assembled_path.length() + 1 > PKG_PATH_MAX) { 63373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 63473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 63573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strcpy(path, assembled_path.c_str()); 63673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 63773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 63873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 63973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 64073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool initialize_globals() { 64173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* data_path = getenv("ANDROID_DATA"); 64273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (data_path == nullptr) { 64373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not find ANDROID_DATA"); 64473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 64573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 64673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return init_globals_from_data_and_root(data_path, kOTARootDirectory); 64773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 64873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 64973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic bool initialize_directories() { 65073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // This is different from the normal installd. We only do the base 65173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // directory, the rest will be created on demand when each app is compiled. 65273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe mode_t old_umask = umask(0); 65373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(INFO) << "Old umask: " << old_umask; 65473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(OTAPreoptService::kOTADataDirectory, R_OK) < 0) { 65573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not access %s\n", OTAPreoptService::kOTADataDirectory); 65673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 65773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 65873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 65973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 66073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 66173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int log_callback(int type, const char *fmt, ...) { 66273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_list ap; 66373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int priority; 66473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 66573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe switch (type) { 66673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe case SELINUX_WARNING: 66773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_WARN; 66873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 66973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe case SELINUX_INFO: 67073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_INFO; 67173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 67273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe default: 67373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_ERROR; 67473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 67573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 67673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_start(ap, fmt); 67773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG_PRI_VA(priority, "SELinux", fmt, ap); 67873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_end(ap); 67973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 68073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 68173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 68273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int otapreopt_main(const int argc, char *argv[]) { 68373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int selinux_enabled = (is_selinux_enabled() > 0); 68473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 68573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe setenv("ANDROID_LOG_TAGS", "*:v", 1); 68673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe android::base::InitLogging(argv); 68773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 68873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGI("otapreopt firing up\n"); 68973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 69073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (argc < 2) { 69173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Expecting parameters"); 69273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 69373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 69473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 69573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe union selinux_callback cb; 69673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cb.func_log = log_callback; 69773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe selinux_set_callback(SELINUX_CB_LOG, cb); 69873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 69973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!initialize_globals()) { 70073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not initialize globals; exiting.\n"); 70173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 70273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 70373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 70473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!initialize_directories()) { 70573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not create directories; exiting.\n"); 70673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 70773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 70873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 70973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (selinux_enabled && selinux_status_open(true) < 0) { 71073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not open selinux status; exiting.\n"); 71173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 71273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 71373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 71473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int ret = android::installd::gOps.Main(argc, argv); 71573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 71673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return ret; 71773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 71873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 71973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} // namespace installd 72073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} // namespace android 72173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 72273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeint main(const int argc, char *argv[]) { 72373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return android::installd::otapreopt_main(argc, argv); 72473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 725