blob: c60f4faf613003f168c026786b01fb076090836c [file] [log] [blame]
Andreas Gampe9d016d52018-10-19 18:56:50 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "apexd"
18
Andreas Gampee1a40392018-11-30 09:47:17 -080019#include <strings.h>
Andreas Gampe9d016d52018-10-19 18:56:50 -070020
Jiyong Parkb1d81b82019-05-10 21:12:27 +090021#include <ApexProperties.sysprop.h>
Andreas Gampe9d016d52018-10-19 18:56:50 -070022#include <android-base/logging.h>
Andreas Gampe9d016d52018-10-19 18:56:50 -070023
Andreas Gampee1a40392018-11-30 09:47:17 -080024#include "apexd.h"
Andreas Gampe6aaa2fe2019-03-29 14:13:59 -070025#include "apexd_checkpoint_vold.h"
Andreas Gampef7663552019-01-03 09:22:11 -080026#include "apexd_prepostinstall.h"
Martijn Coenen95da2732019-02-13 16:32:07 +010027#include "apexd_prop.h"
Andreas Gampe9d016d52018-10-19 18:56:50 -070028#include "apexservice.h"
29
Jiyong Park4d0f8322019-02-02 19:45:57 +090030#include <android-base/properties.h>
31
Andreas Gampee1a40392018-11-30 09:47:17 -080032namespace {
33
34int HandleSubcommand(char** argv) {
35 if (strcmp("--pre-install", argv[1]) == 0) {
36 LOG(INFO) << "Preinstall subcommand detected";
37 return android::apex::RunPreInstall(argv);
38 }
39
Andreas Gampef7663552019-01-03 09:22:11 -080040 if (strcmp("--post-install", argv[1]) == 0) {
41 LOG(INFO) << "Postinstall subcommand detected";
42 return android::apex::RunPostInstall(argv);
43 }
44
Jiyong Park715e23d2019-02-22 22:14:37 +090045 if (strcmp("--bootstrap", argv[1]) == 0) {
46 LOG(INFO) << "Bootstrap subcommand detected";
47 return android::apex::onBootstrap();
48 }
49
Nikita Ioffe0867c792019-11-06 21:43:13 +000050 if (strcmp("--unmount-all", argv[1]) == 0) {
51 LOG(INFO) << "Unmount all subcommand detected";
52 return android::apex::unmountAll();
53 }
54
Oli Lana18705f2020-01-18 14:35:46 +000055 if (strcmp("--snapshotde", argv[1]) == 0) {
56 LOG(INFO) << "Snapshot DE subcommand detected";
Oli Lan30e598c2020-05-15 17:00:26 +010057 // Need to know if checkpointing is enabled so that a prerestore snapshot
58 // can be taken if it's not.
59 android::base::Result<android::apex::VoldCheckpointInterface>
60 vold_service_st = android::apex::VoldCheckpointInterface::Create();
61 if (!vold_service_st.ok()) {
62 LOG(ERROR) << "Could not retrieve vold service: "
63 << vold_service_st.error();
64 } else {
65 android::apex::initializeVold(&*vold_service_st);
66 }
67
Oli Lan54da92a2020-02-06 11:40:04 +000068 int result = android::apex::snapshotOrRestoreDeUserData();
69
70 if (result == 0) {
71 // Notify other components (e.g. init) that all APEXs are ready to be used
72 // Note that it's important that the binder service is registered at this
73 // point, since other system services might depend on it.
74 android::apex::onAllPackagesReady();
75 }
76 return result;
Oli Lana18705f2020-01-18 14:35:46 +000077 }
78
Andreas Gampee1a40392018-11-30 09:47:17 -080079 LOG(ERROR) << "Unknown subcommand: " << argv[1];
80 return 1;
81}
82
Nikita Ioffee9684ac2020-05-07 14:14:19 +010083void InstallSigtermSignalHandler() {
84 struct sigaction action = {};
85 action.sa_handler = [](int /*signal*/) {
86 // Handle SIGTERM gracefully.
87 // By default, when SIGTERM is received a process will exit with non-zero
88 // exit code, which will trigger reboot_on_failure handler if one is
89 // defined. This doesn't play well with userspace reboot which might
90 // terminate apexd with SIGTERM if apexd was running at the moment of
91 // userspace reboot, hence this custom handler to exit gracefully.
92 _exit(0);
93 };
94 sigaction(SIGTERM, &action, nullptr);
95}
96
Andreas Gampee1a40392018-11-30 09:47:17 -080097} // namespace
98
Andreas Gampe9d016d52018-10-19 18:56:50 -070099int main(int /*argc*/, char** argv) {
Nikita Ioffe9c8e2622019-10-25 01:06:53 +0100100 android::base::InitLogging(argv, &android::base::KernelLogger);
Nikita Ioffe6ed9ccd2019-10-11 11:19:18 +0100101 // TODO: add a -v flag or an external setting to change LogSeverity.
102 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
Andreas Gampe9d016d52018-10-19 18:56:50 -0700103
Nikita Ioffee9684ac2020-05-07 14:14:19 +0100104 InstallSigtermSignalHandler();
105
Nikita Ioffe6ed9ccd2019-10-11 11:19:18 +0100106 const bool has_subcommand = argv[1] != nullptr;
Jiyong Parkb1d81b82019-05-10 21:12:27 +0900107 if (!android::sysprop::ApexProperties::updatable().value_or(false)) {
108 LOG(INFO) << "This device does not support updatable APEX. Exiting";
Nikita Ioffe6ed9ccd2019-10-11 11:19:18 +0100109 if (!has_subcommand) {
Oli Lan54da92a2020-02-06 11:40:04 +0000110 // mark apexd as activated so that init can proceed
111 android::apex::onAllPackagesActivated();
Oli Lan54da92a2020-02-06 11:40:04 +0000112 } else if (strcmp("--snapshotde", argv[1]) == 0) {
113 // mark apexd as ready
114 android::apex::onAllPackagesReady();
Nikita Ioffe6ed9ccd2019-10-11 11:19:18 +0100115 }
Jiyong Parkb1d81b82019-05-10 21:12:27 +0900116 return 0;
117 }
118
Nikita Ioffe6ed9ccd2019-10-11 11:19:18 +0100119 if (has_subcommand) {
Andreas Gampee1a40392018-11-30 09:47:17 -0800120 return HandleSubcommand(argv);
121 }
Andreas Gampe9d016d52018-10-19 18:56:50 -0700122
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100123 android::base::Result<android::apex::VoldCheckpointInterface>
Andreas Gampe6aaa2fe2019-03-29 14:13:59 -0700124 vold_service_st = android::apex::VoldCheckpointInterface::Create();
125 android::apex::VoldCheckpointInterface* vold_service = nullptr;
Bernie Innocentid04d5d02020-02-06 22:01:51 +0900126 if (!vold_service_st.ok()) {
Andreas Gampe6aaa2fe2019-03-29 14:13:59 -0700127 LOG(ERROR) << "Could not retrieve vold service: "
Mohammad Samiul Islambd6ab0f2019-06-20 15:55:27 +0100128 << vold_service_st.error();
Andreas Gampe6aaa2fe2019-03-29 14:13:59 -0700129 } else {
130 vold_service = &*vold_service_st;
131 }
Nikita Ioffedee4b6e2020-04-22 01:01:17 +0100132 android::apex::initialize(vold_service);
Andreas Gampe6aaa2fe2019-03-29 14:13:59 -0700133
Nikita Ioffedee4b6e2020-04-22 01:01:17 +0100134 bool booting = android::apex::isBooting();
135 if (booting) {
136 android::apex::migrateSessionsDirIfNeeded();
137 android::apex::onStart();
138 }
Andreas Gampe602ef782018-11-12 16:51:31 -0800139 android::apex::binder::CreateAndRegisterService();
Zimuzo9cc0be42019-01-09 11:37:34 +0000140 android::apex::binder::StartThreadPool();
Jiyong Park715e23d2019-02-22 22:14:37 +0900141
Nikita Ioffedee4b6e2020-04-22 01:01:17 +0100142 if (booting) {
143 // Notify other components (e.g. init) that all APEXs are correctly mounted
144 // and activated (but are not yet ready to be used). Configuration based on
145 // activated APEXs may be performed at this point, but use of APEXs
146 // themselves should wait for the ready status instead, which is set when
147 // the "--snapshotde" subcommand is received and snapshot/restore is
148 // complete.
149 android::apex::onAllPackagesActivated();
150 android::apex::waitForBootStatus(
151 android::apex::revertActiveSessionsAndReboot,
152 android::apex::bootCompletedCleanup);
153 }
Martijn Coenen95da2732019-02-13 16:32:07 +0100154
Jon Spivack1b840302020-02-06 18:34:30 -0800155 android::apex::binder::AllowServiceShutdown();
156
Andreas Gampe602ef782018-11-12 16:51:31 -0800157 android::apex::binder::JoinThreadPool();
Andreas Gampe9d016d52018-10-19 18:56:50 -0700158 return 1;
159}