blob: 859f371c5aa7a6eec5730daebb8b95c2424bf792 [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 Mauery744b3c82018-12-18 16:11:38 -080048 rc =
49 connect(conFD(), (struct sockaddr*)&addr,
50 sizeof(addr) - sizeof(addr.sun_path) + CONSOLE_SOCKET_PATH_LEN);
Tom Joseph22c5ad32017-03-14 18:04:22 +053051 if (rc < 0)
52 {
53 log<level::ERR>("Failed to connect to host console socket address",
Vernon Mauery9e801a22018-10-12 13:20:49 -070054 entry("ERRNO=%d", errno));
Tom Joseph22c5ad32017-03-14 18:04:22 +053055 consoleFD.reset();
56 throw std::runtime_error("Failed to connect to console server");
57 }
58}
59
Vernon Mauery70fd29c2017-11-30 13:11:43 -080060int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const
Tom Josephb51f6412017-03-14 18:08:14 +053061{
62 auto inBuffer = input.data();
63 auto inBufferSize = input.size();
64 size_t pos = 0;
65 ssize_t rc = 0;
66 int errVal = 0;
67 auto& conFD = *(consoleFD.get());
68
69 for (pos = 0; pos < inBufferSize; pos += rc)
70 {
71 rc = write(conFD(), inBuffer + pos, inBufferSize - pos);
72 if (rc <= 0)
73 {
74 if (errno == EINTR)
75 {
76 log<level::INFO>(" Retrying to handle EINTR",
Vernon Mauery9e801a22018-10-12 13:20:49 -070077 entry("ERRNO=%d", errno));
Tom Josephb51f6412017-03-14 18:08:14 +053078 rc = 0;
79 continue;
80 }
81 else
82 {
83 errVal = errno;
84 log<level::ERR>("Failed to write to host console socket",
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 entry("ERRNO=%d", errno));
Tom Josephb51f6412017-03-14 18:08:14 +053086 return -errVal;
87 }
88 }
89 }
90
91 return 0;
92}
93
Tom Joseph2e44e0e2017-03-14 18:09:11 +053094void Manager::startPayloadInstance(uint8_t payloadInstance,
95 session::SessionID sessionID)
96{
97 if (payloadMap.empty())
98 {
99 initHostConsoleFd();
100
101 // Register the fd in the sd_event_loop
Vernon Mauery9e801a22018-10-12 13:20:49 -0700102 std::get<eventloop::EventLoop&>(singletonPool)
103 .startHostConsole(*(consoleFD.get()));
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530104 }
105
106 // Create the SOL Context data for payload instance
Vernon Mauery9e801a22018-10-12 13:20:49 -0700107 auto context = std::make_unique<Context>(retryCount, sendThreshold,
108 payloadInstance, sessionID);
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530109
Vernon Mauery9e801a22018-10-12 13:20:49 -0700110 std::get<eventloop::EventLoop&>(singletonPool)
111 .startSOLPayloadInstance(
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530112 payloadInstance,
Vernon Mauery9e801a22018-10-12 13:20:49 -0700113 std::chrono::duration_cast<eventloop::IntervalType>(
114 accumulateInterval),
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530115 std::chrono::duration_cast<eventloop::IntervalType>(retryInterval));
116
117 payloadMap.emplace(payloadInstance, std::move(context));
118}
119
Tom Joseph4ff14b52017-03-14 18:10:52 +0530120void Manager::stopPayloadInstance(uint8_t payloadInstance)
121{
122 auto iter = payloadMap.find(payloadInstance);
123 if (iter == payloadMap.end())
124 {
125 throw std::runtime_error("SOL Payload instance not found ");
126 }
127
128 payloadMap.erase(iter);
129
Vernon Mauery9e801a22018-10-12 13:20:49 -0700130 std::get<eventloop::EventLoop&>(singletonPool)
131 .stopSOLPayloadInstance(payloadInstance);
Tom Joseph4ff14b52017-03-14 18:10:52 +0530132
133 if (payloadMap.empty())
134 {
Tom Joseph4ff14b52017-03-14 18:10:52 +0530135 consoleFD.reset();
Tom Josephde203ce2017-08-01 16:48:06 +0530136
137 dataBuffer.erase(dataBuffer.size());
Tom Joseph4ff14b52017-03-14 18:10:52 +0530138 }
139}
140
Tom Joseph22c5ad32017-03-14 18:04:22 +0530141} // namespace sol