]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephfs_proxy: gracefully handle connection close
authorXavi Hernandez <xhernandez@gmail.com>
Fri, 14 Feb 2025 16:01:07 +0000 (17:01 +0100)
committerXavi Hernandez <xhernandez@gmail.com>
Fri, 14 Feb 2025 16:48:19 +0000 (17:48 +0100)
When a connection is closed while not expecting data, just return a
0-bytes read instead of raising an error.

Signed-off-by: Xavi Hernandez <xhernandez@gmail.com>
src/libcephfs_proxy/libcephfsd.c
src/libcephfs_proxy/proxy_link.c

index 5c1fc4a44b1112433bbd66f532be6d52b337ba8e..6d04838465cdd8c48be9d335b7c81725244a0acd 100644 (file)
@@ -1627,28 +1627,32 @@ static void serve_binary(proxy_client_t *client)
                req_iov[1].iov_len = size;
 
                err = proxy_link_req_recv(client->sd, req_iov, 2);
-               if (err > 0) {
-                       if (req.header.op >= LIBCEPHFSD_OP_TOTAL_OPS) {
-                               err = send_error(client, -ENOSYS);
-                       } else if (libcephfsd_handlers[req.header.op] == NULL) {
-                               err = send_error(client, -EOPNOTSUPP);
-                       } else {
-                               err = libcephfsd_handlers[req.header.op](
-                                       client, &req, req_iov[1].iov_base,
-                                       req.header.data_len);
-                       }
+               if (err <= 0) {
+                       break;
                }
 
-               if (req_iov[1].iov_base != buffer) {
-                       /* Free the buffer if it was temporarily allocated. */
-                       proxy_free(req_iov[1].iov_base);
+               if (req.header.op >= LIBCEPHFSD_OP_TOTAL_OPS) {
+                       err = send_error(client, -ENOSYS);
+               } else if (libcephfsd_handlers[req.header.op] == NULL) {
+                       err = send_error(client, -EOPNOTSUPP);
+               } else {
+                       err = libcephfsd_handlers[req.header.op](
+                               client, &req, req_iov[1].iov_base,
+                               req.header.data_len);
                }
-
                if (err < 0) {
                        break;
                }
+
+               if (req_iov[1].iov_base != buffer) {
+                       /* Free the buffer if it was temporarily allocated. */
+                       proxy_free(req_iov[1].iov_base);
+               }
        }
 
+       if (req_iov[1].iov_base != buffer) {
+               proxy_free(req_iov[1].iov_base);
+       }
        proxy_free(buffer);
 }
 
index c1ae0c13d9826f2aca35f2083c7fd9bd7a250504..066aa8ef546ddf87973781d9f2b4c8fc181a866f 100644 (file)
@@ -731,7 +731,11 @@ int32_t proxy_link_recv(int32_t sd, struct iovec *iov, int32_t count)
                                         "Failed to receive data");
                }
                if (len == 0) {
-                       return proxy_log(LOG_ERR, ENODATA, "Partial read");
+                       if (total > 0) {
+                               return proxy_log(LOG_ERR, EPIPE,
+                                                "Partial read");
+                       }
+                       return 0;
                }
                total += len;
 
@@ -773,7 +777,7 @@ int32_t proxy_link_req_recv(int32_t sd, struct iovec *iov, int32_t count)
        len = iov->iov_len;
        iov->iov_len = sizeof(proxy_link_req_t);
        err = proxy_link_recv(sd, iov, 1);
-       if (err < 0) {
+       if (err <= 0) {
                return err;
        }
        total = err;
@@ -813,7 +817,10 @@ int32_t proxy_link_req_recv(int32_t sd, struct iovec *iov, int32_t count)
        }
 
        err = proxy_link_recv(sd, iov, count);
-       if (err < 0) {
+       if (err <= 0) {
+               if (err == 0) {
+                       return proxy_log(LOG_ERR, EPIPE, "Partial read");
+               }
                return err;
        }
 
@@ -843,7 +850,12 @@ int32_t proxy_link_ans_recv(int32_t sd, struct iovec *iov, int32_t count)
        len = iov->iov_len;
        iov->iov_len = sizeof(proxy_link_ans_t);
        err = proxy_link_recv(sd, iov, 1);
-       if (err < 0) {
+       if (err <= 0) {
+               if (err == 0) {
+                       return proxy_log(LOG_ERR, EPIPE,
+                                        "Connection closed while waiting for "
+                                        "an answer");
+               }
                return err;
        }
        total = err;
@@ -876,7 +888,10 @@ int32_t proxy_link_ans_recv(int32_t sd, struct iovec *iov, int32_t count)
        }
 
        err = proxy_link_recv(sd, iov, count);
-       if (err < 0) {
+       if (err <= 0) {
+               if (err == 0) {
+                       return proxy_log(LOG_ERR, EPIPE, "Partial read");
+               }
                return err;
        }