| Tom Joseph | 22c5ad3 | 2017-03-14 18:04:22 +0530 | [diff] [blame] | 1 | #include <sys/socket.h> | 
|  | 2 | #include <sys/un.h> | 
| Tom Joseph | 2e44e0e | 2017-03-14 18:09:11 +0530 | [diff] [blame] | 3 | #include <chrono> | 
| Tom Joseph | 22c5ad3 | 2017-03-14 18:04:22 +0530 | [diff] [blame] | 4 | #include <cmath> | 
|  | 5 | #include <phosphor-logging/log.hpp> | 
|  | 6 | #include "main.hpp" | 
|  | 7 | #include "sol_context.hpp" | 
|  | 8 | #include "sol_manager.hpp" | 
|  | 9 |  | 
|  | 10 | namespace sol | 
|  | 11 | { | 
|  | 12 |  | 
|  | 13 | using namespace phosphor::logging; | 
|  | 14 |  | 
| Tom Joseph | b81f761 | 2017-04-25 17:59:02 +0530 | [diff] [blame] | 15 | CustomFD::~CustomFD() | 
|  | 16 | { | 
|  | 17 | if(fd >= 0) | 
|  | 18 | { | 
|  | 19 | // Remove the host console descriptor from the sd_event_loop | 
|  | 20 | std::get<eventloop::EventLoop&>(singletonPool).stopHostConsole(); | 
|  | 21 | close(fd); | 
|  | 22 | } | 
|  | 23 | } | 
|  | 24 |  | 
| Tom Joseph | 22c5ad3 | 2017-03-14 18:04:22 +0530 | [diff] [blame] | 25 | void Manager::initHostConsoleFd() | 
|  | 26 | { | 
|  | 27 | struct sockaddr_un addr; | 
|  | 28 | int rc = 0; | 
|  | 29 | int fd = 0; | 
|  | 30 |  | 
|  | 31 | fd = socket(AF_UNIX, SOCK_STREAM, 0); | 
|  | 32 | if (fd < 0) | 
|  | 33 | { | 
|  | 34 | log<level::ERR>("Failed to open the host console socket", | 
|  | 35 | entry("ERRNO=%d", errno)); | 
|  | 36 | throw std::runtime_error("Failed to open the host console socket"); | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | memset(&addr, 0, sizeof(addr)); | 
|  | 40 | addr.sun_family = AF_UNIX; | 
|  | 41 | memcpy(&addr.sun_path, &CONSOLE_SOCKET_PATH, CONSOLE_SOCKET_PATH_LEN); | 
|  | 42 | consoleFD = std::make_unique<CustomFD>(fd); | 
|  | 43 | auto& conFD = *(consoleFD.get()); | 
|  | 44 |  | 
|  | 45 | rc = connect(conFD(), (struct sockaddr *)&addr, sizeof(addr)); | 
|  | 46 | if (rc < 0) | 
|  | 47 | { | 
|  | 48 | log<level::ERR>("Failed to connect to host console socket address", | 
|  | 49 | entry("ERRNO=%d", errno)); | 
|  | 50 | consoleFD.reset(); | 
|  | 51 | throw std::runtime_error("Failed to connect to console server"); | 
|  | 52 | } | 
|  | 53 | } | 
|  | 54 |  | 
| Vernon Mauery | 70fd29c | 2017-11-30 13:11:43 -0800 | [diff] [blame^] | 55 | int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const | 
| Tom Joseph | b51f641 | 2017-03-14 18:08:14 +0530 | [diff] [blame] | 56 | { | 
|  | 57 | auto inBuffer = input.data(); | 
|  | 58 | auto inBufferSize = input.size(); | 
|  | 59 | size_t pos = 0; | 
|  | 60 | ssize_t rc = 0; | 
|  | 61 | int errVal = 0; | 
|  | 62 | auto& conFD = *(consoleFD.get()); | 
|  | 63 |  | 
|  | 64 | for (pos = 0; pos < inBufferSize; pos += rc) | 
|  | 65 | { | 
|  | 66 | rc = write(conFD(), inBuffer + pos, inBufferSize - pos); | 
|  | 67 | if (rc <= 0) | 
|  | 68 | { | 
|  | 69 | if (errno == EINTR) | 
|  | 70 | { | 
|  | 71 | log<level::INFO>(" Retrying to handle EINTR", | 
|  | 72 | entry("ERRNO=%d", errno)); | 
|  | 73 | rc = 0; | 
|  | 74 | continue; | 
|  | 75 | } | 
|  | 76 | else | 
|  | 77 | { | 
|  | 78 | errVal = errno; | 
|  | 79 | log<level::ERR>("Failed to write to host console socket", | 
|  | 80 | entry("ERRNO=%d", errno)); | 
|  | 81 | return -errVal; | 
|  | 82 | } | 
|  | 83 | } | 
|  | 84 | } | 
|  | 85 |  | 
|  | 86 | return 0; | 
|  | 87 | } | 
|  | 88 |  | 
| Tom Joseph | 2e44e0e | 2017-03-14 18:09:11 +0530 | [diff] [blame] | 89 | void Manager::startPayloadInstance(uint8_t payloadInstance, | 
|  | 90 | session::SessionID sessionID) | 
|  | 91 | { | 
|  | 92 | if (payloadMap.empty()) | 
|  | 93 | { | 
|  | 94 | initHostConsoleFd(); | 
|  | 95 |  | 
|  | 96 | // Register the fd in the sd_event_loop | 
|  | 97 | std::get<eventloop::EventLoop&>(singletonPool).startHostConsole( | 
|  | 98 | *(consoleFD.get())); | 
|  | 99 | } | 
|  | 100 |  | 
|  | 101 | // Create the SOL Context data for payload instance | 
|  | 102 | auto context = std::make_unique<Context>( | 
| Tom Joseph | 32f07b8 | 2017-04-25 20:19:44 +0530 | [diff] [blame] | 103 | retryCount, sendThreshold, payloadInstance, sessionID); | 
| Tom Joseph | 2e44e0e | 2017-03-14 18:09:11 +0530 | [diff] [blame] | 104 |  | 
| Tom Joseph | 2e44e0e | 2017-03-14 18:09:11 +0530 | [diff] [blame] | 105 | std::get<eventloop::EventLoop&>(singletonPool).startSOLPayloadInstance( | 
|  | 106 | payloadInstance, | 
| Tom Joseph | 704f342 | 2017-04-26 10:13:03 +0530 | [diff] [blame] | 107 | std::chrono::duration_cast<eventloop::IntervalType> | 
|  | 108 | (accumulateInterval), | 
| Tom Joseph | 2e44e0e | 2017-03-14 18:09:11 +0530 | [diff] [blame] | 109 | std::chrono::duration_cast<eventloop::IntervalType>(retryInterval)); | 
|  | 110 |  | 
|  | 111 | payloadMap.emplace(payloadInstance, std::move(context)); | 
|  | 112 | } | 
|  | 113 |  | 
| Tom Joseph | 4ff14b5 | 2017-03-14 18:10:52 +0530 | [diff] [blame] | 114 | void Manager::stopPayloadInstance(uint8_t payloadInstance) | 
|  | 115 | { | 
|  | 116 | auto iter = payloadMap.find(payloadInstance); | 
|  | 117 | if (iter == payloadMap.end()) | 
|  | 118 | { | 
|  | 119 | throw std::runtime_error("SOL Payload instance not found "); | 
|  | 120 | } | 
|  | 121 |  | 
|  | 122 | payloadMap.erase(iter); | 
|  | 123 |  | 
|  | 124 | std::get<eventloop::EventLoop&>(singletonPool).stopSOLPayloadInstance( | 
|  | 125 | payloadInstance); | 
|  | 126 |  | 
|  | 127 | if (payloadMap.empty()) | 
|  | 128 | { | 
| Tom Joseph | 4ff14b5 | 2017-03-14 18:10:52 +0530 | [diff] [blame] | 129 | consoleFD.reset(); | 
| Tom Joseph | de203ce | 2017-08-01 16:48:06 +0530 | [diff] [blame] | 130 |  | 
|  | 131 | dataBuffer.erase(dataBuffer.size()); | 
| Tom Joseph | 4ff14b5 | 2017-03-14 18:10:52 +0530 | [diff] [blame] | 132 | } | 
|  | 133 | } | 
|  | 134 |  | 
| Tom Joseph | 22c5ad3 | 2017-03-14 18:04:22 +0530 | [diff] [blame] | 135 | } // namespace sol |