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