*/
#include "lease-server.h"
+
+#include "dlm-protocol.h"
#include "log.h"
#include "socket-path.h"
int nservers;
};
-static struct ls_client *client_connect(struct ls *ls, struct ls_server *serv)
+static void client_connect(struct ls *ls, struct ls_server *serv)
{
int cfd = accept(serv->listen.fd, NULL, NULL);
if (cfd < 0) {
DEBUG_LOG("accept failed on %s: %s\n", serv->address.sun_path,
strerror(errno));
- return NULL;
+ return;
}
struct ls_client *client = NULL;
}
if (!client) {
close(cfd);
- return NULL;
+ return;
}
client->socket.fd = cfd;
struct epoll_event ev = {
- .events = POLLHUP,
+ .events = POLLIN,
.data.ptr = &client->socket,
};
if (epoll_ctl(ls->epoll_fd, EPOLL_CTL_ADD, cfd, &ev)) {
DEBUG_LOG("epoll_ctl add failed: %s\n", strerror(errno));
close(cfd);
- return NULL;
+ return;
}
client->is_connected = true;
- return client;
+}
+
+static int parse_client_request(struct ls_socket *client)
+{
+ int ret = -1;
+ struct dlm_client_request hdr;
+ if (!receive_dlm_client_request(client->fd, &hdr))
+ return ret;
+
+ switch (hdr.opcode) {
+ case DLM_GET_LEASE:
+ ret = LS_REQ_GET_LEASE;
+ break;
+ case DLM_RELEASE_LEASE:
+ ret = LS_REQ_RELEASE_LEASE;
+ break;
+ default:
+ ERROR_LOG("Unexpected client request received\n");
+ break;
+ };
+
+ return ret;
}
static int create_socket_lock(struct sockaddr_un *addr)
address->sun_family = AF_UNIX;
- int server_socket = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
+ int server_socket = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
if (server_socket < 0) {
DEBUG_LOG("Socket creation failed: %s\n", strerror(errno));
return false;
return NULL;
}
- ls->servers = calloc(count, sizeof(struct ls_server));
- if (!ls->servers) {
- DEBUG_LOG("Memory allocation failed: %s\n", strerror(errno));
- goto err;
- }
-
ls->epoll_fd = epoll_create1(0);
if (ls->epoll_fd < 0) {
DEBUG_LOG("epoll_create failed: %s\n", strerror(errno));
+ free(ls);
+ return NULL;
+ }
+
+ ls->servers = calloc(count, sizeof(struct ls_server));
+ if (!ls->servers) {
+ DEBUG_LOG("Memory allocation failed: %s\n", strerror(errno));
goto err;
}
struct ls_socket *sock = ev.data.ptr;
assert(sock);
- struct ls_server *server;
- struct ls_client *client;
-
if (sock->is_server) {
- if (!(ev.events & POLLIN))
- continue;
+ if (ev.events & POLLIN)
+ client_connect(ls, sock->server);
+ continue;
+ }
- server = sock->server;
- client = client_connect(ls, server);
- if (client)
- request = LS_REQ_GET_LEASE;
- } else {
- if (!(ev.events & POLLHUP))
- continue;
+ if (ev.events & POLLIN)
+ request = parse_client_request(sock);
- client = sock->client;
- server = client->serv;
- request = LS_REQ_RELEASE_LEASE;
- }
+ if (request < 0 && (ev.events & POLLHUP))
+ request = LS_REQ_CLIENT_DISCONNECT;
+
+ struct ls_client *client = sock->client;
+ struct ls_server *server = client->serv;
req->lease_handle = server->lease_handle;
req->client = client;
assert(ls);
assert(client);
+ struct ls_server *serv = client->serv;
+
if (fd < 0)
return false;
- char data[1];
- struct iovec iov = {
- .iov_base = data,
- .iov_len = sizeof(data),
- };
-
- char ctrl_buf[CMSG_SPACE(sizeof(int))] = {0};
-
- struct msghdr msg = {
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_controllen = sizeof(ctrl_buf),
- .msg_control = ctrl_buf,
- };
-
- struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- *((int *)CMSG_DATA(cmsg)) = fd;
-
- struct ls_server *serv = client->serv;
-
- if (sendmsg(client->socket.fd, &msg, 0) < 0) {
+ if (!send_lease_fd(client->socket.fd, fd)) {
DEBUG_LOG("sendmsg failed on %s: %s\n", serv->address.sun_path,
strerror(errno));
return false;
}
- INFO_LOG("Lease request granted on %s\n", serv->address.sun_path);
+ if (fd > 0)
+ INFO_LOG("Lease request granted on %s\n",
+ serv->address.sun_path);
+
return true;
}