Use poll() instead of epoll() for ifchd and sockd.

poll() is simpler, portable, and the scalability advantages of
epoll are inapplicable here.
This commit is contained in:
Nicholas J. Kain 2020-10-20 05:09:26 -04:00
parent 06a541261e
commit af9d45719f
2 changed files with 40 additions and 54 deletions

View File

@ -34,7 +34,7 @@
#include <sys/un.h> #include <sys/un.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/epoll.h> #include <poll.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
@ -53,10 +53,6 @@
struct ifchd_client cl; struct ifchd_client cl;
static int epollfd;
/* Slots are for the ndhc -> ifchd socket. */
static struct epoll_event events[2];
static int resolv_conf_fd = -1; static int resolv_conf_fd = -1;
/* int ntp_conf_fd = -1; */ /* int ntp_conf_fd = -1; */
static int resolv_conf_head_fd = -1; static int resolv_conf_head_fd = -1;
@ -341,36 +337,33 @@ static void process_client_socket(void)
static void do_ifch_work(void) static void do_ifch_work(void)
{ {
epollfd = epoll_create1(0);
if (epollfd < 0)
suicide("epoll_create1 failed");
cl.state = STATE_NOTHING; cl.state = STATE_NOTHING;
memset(cl.ibuf, 0, sizeof cl.ibuf); memset(cl.ibuf, 0, sizeof cl.ibuf);
memset(cl.namesvrs, 0, sizeof cl.namesvrs); memset(cl.namesvrs, 0, sizeof cl.namesvrs);
memset(cl.domains, 0, sizeof cl.domains); memset(cl.domains, 0, sizeof cl.domains);
epoll_add(epollfd, ifchSock[1]); struct pollfd pfds[2] = {0};
epoll_add(epollfd, ifchStream[1]); pfds[0].fd = ifchSock[1];
pfds[0].events = POLLIN|POLLHUP|POLLERR|POLLRDHUP;
pfds[1].fd = ifchStream[1];
pfds[1].events = POLLHUP|POLLERR|POLLRDHUP;
for (;;) { for (;;) {
int r = epoll_wait(epollfd, events, 2, -1); if (poll(pfds, 2, -1) < 0) {
if (r < 0) { if (errno == EINTR) continue;
if (errno == EINTR) else suicide("pollt failed");
continue;
else
suicide("epoll_wait failed");
} }
for (int i = 0; i < r; ++i) { if (pfds[0].revents & POLLIN) {
int fd = events[i].data.fd; pfds[0].revents &= ~POLLIN;
if (fd == ifchSock[1]) { process_client_socket();
if (events[i].events & EPOLLIN) }
process_client_socket(); if (pfds[0].revents & (POLLHUP|POLLERR|POLLRDHUP)) {
} else if (fd == ifchStream[1]) { pfds[0].revents &= ~(POLLHUP|POLLERR|POLLRDHUP);
if (events[i].events & (EPOLLHUP|EPOLLERR|EPOLLRDHUP)) suicide("ifchSock closed unexpectedly");
exit(EXIT_SUCCESS); }
} else if (pfds[1].revents & (POLLHUP|POLLERR|POLLRDHUP)) {
suicide("ifch: unexpected fd while performing epoll"); pfds[1].revents &= ~(POLLHUP|POLLERR|POLLRDHUP);
exit(EXIT_SUCCESS);
} }
} }
} }

View File

@ -36,7 +36,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <assert.h> #include <assert.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/epoll.h> #include <poll.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/prctl.h> #include <sys/prctl.h>
@ -58,10 +58,6 @@
#include "dhcp.h" #include "dhcp.h"
#include "sys.h" #include "sys.h"
static int epollfd;
/* Slots are for the ndhc -> ifchd socket. */
static struct epoll_event events[2];
uid_t sockd_uid = 0; uid_t sockd_uid = 0;
gid_t sockd_gid = 0; gid_t sockd_gid = 0;
@ -550,31 +546,28 @@ static void process_client_socket(void)
static void do_sockd_work(void) static void do_sockd_work(void)
{ {
epollfd = epoll_create1(0); struct pollfd pfds[2] = {0};
if (epollfd < 0) pfds[0].fd = sockdSock[1];
suicide("epoll_create1 failed"); pfds[0].events = POLLIN|POLLHUP|POLLERR|POLLRDHUP;
pfds[1].fd = sockdStream[1];
epoll_add(epollfd, sockdSock[1]); pfds[1].events = POLLHUP|POLLERR|POLLRDHUP;
epoll_add(epollfd, sockdStream[1]);
for (;;) { for (;;) {
int r = epoll_wait(epollfd, events, 2, -1); if (poll(pfds, 2, -1) < 0) {
if (r < 0) { if (errno == EINTR) continue;
if (errno == EINTR) else suicide("poll failed");
continue;
else
suicide("epoll_wait failed");
} }
for (int i = 0; i < r; ++i) { if (pfds[0].revents & POLLIN) {
int fd = events[i].data.fd; pfds[0].revents &= ~POLLIN;
if (fd == sockdSock[1]) { process_client_socket();
if (events[i].events & EPOLLIN) }
process_client_socket(); if (pfds[0].revents & (POLLHUP|POLLERR|POLLRDHUP)) {
} else if (fd == sockdStream[1]) { pfds[0].revents &= ~(POLLHUP|POLLERR|POLLRDHUP);
if (events[i].events & (EPOLLHUP|EPOLLERR|EPOLLRDHUP)) suicide("sockdSock closed unexpectedly");
exit(EXIT_SUCCESS); }
} else if (pfds[1].revents & (POLLHUP|POLLERR|POLLRDHUP)) {
suicide("sockd: unexpected fd while performing epoll"); pfds[1].revents &= ~(POLLHUP|POLLERR|POLLRDHUP);
exit(EXIT_SUCCESS);
} }
} }
} }