xref: /aosp_15_r20/frameworks/native/cmds/dumpstate/DumpstateUtil.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker #ifndef ANDROID_OS_DUMPSTATE_UTIL_H_
17*38e8c45fSAndroid Build Coastguard Worker #define ANDROID_OS_DUMPSTATE_UTIL_H_
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <cstdint>
20*38e8c45fSAndroid Build Coastguard Worker #include <string>
21*38e8c45fSAndroid Build Coastguard Worker #include <vector>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker /*
24*38e8c45fSAndroid Build Coastguard Worker  * Converts seconds to milliseconds.
25*38e8c45fSAndroid Build Coastguard Worker  */
26*38e8c45fSAndroid Build Coastguard Worker #define SEC_TO_MSEC(second) (second * 1000)
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker /*
29*38e8c45fSAndroid Build Coastguard Worker  * Converts milliseconds to seconds.
30*38e8c45fSAndroid Build Coastguard Worker  */
31*38e8c45fSAndroid Build Coastguard Worker #define MSEC_TO_SEC(millisecond) (millisecond / 1000)
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker namespace android {
34*38e8c45fSAndroid Build Coastguard Worker namespace os {
35*38e8c45fSAndroid Build Coastguard Worker namespace dumpstate {
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker /*
38*38e8c45fSAndroid Build Coastguard Worker  * Defines the Linux account that should be executing a command.
39*38e8c45fSAndroid Build Coastguard Worker  */
40*38e8c45fSAndroid Build Coastguard Worker enum PrivilegeMode {
41*38e8c45fSAndroid Build Coastguard Worker     /* Explicitly change the `uid` and `gid` to be `shell`.*/
42*38e8c45fSAndroid Build Coastguard Worker     DROP_ROOT,
43*38e8c45fSAndroid Build Coastguard Worker     /* Don't change the `uid` and `gid`. */
44*38e8c45fSAndroid Build Coastguard Worker     DONT_DROP_ROOT,
45*38e8c45fSAndroid Build Coastguard Worker     /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
46*38e8c45fSAndroid Build Coastguard Worker     SU_ROOT
47*38e8c45fSAndroid Build Coastguard Worker };
48*38e8c45fSAndroid Build Coastguard Worker 
49*38e8c45fSAndroid Build Coastguard Worker /*
50*38e8c45fSAndroid Build Coastguard Worker  * Defines what should happen with the main output stream (`stdout` or fd) of a command.
51*38e8c45fSAndroid Build Coastguard Worker  */
52*38e8c45fSAndroid Build Coastguard Worker enum OutputMode {
53*38e8c45fSAndroid Build Coastguard Worker     /* Don't change main output. */
54*38e8c45fSAndroid Build Coastguard Worker     NORMAL_OUTPUT,
55*38e8c45fSAndroid Build Coastguard Worker     /* Redirect main output to `stderr`. */
56*38e8c45fSAndroid Build Coastguard Worker     REDIRECT_TO_STDERR
57*38e8c45fSAndroid Build Coastguard Worker };
58*38e8c45fSAndroid Build Coastguard Worker 
59*38e8c45fSAndroid Build Coastguard Worker /*
60*38e8c45fSAndroid Build Coastguard Worker  * Value object used to set command options.
61*38e8c45fSAndroid Build Coastguard Worker  *
62*38e8c45fSAndroid Build Coastguard Worker  * Typically constructed using a builder with chained setters. Examples:
63*38e8c45fSAndroid Build Coastguard Worker  *
64*38e8c45fSAndroid Build Coastguard Worker  *  CommandOptions::WithTimeout(20).AsRoot().Build();
65*38e8c45fSAndroid Build Coastguard Worker  *  CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
66*38e8c45fSAndroid Build Coastguard Worker  *
67*38e8c45fSAndroid Build Coastguard Worker  * Although the builder could be used to dynamically set values. Example:
68*38e8c45fSAndroid Build Coastguard Worker  *
69*38e8c45fSAndroid Build Coastguard Worker  *  CommandOptions::CommandOptionsBuilder options =
70*38e8c45fSAndroid Build Coastguard Worker  *  CommandOptions::WithTimeout(10);
71*38e8c45fSAndroid Build Coastguard Worker  *  if (!is_user_build()) {
72*38e8c45fSAndroid Build Coastguard Worker  *    options.AsRoot();
73*38e8c45fSAndroid Build Coastguard Worker  *  }
74*38e8c45fSAndroid Build Coastguard Worker  *  RunCommand("command", {"args"}, options.Build());
75*38e8c45fSAndroid Build Coastguard Worker  */
76*38e8c45fSAndroid Build Coastguard Worker class CommandOptions {
77*38e8c45fSAndroid Build Coastguard Worker   private:
78*38e8c45fSAndroid Build Coastguard Worker     class CommandOptionsValues {
79*38e8c45fSAndroid Build Coastguard Worker       private:
80*38e8c45fSAndroid Build Coastguard Worker         explicit CommandOptionsValues(int64_t timeout_ms);
81*38e8c45fSAndroid Build Coastguard Worker 
82*38e8c45fSAndroid Build Coastguard Worker         int64_t timeout_ms_;
83*38e8c45fSAndroid Build Coastguard Worker         bool always_;
84*38e8c45fSAndroid Build Coastguard Worker         bool close_all_fds_on_exec_;
85*38e8c45fSAndroid Build Coastguard Worker         PrivilegeMode account_mode_;
86*38e8c45fSAndroid Build Coastguard Worker         OutputMode output_mode_;
87*38e8c45fSAndroid Build Coastguard Worker         std::string logging_message_;
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker         friend class CommandOptions;
90*38e8c45fSAndroid Build Coastguard Worker         friend class CommandOptionsBuilder;
91*38e8c45fSAndroid Build Coastguard Worker     };
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     explicit CommandOptions(const CommandOptionsValues& values);
94*38e8c45fSAndroid Build Coastguard Worker 
95*38e8c45fSAndroid Build Coastguard Worker     const CommandOptionsValues values;
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker   public:
98*38e8c45fSAndroid Build Coastguard Worker     class CommandOptionsBuilder {
99*38e8c45fSAndroid Build Coastguard Worker       public:
100*38e8c45fSAndroid Build Coastguard Worker         /* Sets the command to always run, even on `dry-run` mode. */
101*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& Always();
102*38e8c45fSAndroid Build Coastguard Worker         /*
103*38e8c45fSAndroid Build Coastguard Worker          * Sets the command's PrivilegeMode as `SU_ROOT` unless overridden by system property
104*38e8c45fSAndroid Build Coastguard Worker          * 'dumpstate.unroot'.
105*38e8c45fSAndroid Build Coastguard Worker          */
106*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& AsRoot();
107*38e8c45fSAndroid Build Coastguard Worker         /*
108*38e8c45fSAndroid Build Coastguard Worker          * Runs AsRoot() on userdebug builds. No-op on user builds since 'su' is
109*38e8c45fSAndroid Build Coastguard Worker          * not available. This is used for commands that return some useful information even
110*38e8c45fSAndroid Build Coastguard Worker          * when run as shell.
111*38e8c45fSAndroid Build Coastguard Worker          */
112*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& AsRootIfAvailable();
113*38e8c45fSAndroid Build Coastguard Worker         /* Sets the command's PrivilegeMode as `DROP_ROOT` */
114*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& DropRoot();
115*38e8c45fSAndroid Build Coastguard Worker         /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
116*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& RedirectStderr();
117*38e8c45fSAndroid Build Coastguard Worker         /* Closes all file descriptors before exec-ing the target process. This
118*38e8c45fSAndroid Build Coastguard Worker          * includes also stdio pipes, which are dup-ed on /dev/null. It prevents
119*38e8c45fSAndroid Build Coastguard Worker          * leaking opened FDs to the target process, which in turn can hit
120*38e8c45fSAndroid Build Coastguard Worker          * selinux denials in presence of auto_trans rules.
121*38e8c45fSAndroid Build Coastguard Worker          */
122*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& CloseAllFileDescriptorsOnExec();
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker         /* When not empty, logs a message before executing the command.
125*38e8c45fSAndroid Build Coastguard Worker          * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
126*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsBuilder& Log(const std::string& message);
127*38e8c45fSAndroid Build Coastguard Worker         /* Builds the command options. */
128*38e8c45fSAndroid Build Coastguard Worker         CommandOptions Build();
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker       private:
131*38e8c45fSAndroid Build Coastguard Worker         explicit CommandOptionsBuilder(int64_t timeout_ms);
132*38e8c45fSAndroid Build Coastguard Worker         CommandOptionsValues values;
133*38e8c45fSAndroid Build Coastguard Worker         friend class CommandOptions;
134*38e8c45fSAndroid Build Coastguard Worker     };
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     /** Gets the command timeout in seconds. */
137*38e8c45fSAndroid Build Coastguard Worker     int64_t Timeout() const;
138*38e8c45fSAndroid Build Coastguard Worker     /** Gets the command timeout in milliseconds. */
139*38e8c45fSAndroid Build Coastguard Worker     int64_t TimeoutInMs() const;
140*38e8c45fSAndroid Build Coastguard Worker     /* Checks whether the command should always be run, even on dry-run mode. */
141*38e8c45fSAndroid Build Coastguard Worker     bool Always() const;
142*38e8c45fSAndroid Build Coastguard Worker     /* Checks whether all FDs should be closed prior to the exec() calls. */
143*38e8c45fSAndroid Build Coastguard Worker     bool ShouldCloseAllFileDescriptorsOnExec() const;
144*38e8c45fSAndroid Build Coastguard Worker     /** Gets the PrivilegeMode of the command. */
145*38e8c45fSAndroid Build Coastguard Worker     PrivilegeMode PrivilegeMode() const;
146*38e8c45fSAndroid Build Coastguard Worker     /** Gets the OutputMode of the command. */
147*38e8c45fSAndroid Build Coastguard Worker     OutputMode OutputMode() const;
148*38e8c45fSAndroid Build Coastguard Worker     /** Gets the logging message header, it any. */
149*38e8c45fSAndroid Build Coastguard Worker     std::string LoggingMessage() const;
150*38e8c45fSAndroid Build Coastguard Worker 
151*38e8c45fSAndroid Build Coastguard Worker     /** Creates a builder with the requied timeout in seconds. */
152*38e8c45fSAndroid Build Coastguard Worker     static CommandOptionsBuilder WithTimeout(int64_t timeout_sec);
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     /** Creates a builder with the requied timeout in milliseconds. */
155*38e8c45fSAndroid Build Coastguard Worker     static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms);
156*38e8c45fSAndroid Build Coastguard Worker 
157*38e8c45fSAndroid Build Coastguard Worker     // Common options.
158*38e8c45fSAndroid Build Coastguard Worker     static CommandOptions DEFAULT;
159*38e8c45fSAndroid Build Coastguard Worker     static CommandOptions AS_ROOT;
160*38e8c45fSAndroid Build Coastguard Worker };
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker /*
163*38e8c45fSAndroid Build Coastguard Worker  * System properties helper.
164*38e8c45fSAndroid Build Coastguard Worker  */
165*38e8c45fSAndroid Build Coastguard Worker class PropertiesHelper {
166*38e8c45fSAndroid Build Coastguard Worker     friend class DumpstateBaseTest;
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker   public:
169*38e8c45fSAndroid Build Coastguard Worker     /*
170*38e8c45fSAndroid Build Coastguard Worker      * Gets whether device is running a `user` build.
171*38e8c45fSAndroid Build Coastguard Worker      */
172*38e8c45fSAndroid Build Coastguard Worker     static bool IsUserBuild();
173*38e8c45fSAndroid Build Coastguard Worker 
174*38e8c45fSAndroid Build Coastguard Worker     /*
175*38e8c45fSAndroid Build Coastguard Worker      * When running in dry-run mode, skips the real dumps and just print the section headers.
176*38e8c45fSAndroid Build Coastguard Worker      *
177*38e8c45fSAndroid Build Coastguard Worker      * Useful when debugging dumpstate or other bugreport-related activities.
178*38e8c45fSAndroid Build Coastguard Worker      *
179*38e8c45fSAndroid Build Coastguard Worker      * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
180*38e8c45fSAndroid Build Coastguard Worker      */
181*38e8c45fSAndroid Build Coastguard Worker     static bool IsDryRun();
182*38e8c45fSAndroid Build Coastguard Worker 
183*38e8c45fSAndroid Build Coastguard Worker     /**
184*38e8c45fSAndroid Build Coastguard Worker      * Checks whether root availability should be overridden.
185*38e8c45fSAndroid Build Coastguard Worker      *
186*38e8c45fSAndroid Build Coastguard Worker      * Useful to verify how dumpstate would work in a device with an user build.
187*38e8c45fSAndroid Build Coastguard Worker      */
188*38e8c45fSAndroid Build Coastguard Worker     static bool IsUnroot();
189*38e8c45fSAndroid Build Coastguard Worker 
190*38e8c45fSAndroid Build Coastguard Worker     /*
191*38e8c45fSAndroid Build Coastguard Worker      * Whether or not the parallel run is enabled. Setting the system property
192*38e8c45fSAndroid Build Coastguard Worker      * 'dumpstate.parallel_run' to false to disable it, otherwise it returns
193*38e8c45fSAndroid Build Coastguard Worker      * true by default.
194*38e8c45fSAndroid Build Coastguard Worker      */
195*38e8c45fSAndroid Build Coastguard Worker     static bool IsParallelRun();
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker     /*
198*38e8c45fSAndroid Build Coastguard Worker      * Strict-run mode is determined by the `dumpstate.strict_run` sysprop which
199*38e8c45fSAndroid Build Coastguard Worker      * will default to true. This results in shortened timeouts for flaky
200*38e8c45fSAndroid Build Coastguard Worker      * sections.
201*38e8c45fSAndroid Build Coastguard Worker      */
202*38e8c45fSAndroid Build Coastguard Worker     static bool IsStrictRun();
203*38e8c45fSAndroid Build Coastguard Worker 
204*38e8c45fSAndroid Build Coastguard Worker   private:
205*38e8c45fSAndroid Build Coastguard Worker     static std::string build_type_;
206*38e8c45fSAndroid Build Coastguard Worker     static int dry_run_;
207*38e8c45fSAndroid Build Coastguard Worker     static int unroot_;
208*38e8c45fSAndroid Build Coastguard Worker     static int parallel_run_;
209*38e8c45fSAndroid Build Coastguard Worker     static int strict_run_;
210*38e8c45fSAndroid Build Coastguard Worker };
211*38e8c45fSAndroid Build Coastguard Worker 
212*38e8c45fSAndroid Build Coastguard Worker /*
213*38e8c45fSAndroid Build Coastguard Worker  * Forks a command, waits for it to finish, and returns its status.
214*38e8c45fSAndroid Build Coastguard Worker  *
215*38e8c45fSAndroid Build Coastguard Worker  * |fd| file descriptor that receives the command's 'stdout'.
216*38e8c45fSAndroid Build Coastguard Worker  * |title| description of the command printed on `stdout` (or empty to skip
217*38e8c45fSAndroid Build Coastguard Worker  * description).
218*38e8c45fSAndroid Build Coastguard Worker  * |full_command| array containing the command (first entry) and its arguments.
219*38e8c45fSAndroid Build Coastguard Worker  *                Must contain at least one element.
220*38e8c45fSAndroid Build Coastguard Worker  * |options| optional argument defining the command's behavior.
221*38e8c45fSAndroid Build Coastguard Worker  */
222*38e8c45fSAndroid Build Coastguard Worker int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
223*38e8c45fSAndroid Build Coastguard Worker                    const CommandOptions& options = CommandOptions::DEFAULT);
224*38e8c45fSAndroid Build Coastguard Worker 
225*38e8c45fSAndroid Build Coastguard Worker /*
226*38e8c45fSAndroid Build Coastguard Worker  * Dumps the contents of a file into a file descriptor.
227*38e8c45fSAndroid Build Coastguard Worker  *
228*38e8c45fSAndroid Build Coastguard Worker  * |fd| file descriptor where the file is dumped into.
229*38e8c45fSAndroid Build Coastguard Worker  * |title| description of the command printed on `stdout` (or empty to skip
230*38e8c45fSAndroid Build Coastguard Worker  * description).
231*38e8c45fSAndroid Build Coastguard Worker  * |path| location of the file to be dumped.
232*38e8c45fSAndroid Build Coastguard Worker  */
233*38e8c45fSAndroid Build Coastguard Worker int DumpFileToFd(int fd, const std::string& title, const std::string& path);
234*38e8c45fSAndroid Build Coastguard Worker 
235*38e8c45fSAndroid Build Coastguard Worker }  // namespace dumpstate
236*38e8c45fSAndroid Build Coastguard Worker }  // namespace os
237*38e8c45fSAndroid Build Coastguard Worker }  // namespace android
238*38e8c45fSAndroid Build Coastguard Worker 
239*38e8c45fSAndroid Build Coastguard Worker #endif  // ANDROID_OS_DUMPSTATE_UTIL_H_
240