blob: b00c46e0db21f6fc9871bf99c3f0731dd0b4a97a [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>
21
Vishnu Nair6921f802017-11-22 09:17:23 -080022/*
23 * Converts seconds to milliseconds.
24 */
25#define SEC_TO_MSEC(second) (second * 1000)
26
27/*
28 * Converts milliseconds to seconds.
29 */
30#define MSEC_TO_SEC(millisecond) (millisecond / 1000)
31
Felipe Leme47e9be22016-12-21 15:37:07 -080032namespace android {
33namespace os {
34namespace dumpstate {
Felipe Leme6f674ae2016-11-18 17:10:33 -080035
Felipe Lemebda15a02016-11-16 17:48:25 -080036/*
Felipe Leme46b85da2016-11-21 17:40:45 -080037 * Defines the Linux account that should be executing a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080038 */
Felipe Leme46b85da2016-11-21 17:40:45 -080039enum PrivilegeMode {
Felipe Lemebda15a02016-11-16 17:48:25 -080040 /* Explicitly change the `uid` and `gid` to be `shell`.*/
41 DROP_ROOT,
42 /* Don't change the `uid` and `gid`. */
43 DONT_DROP_ROOT,
44 /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
45 SU_ROOT
46};
47
48/*
Felipe Leme46b85da2016-11-21 17:40:45 -080049 * Defines what should happen with the main output stream (`stdout` or fd) of a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080050 */
Felipe Leme46b85da2016-11-21 17:40:45 -080051enum OutputMode {
52 /* Don't change main output. */
53 NORMAL_OUTPUT,
54 /* Redirect main output to `stderr`. */
Felipe Lemebda15a02016-11-16 17:48:25 -080055 REDIRECT_TO_STDERR
56};
57
58/*
59 * Value object used to set command options.
60 *
61 * Typically constructed using a builder with chained setters. Examples:
62 *
63 * CommandOptions::WithTimeout(20).AsRoot().Build();
64 * CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
65 *
66 * Although the builder could be used to dynamically set values. Example:
67 *
68 * CommandOptions::CommandOptionsBuilder options =
69 * CommandOptions::WithTimeout(10);
70 * if (!is_user_build()) {
71 * options.AsRoot();
72 * }
73 * RunCommand("command", {"args"}, options.Build());
74 */
75class CommandOptions {
76 private:
77 class CommandOptionsValues {
78 private:
Chih-Hung Hsiehd0937e62018-12-20 15:43:57 -080079 explicit CommandOptionsValues(int64_t timeout_ms);
Felipe Lemebda15a02016-11-16 17:48:25 -080080
Vishnu Nair6921f802017-11-22 09:17:23 -080081 int64_t timeout_ms_;
Felipe Lemebda15a02016-11-16 17:48:25 -080082 bool always_;
Primiano Tuccifaaaafb2021-01-14 12:26:29 +000083 bool close_all_fds_on_exec_;
Felipe Leme46b85da2016-11-21 17:40:45 -080084 PrivilegeMode account_mode_;
85 OutputMode output_mode_;
Felipe Lemebda15a02016-11-16 17:48:25 -080086 std::string logging_message_;
87
88 friend class CommandOptions;
89 friend class CommandOptionsBuilder;
90 };
91
Chih-Hung Hsiehd0937e62018-12-20 15:43:57 -080092 explicit CommandOptions(const CommandOptionsValues& values);
Felipe Lemebda15a02016-11-16 17:48:25 -080093
94 const CommandOptionsValues values;
95
96 public:
97 class CommandOptionsBuilder {
98 public:
99 /* Sets the command to always run, even on `dry-run` mode. */
100 CommandOptionsBuilder& Always();
Nandana Dutt4b392be2018-11-02 16:17:05 +0000101 /*
102 * Sets the command's PrivilegeMode as `SU_ROOT` unless overridden by system property
103 * 'dumpstate.unroot'.
104 */
Felipe Lemebda15a02016-11-16 17:48:25 -0800105 CommandOptionsBuilder& AsRoot();
Nandana Dutt4b392be2018-11-02 16:17:05 +0000106 /*
107 * Runs AsRoot() on userdebug builds. No-op on user builds since 'su' is
108 * not available. This is used for commands that return some useful information even
109 * when run as shell.
110 */
Yifan Hong48e83a12017-10-03 14:10:07 -0700111 CommandOptionsBuilder& AsRootIfAvailable();
Felipe Leme46b85da2016-11-21 17:40:45 -0800112 /* Sets the command's PrivilegeMode as `DROP_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -0800113 CommandOptionsBuilder& DropRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -0800114 /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
Felipe Lemebda15a02016-11-16 17:48:25 -0800115 CommandOptionsBuilder& RedirectStderr();
Primiano Tuccifaaaafb2021-01-14 12:26:29 +0000116 /* Closes all file descriptors before exec-ing the target process. This
117 * includes also stdio pipes, which are dup-ed on /dev/null. It prevents
118 * leaking opened FDs to the target process, which in turn can hit
119 * selinux denials in presence of auto_trans rules.
120 */
121 CommandOptionsBuilder& CloseAllFileDescriptorsOnExec();
122
Felipe Lemebda15a02016-11-16 17:48:25 -0800123 /* When not empty, logs a message before executing the command.
124 * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
125 CommandOptionsBuilder& Log(const std::string& message);
126 /* Builds the command options. */
127 CommandOptions Build();
128
129 private:
Chih-Hung Hsiehd0937e62018-12-20 15:43:57 -0800130 explicit CommandOptionsBuilder(int64_t timeout_ms);
Felipe Lemebda15a02016-11-16 17:48:25 -0800131 CommandOptionsValues values;
132 friend class CommandOptions;
133 };
134
Vishnu Nair6921f802017-11-22 09:17:23 -0800135 /** Gets the command timeout in seconds. */
Felipe Lemebda15a02016-11-16 17:48:25 -0800136 int64_t Timeout() const;
Vishnu Nair6921f802017-11-22 09:17:23 -0800137 /** Gets the command timeout in milliseconds. */
138 int64_t TimeoutInMs() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800139 /* Checks whether the command should always be run, even on dry-run mode. */
140 bool Always() const;
Primiano Tuccifaaaafb2021-01-14 12:26:29 +0000141 /* Checks whether all FDs should be closed prior to the exec() calls. */
142 bool ShouldCloseAllFileDescriptorsOnExec() const;
Felipe Leme46b85da2016-11-21 17:40:45 -0800143 /** Gets the PrivilegeMode of the command. */
144 PrivilegeMode PrivilegeMode() const;
145 /** Gets the OutputMode of the command. */
146 OutputMode OutputMode() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800147 /** Gets the logging message header, it any. */
148 std::string LoggingMessage() const;
149
Vishnu Nair6921f802017-11-22 09:17:23 -0800150 /** Creates a builder with the requied timeout in seconds. */
151 static CommandOptionsBuilder WithTimeout(int64_t timeout_sec);
152
153 /** Creates a builder with the requied timeout in milliseconds. */
154 static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms);
Felipe Lemebda15a02016-11-16 17:48:25 -0800155
156 // Common options.
157 static CommandOptions DEFAULT;
Felipe Lemef0292972016-11-22 13:57:05 -0800158 static CommandOptions AS_ROOT;
Felipe Lemef0292972016-11-22 13:57:05 -0800159};
160
161/*
162 * System properties helper.
163 */
164class PropertiesHelper {
165 friend class DumpstateBaseTest;
166
167 public:
168 /*
169 * Gets whether device is running a `user` build.
170 */
171 static bool IsUserBuild();
172
173 /*
174 * When running in dry-run mode, skips the real dumps and just print the section headers.
175 *
176 * Useful when debugging dumpstate or other bugreport-related activities.
177 *
178 * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
179 */
180 static bool IsDryRun();
181
Nandana Dutt4b392be2018-11-02 16:17:05 +0000182 /**
183 * Checks whether root availability should be overridden.
184 *
185 * Useful to verify how dumpstate would work in a device with an user build.
186 */
187 static bool IsUnroot();
188
Rhed Jao1c855122020-07-16 17:37:39 +0800189 /*
190 * Whether or not the parallel run is enabled. Setting the system property
191 * 'dumpstate.parallel_run' to false to disable it, otherwise it returns
192 * true by default.
193 */
194 static bool IsParallelRun();
195
Felipe Lemef0292972016-11-22 13:57:05 -0800196 private:
197 static std::string build_type_;
198 static int dry_run_;
Nandana Dutt4b392be2018-11-02 16:17:05 +0000199 static int unroot_;
Rhed Jao1c855122020-07-16 17:37:39 +0800200 static int parallel_run_;
Felipe Lemebda15a02016-11-16 17:48:25 -0800201};
202
203/*
204 * Forks a command, waits for it to finish, and returns its status.
205 *
206 * |fd| file descriptor that receives the command's 'stdout'.
Felipe Lemef0292972016-11-22 13:57:05 -0800207 * |title| description of the command printed on `stdout` (or empty to skip
208 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800209 * |full_command| array containing the command (first entry) and its arguments.
Felipe Leme46b85da2016-11-21 17:40:45 -0800210 * Must contain at least one element.
Felipe Lemebda15a02016-11-16 17:48:25 -0800211 * |options| optional argument defining the command's behavior.
Felipe Lemebda15a02016-11-16 17:48:25 -0800212 */
Felipe Lemef0292972016-11-22 13:57:05 -0800213int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
Felipe Leme46b85da2016-11-21 17:40:45 -0800214 const CommandOptions& options = CommandOptions::DEFAULT);
Felipe Lemebda15a02016-11-16 17:48:25 -0800215
216/*
217 * Dumps the contents of a file into a file descriptor.
218 *
219 * |fd| file descriptor where the file is dumped into.
Felipe Lemef0292972016-11-22 13:57:05 -0800220 * |title| description of the command printed on `stdout` (or empty to skip
221 * description).
Felipe Lemebda15a02016-11-16 17:48:25 -0800222 * |path| location of the file to be dumped.
223 */
Felipe Lemef0292972016-11-22 13:57:05 -0800224int DumpFileToFd(int fd, const std::string& title, const std::string& path);
Felipe Lemebda15a02016-11-16 17:48:25 -0800225
Felipe Leme47e9be22016-12-21 15:37:07 -0800226} // namespace dumpstate
227} // namespace os
228} // namespace android
229
230#endif // ANDROID_OS_DUMPSTATE_UTIL_H_