1 /* 2 * Copyright (C) 2018 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 #pragma once 17 18 #include <atomic> 19 #include <memory> 20 #include <mutex> 21 #include <set> 22 #include <string> 23 #include <thread> 24 #include <utility> 25 #include <vector> 26 27 #include "common/libs/utils/result.h" 28 #include "common/libs/utils/subprocess.h" 29 #include "host/libs/config/command_source.h" 30 31 namespace cuttlefish { 32 33 struct MonitorEntry { 34 std::unique_ptr<Command> cmd; 35 bool can_sandbox; 36 std::unique_ptr<Subprocess> proc; 37 bool is_critical; 38 MonitorEntryMonitorEntry39 MonitorEntry(Command command, bool is_critical) 40 : cmd(new Command(std::move(command))), is_critical(is_critical) {} 41 }; 42 43 // Launches and keeps track of subprocesses, decides response if they 44 // unexpectedly exit 45 class ProcessMonitor { 46 public: 47 class Properties { 48 public: 49 Properties& RestartSubprocesses(bool) &; 50 Properties RestartSubprocesses(bool) &&; 51 52 Properties& AddCommand(MonitorCommand) &; 53 Properties AddCommand(MonitorCommand) &&; 54 55 Properties& StraceCommands(std::set<std::string>) &; 56 Properties StraceCommands(std::set<std::string>) &&; 57 58 Properties& StraceLogDir(std::string) &; 59 Properties StraceLogDir(std::string) &&; 60 61 Properties& SandboxProcesses(bool) &; 62 Properties SandboxProcesses(bool) &&; 63 64 template <typename T> AddCommands(T commands)65 Properties& AddCommands(T commands) & { 66 for (auto& command : commands) { 67 AddCommand(std::move(command)); 68 } 69 return *this; 70 } 71 72 template <typename T> AddCommands(T commands)73 Properties AddCommands(T commands) && { 74 return std::move(AddCommands(std::move(commands))); 75 } 76 77 private: 78 bool restart_subprocesses_; 79 std::vector<MonitorEntry> entries_; 80 std::set<std::string> strace_commands_; 81 std::string strace_log_dir_; 82 bool sandbox_processes_; 83 84 friend class ProcessMonitor; 85 }; 86 /* 87 * secure_env_fd is to send suspend/resume commands to secure_env. 88 */ 89 ProcessMonitor(Properties&&, const SharedFD& secure_env_fd); 90 91 // Start all processes given by AddCommand. 92 Result<void> StartAndMonitorProcesses(); 93 // Stops all monitored subprocesses. 94 Result<void> StopMonitoredProcesses(); 95 // Suspend all host subprocesses 96 Result<void> SuspendMonitoredProcesses(); 97 // Resume all host subprocesses 98 Result<void> ResumeMonitoredProcesses(); 99 100 private: 101 Result<void> StartSubprocesses(Properties& properties); 102 Result<void> MonitorRoutine(); 103 Result<void> ReadMonitorSocketLoop(std::atomic_bool&); 104 /* 105 * The child run_cvd process suspends the host processes 106 */ 107 Result<void> SuspendHostProcessesImpl(); 108 /* 109 * The child run_cvd process resumes the host processes 110 */ 111 Result<void> ResumeHostProcessesImpl(); 112 113 Properties properties_; 114 const SharedFD channel_to_secure_env_; 115 pid_t monitor_; 116 SharedFD parent_monitor_socket_; 117 SharedFD child_monitor_socket_; 118 119 /* 120 * The lock that should be acquired when multiple threads 121 * access to properties_. Currently, used by the child 122 * run_cvd process that runs MonitorRoutine() 123 */ 124 std::mutex properties_mutex_; 125 }; 126 127 } // namespace cuttlefish 128