This is an automated email from the git hooks/post-receive script.
teigland pushed a commit to branch master
in repository sanlock.
The following commit(s) were added to refs/heads/master by this push:
new 8e4af6e sanlock: socket send and recv retries
8e4af6e is described below
commit 8e4af6ef6201aa7c7aa9aaeeadee9fc7ce2f476d
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue May 4 13:38:53 2021 -0500
sanlock: socket send and recv retries
ignore EINTR from send() and recv()
check for and handle partial send()
for completeness, not seen in practice.
---
src/client.c | 28 ++++++--
src/client_cmd.c | 24 ++++++-
src/cmd.c | 206 ++++++++++++++++++++++++++++++++-----------------------
src/lockspace.c | 4 +-
src/main.c | 19 ++++-
5 files changed, 183 insertions(+), 98 deletions(-)
diff --git a/src/client.c b/src/client.c
index 89fb68e..5dc7650 100644
--- a/src/client.c
+++ b/src/client.c
@@ -74,7 +74,9 @@ static int send_header(int sock, int cmd, uint32_t cmd_flags, int
datalen,
uint32_t data, uint32_t data2)
{
struct sm_header header;
- int rv;
+ size_t rem = sizeof(header);
+ size_t off = 0;
+ ssize_t rv;
memset(&header, 0, sizeof(header));
header.magic = SM_MAGIC;
@@ -86,24 +88,36 @@ static int send_header(int sock, int cmd, uint32_t cmd_flags, int
datalen,
header.data2 = data2;
retry:
- rv = send(sock, (void *) &header, sizeof(header), 0);
+ rv = send(sock, (char *)&header + off, rem, 0);
if (rv == -1 && errno == EINTR)
goto retry;
-
if (rv < 0)
return -errno;
-
+ if (rv < rem) {
+ rem -= rv;
+ off += rv;
+ goto retry;
+ }
return 0;
}
static ssize_t send_data(int sockfd, const void *buf, size_t len, int flags)
{
+ size_t rem = len;
+ size_t off = 0;
ssize_t rv;
retry:
- rv = send(sockfd, buf, len, flags);
+ rv = send(sockfd, (char *)buf + off, rem, flags);
if (rv == -1 && errno == EINTR)
goto retry;
- return rv;
+ if (rv < 0)
+ return -errno;
+ if (rv < rem) {
+ rem -= rv;
+ off += rv;
+ goto retry;
+ }
+ return 0;
}
static ssize_t recv_data(int sockfd, void *buf, size_t len, int flags)
@@ -138,7 +152,7 @@ int send_command(int cmd, uint32_t data)
static int recv_result(int fd)
{
struct sm_header h;
- int rv;
+ ssize_t rv;
memset(&h, 0, sizeof(h));
retry:
diff --git a/src/client_cmd.c b/src/client_cmd.c
index fb22435..e06d0f7 100644
--- a/src/client_cmd.c
+++ b/src/client_cmd.c
@@ -56,6 +56,26 @@ static void print_debug(char *str, int len)
printf(" %s\n", p);
}
+static ssize_t send_all(int sockfd, const void *buf, size_t len, int flags)
+{
+ size_t rem = len;
+ size_t off = 0;
+ ssize_t rv;
+
+retry:
+ rv = send(sockfd, (char *)buf + off, rem, flags);
+ if (rv == -1 && errno == EINTR)
+ goto retry;
+ if (rv < 0)
+ return -errno;
+ if (rv < rem) {
+ rem -= rv;
+ off += rv;
+ goto retry;
+ }
+ return 0;
+}
+
static void status_daemon(struct sanlk_state *st, char *str, int debug)
{
printf("daemon %.48s\n", st->name);
@@ -474,7 +494,7 @@ static int lockspace_host_status(int debug, char *lockspace_name)
memset(&lockspace, 0, sizeof(lockspace));
snprintf(lockspace.name, SANLK_NAME_LEN, "%s", lockspace_name);
- rv = send(fd, &lockspace, sizeof(lockspace), 0);
+ rv = send_all(fd, &lockspace, sizeof(lockspace), 0);
if (rv < 0)
goto out;
@@ -603,7 +623,7 @@ int sanlock_renewal(char *lockspace_name)
memset(&lockspace, 0, sizeof(lockspace));
snprintf(lockspace.name, SANLK_NAME_LEN, "%s", lockspace_name);
- rv = send(fd, &lockspace, sizeof(lockspace), 0);
+ rv = send_all(fd, &lockspace, sizeof(lockspace), 0);
if (rv < 0)
goto out;
diff --git a/src/cmd.c b/src/cmd.c
index 3137df0..6815585 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -57,6 +57,38 @@ void send_result(int ci, int fd, struct sm_header *h_recv, int
result);
static uint32_t token_id_counter = 1;
+static ssize_t recv_loop(int sockfd, void *buf, size_t len, int flags)
+{
+ ssize_t rv;
+
+ for (;;) {
+ rv = recv(sockfd, buf, len, flags);
+ if (rv == -1 && errno == EINTR)
+ continue;
+ return rv;
+ }
+}
+
+static ssize_t send_all(int sockfd, const void *buf, size_t len, int flags)
+{
+ size_t rem = len;
+ size_t off = 0;
+ ssize_t rv;
+
+retry:
+ rv = send(sockfd, (char *)buf + off, rem, flags);
+ if (rv == -1 && errno == EINTR)
+ goto retry;
+ if (rv < 0)
+ return -errno;
+ if (rv < rem) {
+ rem -= rv;
+ off += rv;
+ goto retry;
+ }
+ return 0;
+}
+
static void release_cl_tokens(struct task *task, struct client *cl)
{
struct token *token;
@@ -251,7 +283,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca,
uint32_t cmd)
* receive sanlk_resource, create token for it
*/
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv > 0)
pos += rv;
if (rv != sizeof(struct sanlk_resource)) {
@@ -295,7 +327,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca,
uint32_t cmd)
* in sanlk_disk (TODO: let these differ?)
*/
- rv = recv(fd, token->disks, disks_len, MSG_WAITALL);
+ rv = recv_loop(fd, token->disks, disks_len, MSG_WAITALL);
if (rv > 0)
pos += rv;
if (rv != disks_len) {
@@ -317,7 +349,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca,
uint32_t cmd)
alloc_count++;
}
- rv = recv(fd, &opt, sizeof(struct sanlk_options), MSG_WAITALL);
+ rv = recv_loop(fd, &opt, sizeof(struct sanlk_options), MSG_WAITALL);
if (rv > 0)
pos += rv;
if (rv != sizeof(struct sanlk_options)) {
@@ -336,7 +368,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca,
uint32_t cmd)
goto done;
}
- rv = recv(fd, opt_str, opt.len, MSG_WAITALL);
+ rv = recv_loop(fd, opt_str, opt.len, MSG_WAITALL);
if (rv > 0)
pos += rv;
if (rv != opt.len) {
@@ -575,7 +607,7 @@ static void cmd_release(struct task *task, struct cmd_args *ca,
uint32_t cmd)
}
if (ca->header.cmd_flags & SANLK_REL_ORPHAN) {
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_release %d,%d,%d recv res %d %d",
cl_ci, cl_fd, cl_pid, rv, errno);
@@ -588,7 +620,7 @@ static void cmd_release(struct task *task, struct cmd_args *ca,
uint32_t cmd)
}
if (ca->header.cmd_flags & SANLK_REL_RENAME) {
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_release %d,%d,%d recv res %d %d",
cl_ci, cl_fd, cl_pid, rv, errno);
@@ -597,7 +629,7 @@ static void cmd_release(struct task *task, struct cmd_args *ca,
uint32_t cmd)
}
/* second res struct has new name for first res */
- rv = recv(fd, &new, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &new, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_release %d,%d,%d recv new %d %d",
cl_ci, cl_fd, cl_pid, rv, errno);
@@ -638,7 +670,7 @@ static void cmd_release(struct task *task, struct cmd_args *ca,
uint32_t cmd)
/* caller is specifying specific resources to release */
for (i = 0; i < ca->header.data; i++) {
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_release %d,%d,%d recv res %d %d",
cl_ci, cl_fd, cl_pid, rv, errno);
@@ -851,12 +883,12 @@ static void cmd_inquire(struct task *task, struct cmd_args *ca,
uint32_t cmd)
if (state) {
h.length = sizeof(h) + state_strlen + 1;
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
- send(fd, state, state_strlen + 1, MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, state, state_strlen + 1, MSG_NOSIGNAL);
free(state);
} else {
h.length = sizeof(h);
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
}
client_resume(ca->ci_in);
@@ -899,7 +931,7 @@ static void cmd_convert(struct task *task, struct cmd_args *ca,
uint32_t cmd)
log_cmd(cmd, "cmd_convert %d,%d,%d ci_in %d fd %d",
cl_ci, cl_fd, cl_pid, ca->ci_in, fd);
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
result = -ENOTCONN;
goto reply;
@@ -963,7 +995,7 @@ static void cmd_request(struct task *task, struct cmd_args *ca,
uint32_t cmd)
/* receiving and setting up token copied from cmd_acquire */
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_request %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1004,7 +1036,7 @@ static void cmd_request(struct task *task, struct cmd_args *ca,
uint32_t cmd)
* in sanlk_disk (TODO: let these differ?)
*/
- rv = recv(fd, token->disks, disks_len, MSG_WAITALL);
+ rv = recv_loop(fd, token->disks, disks_len, MSG_WAITALL);
if (rv != disks_len) {
result = -ENOTCONN;
goto reply_free;
@@ -1078,7 +1110,7 @@ static void cmd_examine(struct task *task GNUC_UNUSED, struct
cmd_args *ca, uint
ls = &buf.s;
}
- rv = recv(fd, &buf, datalen, MSG_WAITALL);
+ rv = recv_loop(fd, &buf, datalen, MSG_WAITALL);
if (rv != datalen) {
log_error("cmd_examine %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1113,7 +1145,7 @@ static void cmd_set_lvb(struct task *task GNUC_UNUSED, struct
cmd_args *ca, uint
fd = client[ca->ci_in].fd;
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_set_lvb %d,%d recv %d %d", ca->ci_in, fd, rv, errno);
result = -ENOTCONN;
@@ -1137,7 +1169,7 @@ static void cmd_set_lvb(struct task *task GNUC_UNUSED, struct
cmd_args *ca, uint
goto reply;
}
- rv = recv(fd, lvb, lvblen, MSG_WAITALL);
+ rv = recv_loop(fd, lvb, lvblen, MSG_WAITALL);
if (rv != lvblen) {
log_error("cmd_set_lvb %d,%d recv lvblen %d lvb %d %d",
ca->ci_in, fd, lvblen, rv, errno);
@@ -1166,7 +1198,7 @@ static void cmd_get_lvb(struct task *task GNUC_UNUSED, struct
cmd_args *ca, uint
fd = client[ca->ci_in].fd;
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_get_lvb %d,%d recv %d %d", ca->ci_in, fd, rv, errno);
result = -ENOTCONN;
@@ -1187,10 +1219,10 @@ static void cmd_get_lvb(struct task *task GNUC_UNUSED, struct
cmd_args *ca, uint
h.data2 = 0;
h.length = sizeof(h) + lvblen;
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
if (lvb) {
- send(fd, lvb, lvblen, MSG_NOSIGNAL);
+ send_all(fd, lvb, lvblen, MSG_NOSIGNAL);
free(lvb);
}
@@ -1259,7 +1291,7 @@ void daemon_shutdown_reply(void)
h.version = SM_PROTO;
h.length = sizeof(h);
- send(shutdown_reply_fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(shutdown_reply_fd, &h, sizeof(h), MSG_NOSIGNAL);
close(shutdown_reply_fd);
client_resume(shutdown_reply_ci);
@@ -1275,7 +1307,7 @@ static void cmd_add_lockspace(struct cmd_args *ca, uint32_t cmd)
fd = client[ca->ci_in].fd;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_add_lockspace %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1324,7 +1356,7 @@ static void cmd_inq_lockspace(struct cmd_args *ca, uint32_t cmd)
fd = client[ca->ci_in].fd;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_inq_lockspace %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1408,7 +1440,7 @@ static void cmd_rem_lockspace(struct cmd_args *ca, uint32_t cmd)
fd = client[ca->ci_in].fd;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_rem_lockspace %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1456,7 +1488,7 @@ static void cmd_align(struct task *task GNUC_UNUSED, struct cmd_args
*ca, uint32
fd = client[ca->ci_in].fd;
- rv = recv(fd, &disk, sizeof(struct sanlk_disk), MSG_WAITALL);
+ rv = recv_loop(fd, &disk, sizeof(struct sanlk_disk), MSG_WAITALL);
if (rv != sizeof(struct sanlk_disk)) {
log_error("cmd_align %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1504,7 +1536,7 @@ static void cmd_read_lockspace(struct task *task, struct cmd_args
*ca, uint32_t
fd = client[ca->ci_in].fd;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_read_lockspace %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1568,8 +1600,8 @@ static void cmd_read_lockspace(struct task *task, struct cmd_args
*ca, uint32_t
h.data = result;
h.data2 = io_timeout;
h.length = sizeof(h) + sizeof(lockspace);
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
- send(fd, &lockspace, sizeof(lockspace), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &lockspace, sizeof(lockspace), MSG_NOSIGNAL);
client_resume(ca->ci_in);
}
@@ -1585,7 +1617,7 @@ static void cmd_read_resource(struct task *task, struct cmd_args
*ca, uint32_t c
/* receiving and setting up token copied from cmd_acquire */
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_read_resource %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1620,7 +1652,7 @@ static void cmd_read_resource(struct task *task, struct cmd_args
*ca, uint32_t c
* in sanlk_disk (TODO: let these differ?)
*/
- rv = recv(fd, token->disks, disks_len, MSG_WAITALL);
+ rv = recv_loop(fd, token->disks, disks_len, MSG_WAITALL);
if (rv != disks_len) {
result = -ENOTCONN;
goto reply;
@@ -1668,8 +1700,8 @@ static void cmd_read_resource(struct task *task, struct cmd_args
*ca, uint32_t c
h.data = result;
h.data2 = 0;
h.length = sizeof(h) + sizeof(res);
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
- send(fd, &res, sizeof(res), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &res, sizeof(res), MSG_NOSIGNAL);
client_resume(ca->ci_in);
}
@@ -1686,7 +1718,7 @@ static void cmd_read_resource_owners(struct task *task, struct
cmd_args *ca, uin
/* receiving and setting up token copied from cmd_acquire */
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_read_resource_owners %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1721,7 +1753,7 @@ static void cmd_read_resource_owners(struct task *task, struct
cmd_args *ca, uin
* in sanlk_disk (TODO: let these differ?)
*/
- rv = recv(fd, token->disks, disks_len, MSG_WAITALL);
+ rv = recv_loop(fd, token->disks, disks_len, MSG_WAITALL);
if (rv != disks_len) {
result = -ENOTCONN;
goto reply;
@@ -1771,10 +1803,10 @@ static void cmd_read_resource_owners(struct task *task, struct
cmd_args *ca, uin
h.data = result;
h.data2 = count;
h.length = sizeof(h) + sizeof(res) + send_len;
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
- send(fd, &res, sizeof(res), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &res, sizeof(res), MSG_NOSIGNAL);
if (send_len && send_buf) {
- send(fd, send_buf, send_len, MSG_NOSIGNAL);
+ send_all(fd, send_buf, send_len, MSG_NOSIGNAL);
free(send_buf);
}
@@ -1790,7 +1822,7 @@ static void cmd_write_lockspace(struct task *task, struct cmd_args
*ca, uint32_t
fd = client[ca->ci_in].fd;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
log_error("cmd_write_lockspace %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1849,7 +1881,7 @@ static void cmd_write_resource(struct task *task, struct cmd_args
*ca, uint32_t
/* receiving and setting up token copied from cmd_acquire */
- rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ rv = recv_loop(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
if (rv != sizeof(struct sanlk_resource)) {
log_error("cmd_write_resource %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -1885,7 +1917,7 @@ static void cmd_write_resource(struct task *task, struct cmd_args
*ca, uint32_t
* in sanlk_disk (TODO: let these differ?)
*/
- rv = recv(fd, token->disks, disks_len, MSG_WAITALL);
+ rv = recv_loop(fd, token->disks, disks_len, MSG_WAITALL);
if (rv != disks_len) {
result = -ENOTCONN;
goto reply;
@@ -1948,7 +1980,7 @@ static void cmd_killpath(struct task *task, struct cmd_args *ca,
uint32_t cmd)
log_cmd(cmd, "cmd_killpath %d,%d,%d flags %x",
cl_ci, cl_fd, cl_pid, ca->header.cmd_flags);
- rv = recv(cl_fd, cl->killpath, SANLK_HELPER_PATH_LEN, MSG_WAITALL);
+ rv = recv_loop(cl_fd, cl->killpath, SANLK_HELPER_PATH_LEN, MSG_WAITALL);
if (rv != SANLK_HELPER_PATH_LEN) {
log_error("cmd_killpath %d,%d,%d recv path %d %d",
cl_ci, cl_fd, cl_pid, rv, errno);
@@ -1958,7 +1990,7 @@ static void cmd_killpath(struct task *task, struct cmd_args *ca,
uint32_t cmd)
goto done;
}
- rv = recv(cl_fd, cl->killargs, SANLK_HELPER_ARGS_LEN, MSG_WAITALL);
+ rv = recv_loop(cl_fd, cl->killargs, SANLK_HELPER_ARGS_LEN, MSG_WAITALL);
if (rv != SANLK_HELPER_ARGS_LEN) {
log_error("cmd_killpath %d,%d,%d recv args %d %d",
cl_ci, cl_fd, cl_pid, rv, errno);
@@ -2001,13 +2033,13 @@ static void cmd_set_event(struct task *task GNUC_UNUSED, struct
cmd_args *ca, ui
fd = client[ca->ci_in].fd;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
result = -ENOTCONN;
goto reply;
}
- rv = recv(fd, &he, sizeof(struct sanlk_host_event), MSG_WAITALL);
+ rv = recv_loop(fd, &he, sizeof(struct sanlk_host_event), MSG_WAITALL);
if (rv != sizeof(struct sanlk_host_event)) {
result = -ENOTCONN;
goto reply;
@@ -2030,7 +2062,7 @@ static void cmd_format_rindex(struct task *task, struct cmd_args
*ca, uint32_t c
fd = client[ca->ci_in].fd;
- rv = recv(fd, &ri, sizeof(struct sanlk_rindex), MSG_WAITALL);
+ rv = recv_loop(fd, &ri, sizeof(struct sanlk_rindex), MSG_WAITALL);
if (rv != sizeof(struct sanlk_rindex)) {
log_error("cmd_format_rindex %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -2058,7 +2090,7 @@ static void cmd_rebuild_rindex(struct task *task, struct cmd_args
*ca, uint32_t
fd = client[ca->ci_in].fd;
- rv = recv(fd, &ri, sizeof(struct sanlk_rindex), MSG_WAITALL);
+ rv = recv_loop(fd, &ri, sizeof(struct sanlk_rindex), MSG_WAITALL);
if (rv != sizeof(struct sanlk_rindex)) {
log_error("cmd_rebuild_rindex %d,%d recv %d %d",
ca->ci_in, fd, rv, errno);
@@ -2091,14 +2123,14 @@ static void rindex_op(struct task *task, struct cmd_args *ca,
const char *ri_cmd
fd = client[ca->ci_in].fd;
- rv = recv(fd, &ri, sizeof(struct sanlk_rindex), MSG_WAITALL);
+ rv = recv_loop(fd, &ri, sizeof(struct sanlk_rindex), MSG_WAITALL);
if (rv != sizeof(struct sanlk_rindex)) {
log_error("%s %d,%d recv %d %d", ri_cmd_str, ca->ci_in, fd, rv, errno);
result = -ENOTCONN;
goto reply;
}
- rv = recv(fd, &re, sizeof(struct sanlk_rentry), MSG_WAITALL);
+ rv = recv_loop(fd, &re, sizeof(struct sanlk_rentry), MSG_WAITALL);
if (rv != sizeof(struct sanlk_rentry)) {
log_error("%s %d,%d recv %d %d", ri_cmd_str, ca->ci_in, fd, rv, errno);
result = -ENOTCONN;
@@ -2129,8 +2161,8 @@ static void rindex_op(struct task *task, struct cmd_args *ca, const
char *ri_cmd
h.data = result;
h.data2 = 0;
h.length = sizeof(h) + sizeof(re_ret);
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
- send(fd, &re_ret, sizeof(re), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &re_ret, sizeof(re), MSG_NOSIGNAL);
client_resume(ca->ci_in);
}
@@ -2479,9 +2511,9 @@ static void send_state_daemon(int fd)
st.str_len = str_len;
- send(fd, &st, sizeof(st), MSG_NOSIGNAL);
+ send_all(fd, &st, sizeof(st), MSG_NOSIGNAL);
if (str_len)
- send(fd, str, str_len, MSG_NOSIGNAL);
+ send_all(fd, str, str_len, MSG_NOSIGNAL);
}
static void send_state_client(int fd, struct client *cl, int ci)
@@ -2500,9 +2532,9 @@ static void send_state_client(int fd, struct client *cl, int ci)
st.str_len = str_len;
- send(fd, &st, sizeof(st), MSG_NOSIGNAL);
+ send_all(fd, &st, sizeof(st), MSG_NOSIGNAL);
if (str_len)
- send(fd, str, str_len, MSG_NOSIGNAL);
+ send_all(fd, str, str_len, MSG_NOSIGNAL);
}
static void send_state_lockspace(int fd, struct space *sp, const char *list_name)
@@ -2522,16 +2554,16 @@ static void send_state_lockspace(int fd, struct space *sp, const
char *list_name
st.str_len = str_len;
- send(fd, &st, sizeof(st), MSG_NOSIGNAL);
+ send_all(fd, &st, sizeof(st), MSG_NOSIGNAL);
if (str_len)
- send(fd, str, str_len, MSG_NOSIGNAL);
+ send_all(fd, str, str_len, MSG_NOSIGNAL);
memset(&lockspace, 0, sizeof(struct sanlk_lockspace));
strncpy(lockspace.name, sp->space_name, NAME_ID_SIZE);
lockspace.host_id = sp->host_id;
memcpy(&lockspace.host_id_disk, &sp->host_id_disk, sizeof(struct
sanlk_disk));
- send(fd, &lockspace, sizeof(lockspace), MSG_NOSIGNAL);
+ send_all(fd, &lockspace, sizeof(lockspace), MSG_NOSIGNAL);
}
void send_state_resource(int fd, struct resource *r, const char *list_name,
@@ -2556,14 +2588,14 @@ void send_state_resource(int fd, struct resource *r, const char
*list_name,
st.str_len = str_len;
- send(fd, &st, sizeof(st), MSG_NOSIGNAL);
+ send_all(fd, &st, sizeof(st), MSG_NOSIGNAL);
if (str_len)
- send(fd, str, str_len, MSG_NOSIGNAL);
+ send_all(fd, str, str_len, MSG_NOSIGNAL);
- send(fd, &r->r, sizeof(struct sanlk_resource), MSG_NOSIGNAL);
+ send_all(fd, &r->r, sizeof(struct sanlk_resource), MSG_NOSIGNAL);
for (i = 0; i < r->r.num_disks; i++) {
- send(fd, &r->r.disks[i], sizeof(struct sanlk_disk), MSG_NOSIGNAL);
+ send_all(fd, &r->r.disks[i], sizeof(struct sanlk_disk), MSG_NOSIGNAL);
}
}
@@ -2583,9 +2615,9 @@ static void send_state_host(int fd, struct host_status *hs, int
host_id)
st.str_len = str_len;
- send(fd, &st, sizeof(st), MSG_NOSIGNAL);
+ send_all(fd, &st, sizeof(st), MSG_NOSIGNAL);
if (str_len)
- send(fd, str, str_len, MSG_NOSIGNAL);
+ send_all(fd, str, str_len, MSG_NOSIGNAL);
}
static void send_state_renewal(int fd, struct renewal_history *hi)
@@ -2603,9 +2635,9 @@ static void send_state_renewal(int fd, struct renewal_history *hi)
st.str_len = str_len;
- send(fd, &st, sizeof(st), MSG_NOSIGNAL);
+ send_all(fd, &st, sizeof(st), MSG_NOSIGNAL);
if (str_len)
- send(fd, str, str_len, MSG_NOSIGNAL);
+ send_all(fd, str, str_len, MSG_NOSIGNAL);
}
static void cmd_status(int ci, int fd, struct sm_header *h_recv, int client_maxi,
uint32_t cmd)
@@ -2623,7 +2655,7 @@ static void cmd_status(int ci, int fd, struct sm_header *h_recv, int
client_maxi
h.length = sizeof(h);
h.data = 0;
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
send_state_daemon(fd);
@@ -2687,7 +2719,7 @@ static void cmd_host_status(int ci, int fd, struct sm_header
*h_recv, uint32_t c
goto fail;
}
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
h.data = -ENOTCONN;
goto fail;
@@ -2704,7 +2736,7 @@ static void cmd_host_status(int ci, int fd, struct sm_header
*h_recv, uint32_t c
goto fail;
}
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
for (i = 0; i < DEFAULT_MAX_HOSTS; i++) {
hs = &status[i];
@@ -2717,7 +2749,7 @@ static void cmd_host_status(int ci, int fd, struct sm_header
*h_recv, uint32_t c
free(status);
return;
fail:
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
if (status)
free(status);
@@ -2751,7 +2783,7 @@ static void cmd_renewal(int fd, struct sm_header *h_recv)
goto fail;
}
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
h.data = -ENOTCONN;
goto fail;
@@ -2786,7 +2818,7 @@ static void cmd_renewal(int fd, struct sm_header *h_recv)
h.data2 = io_timeout;
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
/* If next slot is non-zero, then we've wrapped and
should begin sending history from next to end
@@ -2808,7 +2840,7 @@ static void cmd_renewal(int fd, struct sm_header *h_recv)
free(history);
return;
fail:
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(h), MSG_NOSIGNAL);
if (history)
free(history);
@@ -2825,8 +2857,8 @@ static void cmd_log_dump(int fd, struct sm_header *h_recv)
h_recv->version = SM_PROTO;
h_recv->data = len;
- send(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
- send(fd, send_data_buf, len, MSG_NOSIGNAL);
+ send_all(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, send_data_buf, len, MSG_NOSIGNAL);
}
static void cmd_get_lockspaces(int ci, int fd, struct sm_header *h_recv, uint32_t cmd)
@@ -2842,8 +2874,8 @@ static void cmd_get_lockspaces(int ci, int fd, struct sm_header
*h_recv, uint32_
h_recv->data = rv;
h_recv->data2 = count;
- send(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
- send(fd, send_data_buf, len, MSG_NOSIGNAL);
+ send_all(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, send_data_buf, len, MSG_NOSIGNAL);
}
static void cmd_get_hosts(int ci, int fd, struct sm_header *h_recv, uint32_t cmd)
@@ -2860,7 +2892,7 @@ static void cmd_get_hosts(int ci, int fd, struct sm_header *h_recv,
uint32_t cmd
h.length = sizeof(h);
h.data = 0;
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
h.data = -ENOTCONN;
goto out;
@@ -2872,9 +2904,9 @@ static void cmd_get_hosts(int ci, int fd, struct sm_header *h_recv,
uint32_t cmd
h.data = rv;
h.data2 = count;
out:
- send(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
if (len)
- send(fd, send_data_buf, len, MSG_NOSIGNAL);
+ send_all(fd, send_data_buf, len, MSG_NOSIGNAL);
}
static void cmd_restrict(int ci, int fd, struct sm_header *h_recv, uint32_t cmd)
@@ -2899,7 +2931,7 @@ static void cmd_version(int ci GNUC_UNUSED, int fd, struct sm_header
*h_recv)
h_recv->data = 0;
h_recv->data2 = sanlock_version_combined;
- send(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
}
static void cmd_reg_event(int fd, struct sm_header *h_recv, uint32_t cmd)
@@ -2913,14 +2945,14 @@ static void cmd_reg_event(int fd, struct sm_header *h_recv,
uint32_t cmd)
h.version = SM_PROTO;
h.length = sizeof(struct sm_header);
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
h.data = -ENOTCONN;
goto out;
}
/* currently unused */
- rv = recv(fd, &he, sizeof(he), MSG_WAITALL);
+ rv = recv_loop(fd, &he, sizeof(he), MSG_WAITALL);
if (rv != sizeof(he)) {
h.data = -ENOTCONN;
goto out;
@@ -2931,7 +2963,7 @@ static void cmd_reg_event(int fd, struct sm_header *h_recv, uint32_t
cmd)
h.data = rv;
out:
log_cmd(cmd, "cmd_reg_event fd %d rv %d", fd, rv);
- send(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
}
static void cmd_end_event(int fd, struct sm_header *h_recv, uint32_t cmd)
@@ -2944,7 +2976,7 @@ static void cmd_end_event(int fd, struct sm_header *h_recv, uint32_t
cmd)
h.version = SM_PROTO;
h.length = sizeof(struct sm_header);
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
h.data = -ENOTCONN;
goto out;
@@ -2955,7 +2987,7 @@ static void cmd_end_event(int fd, struct sm_header *h_recv, uint32_t
cmd)
h.data = rv;
out:
log_cmd(cmd, "cmd_end_event fd %d rv %d", fd, rv);
- send(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
}
static void cmd_set_config(int fd, struct sm_header *h_recv, uint32_t cmd)
@@ -2968,7 +3000,7 @@ static void cmd_set_config(int fd, struct sm_header *h_recv,
uint32_t cmd)
h.version = SM_PROTO;
h.length = sizeof(struct sm_header);
- rv = recv(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
+ rv = recv_loop(fd, &lockspace, sizeof(struct sanlk_lockspace), MSG_WAITALL);
if (rv != sizeof(struct sanlk_lockspace)) {
h.data = -ENOTCONN;
goto out;
@@ -2979,7 +3011,7 @@ static void cmd_set_config(int fd, struct sm_header *h_recv,
uint32_t cmd)
h.data = rv;
out:
log_cmd(cmd, "cmd_set_config fd %d rv %d", fd, rv);
- send(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send_all(fd, &h, sizeof(struct sm_header), MSG_NOSIGNAL);
}
static int get_peer_pid(int fd, int *pid)
diff --git a/src/lockspace.c b/src/lockspace.c
index 41f96cb..2ebc247 100644
--- a/src/lockspace.c
+++ b/src/lockspace.c
@@ -1813,8 +1813,10 @@ int send_event_callbacks(uint32_t space_id,
continue;
fd = sp->event_fds[i];
-
+retry:
rv = send(fd, &cb, sizeof(cb), MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (rv == -1 && errno == EINTR)
+ goto retry;
if (rv < 0) {
log_erros(sp, "send_event_callbacks error %d %d close fd %d", rv, errno,
fd);
close(fd);
diff --git a/src/main.c b/src/main.c
index 026f7da..5b6fabc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -458,6 +458,9 @@ void send_result(int ci, int fd, struct sm_header *h_recv, int
result);
void send_result(int ci, int fd, struct sm_header *h_recv, int result)
{
struct sm_header h;
+ size_t rem = sizeof(h);
+ size_t off = 0;
+ ssize_t rv;
log_client(ci, fd, "send %d", result);
@@ -466,7 +469,18 @@ void send_result(int ci, int fd, struct sm_header *h_recv, int
result)
h.length = sizeof(h);
h.data = result;
h.data2 = 0;
- send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+
+retry:
+ rv = send(fd, (char *)&h + off, rem, MSG_NOSIGNAL);
+ if (rv == -1 && errno == EINTR)
+ goto retry;
+ if (rv < 0)
+ return;
+ if (rv < rem) {
+ rem -= rv;
+ off += rv;
+ goto retry;
+ }
}
void client_pid_dead(int ci);
@@ -1231,7 +1245,10 @@ static void process_connection(int ci)
memset(&h, 0, sizeof(h));
+ retry:
rv = recv(client[ci].fd, &h, sizeof(h), MSG_WAITALL);
+ if (rv == -1 && errno == EINTR)
+ goto retry;
if (!rv)
goto dead;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.