xref: /aosp_15_r20/art/artd/artd.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_ARTD_ARTD_H_
18 #define ART_ARTD_ARTD_H_
19 
20 #include <sys/inotify.h>
21 #include <sys/mount.h>
22 #include <sys/poll.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 
26 #include <csignal>
27 #include <cstdint>
28 #include <functional>
29 #include <memory>
30 #include <mutex>
31 #include <optional>
32 #include <string>
33 #include <unordered_map>
34 #include <unordered_set>
35 #include <utility>
36 #include <vector>
37 
38 #include "aidl/com/android/server/art/BnArtd.h"
39 #include "aidl/com/android/server/art/BnArtdCancellationSignal.h"
40 #include "aidl/com/android/server/art/BnArtdNotification.h"
41 #include "android-base/result.h"
42 #include "android-base/thread_annotations.h"
43 #include "android-base/unique_fd.h"
44 #include "android/binder_auto_utils.h"
45 #include "base/os.h"
46 #include "base/pidfd.h"
47 #include "exec_utils.h"
48 #include "oat/oat_file_assistant_context.h"
49 #include "tools/cmdline_builder.h"
50 #include "tools/system_properties.h"
51 
52 namespace art {
53 namespace artd {
54 
55 // Define these function types instead of getting them from C headers because those from glibc C
56 // headers contain the unwanted `noexcept`.
57 using KillFn = int(pid_t, int);
58 using FstatFn = int(int, struct stat*);
59 using PollFn = int(struct pollfd*, nfds_t, int);
60 using MountFn = int(const char*, const char*, const char*, uint32_t, const void*);
61 
62 android::base::Result<void> Restorecon(
63     const std::string& path,
64     const std::optional<
65         aidl::com::android::server::art::OutputArtifacts::PermissionSettings::SeContext>&
66         se_context,
67     bool recurse);
68 
69 struct Options {
70   // If true, this artd instance is for Pre-reboot Dexopt. It runs in a chroot environment that is
71   // set up by dexopt_chroot_setup.
72   bool is_pre_reboot = false;
73 };
74 
75 class ArtdCancellationSignal : public aidl::com::android::server::art::BnArtdCancellationSignal {
76  public:
ArtdCancellationSignal(std::function<KillFn> kill_func)77   explicit ArtdCancellationSignal(std::function<KillFn> kill_func) : kill_(std::move(kill_func)) {}
78 
79   ndk::ScopedAStatus cancel() override;
80 
81   ndk::ScopedAStatus getType(int64_t* _aidl_return) override;
82 
83   // Returns callbacks to be provided to `ExecUtils`, to register/unregister the process with this
84   // cancellation signal.
85   ExecCallbacks CreateExecCallbacks();
86 
87   bool IsCancelled();
88 
89  private:
90   std::mutex mu_;
91   // True if cancellation has been signaled.
92   bool is_cancelled_ GUARDED_BY(mu_) = false;
93   // The pids of currently running child processes that are bound to this signal.
94   std::unordered_set<pid_t> pids_ GUARDED_BY(mu_);
95 
96   std::function<KillFn> kill_;
97 };
98 
99 class ArtdNotification : public aidl::com::android::server::art::BnArtdNotification {
100  public:
ArtdNotification()101   ArtdNotification() : done_(true) {}
ArtdNotification(std::function<PollFn> poll_func,const std::string & path,android::base::unique_fd && inotify_fd,android::base::unique_fd && pidfd)102   ArtdNotification(std::function<PollFn> poll_func,
103                    const std::string& path,
104                    android::base::unique_fd&& inotify_fd,
105                    android::base::unique_fd&& pidfd)
106       : poll_(poll_func),
107         path_(std::move(path)),
108         inotify_fd_(std::move(inotify_fd)),
109         pidfd_(std::move(pidfd)),
110         done_(false) {}
111 
112   ndk::ScopedAStatus wait(int in_timeoutMs, bool* _aidl_return) EXCLUDES(mu_) override;
113 
114   virtual ~ArtdNotification();
115 
116  private:
117   void CleanUp() EXCLUDES(mu_);
118 
119   const std::function<PollFn> poll_;
120 
121   std::mutex mu_;
122   std::string path_ GUARDED_BY(mu_);
123   android::base::unique_fd inotify_fd_ GUARDED_BY(mu_);
124   android::base::unique_fd pidfd_ GUARDED_BY(mu_);
125   bool done_ GUARDED_BY(mu_);
126   bool is_called_ GUARDED_BY(mu_) = false;
127 };
128 
129 class Artd : public aidl::com::android::server::art::BnArtd {
130  public:
131   explicit Artd(Options&& options,
132                 std::unique_ptr<art::tools::SystemProperties> props =
133                     std::make_unique<art::tools::SystemProperties>(),
134                 std::unique_ptr<ExecUtils> exec_utils = std::make_unique<ExecUtils>(),
135                 std::function<KillFn> kill_func = kill,
136                 std::function<FstatFn> fstat_func = fstat,
137                 std::function<PollFn> poll_func = poll,
138                 std::function<MountFn> mount_func = mount,
139                 std::function<decltype(Restorecon)> restorecon_func = Restorecon,
140                 std::optional<std::string> pre_reboot_tmp_dir = std::nullopt,
141                 std::optional<std::string> init_environ_rc_path = std::nullopt)
options_(std::move (options))142       : options_(std::move(options)),
143         props_(std::move(props)),
144         exec_utils_(std::move(exec_utils)),
145         kill_(std::move(kill_func)),
146         fstat_(std::move(fstat_func)),
147         poll_(std::move(poll_func)),
148         mount_(std::move(mount_func)),
149         restorecon_(std::move(restorecon_func)),
150         pre_reboot_tmp_dir_(std::move(pre_reboot_tmp_dir)),
151         init_environ_rc_path_(std::move(init_environ_rc_path)) {}
152 
153   ndk::ScopedAStatus isAlive(bool* _aidl_return) override;
154 
155   ndk::ScopedAStatus deleteArtifacts(
156       const aidl::com::android::server::art::ArtifactsPath& in_artifactsPath,
157       int64_t* _aidl_return) override;
158 
159   ndk::ScopedAStatus getDexoptStatus(
160       const std::string& in_dexFile,
161       const std::string& in_instructionSet,
162       const std::optional<std::string>& in_classLoaderContext,
163       aidl::com::android::server::art::GetDexoptStatusResult* _aidl_return) override;
164 
165   ndk::ScopedAStatus isProfileUsable(const aidl::com::android::server::art::ProfilePath& in_profile,
166                                      const std::string& in_dexFile,
167                                      bool* _aidl_return) override;
168 
169   ndk::ScopedAStatus copyAndRewriteProfile(
170       const aidl::com::android::server::art::ProfilePath& in_src,
171       aidl::com::android::server::art::OutputProfile* in_dst,
172       const std::string& in_dexFile,
173       aidl::com::android::server::art::CopyAndRewriteProfileResult* _aidl_return) override;
174 
175   ndk::ScopedAStatus copyAndRewriteEmbeddedProfile(
176       aidl::com::android::server::art::OutputProfile* in_dst,
177       const std::string& in_dexFile,
178       aidl::com::android::server::art::CopyAndRewriteProfileResult* _aidl_return) override;
179 
180   ndk::ScopedAStatus commitTmpProfile(
181       const aidl::com::android::server::art::ProfilePath::TmpProfilePath& in_profile) override;
182 
183   ndk::ScopedAStatus deleteProfile(
184       const aidl::com::android::server::art::ProfilePath& in_profile) override;
185 
186   ndk::ScopedAStatus getProfileVisibility(
187       const aidl::com::android::server::art::ProfilePath& in_profile,
188       aidl::com::android::server::art::FileVisibility* _aidl_return) override;
189 
190   ndk::ScopedAStatus mergeProfiles(
191       const std::vector<aidl::com::android::server::art::ProfilePath>& in_profiles,
192       const std::optional<aidl::com::android::server::art::ProfilePath>& in_referenceProfile,
193       aidl::com::android::server::art::OutputProfile* in_outputProfile,
194       const std::vector<std::string>& in_dexFiles,
195       const aidl::com::android::server::art::MergeProfileOptions& in_options,
196       bool* _aidl_return) override;
197 
198   ndk::ScopedAStatus getArtifactsVisibility(
199       const aidl::com::android::server::art::ArtifactsPath& in_artifactsPath,
200       aidl::com::android::server::art::FileVisibility* _aidl_return) override;
201 
202   ndk::ScopedAStatus getDexFileVisibility(
203       const std::string& in_dexFile,
204       aidl::com::android::server::art::FileVisibility* _aidl_return) override;
205 
206   ndk::ScopedAStatus getDmFileVisibility(
207       const aidl::com::android::server::art::DexMetadataPath& in_dmFile,
208       aidl::com::android::server::art::FileVisibility* _aidl_return) override;
209 
210   ndk::ScopedAStatus getDexoptNeeded(
211       const std::string& in_dexFile,
212       const std::string& in_instructionSet,
213       const std::optional<std::string>& in_classLoaderContext,
214       const std::string& in_compilerFilter,
215       int32_t in_dexoptTrigger,
216       aidl::com::android::server::art::GetDexoptNeededResult* _aidl_return) override;
217 
218   ndk::ScopedAStatus dexopt(
219       const aidl::com::android::server::art::OutputArtifacts& in_outputArtifacts,
220       const std::string& in_dexFile,
221       const std::string& in_instructionSet,
222       const std::optional<std::string>& in_classLoaderContext,
223       const std::string& in_compilerFilter,
224       const std::optional<aidl::com::android::server::art::ProfilePath>& in_profile,
225       const std::optional<aidl::com::android::server::art::VdexPath>& in_inputVdex,
226       const std::optional<aidl::com::android::server::art::DexMetadataPath>& in_dmFile,
227       aidl::com::android::server::art::PriorityClass in_priorityClass,
228       const aidl::com::android::server::art::DexoptOptions& in_dexoptOptions,
229       const std::shared_ptr<aidl::com::android::server::art::IArtdCancellationSignal>&
230           in_cancellationSignal,
231       aidl::com::android::server::art::ArtdDexoptResult* _aidl_return) override;
232 
233   ndk::ScopedAStatus createCancellationSignal(
234       std::shared_ptr<aidl::com::android::server::art::IArtdCancellationSignal>* _aidl_return)
235       override;
236 
237   ndk::ScopedAStatus cleanup(
238       const std::vector<aidl::com::android::server::art::ProfilePath>& in_profilesToKeep,
239       const std::vector<aidl::com::android::server::art::ArtifactsPath>& in_artifactsToKeep,
240       const std::vector<aidl::com::android::server::art::VdexPath>& in_vdexFilesToKeep,
241       const std::vector<aidl::com::android::server::art::RuntimeArtifactsPath>&
242           in_runtimeArtifactsToKeep,
243       bool in_keepPreRebootStagedFiles,
244       int64_t* _aidl_return) override;
245 
246   ndk::ScopedAStatus cleanUpPreRebootStagedFiles() override;
247 
248   ndk::ScopedAStatus isInDalvikCache(const std::string& in_dexFile, bool* _aidl_return) override;
249 
250   ndk::ScopedAStatus deleteRuntimeArtifacts(
251       const aidl::com::android::server::art::RuntimeArtifactsPath& in_runtimeArtifactsPath,
252       int64_t* _aidl_return) override;
253 
254   ndk::ScopedAStatus getArtifactsSize(
255       const aidl::com::android::server::art::ArtifactsPath& in_artifactsPath,
256       int64_t* _aidl_return) override;
257 
258   ndk::ScopedAStatus getVdexFileSize(const aidl::com::android::server::art::VdexPath& in_vdexPath,
259                                      int64_t* _aidl_return) override;
260 
261   ndk::ScopedAStatus getRuntimeArtifactsSize(
262       const aidl::com::android::server::art::RuntimeArtifactsPath& in_runtimeArtifactsPath,
263       int64_t* _aidl_return) override;
264 
265   ndk::ScopedAStatus getProfileSize(const aidl::com::android::server::art::ProfilePath& in_profile,
266                                     int64_t* _aidl_return) override;
267 
268   ndk::ScopedAStatus initProfileSaveNotification(
269       const aidl::com::android::server::art::ProfilePath::PrimaryCurProfilePath& in_profilePath,
270       int in_pid,
271       std::shared_ptr<aidl::com::android::server::art::IArtdNotification>* _aidl_return) override;
272 
273   ndk::ScopedAStatus commitPreRebootStagedFiles(
274       const std::vector<aidl::com::android::server::art::ArtifactsPath>& in_artifacts,
275       const std::vector<aidl::com::android::server::art::ProfilePath::WritableProfilePath>&
276           in_profiles,
277       bool* _aidl_return) override;
278 
279   ndk::ScopedAStatus checkPreRebootSystemRequirements(const std::string& in_chrootDir,
280                                                       bool* _aidl_return) override;
281 
282   ndk::ScopedAStatus preRebootInit(
283       const std::shared_ptr<aidl::com::android::server::art::IArtdCancellationSignal>&
284           in_cancellationSignal,
285       bool* _aidl_return) override;
286 
287   ndk::ScopedAStatus validateDexPath(const std::string& in_dexFile,
288                                      std::optional<std::string>* _aidl_return) override;
289 
290   ndk::ScopedAStatus validateClassLoaderContext(const std::string& in_dexFile,
291                                                 const std::string& in_classLoaderContext,
292                                                 std::optional<std::string>* _aidl_return) override;
293 
294   android::base::Result<void> Start();
295 
296  private:
297   android::base::Result<OatFileAssistantContext*> GetOatFileAssistantContext()
298       EXCLUDES(ofa_context_mu_);
299 
300   android::base::Result<const std::vector<std::string>*> GetBootImageLocations()
301       EXCLUDES(cache_mu_);
302 
303   android::base::Result<const std::vector<std::string>*> GetBootClassPath() EXCLUDES(cache_mu_);
304 
305   bool UseJitZygote() EXCLUDES(cache_mu_);
306   bool UseJitZygoteLocked() REQUIRES(cache_mu_);
307 
308   const std::string& GetUserDefinedBootImageLocations() EXCLUDES(cache_mu_);
309   const std::string& GetUserDefinedBootImageLocationsLocked() REQUIRES(cache_mu_);
310 
311   bool DenyArtApexDataFiles() EXCLUDES(cache_mu_);
312   bool DenyArtApexDataFilesLocked() REQUIRES(cache_mu_);
313 
314   android::base::Result<int> ExecAndReturnCode(const std::vector<std::string>& arg_vector,
315                                                int timeout_sec,
316                                                const ExecCallbacks& callbacks = ExecCallbacks(),
317                                                ProcessStat* stat = nullptr) const;
318 
319   android::base::Result<std::string> GetProfman();
320 
321   android::base::Result<tools::CmdlineBuilder> GetArtExecCmdlineBuilder();
322 
323   bool ShouldUseDex2Oat64();
324 
325   bool ShouldUseDebugBinaries();
326 
327   android::base::Result<std::string> GetDex2Oat();
328 
329   bool ShouldCreateSwapFileForDexopt();
330 
331   void AddBootImageFlags(/*out*/ art::tools::CmdlineBuilder& args);
332 
333   void AddCompilerConfigFlags(const std::string& instruction_set,
334                               const std::string& compiler_filter,
335                               aidl::com::android::server::art::PriorityClass priority_class,
336                               const aidl::com::android::server::art::DexoptOptions& dexopt_options,
337                               /*out*/ art::tools::CmdlineBuilder& args);
338 
339   void AddPerfConfigFlags(aidl::com::android::server::art::PriorityClass priority_class,
340                           /*out*/ art::tools::CmdlineBuilder& art_exec_args,
341                           /*out*/ art::tools::CmdlineBuilder& args);
342 
343   android::base::Result<struct stat> Fstat(const art::File& file) const;
344 
345   // Creates a new dir at `source` and bind-mounts it at `target`.
346   android::base::Result<void> BindMountNewDir(const std::string& source,
347                                               const std::string& target) const;
348 
349   android::base::Result<void> BindMount(const std::string& source, const std::string& target) const;
350 
351   ndk::ScopedAStatus CopyAndRewriteProfileImpl(
352       File src,
353       aidl::com::android::server::art::OutputProfile* dst_aidl,
354       const std::string& dex_path,
355       aidl::com::android::server::art::CopyAndRewriteProfileResult* aidl_return);
356 
357   android::base::Result<void> PreRebootInitClearEnvs();
358   android::base::Result<void> PreRebootInitSetEnvFromFile(const std::string& path);
359   android::base::Result<void> PreRebootInitDeriveClasspath(const std::string& path);
360   android::base::Result<bool> PreRebootInitBootImages(ArtdCancellationSignal* cancellation_signal);
361 
362   std::mutex cache_mu_;
363   std::optional<std::vector<std::string>> cached_boot_image_locations_ GUARDED_BY(cache_mu_);
364   std::optional<std::vector<std::string>> cached_boot_class_path_ GUARDED_BY(cache_mu_);
365   std::optional<bool> cached_use_jit_zygote_ GUARDED_BY(cache_mu_);
366   std::optional<std::string> cached_user_defined_boot_image_locations_ GUARDED_BY(cache_mu_);
367   std::optional<bool> cached_deny_art_apex_data_files_ GUARDED_BY(cache_mu_);
368 
369   std::mutex ofa_context_mu_;
370   std::unique_ptr<OatFileAssistantContext> ofa_context_ GUARDED_BY(ofa_context_mu_);
371 
372   const Options options_;
373   const std::unique_ptr<art::tools::SystemProperties> props_;
374   const std::unique_ptr<ExecUtils> exec_utils_;
375   const std::function<KillFn> kill_;
376   const std::function<FstatFn> fstat_;
377   const std::function<PollFn> poll_;
378   const std::function<MountFn> mount_;
379   const std::function<decltype(Restorecon)> restorecon_;
380   const std::optional<std::string> pre_reboot_tmp_dir_;
381   const std::optional<std::string> init_environ_rc_path_;
382 };
383 
384 // A class for getting system properties from a `build.prop` file.
385 // Note that this class ignores import statements and only reads properties from the given file
386 // itself. To read properties from an imported file, insatiate this class with the imported file
387 // directly.
388 class BuildSystemProperties : public tools::SystemProperties {
389  public:
390   // Creates an instance and loads system properties from the `build.prop` file specified at the
391   // given path.
392   static android::base::Result<BuildSystemProperties> Create(const std::string& filename);
393 
394  protected:
395   std::string GetProperty(const std::string& key) const override;
396 
397  private:
BuildSystemProperties(std::unordered_map<std::string,std::string> && system_properties)398   explicit BuildSystemProperties(std::unordered_map<std::string, std::string>&& system_properties)
399       : system_properties_(std::move(system_properties)) {}
400 
401   const std::unordered_map<std::string, std::string> system_properties_;
402 };
403 
404 }  // namespace artd
405 }  // namespace art
406 
407 #endif  // ART_ARTD_ARTD_H_
408