forked from lei.chen/myxce
fix(libxce-failover): classify and propagate netio I/O errors on failover
Add io_classify_io_error and propagate endpoint/epoll errors through endpoint_update_epoll and cbuf_get instead of swallowing them, so client failover surfaces the real error rather than hanging. Adds netio arm-failure, close-propagation, and request send-propagation tests. Pre-existing uncommitted work, committed to establish a clean baseline before ha-commit-durability implementation.
This commit is contained in:
parent
749e194207
commit
80bb1d766e
7 changed files with 347 additions and 41 deletions
72
src/lib/testsuite/test_request_send_propagation.c
Normal file
72
src/lib/testsuite/test_request_send_propagation.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* test_request_send_propagation.c — bug-650: xce_request() must PROPAGATE an
|
||||
* endpoint_enq() send failure, not swallow it.
|
||||
*
|
||||
* xce_request() (and the other request.c senders) ignored endpoint_enq()'s
|
||||
* return and always returned 0. So when the transport was dead — endpoint_enq()
|
||||
* returns <0 and marks the endpoint dead (bug-646) — xce_request() still
|
||||
* reported success. xce_jobsubmit() then fell through to a BLOCKING cbuf_get()
|
||||
* and hung forever waiting for a reply to a request that was never transmitted
|
||||
* (server idle, client fd unconnected). xce_request() must return the negative
|
||||
* enq error so the failover loop rotates instead of blocking.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <unity/unity.h>
|
||||
#include "netio.h"
|
||||
#include "request.h"
|
||||
|
||||
/*
|
||||
* A request that ENCODES successfully but whose send fails because the endpoint
|
||||
* is dead (EPOLL_CTL_MOD on an fd that is not registered → ENOENT) must make
|
||||
* xce_request() return a negative error, not 0.
|
||||
*/
|
||||
static void test_xce_request_propagates_send_failure(void)
|
||||
{
|
||||
iomgr_t iomgr;
|
||||
memset(&iomgr, 0, sizeof(iomgr));
|
||||
TEST_ASSERT_EQUAL_INT(0, iomgr_init(&iomgr));
|
||||
|
||||
endpoint_t *ep = endpoint_get();
|
||||
TEST_ASSERT_NOT_NULL(ep);
|
||||
|
||||
ep->fd = socket(AF_INET, SOCK_STREAM, 0); /* valid fd, NOT in the epoll */
|
||||
TEST_ASSERT_TRUE(ep->fd >= 0);
|
||||
ep->iomgr = &iomgr;
|
||||
ep->ssl_handshake_done = 1;
|
||||
ep->flags = 0; /* force iomgr_update_poll MOD on the unregistered fd */
|
||||
|
||||
char nm[] = "tester";
|
||||
char ky[] = "key";
|
||||
xce_peerinfo_t peer = { .name = nm, .key = ky };
|
||||
ep->peer = &peer;
|
||||
|
||||
xce_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.opcode = OPCode_nop;
|
||||
req.seq = 42;
|
||||
|
||||
int rc = xce_request(ep, &req);
|
||||
|
||||
/* Old code: always 0 (swallowed). Fixed: the negative enq error propagates. */
|
||||
TEST_ASSERT_TRUE(rc < 0);
|
||||
|
||||
endpoint_fini(ep);
|
||||
free(ep);
|
||||
close(iomgr.epoll_fd);
|
||||
printf("test_xce_request_propagates_send_failure: PASS\n");
|
||||
}
|
||||
|
||||
void test_request_send_propagation(void)
|
||||
{
|
||||
printf("\n>> request send-failure propagation tests\n\n");
|
||||
|
||||
RUN_TEST(test_xce_request_propagates_send_failure);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue