blob: ae7152a26adbbdb59c32c145f3f64ef34ff1e71c [file] [log] [blame]
Felipe Lemebda15a02016-11-16 17:48:25 -08001/*
Felipe Leme6f674ae2016-11-18 17:10:33 -08002 * Copyright (C) 2016 The Android Open Source Project
Felipe Lemebda15a02016-11-16 17:48:25 -08003 *
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 */
Felipe Leme47e9be22016-12-21 15:37:07 -080016#ifndef ANDROID_OS_DUMPSTATE_UTIL_H_
17#define ANDROID_OS_DUMPSTATE_UTIL_H_
Felipe Lemebda15a02016-11-16 17:48:25 -080018
Felipe Lemef0292972016-11-22 13:57:05 -080019#include <cstdint>
20#include <string>
Yi Kong7a2045d2024-05-24 00:43:25 +090021#include <vector>
Felipe Lemef0292972016-11-22 13:57:05 -080022
Vishnu Nair6921f802017-11-22 09:17:23 -080023/*
24 * Converts seconds to milliseconds.
25 */
26#define SEC_TO_MSEC(second) (second * 1000)
27
28/*
29 * Converts milliseconds to seconds.
30 */
31#define MSEC_TO_SEC(millisecond) (millisecond / 1000)
32
Felipe Leme47e9be22016-12-21 15:37:07 -080033namespace android {
34namespace os {
35namespace dumpstate {
Felipe Leme6f674ae2016-11-18 17:10:33 -080036
Felipe Lemebda15a02016-11-16 17:48:25 -080037/*
Felipe Leme46b85da2016-11-21 17:40:45 -080038 * Defines the Linux account that should be executing a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080039 */
Felipe Leme46b85da2016-11-21 17:40:45 -080040enum PrivilegeMode {
Felipe Lemebda15a02016-11-16 17:48:25 -080041 /* Explicitly change the `uid` and `gid` to be `shell`.*/
42 DROP_ROOT,
43 /* Don't change the `uid` and `gid`. */
44 DONT_DROP_ROOT,
45 /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
46 SU_ROOT
47};
48
49/*
Felipe Leme46b85da2016-11-21 17:40:45 -080050 * Defines what should happen with the main output stream (`stdout` or fd) of a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080051 */
Felipe Leme46b85da2016-11-21 17:40:45 -080052enum OutputMode {
53 /* Don't change main output. */
54 NORMAL_OUTPUT,
55 /* Redirect main output to `stderr`. */
Felipe Lemebda15a02016-11-16 17:48:25 -080056 REDIRECT_TO_STDERR
57};
58
59/*
60 * Value object used to set command options.
61 *
62 * Typically constructed using a builder with chained setters. Examples:
63 *
64 * CommandOptions::WithTimeout(20).AsRoot().Build();
65 * CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
66 *
67 * Although the builder could be used to dynamically set values. Example:
68 *
69 * CommandOptions::CommandOptionsBuilder options =
70 * CommandOptions::WithTimeout(10);
71 * if (!is_user_build()) {
72 * options.AsRoot();
73 * }
74 * RunCommand("command", {"args"}, options.Build());
75 */
76class CommandOptions {
77 private:
78 class CommandOptionsValues {
79 private:
Chih-Hung Hsiehd0937e62018-12-20 15:43:57 -080080 explicit CommandOptionsValues(int64_t timeout_ms);
Felipe Lemebda15a02016-11-16 17:48:25 -080081
Vishnu Nair6921f802017-11-22 09:17:23 -080082 int64_t timeout_ms_;
Felipe Lemebda15a02016-11-16 17:48:25 -080083 bool always_;
Primiano Tuccifaaaafb2021-01-14 12:26:29 +000084 bool close_all_fds_on_exec_;
Felipe Leme46b85da2016-11-21 17:40:45 -080085 PrivilegeMode account_mode_;
86 OutputMode output_mode_;
Felipe Lemebda15a02016-11-16 17:48:25 -080087 std::string logging_message_;
88
89 friend class CommandOptions;
90 friend class CommandOptionsBuilder;
91 };
92
Chih-Hung Hsiehd0937e62018-12-20 15:43:57 -080093 explicit CommandOptions(const CommandOptionsValues& values);
Felipe Lemebda15a02016-11-16 17:48:25 -080094
95 const CommandOptionsValues values;
96
97 public:
98 class CommandOptionsBuilder {
99 public:
100 /* Sets the command to always run, even on `dry-run` mode. */
101 CommandOptionsBuilder& Always();
Nandana Dutt4b392be2018-11-02 16:17:05 +0000102 /*
103 * Sets the command's PrivilegeMode as `SU_ROOT` unless overridden by system property
104 * 'dumpstate.unroot'.
105 */
Felipe Lemebda15a02016-11-16 17:48:25 -0800106 CommandOptionsBuilder& AsRoot();
Nandana Dutt4b392be2018-11-02 16:17:05 +0000107 /*
108 * Runs AsRoot() on userdebug builds. No-op on user builds since 'su' is
109 * not available. This is used for commands that return some useful information even
110 * when run as shell.
111 */
Yifan Hong48e83a12017-10-03 14:10:07 -0700112 CommandOptionsBuilder& AsRootIfAvailable();
Felipe Leme46b85da2016-11-21 17:40:45 -0800113 /* Sets the command's PrivilegeMode as `DROP_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -0800114 CommandOptionsBuilder& DropRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -0800115 /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
Felipe Lemebda15a02016-11-16 17:48:25 -0800116 CommandOptionsBuilder& RedirectStderr();
Primiano Tuccifaaaafb2021-01-14 12:26:29 +0000117 /* Closes all file descriptors before exec-ing the target process. This
118 * includes also stdio pipes, which are dup-ed on /dev/null. It prevents
119 * leaking opened FDs to the target process, which in turn can hit
120 * selinux denials in presence of auto_trans rules.
121 */
122 CommandOptionsBuilder& CloseAllFileDescriptorsOnExec();
123
Felipe Lemebda15a02016-11-16 17:48:25 -0800124 /* When not empty, logs a message before executing the command.
125 * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
126 CommandOptionsBuilder& Log(const std::string& message);
127 /* Builds the command options. */
128 CommandOptions Build();
129
130 private:
Chih-Hung Hsiehd0937e62018-12-20 15:43:57 -0800131 explicit CommandOptionsBuilder(int64_t timeout_ms);
Felipe Lemebda15a02016-11-16 17:48:25 -0800132 CommandOptionsValues values;
133 friend class CommandOptions;
134 };
135
Vishnu Nair6921f802017-11-22 09:17:23 -0800136 /** Gets the command timeout in seconds. */
Felipe Lemebda15a02016-11-16 17:48:25 -0800137 int64_t Timeout() const;
Vishnu Nair6921f802017-11-22 09:17:23 -0800138 /** Gets the command timeout in milliseconds. */
139 int64_t TimeoutInMs() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800140 /* Checks whether the command should always be run, even on dry-run mode. */
141 bool Always() const;
Primiano Tuccifaaaafb2021-01-14 12:26:29 +0000142 /* Checks whether all FDs should be closed prior to the exec() calls. */
143 bool ShouldCloseAllFileDescriptorsOnExec() const;
Felipe Leme46b85da2016-11-21 17:40:45 -0800144 /** Gets the PrivilegeMode of the command. */
145 PrivilegeMode PrivilegeMode() const;
146 /** Gets the OutputMode of the command. */
147 OutputMode OutputMode() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800148 /** Gets the logging message header, it any. */
149 std::string LoggingMessage() const;
150
Vishnu Nair6921f802017-11-22 09:17:23 -0800151 /** Creates a builder with the requied timeout in seconds. */
152 static CommandOptionsBuilder WithTimeout(int64_t timeout_sec);
153
154 /** Creates a builder with the requied timeout in milliseconds. */
155 static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms);
Felipe Lemebda15a02016-11-16 17:48:25 -0800156
157 // Common options.
158 static CommandOptions DEFAULT;
Felipe Lemef0292972016-11-22 13:57:05 -0800159 static CommandOptions AS_ROOT;
Felipe Lemef0292972016-11-22 13:57:05 -0800160};
161
162/*
163 * System properties helper.
164 */
165class PropertiesHelper {
166 friend class DumpstateBaseTest;
167
168 public:
169 /*
170 * Gets whether device is running a `user` build.
171 */
172 static bool IsUserBuild();
173
174 /*
175 * When running in dry-run mode, skips the real dumps and just print the section headers.
176 *
177 * Useful when debugging dumpstate or other bugreport-related activities.
178 *
179 * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
180 */
181 static bool IsDryRun();
182
Nandana Dutt4b392be2018-11-02 16:17:05 +0000183 /**
184 * Checks whether root availability should be overridden.
185 *
186 * Useful to verify how dumpstate would work in a device with an user build.
187 */
188 static bool IsUnroot();
189
Rhed Jao1c855122020-07-16 17:37:39 +0800190 /*
191 * Whether or not the parallel run is enabled. Setting the system property
192 * 'dumpstate.parallel_run' to false to disable it, otherwise it returns
193 * true by default.
194 */
195 static bool IsParallelRun();
196
Kevin Jeonfa64e642023-07-27 11:36:41 -0400197 /*
198 * Strict-run mode is determined by the `dumpstate.strict_run` sysprop which
199 * will default to true. This results in shortened timeouts for flaky
200 * sections.
201 */
202 static bool IsStrictRun();
203
Felipe Lemef0292972016-11-22 13:57:05 -0800204 private:
205 static std::string build_type_;
206 static int dry_run_;
Nandana Dutt4b392be2018-11-02 16:17:05 +0000207 static int unroot_;
Rhed Jao1c855122020-07-16 17:37:39 +0800208 static int parallel_run_;
Kevin Jeonfa64e642023-07-27 11:36:41 -0400209 static int strict_run_;
Felipe Lemebda15a02016-11-16 17:48:25 -0800210};
211
212/*
213 * Forks a command, waits for it to finish, and returns its status.
214 *
215 * |fd| file descriptor that receives the command's 'stdout'.
Felipe Lemef0292972016-11-22 13:57:05 -0800216 * |title| description of the command printed on `stdout` (or empty to skip
217 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800218 * |full_command| array containing the command (first entry) and its arguments.
Felipe Leme46b85da2016-11-21 17:40:45 -0800219 * Must contain at least one element.
Felipe Lemebda15a02016-11-16 17:48:25 -0800220 * |options| optional argument defining the command's behavior.
Felipe Lemebda15a02016-11-16 17:48:25 -0800221 */
Felipe Lemef0292972016-11-22 13:57:05 -0800222int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -0800223 const CommandOptions& options = CommandOptions::DEFAULT);
Felipe Lemebda15a02016-11-16 17:48:25 -0800224
225/*
226 * Dumps the contents of a file into a file descriptor.
227 *
228 * |fd| file descriptor where the file is dumped into.
Felipe Lemef0292972016-11-22 13:57:05 -0800229 * |title| description of the command printed on `stdout` (or empty to skip
230 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800231 * |path| location of the file to be dumped.
232 */
Felipe Lemef0292972016-11-22 13:57:05 -0800233int DumpFileToFd(int fd, const std::string& title, const std::string& path);
Felipe Lemebda15a02016-11-16 17:48:25 -0800234
Felipe Leme47e9be22016-12-21 15:37:07 -0800235} // namespace dumpstate
236} // namespace os
237} // namespace android
238
239#endif // ANDROID_OS_DUMPSTATE_UTIL_H_