30 #include <arpa/inet.h>
34 #include <sys/socket.h>
36 #include <sys/types.h>
58 fatal_if(
system ==
nullptr,
"Requires a system to share memory from!");
64 sockaddr_un serv_addr = {};
65 serv_addr.sun_family = AF_UNIX;
67 sizeof(serv_addr.sun_path) - 1);
71 warn(
"%s: unix socket path truncated, expect '%s' but get '%s'",
79 "%s: the server path %s was occupied and will be replaced. Please "
80 "make sure there is no other server using the same path.",
82 int bind_retv = bind(
serverFd,
reinterpret_cast<sockaddr*
>(&serv_addr),
84 fatal_if(bind_retv != 0,
"%s: cannot bind unix socket: %s",
name(),
87 int listen_retv = listen(
serverFd, 1);
88 fatal_if(listen_retv != 0,
"%s: listen failed: %s",
name(),
98 warn_if(unlink_retv != 0,
"%s: cannot unlink unix socket: %s",
name(),
101 warn_if(close_retv != 0,
"%s: cannot close unix socket: %s",
name(),
121 char* char_buffer =
reinterpret_cast<char*
>(buffer);
123 ssize_t retv = recv(pfd.fd, char_buffer +
offset, size -
offset, 0);
126 }
else if (errno != EINTR) {
127 warn(
"%s: recv failed: %s",
name(), strerror(errno));
137 panic_if(revents & (POLLERR | POLLNVAL),
"%s: listen socket is broken",
140 panic_if(cli_fd < 0,
"%s: accept failed: %s",
name(), strerror(errno));
141 inform(
"%s: accept new connection %d",
name(), cli_fd);
142 shmServer->clientSocketEvents[cli_fd].reset(
152 if (revents & (POLLHUP | POLLERR | POLLNVAL)) {
164 if (!tryReadAll(&req_type,
sizeof(req_type))) {
168 warn(
"%s: receive unknown request: %d",
name(),
169 static_cast<int>(req_type));
172 if (!tryReadAll(&request,
sizeof(request))) {
175 AddrRange range(request.start, request.end);
179 const auto& stores = shmServer->system->getPhysMem().getBackingStore();
180 auto it = std::find_if(
182 return entry.shmFd >= 0 && range.isSubset(entry.range);
184 if (it == stores.end()) {
185 warn(
"%s: cannot find backing store for %s",
name(),
189 inform(
"%s: find shared backing store for %s at %s, shm=%d:%lld",
191 (
unsigned long long)it->shmOffset);
205 response.offset = it->shmOffset + (range.
start() - it->range.start());
206 iovec ios = {.iov_base = &response, .iov_len =
sizeof(response)};
212 char buf[CMSG_SPACE(
sizeof(it->shmFd))];
213 struct cmsghdr
align;
215 msg.msg_control = cmsgs.buf;
216 msg.msg_controllen =
sizeof(cmsgs.buf);
217 cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
218 cmsg->cmsg_level = SOL_SOCKET;
219 cmsg->cmsg_type = SCM_RIGHTS;
220 cmsg->cmsg_len = CMSG_LEN(
sizeof(it->shmFd));
221 memcpy(CMSG_DATA(cmsg), &it->shmFd,
sizeof(it->shmFd));
223 int retv = sendmsg(pfd.fd, &msg, 0);
225 warn(
"%s: sendmsg failed: %s",
name(), strerror(errno));
228 if (retv !=
sizeof(response)) {
229 warn(
"%s: failed to send all response at once",
name());
242 shmServer->clientSocketEvents.erase(pfd.fd);
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
static int socketCloexec(int domain, int type, int protocol)
static int acceptCloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
virtual std::string name() const
Abstract superclass for simulation objects.
A single entry for the backing store.
bool tryReadAll(void *buffer, size_t size)
BaseShmPollEvent(int fd, SharedMemoryServer *shm_server)
const std::string & name() const
void process(int revent) override
void process(int revent) override
SharedMemoryServer(const SharedMemoryServerParams ¶ms)
std::string unixSocketPath
std::unique_ptr< ListenSocketEvent > listenSocketEvent
Addr start() const
Get the start address of the range.
std::string to_string() const
Get a string representation of the range.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
void schedule(PollEvent *event)
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
const Info * resolve(const std::string &name)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
void align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp, int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
const std::string to_string(sc_enc enc)
Overload hash function for BasicBlockRange type.
const std::string & name()