From fd5ec4c01b4796abe9153aa45b2c26fbacc1ab2a Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mar 10 2020 17:28:01 +0000 Subject: sanlock: fix connection processing error path Don't close the connection fd in process_cmd_thread_unregistered error path, avoiding possible problems like that fixed in 62ba5d194100f71cbed32214e0aeb76f690f4093. Handle it like process_cmd_thread_registered by receiving any data, sending an error back to the client, and resume the client. Call client_free() in the following cases to close the client connection instead of doing nothing and waiting for a poll error on the connection to clean it up later: - when recv() returns zero - when client_suspend() finds an error - when receiving an unknown cmd These error paths are not exercised by normal usage. --- diff --git a/src/main.c b/src/main.c index 5d2a9b6..d2e8c9a 100644 --- a/src/main.c +++ b/src/main.c @@ -944,6 +944,7 @@ static int thread_pool_add_work(struct cmd_args *ca) rv = pthread_create(&th, NULL, thread_pool_worker, (void *)(long)pool.num_workers); if (rv < 0) { + log_error("thread_pool_add_work ci %d error %d", ca->ci_in, rv); list_del(&ca->list); pthread_mutex_unlock(&pool.mutex); return rv; @@ -1023,8 +1024,11 @@ static void process_cmd_thread_unregistered(int ci_in, struct sm_header *h_recv) fail_free: free(ca); fail: + log_error("cmd %d %d:%d process_unreg error %d", + h_recv->cmd, ci_in, client[ci_in].fd, rv); + client_recv_all(ci_in, h_recv, 0); send_result(client[ci_in].fd, h_recv, rv); - close(client[ci_in].fd); + client_resume(ci_in); } /* @@ -1183,7 +1187,8 @@ static void process_connection(int ci) rv = recv(client[ci].fd, &h, sizeof(h), MSG_WAITALL); if (!rv) - return; + goto dead; + if (rv < 0) { log_error("ci %d fd %d pid %d recv errno %d", ci, client[ci].fd, client[ci].pid, errno); @@ -1253,7 +1258,7 @@ static void process_connection(int ci) case SM_CMD_DELETE_RESOURCE: rv = client_suspend(ci); if (rv < 0) - return; + goto dead; process_cmd_thread_unregistered(ci, &h); break; case SM_CMD_ACQUIRE: @@ -1265,11 +1270,12 @@ static void process_connection(int ci) while the thread is working on it */ rv = client_suspend(ci); if (rv < 0) - return; + goto dead; process_cmd_thread_registered(ci, &h); break; default: - log_error("ci %d cmd %d unknown", ci, h.cmd); + log_error("process_connection ci %d fd %d cmd %d unknown", ci, client[ci].fd, h.cmd); + goto dead; }; return;