otapreopt.cpp revision b39d2f093242fe03772b540c031e914e857b9dc2
1/*
2 ** Copyright 2016, 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#include <algorithm>
18#include <inttypes.h>
19#include <limits>
20#include <random>
21#include <regex>
22#include <selinux/android.h>
23#include <selinux/avc.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/capability.h>
27#include <sys/prctl.h>
28#include <sys/stat.h>
29#include <sys/wait.h>
30
31#include <android-base/logging.h>
32#include <android-base/macros.h>
33#include <android-base/stringprintf.h>
34#include <android-base/strings.h>
35#include <cutils/fs.h>
36#include <cutils/properties.h>
37#include <dex2oat_return_codes.h>
38#include <log/log.h>
39#include <private/android_filesystem_config.h>
40
41#include "dexopt.h"
42#include "file_parsing.h"
43#include "globals.h"
44#include "installd_constants.h"
45#include "installd_deps.h"  // Need to fill in requirements of commands.
46#include "otapreopt_utils.h"
47#include "system_properties.h"
48#include "utils.h"
49
50#ifndef LOG_TAG
51#define LOG_TAG "otapreopt"
52#endif
53
54#define BUFFER_MAX    1024  /* input buffer for commands */
55#define TOKEN_MAX     16    /* max number of arguments in buffer */
56#define REPLY_MAX     256   /* largest reply allowed */
57
58using android::base::EndsWith;
59using android::base::Join;
60using android::base::Split;
61using android::base::StartsWith;
62using android::base::StringPrintf;
63
64namespace android {
65namespace installd {
66
67template<typename T>
68static constexpr T RoundDown(T x, typename std::decay<T>::type n) {
69    return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n);
70}
71
72template<typename T>
73static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
74    return RoundDown(x + n - 1, n);
75}
76
77class OTAPreoptService {
78 public:
79    // Main driver. Performs the following steps.
80    //
81    // 1) Parse options (read system properties etc from B partition).
82    //
83    // 2) Read in package data.
84    //
85    // 3) Prepare environment variables.
86    //
87    // 4) Prepare(compile) boot image, if necessary.
88    //
89    // 5) Run update.
90    int Main(int argc, char** argv) {
91        if (!ReadArguments(argc, argv)) {
92            LOG(ERROR) << "Failed reading command line.";
93            return 1;
94        }
95
96        if (!ReadSystemProperties()) {
97            LOG(ERROR)<< "Failed reading system properties.";
98            return 2;
99        }
100
101        if (!ReadEnvironment()) {
102            LOG(ERROR) << "Failed reading environment properties.";
103            return 3;
104        }
105
106        if (!CheckAndInitializeInstalldGlobals()) {
107            LOG(ERROR) << "Failed initializing globals.";
108            return 4;
109        }
110
111        PrepareEnvironment();
112
113        if (!PrepareBootImage(/* force */ false)) {
114            LOG(ERROR) << "Failed preparing boot image.";
115            return 5;
116        }
117
118        int dexopt_retcode = RunPreopt();
119
120        return dexopt_retcode;
121    }
122
123    int GetProperty(const char* key, char* value, const char* default_value) const {
124        const std::string* prop_value = system_properties_.GetProperty(key);
125        if (prop_value == nullptr) {
126            if (default_value == nullptr) {
127                return 0;
128            }
129            // Copy in the default value.
130            strncpy(value, default_value, kPropertyValueMax - 1);
131            value[kPropertyValueMax - 1] = 0;
132            return strlen(default_value);// TODO: Need to truncate?
133        }
134        size_t size = std::min(kPropertyValueMax - 1, prop_value->length());
135        strncpy(value, prop_value->data(), size);
136        value[size] = 0;
137        return static_cast<int>(size);
138    }
139
140    std::string GetOTADataDirectory() const {
141        return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str());
142    }
143
144    const std::string& GetTargetSlot() const {
145        return target_slot_;
146    }
147
148private:
149
150    struct Parameters {
151        const char *apk_path;
152        uid_t uid;
153        const char *pkgName;
154        const char *instruction_set;
155        int dexopt_needed;
156        const char* oat_dir;
157        int dexopt_flags;
158        const char* compiler_filter;
159        const char* volume_uuid;
160        const char* shared_libraries;
161        const char* se_info;
162    };
163
164    bool ReadSystemProperties() {
165        static constexpr const char* kPropertyFiles[] = {
166                "/default.prop", "/system/build.prop"
167        };
168
169        for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) {
170            if (!system_properties_.Load(kPropertyFiles[i])) {
171                return false;
172            }
173        }
174
175        return true;
176    }
177
178    bool ReadEnvironment() {
179        // Parse the environment variables from init.environ.rc, which have the form
180        //   export NAME VALUE
181        // For simplicity, don't respect string quotation. The values we are interested in can be
182        // encoded without them.
183        std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)");
184        bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) {
185            std::smatch export_match;
186            if (!std::regex_match(line, export_match, export_regex)) {
187                return true;
188            }
189
190            if (export_match.size() != 3) {
191                return true;
192            }
193
194            std::string name = export_match[1].str();
195            std::string value = export_match[2].str();
196
197            system_properties_.SetProperty(name, value);
198
199            return true;
200        });
201        if (!parse_result) {
202            return false;
203        }
204
205        if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) {
206            return false;
207        }
208        android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName);
209
210        if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) {
211            return false;
212        }
213        android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName);
214
215        if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) {
216            return false;
217        }
218        boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName);
219
220        if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) {
221            return false;
222        }
223        asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME);
224
225        return true;
226    }
227
228    const std::string& GetAndroidData() const {
229        return android_data_;
230    }
231
232    const std::string& GetAndroidRoot() const {
233        return android_root_;
234    }
235
236    const std::string GetOtaDirectoryPrefix() const {
237        return GetAndroidData() + "/ota";
238    }
239
240    bool CheckAndInitializeInstalldGlobals() {
241        // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We
242        // do not use any datapath that includes this, but we'll still have to set it.
243        CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr);
244        int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0);
245        if (result != 0) {
246            LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable";
247            return false;
248        }
249
250        if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) {
251            LOG(ERROR) << "Could not initialize globals; exiting.";
252            return false;
253        }
254
255        // This is different from the normal installd. We only do the base
256        // directory, the rest will be created on demand when each app is compiled.
257        if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) {
258            LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix();
259            return false;
260        }
261
262        return true;
263    }
264
265    bool ParseUInt(const char* in, uint32_t* out) {
266        char* end;
267        long long int result = strtoll(in, &end, 0);
268        if (in == end || *end != '\0') {
269            return false;
270        }
271        if (result < std::numeric_limits<uint32_t>::min() ||
272                std::numeric_limits<uint32_t>::max() < result) {
273            return false;
274        }
275        *out = static_cast<uint32_t>(result);
276        return true;
277    }
278
279    bool ReadArguments(int argc, char** argv) {
280        // Expected command line:
281        //   target-slot [version] dexopt {DEXOPT_PARAMETERS}
282
283        const char* target_slot_arg = argv[1];
284        if (target_slot_arg == nullptr) {
285            LOG(ERROR) << "Missing parameters";
286            return false;
287        }
288        // Sanitize value. Only allow (a-zA-Z0-9_)+.
289        target_slot_ = target_slot_arg;
290        if (!ValidateTargetSlotSuffix(target_slot_)) {
291            LOG(ERROR) << "Target slot suffix not legal: " << target_slot_;
292            return false;
293        }
294
295        // Check for version or "dexopt" next.
296        if (argv[2] == nullptr) {
297            LOG(ERROR) << "Missing parameters";
298            return false;
299        }
300
301        if (std::string("dexopt").compare(argv[2]) == 0) {
302            // This is version 1 (N) or pre-versioning version 2.
303            constexpr int kV2ArgCount =   1   // "otapreopt"
304                                        + 1   // slot
305                                        + 1   // "dexopt"
306                                        + 1   // apk_path
307                                        + 1   // uid
308                                        + 1   // pkg
309                                        + 1   // isa
310                                        + 1   // dexopt_needed
311                                        + 1   // oat_dir
312                                        + 1   // dexopt_flags
313                                        + 1   // filter
314                                        + 1   // volume
315                                        + 1   // libs
316                                        + 1   // seinfo
317                                        + 1;  // null
318            if (argc == kV2ArgCount) {
319                return ReadArgumentsV2(argc, argv, false);
320            } else {
321                return ReadArgumentsV1(argc, argv);
322            }
323        }
324
325        uint32_t version;
326        if (!ParseUInt(argv[2], &version)) {
327            LOG(ERROR) << "Could not parse version: " << argv[2];
328            return false;
329        }
330
331        switch (version) {
332            case 2:
333                return ReadArgumentsV2(argc, argv, true);
334
335            default:
336                LOG(ERROR) << "Unsupported version " << version;
337                return false;
338        }
339    }
340
341    bool ReadArgumentsV2(int argc ATTRIBUTE_UNUSED, char** argv, bool versioned) {
342        size_t dexopt_index = versioned ? 3 : 2;
343
344        // Check for "dexopt".
345        if (argv[dexopt_index] == nullptr) {
346            LOG(ERROR) << "Missing parameters";
347            return false;
348        }
349        if (std::string("dexopt").compare(argv[dexopt_index]) != 0) {
350            LOG(ERROR) << "Expected \"dexopt\"";
351            return false;
352        }
353
354        size_t param_index = 0;
355        for (;; ++param_index) {
356            const char* param = argv[dexopt_index + 1 + param_index];
357            if (param == nullptr) {
358                break;
359            }
360
361            switch (param_index) {
362                case 0:
363                    package_parameters_.apk_path = param;
364                    break;
365
366                case 1:
367                    package_parameters_.uid = atoi(param);
368                    break;
369
370                case 2:
371                    package_parameters_.pkgName = param;
372                    break;
373
374                case 3:
375                    package_parameters_.instruction_set = param;
376                    break;
377
378                case 4:
379                    package_parameters_.dexopt_needed = atoi(param);
380                    break;
381
382                case 5:
383                    package_parameters_.oat_dir = param;
384                    break;
385
386                case 6:
387                    package_parameters_.dexopt_flags = atoi(param);
388                    break;
389
390                case 7:
391                    package_parameters_.compiler_filter = param;
392                    break;
393
394                case 8:
395                    package_parameters_.volume_uuid = ParseNull(param);
396                    break;
397
398                case 9:
399                    package_parameters_.shared_libraries = ParseNull(param);
400                    break;
401
402                case 10:
403                    package_parameters_.se_info = ParseNull(param);
404                    break;
405
406                default:
407                    LOG(ERROR) << "Too many arguments, got " << param;
408                    return false;
409            }
410        }
411
412        if (param_index != 11) {
413            LOG(ERROR) << "Not enough parameters";
414            return false;
415        }
416
417        return true;
418    }
419
420    static int ReplaceMask(int input, int old_mask, int new_mask) {
421        return (input & old_mask) != 0 ? new_mask : 0;
422    }
423
424    bool ReadArgumentsV1(int argc ATTRIBUTE_UNUSED, char** argv) {
425        // Check for "dexopt".
426        if (argv[2] == nullptr) {
427            LOG(ERROR) << "Missing parameters";
428            return false;
429        }
430        if (std::string("dexopt").compare(argv[2]) != 0) {
431            LOG(ERROR) << "Expected \"dexopt\"";
432            return false;
433        }
434
435        size_t param_index = 0;
436        for (;; ++param_index) {
437            const char* param = argv[3 + param_index];
438            if (param == nullptr) {
439                break;
440            }
441
442            switch (param_index) {
443                case 0:
444                    package_parameters_.apk_path = param;
445                    break;
446
447                case 1:
448                    package_parameters_.uid = atoi(param);
449                    break;
450
451                case 2:
452                    package_parameters_.pkgName = param;
453                    break;
454
455                case 3:
456                    package_parameters_.instruction_set = param;
457                    break;
458
459                case 4: {
460                    // Version 1 had:
461                    //   DEXOPT_DEX2OAT_NEEDED       = 1
462                    //   DEXOPT_PATCHOAT_NEEDED      = 2
463                    //   DEXOPT_SELF_PATCHOAT_NEEDED = 3
464                    // We will simply use DEX2OAT_FROM_SCRATCH.
465                    package_parameters_.dexopt_needed = DEX2OAT_FROM_SCRATCH;
466                    break;
467                }
468
469                case 5:
470                    package_parameters_.oat_dir = param;
471                    break;
472
473                case 6: {
474                    // Version 1 had:
475                    constexpr int OLD_DEXOPT_PUBLIC         = 1 << 1;
476                    constexpr int OLD_DEXOPT_SAFEMODE       = 1 << 2;
477                    constexpr int OLD_DEXOPT_DEBUGGABLE     = 1 << 3;
478                    constexpr int OLD_DEXOPT_BOOTCOMPLETE   = 1 << 4;
479                    constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5;
480                    constexpr int OLD_DEXOPT_OTA            = 1 << 6;
481                    int input = atoi(param);
482                    package_parameters_.dexopt_flags =
483                            ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) |
484                            ReplaceMask(input, OLD_DEXOPT_SAFEMODE, DEXOPT_SAFEMODE) |
485                            ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) |
486                            ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) |
487                            ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) |
488                            ReplaceMask(input, OLD_DEXOPT_OTA, 0);
489                    break;
490                }
491
492                case 7:
493                    package_parameters_.compiler_filter = param;
494                    break;
495
496                case 8:
497                    package_parameters_.volume_uuid = ParseNull(param);
498                    break;
499
500                case 9:
501                    package_parameters_.shared_libraries = ParseNull(param);
502                    break;
503
504                default:
505                    LOG(ERROR) << "Too many arguments, got " << param;
506                    return false;
507            }
508        }
509
510        if (param_index != 10) {
511            LOG(ERROR) << "Not enough parameters";
512            return false;
513        }
514
515        // Set se_info to null. It is only relevant for secondary dex files, which we won't
516        // receive from a v1 A side.
517        package_parameters_.se_info = nullptr;
518
519        return true;
520    }
521
522    void PrepareEnvironment() {
523        environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str()));
524        environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str()));
525        environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str()));
526
527        for (const std::string& e : environ_) {
528            putenv(const_cast<char*>(e.c_str()));
529        }
530    }
531
532    // Ensure that we have the right boot image. The first time any app is
533    // compiled, we'll try to generate it.
534    bool PrepareBootImage(bool force) const {
535        if (package_parameters_.instruction_set == nullptr) {
536            LOG(ERROR) << "Instruction set missing.";
537            return false;
538        }
539        const char* isa = package_parameters_.instruction_set;
540
541        // Check whether the file exists where expected.
542        std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE;
543        std::string isa_path = dalvik_cache + "/" + isa;
544        std::string art_path = isa_path + "/system@framework@boot.art";
545        std::string oat_path = isa_path + "/system@framework@boot.oat";
546        bool cleared = false;
547        if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) {
548            // Files exist, assume everything is alright if not forced. Otherwise clean up.
549            if (!force) {
550                return true;
551            }
552            ClearDirectory(isa_path);
553            cleared = true;
554        }
555
556        // Reset umask in otapreopt, so that we control the the access for the files we create.
557        umask(0);
558
559        // Create the directories, if necessary.
560        if (access(dalvik_cache.c_str(), F_OK) != 0) {
561            if (!CreatePath(dalvik_cache)) {
562                PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache;
563                return false;
564            }
565        }
566        if (access(isa_path.c_str(), F_OK) != 0) {
567            if (!CreatePath(isa_path)) {
568                PLOG(ERROR) << "Could not create dalvik-cache isa dir";
569                return false;
570            }
571        }
572
573        // Prepare to create.
574        if (!cleared) {
575            ClearDirectory(isa_path);
576        }
577
578        std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
579        if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
580          return PatchoatBootImage(art_path, isa);
581        } else {
582          // No preopted boot image. Try to compile.
583          return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
584        }
585    }
586
587    static bool CreatePath(const std::string& path) {
588        // Create the given path. Use string processing instead of dirname, as dirname's need for
589        // a writable char buffer is painful.
590
591        // First, try to use the full path.
592        if (mkdir(path.c_str(), 0711) == 0) {
593            return true;
594        }
595        if (errno != ENOENT) {
596            PLOG(ERROR) << "Could not create path " << path;
597            return false;
598        }
599
600        // Now find the parent and try that first.
601        size_t last_slash = path.find_last_of('/');
602        if (last_slash == std::string::npos || last_slash == 0) {
603            PLOG(ERROR) << "Could not create " << path;
604            return false;
605        }
606
607        if (!CreatePath(path.substr(0, last_slash))) {
608            return false;
609        }
610
611        if (mkdir(path.c_str(), 0711) == 0) {
612            return true;
613        }
614        PLOG(ERROR) << "Could not create " << path;
615        return false;
616    }
617
618    static void ClearDirectory(const std::string& dir) {
619        DIR* c_dir = opendir(dir.c_str());
620        if (c_dir == nullptr) {
621            PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents";
622            return;
623        }
624
625        for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
626            const char* name = de->d_name;
627            if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
628                continue;
629            }
630            // We only want to delete regular files and symbolic links.
631            std::string file = StringPrintf("%s/%s", dir.c_str(), name);
632            if (de->d_type != DT_REG && de->d_type != DT_LNK) {
633                LOG(WARNING) << "Unexpected file "
634                             << file
635                             << " of type "
636                             << std::hex
637                             << de->d_type
638                             << " encountered.";
639            } else {
640                // Try to unlink the file.
641                if (unlink(file.c_str()) != 0) {
642                    PLOG(ERROR) << "Unable to unlink " << file;
643                }
644            }
645        }
646        CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
647    }
648
649    bool PatchoatBootImage(const std::string& art_path, const char* isa) const {
650        // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
651
652        std::vector<std::string> cmd;
653        cmd.push_back("/system/bin/patchoat");
654
655        cmd.push_back("--input-image-location=/system/framework/boot.art");
656        cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str()));
657
658        cmd.push_back(StringPrintf("--instruction-set=%s", isa));
659
660        int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
661                                                          ART_BASE_ADDRESS_MAX_DELTA);
662        cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset));
663
664        std::string error_msg;
665        bool result = Exec(cmd, &error_msg);
666        if (!result) {
667            LOG(ERROR) << "Could not generate boot image: " << error_msg;
668        }
669        return result;
670    }
671
672    bool Dex2oatBootImage(const std::string& boot_cp,
673                          const std::string& art_path,
674                          const std::string& oat_path,
675                          const char* isa) const {
676        // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
677        std::vector<std::string> cmd;
678        cmd.push_back("/system/bin/dex2oat");
679        cmd.push_back(StringPrintf("--image=%s", art_path.c_str()));
680        for (const std::string& boot_part : Split(boot_cp, ":")) {
681            cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str()));
682        }
683        cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str()));
684
685        int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
686                ART_BASE_ADDRESS_MAX_DELTA);
687        cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset));
688
689        cmd.push_back(StringPrintf("--instruction-set=%s", isa));
690
691        // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp.
692        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms",
693                "-Xms",
694                true,
695                cmd);
696        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx",
697                "-Xmx",
698                true,
699                cmd);
700        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter",
701                "--compiler-filter=",
702                false,
703                cmd);
704        cmd.push_back("--image-classes=/system/etc/preloaded-classes");
705        // TODO: Compiled-classes.
706        const std::string* extra_opts =
707                system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags");
708        if (extra_opts != nullptr) {
709            std::vector<std::string> extra_vals = Split(*extra_opts, " ");
710            cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end());
711        }
712        // TODO: Should we lower this? It's usually set close to max, because
713        //       normally there's not much else going on at boot.
714        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads",
715                "-j",
716                false,
717                cmd);
718        AddCompilerOptionFromSystemProperty(
719                StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(),
720                "--instruction-set-variant=",
721                false,
722                cmd);
723        AddCompilerOptionFromSystemProperty(
724                StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(),
725                "--instruction-set-features=",
726                false,
727                cmd);
728
729        std::string error_msg;
730        bool result = Exec(cmd, &error_msg);
731        if (!result) {
732            LOG(ERROR) << "Could not generate boot image: " << error_msg;
733        }
734        return result;
735    }
736
737    static const char* ParseNull(const char* arg) {
738        return (strcmp(arg, "!") == 0) ? nullptr : arg;
739    }
740
741    bool ShouldSkipPreopt() const {
742        // There's one thing we have to be careful about: we may/will be asked to compile an app
743        // living in the system image. This may be a valid request - if the app wasn't compiled,
744        // e.g., if the system image wasn't large enough to include preopted files. However, the
745        // data we have is from the old system, so the driver (the OTA service) can't actually
746        // know. Thus, we will get requests for apps that have preopted components. To avoid
747        // duplication (we'd generate files that are not used and are *not* cleaned up), do two
748        // simple checks:
749        //
750        // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image)
751        //    (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.)
752        //
753        // 2) If you replace the name in the apk_path with "oat," does the path exist?
754        //    (=have a subdirectory for preopted files)
755        //
756        // If the answer to both is yes, skip the dexopt.
757        //
758        // Note: while one may think it's OK to call dexopt and it will fail (because APKs should
759        //       be stripped), that's not true for APKs signed outside the build system (so the
760        //       jar content must be exactly the same).
761
762        //       (This is ugly as it's the only thing where we need to understand the contents
763        //        of package_parameters_, but it beats postponing the decision or using the call-
764        //        backs to do weird things.)
765        const char* apk_path = package_parameters_.apk_path;
766        CHECK(apk_path != nullptr);
767        if (StartsWith(apk_path, android_root_.c_str())) {
768            const char* last_slash = strrchr(apk_path, '/');
769            if (last_slash != nullptr) {
770                std::string path(apk_path, last_slash - apk_path + 1);
771                CHECK(EndsWith(path, "/"));
772                path = path + "oat";
773                if (access(path.c_str(), F_OK) == 0) {
774                    return true;
775                }
776            }
777        }
778
779        // Another issue is unavailability of files in the new system. If the partition
780        // layout changes, otapreopt_chroot may not know about this. Then files from that
781        // partition will not be available and fail to build. This is problematic, as
782        // this tool will wipe the OTA artifact cache and try again (for robustness after
783        // a failed OTA with remaining cache artifacts).
784        if (access(apk_path, F_OK) != 0) {
785            LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path;
786            return true;
787        }
788
789        return false;
790    }
791
792    // Run dexopt with the parameters of package_parameters_.
793    int Dexopt() {
794        return dexopt(package_parameters_.apk_path,
795                      package_parameters_.uid,
796                      package_parameters_.pkgName,
797                      package_parameters_.instruction_set,
798                      package_parameters_.dexopt_needed,
799                      package_parameters_.oat_dir,
800                      package_parameters_.dexopt_flags,
801                      package_parameters_.compiler_filter,
802                      package_parameters_.volume_uuid,
803                      package_parameters_.shared_libraries,
804                      package_parameters_.se_info);
805    }
806
807    int RunPreopt() {
808        if (ShouldSkipPreopt()) {
809            return 0;
810        }
811
812        int dexopt_result = Dexopt();
813        if (dexopt_result == 0) {
814            return 0;
815        }
816
817        // If the dexopt failed, we may have a stale boot image from a previous OTA run.
818        // Then regenerate and retry.
819        if (WEXITSTATUS(dexopt_result) ==
820                static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) {
821            if (!PrepareBootImage(/* force */ true)) {
822                LOG(ERROR) << "Forced boot image creating failed. Original error return was "
823                        << dexopt_result;
824                return dexopt_result;
825            }
826
827            int dexopt_result_boot_image_retry = Dexopt();
828            if (dexopt_result_boot_image_retry == 0) {
829                return 0;
830            }
831        }
832
833        // If this was a profile-guided run, we may have profile version issues. Try to downgrade,
834        // if possible.
835        if ((package_parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) {
836            return dexopt_result;
837        }
838
839        LOG(WARNING) << "Downgrading compiler filter in an attempt to progress compilation";
840        package_parameters_.dexopt_flags &= ~DEXOPT_PROFILE_GUIDED;
841        return Dexopt();
842    }
843
844    ////////////////////////////////////
845    // Helpers, mostly taken from ART //
846    ////////////////////////////////////
847
848    // Wrapper on fork/execv to run a command in a subprocess.
849    static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) {
850        const std::string command_line = Join(arg_vector, ' ');
851
852        CHECK_GE(arg_vector.size(), 1U) << command_line;
853
854        // Convert the args to char pointers.
855        const char* program = arg_vector[0].c_str();
856        std::vector<char*> args;
857        for (size_t i = 0; i < arg_vector.size(); ++i) {
858            const std::string& arg = arg_vector[i];
859            char* arg_str = const_cast<char*>(arg.c_str());
860            CHECK(arg_str != nullptr) << i;
861            args.push_back(arg_str);
862        }
863        args.push_back(nullptr);
864
865        // Fork and exec.
866        pid_t pid = fork();
867        if (pid == 0) {
868            // No allocation allowed between fork and exec.
869
870            // Change process groups, so we don't get reaped by ProcessManager.
871            setpgid(0, 0);
872
873            execv(program, &args[0]);
874
875            PLOG(ERROR) << "Failed to execv(" << command_line << ")";
876            // _exit to avoid atexit handlers in child.
877            _exit(1);
878        } else {
879            if (pid == -1) {
880                *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
881                        command_line.c_str(), strerror(errno));
882                return false;
883            }
884
885            // wait for subprocess to finish
886            int status;
887            pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
888            if (got_pid != pid) {
889                *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
890                        "wanted %d, got %d: %s",
891                        command_line.c_str(), pid, got_pid, strerror(errno));
892                return false;
893            }
894            if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
895                *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
896                        command_line.c_str());
897                return false;
898            }
899        }
900        return true;
901    }
902
903    // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc.
904    static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) {
905        constexpr size_t kPageSize = PAGE_SIZE;
906        CHECK_EQ(min_delta % kPageSize, 0u);
907        CHECK_EQ(max_delta % kPageSize, 0u);
908        CHECK_LT(min_delta, max_delta);
909
910        std::default_random_engine generator;
911        generator.seed(GetSeed());
912        std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta);
913        int32_t r = distribution(generator);
914        if (r % 2 == 0) {
915            r = RoundUp(r, kPageSize);
916        } else {
917            r = RoundDown(r, kPageSize);
918        }
919        CHECK_LE(min_delta, r);
920        CHECK_GE(max_delta, r);
921        CHECK_EQ(r % kPageSize, 0u);
922        return r;
923    }
924
925    static uint64_t GetSeed() {
926#ifdef __BIONIC__
927        // Bionic exposes arc4random, use it.
928        uint64_t random_data;
929        arc4random_buf(&random_data, sizeof(random_data));
930        return random_data;
931#else
932#error "This is only supposed to run with bionic. Otherwise, implement..."
933#endif
934    }
935
936    void AddCompilerOptionFromSystemProperty(const char* system_property,
937            const char* prefix,
938            bool runtime,
939            std::vector<std::string>& out) const {
940        const std::string* value = system_properties_.GetProperty(system_property);
941        if (value != nullptr) {
942            if (runtime) {
943                out.push_back("--runtime-arg");
944            }
945            if (prefix != nullptr) {
946                out.push_back(StringPrintf("%s%s", prefix, value->c_str()));
947            } else {
948                out.push_back(*value);
949            }
950        }
951    }
952
953    static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH";
954    static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT";
955    static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA";
956    // The index of the instruction-set string inside the package parameters. Needed for
957    // some special-casing that requires knowledge of the instruction-set.
958    static constexpr size_t kISAIndex = 3;
959
960    // Stores the system properties read out of the B partition. We need to use these properties
961    // to compile, instead of the A properties we could get from init/get_property.
962    SystemProperties system_properties_;
963
964    // Some select properties that are always needed.
965    std::string target_slot_;
966    std::string android_root_;
967    std::string android_data_;
968    std::string boot_classpath_;
969    std::string asec_mountpoint_;
970
971    Parameters package_parameters_;
972
973    // Store environment values we need to set.
974    std::vector<std::string> environ_;
975};
976
977OTAPreoptService gOps;
978
979////////////////////////
980// Plug-in functions. //
981////////////////////////
982
983int get_property(const char *key, char *value, const char *default_value) {
984    return gOps.GetProperty(key, value, default_value);
985}
986
987// Compute the output path of
988bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir,
989                             const char *apk_path,
990                             const char *instruction_set) {
991    const char *file_name_start;
992    const char *file_name_end;
993
994    file_name_start = strrchr(apk_path, '/');
995    if (file_name_start == nullptr) {
996        ALOGE("apk_path '%s' has no '/'s in it\n", apk_path);
997        return false;
998    }
999    file_name_end = strrchr(file_name_start, '.');
1000    if (file_name_end == nullptr) {
1001        ALOGE("apk_path '%s' has no extension\n", apk_path);
1002        return false;
1003    }
1004
1005    // Calculate file_name
1006    file_name_start++;  // Move past '/', is valid as file_name_end is valid.
1007    size_t file_name_len = file_name_end - file_name_start;
1008    std::string file_name(file_name_start, file_name_len);
1009
1010    // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b
1011    snprintf(path,
1012             PKG_PATH_MAX,
1013             "%s/%s/%s.odex.%s",
1014             oat_dir,
1015             instruction_set,
1016             file_name.c_str(),
1017             gOps.GetTargetSlot().c_str());
1018    return true;
1019}
1020
1021/*
1022 * Computes the odex file for the given apk_path and instruction_set.
1023 * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex
1024 *
1025 * Returns false if it failed to determine the odex file path.
1026 */
1027bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
1028                              const char *instruction_set) {
1029    const char *path_end = strrchr(apk_path, '/');
1030    if (path_end == nullptr) {
1031        ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path);
1032        return false;
1033    }
1034    std::string path_component(apk_path, path_end - apk_path);
1035
1036    const char *name_begin = path_end + 1;
1037    const char *extension_start = strrchr(name_begin, '.');
1038    if (extension_start == nullptr) {
1039        ALOGE("apk_path '%s' has no extension.\n", apk_path);
1040        return false;
1041    }
1042    std::string name_component(name_begin, extension_start - name_begin);
1043
1044    std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s",
1045                                        path_component.c_str(),
1046                                        instruction_set,
1047                                        name_component.c_str(),
1048                                        gOps.GetTargetSlot().c_str());
1049    if (new_path.length() >= PKG_PATH_MAX) {
1050        LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path;
1051        return false;
1052    }
1053    strcpy(path, new_path.c_str());
1054    return true;
1055}
1056
1057bool create_cache_path(char path[PKG_PATH_MAX],
1058                       const char *src,
1059                       const char *instruction_set) {
1060    size_t srclen = strlen(src);
1061
1062        /* demand that we are an absolute path */
1063    if ((src == 0) || (src[0] != '/') || strstr(src,"..")) {
1064        return false;
1065    }
1066
1067    if (srclen > PKG_PATH_MAX) {        // XXX: PKG_NAME_MAX?
1068        return false;
1069    }
1070
1071    std::string from_src = std::string(src + 1);
1072    std::replace(from_src.begin(), from_src.end(), '/', '@');
1073
1074    std::string assembled_path = StringPrintf("%s/%s/%s/%s%s",
1075                                              gOps.GetOTADataDirectory().c_str(),
1076                                              DALVIK_CACHE,
1077                                              instruction_set,
1078                                              from_src.c_str(),
1079                                              DALVIK_CACHE_POSTFIX);
1080
1081    if (assembled_path.length() + 1 > PKG_PATH_MAX) {
1082        return false;
1083    }
1084    strcpy(path, assembled_path.c_str());
1085
1086    return true;
1087}
1088
1089static int log_callback(int type, const char *fmt, ...) {
1090    va_list ap;
1091    int priority;
1092
1093    switch (type) {
1094        case SELINUX_WARNING:
1095            priority = ANDROID_LOG_WARN;
1096            break;
1097        case SELINUX_INFO:
1098            priority = ANDROID_LOG_INFO;
1099            break;
1100        default:
1101            priority = ANDROID_LOG_ERROR;
1102            break;
1103    }
1104    va_start(ap, fmt);
1105    LOG_PRI_VA(priority, "SELinux", fmt, ap);
1106    va_end(ap);
1107    return 0;
1108}
1109
1110static int otapreopt_main(const int argc, char *argv[]) {
1111    int selinux_enabled = (is_selinux_enabled() > 0);
1112
1113    setenv("ANDROID_LOG_TAGS", "*:v", 1);
1114    android::base::InitLogging(argv);
1115
1116    if (argc < 2) {
1117        ALOGE("Expecting parameters");
1118        exit(1);
1119    }
1120
1121    union selinux_callback cb;
1122    cb.func_log = log_callback;
1123    selinux_set_callback(SELINUX_CB_LOG, cb);
1124
1125    if (selinux_enabled && selinux_status_open(true) < 0) {
1126        ALOGE("Could not open selinux status; exiting.\n");
1127        exit(1);
1128    }
1129
1130    int ret = android::installd::gOps.Main(argc, argv);
1131
1132    return ret;
1133}
1134
1135}  // namespace installd
1136}  // namespace android
1137
1138int main(const int argc, char *argv[]) {
1139    return android::installd::otapreopt_main(argc, argv);
1140}
1141