mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-07 19:49:33 -04:00
Merge branch 'vsock-test-improve-sigpipe-test-reliability'
Stefano Garzarella says: ==================== vsock/test: improve sigpipe test reliability Running the tests continuously I noticed that sometimes the sigpipe test would fail due to a race between the control message of the test and the vsock transport messages. While I was at it I also improved the test by checking the errno we expect. v1: https://lore.kernel.org/20250508142005.135857-1-sgarzare@redhat.com ==================== Link: https://patch.msgid.link/20250514141927.159456-1-sgarzare@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "timeout.h"
|
||||
|
||||
static volatile bool timeout;
|
||||
@@ -28,6 +29,8 @@ static volatile bool timeout;
|
||||
/* SIGALRM handler function. Do not use sleep(2), alarm(2), or
|
||||
* setitimer(2) while using this API - they may interfere with each
|
||||
* other.
|
||||
*
|
||||
* If you need to sleep, please use timeout_sleep() provided by this API.
|
||||
*/
|
||||
void sigalrm(int signo)
|
||||
{
|
||||
@@ -58,3 +61,18 @@ void timeout_end(void)
|
||||
alarm(0);
|
||||
timeout = false;
|
||||
}
|
||||
|
||||
/* Sleep in a timeout section.
|
||||
*
|
||||
* nanosleep(2) can be used with this API since POSIX.1 explicitly
|
||||
* specifies that it does not interact with signals.
|
||||
*/
|
||||
int timeout_usleep(useconds_t usec)
|
||||
{
|
||||
struct timespec ts = {
|
||||
.tv_sec = usec / 1000000,
|
||||
.tv_nsec = (usec % 1000000) * 1000,
|
||||
};
|
||||
|
||||
return nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ void sigalrm(int signo);
|
||||
void timeout_begin(unsigned int seconds);
|
||||
void timeout_check(const char *operation);
|
||||
void timeout_end(void);
|
||||
int timeout_usleep(useconds_t usec);
|
||||
|
||||
#endif /* TIMEOUT_H */
|
||||
|
||||
@@ -1058,18 +1058,39 @@ static void sigpipe(int signo)
|
||||
have_sigpipe = 1;
|
||||
}
|
||||
|
||||
#define SEND_SLEEP_USEC (10 * 1000)
|
||||
|
||||
static void test_stream_check_sigpipe(int fd)
|
||||
{
|
||||
ssize_t res;
|
||||
|
||||
have_sigpipe = 0;
|
||||
|
||||
res = send(fd, "A", 1, 0);
|
||||
if (res != -1) {
|
||||
fprintf(stderr, "expected send(2) failure, got %zi\n", res);
|
||||
/* When the other peer calls shutdown(SHUT_RD), there is a chance that
|
||||
* the send() call could occur before the message carrying the close
|
||||
* information arrives over the transport. In such cases, the send()
|
||||
* might still succeed. To avoid this race, let's retry the send() call
|
||||
* a few times, ensuring the test is more reliable.
|
||||
*/
|
||||
timeout_begin(TIMEOUT);
|
||||
while(1) {
|
||||
res = send(fd, "A", 1, 0);
|
||||
if (res == -1 && errno != EINTR)
|
||||
break;
|
||||
|
||||
/* Sleep a little before trying again to avoid flooding the
|
||||
* other peer and filling its receive buffer, causing
|
||||
* false-negative.
|
||||
*/
|
||||
timeout_usleep(SEND_SLEEP_USEC);
|
||||
timeout_check("send");
|
||||
}
|
||||
timeout_end();
|
||||
|
||||
if (errno != EPIPE) {
|
||||
fprintf(stderr, "unexpected send(2) errno %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!have_sigpipe) {
|
||||
fprintf(stderr, "SIGPIPE expected\n");
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -1077,12 +1098,21 @@ static void test_stream_check_sigpipe(int fd)
|
||||
|
||||
have_sigpipe = 0;
|
||||
|
||||
res = send(fd, "A", 1, MSG_NOSIGNAL);
|
||||
if (res != -1) {
|
||||
fprintf(stderr, "expected send(2) failure, got %zi\n", res);
|
||||
timeout_begin(TIMEOUT);
|
||||
while(1) {
|
||||
res = send(fd, "A", 1, MSG_NOSIGNAL);
|
||||
if (res == -1 && errno != EINTR)
|
||||
break;
|
||||
|
||||
timeout_usleep(SEND_SLEEP_USEC);
|
||||
timeout_check("send");
|
||||
}
|
||||
timeout_end();
|
||||
|
||||
if (errno != EPIPE) {
|
||||
fprintf(stderr, "unexpected send(2) errno %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (have_sigpipe) {
|
||||
fprintf(stderr, "SIGPIPE not expected\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
Reference in New Issue
Block a user