blob: 66d2b492a29f3b92a62dadaa22d6ccecd60c9958 [file] [log] [blame]
Vernon Mauery9e801a22018-10-12 13:20:49 -07001#include "sol_manager.hpp"
2
3#include "main.hpp"
4#include "sol_context.hpp"
5
Tom Joseph22c5ad32017-03-14 18:04:22 +05306#include <sys/socket.h>
7#include <sys/un.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07008
Tom Joseph2e44e0e2017-03-14 18:09:11 +05309#include <chrono>
Tom Joseph22c5ad32017-03-14 18:04:22 +053010#include <cmath>
11#include <phosphor-logging/log.hpp>
Tom Joseph22c5ad32017-03-14 18:04:22 +053012
13namespace sol
14{
15
16using namespace phosphor::logging;
17
Tom Josephb81f7612017-04-25 17:59:02 +053018CustomFD::~CustomFD()
19{
Vernon Mauery9e801a22018-10-12 13:20:49 -070020 if (fd >= 0)
Tom Josephb81f7612017-04-25 17:59:02 +053021 {
22 // Remove the host console descriptor from the sd_event_loop
23 std::get<eventloop::EventLoop&>(singletonPool).stopHostConsole();
24 close(fd);
25 }
26}
27
Tom Joseph22c5ad32017-03-14 18:04:22 +053028void Manager::initHostConsoleFd()
29{
30 struct sockaddr_un addr;
31 int rc = 0;
32 int fd = 0;
33
34 fd = socket(AF_UNIX, SOCK_STREAM, 0);
35 if (fd < 0)
36 {
37 log<level::ERR>("Failed to open the host console socket",
Vernon Mauery9e801a22018-10-12 13:20:49 -070038 entry("ERRNO=%d", errno));
Tom Joseph22c5ad32017-03-14 18:04:22 +053039 throw std::runtime_error("Failed to open the host console socket");
40 }
41
42 memset(&addr, 0, sizeof(addr));
43 addr.sun_family = AF_UNIX;
44 memcpy(&addr.sun_path, &CONSOLE_SOCKET_PATH, CONSOLE_SOCKET_PATH_LEN);
45 consoleFD = std::make_unique<CustomFD>(fd);
46 auto& conFD = *(consoleFD.get());
47
Vernon Mauery9e801a22018-10-12 13:20:49 -070048 rc = connect(conFD(), (struct sockaddr*)&addr, sizeof(addr));
Tom Joseph22c5ad32017-03-14 18:04:22 +053049 if (rc < 0)
50 {
51 log<level::ERR>("Failed to connect to host console socket address",
Vernon Mauery9e801a22018-10-12 13:20:49 -070052 entry("ERRNO=%d", errno));
Tom Joseph22c5ad32017-03-14 18:04:22 +053053 consoleFD.reset();
54 throw std::runtime_error("Failed to connect to console server");
55 }
56}
57
Vernon Mauery70fd29c2017-11-30 13:11:43 -080058int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const
Tom Josephb51f6412017-03-14 18:08:14 +053059{
60 auto inBuffer = input.data();
61 auto inBufferSize = input.size();
62 size_t pos = 0;
63 ssize_t rc = 0;
64 int errVal = 0;
65 auto& conFD = *(consoleFD.get());
66
67 for (pos = 0; pos < inBufferSize; pos += rc)
68 {
69 rc = write(conFD(), inBuffer + pos, inBufferSize - pos);
70 if (rc <= 0)
71 {
72 if (errno == EINTR)
73 {
74 log<level::INFO>(" Retrying to handle EINTR",
Vernon Mauery9e801a22018-10-12 13:20:49 -070075 entry("ERRNO=%d", errno));
Tom Josephb51f6412017-03-14 18:08:14 +053076 rc = 0;
77 continue;
78 }
79 else
80 {
81 errVal = errno;
82 log<level::ERR>("Failed to write to host console socket",
Vernon Mauery9e801a22018-10-12 13:20:49 -070083 entry("ERRNO=%d", errno));
Tom Josephb51f6412017-03-14 18:08:14 +053084 return -errVal;
85 }
86 }
87 }
88
89 return 0;
90}
91
Tom Joseph2e44e0e2017-03-14 18:09:11 +053092void Manager::startPayloadInstance(uint8_t payloadInstance,
93 session::SessionID sessionID)
94{
95 if (payloadMap.empty())
96 {
97 initHostConsoleFd();
98
99 // Register the fd in the sd_event_loop
Vernon Mauery9e801a22018-10-12 13:20:49 -0700100 std::get<eventloop::EventLoop&>(singletonPool)
101 .startHostConsole(*(consoleFD.get()));
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530102 }
103
104 // Create the SOL Context data for payload instance
Vernon Mauery9e801a22018-10-12 13:20:49 -0700105 auto context = std::make_unique<Context>(retryCount, sendThreshold,
106 payloadInstance, sessionID);
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530107
Vernon Mauery9e801a22018-10-12 13:20:49 -0700108 std::get<eventloop::EventLoop&>(singletonPool)
109 .startSOLPayloadInstance(
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530110 payloadInstance,
Vernon Mauery9e801a22018-10-12 13:20:49 -0700111 std::chrono::duration_cast<eventloop::IntervalType>(
112 accumulateInterval),
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530113 std::chrono::duration_cast<eventloop::IntervalType>(retryInterval));
114
115 payloadMap.emplace(payloadInstance, std::move(context));
116}
117
Tom Joseph4ff14b52017-03-14 18:10:52 +0530118void Manager::stopPayloadInstance(uint8_t payloadInstance)
119{
120 auto iter = payloadMap.find(payloadInstance);
121 if (iter == payloadMap.end())
122 {
123 throw std::runtime_error("SOL Payload instance not found ");
124 }
125
126 payloadMap.erase(iter);
127
Vernon Mauery9e801a22018-10-12 13:20:49 -0700128 std::get<eventloop::EventLoop&>(singletonPool)
129 .stopSOLPayloadInstance(payloadInstance);
Tom Joseph4ff14b52017-03-14 18:10:52 +0530130
131 if (payloadMap.empty())
132 {
Tom Joseph4ff14b52017-03-14 18:10:52 +0530133 consoleFD.reset();
Tom Josephde203ce2017-08-01 16:48:06 +0530134
135 dataBuffer.erase(dataBuffer.size());
Tom Joseph4ff14b52017-03-14 18:10:52 +0530136 }
137}
138
Tom Joseph22c5ad32017-03-14 18:04:22 +0530139} // namespace sol