blob: 889065f779b75bad76650765f2d2fc2759c88565 [file] [log] [blame]
Tom Joseph22c5ad32017-03-14 18:04:22 +05301#include <sys/socket.h>
2#include <sys/un.h>
Tom Joseph2e44e0e2017-03-14 18:09:11 +05303#include <chrono>
Tom Joseph22c5ad32017-03-14 18:04:22 +05304#include <cmath>
5#include <phosphor-logging/log.hpp>
6#include "main.hpp"
7#include "sol_context.hpp"
8#include "sol_manager.hpp"
9
10namespace sol
11{
12
13using namespace phosphor::logging;
14
Tom Josephb81f7612017-04-25 17:59:02 +053015CustomFD::~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 Joseph22c5ad32017-03-14 18:04:22 +053025void 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
Tom Josephb51f6412017-03-14 18:08:14 +053055int Manager::writeConsoleSocket(const Buffer& input) const
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 Joseph2e44e0e2017-03-14 18:09:11 +053089void 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 Joseph32f07b82017-04-25 20:19:44 +0530103 retryCount, sendThreshold, payloadInstance, sessionID);
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530104
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530105 std::get<eventloop::EventLoop&>(singletonPool).startSOLPayloadInstance(
106 payloadInstance,
Tom Joseph704f3422017-04-26 10:13:03 +0530107 std::chrono::duration_cast<eventloop::IntervalType>
108 (accumulateInterval),
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530109 std::chrono::duration_cast<eventloop::IntervalType>(retryInterval));
110
111 payloadMap.emplace(payloadInstance, std::move(context));
112}
113
Tom Joseph4ff14b52017-03-14 18:10:52 +0530114void 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 Joseph4ff14b52017-03-14 18:10:52 +0530129 consoleFD.reset();
Tom Josephde203ce2017-08-01 16:48:06 +0530130
131 dataBuffer.erase(dataBuffer.size());
Tom Joseph4ff14b52017-03-14 18:10:52 +0530132 }
133}
134
Tom Joseph22c5ad32017-03-14 18:04:22 +0530135} // namespace sol