Changeset View
Standalone View
lib/libc/tests/sys/sendfile_test.c
Context not available. | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <netinet/in.h> | |||||
#include <arpa/inet.h> | |||||
#include <atf-c.h> | #include <atf-c.h> | ||||
Context not available. | |||||
#define SOURCE_FILE "source" | #define SOURCE_FILE "source" | ||||
#define DESTINATION_FILE "dest" | #define DESTINATION_FILE "dest" | ||||
#define PORTRANGE_FIRST "net.inet.ip.portrange.first" | |||||
#define PORTRANGE_LAST "net.inet.ip.portrange.last" | |||||
static int portrange_first, portrange_last; | |||||
static int | static int | ||||
get_int_via_sysctlbyname(const char *oidname) | get_int_via_sysctlbyname(const char *oidname) | ||||
{ | { | ||||
Context not available. | |||||
return (int_value); | return (int_value); | ||||
} | } | ||||
static int | |||||
generate_random_port(int seed) | |||||
{ | |||||
int random_port; | |||||
printf("Generating a random port with seed=%d\n", seed); | |||||
if (portrange_first == 0) { | |||||
portrange_first = get_int_via_sysctlbyname(PORTRANGE_FIRST); | |||||
printf("Port range lower bound: %d\n", portrange_first); | |||||
} | |||||
if (portrange_last == 0) { | |||||
portrange_last = get_int_via_sysctlbyname(PORTRANGE_LAST); | |||||
printf("Port range upper bound: %d\n", portrange_last); | |||||
} | |||||
srand((unsigned)seed); | |||||
random_port = rand() % (portrange_last - portrange_first) + | |||||
portrange_first; | |||||
printf("Random port generated: %d\n", random_port); | |||||
return (random_port); | |||||
} | |||||
static void | static void | ||||
resolve_localhost(struct addrinfo **res, int domain, int type, int port) | resolve_localhost(struct addrinfo **res, int domain, int type, int port) | ||||
{ | { | ||||
Context not available. | |||||
return (sock); | return (sock); | ||||
} | } | ||||
/* | |||||
* XXX: use linear probing to find a free port and eliminate `port` argument as | |||||
* a [const] int (it will need to be a pointer so it can be passed back out of | |||||
* the function and can influence which port `setup_client(..)` connects on. | |||||
*/ | |||||
static int | static int | ||||
setup_server(int domain, int type, int port) | setup_server(int domain, int type, int *port) | ||||
{ | { | ||||
struct addrinfo *res; | struct addrinfo *res; | ||||
char host[NI_MAXHOST+1]; | char host[NI_MAXHOST+1]; | ||||
int error, sock; | int error, sock; | ||||
struct sockaddr server; | |||||
socklen_t len; | |||||
resolve_localhost(&res, domain, type, port); | resolve_localhost(&res, domain, type, 0); | ||||
sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol); | sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||||
error = getnameinfo( | error = getnameinfo( | ||||
Context not available. | |||||
/* Avoid a double print when forked by flushing. */ | /* Avoid a double print when forked by flushing. */ | ||||
fflush(stdout); | fflush(stdout); | ||||
error = bind(sock, res->ai_addr, res->ai_addrlen); | error = bind(sock, res->ai_addr, res->ai_addrlen); | ||||
len = res->ai_addrlen; | |||||
freeaddrinfo(res); | freeaddrinfo(res); | ||||
ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno)); | ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno)); | ||||
error = listen(sock, 1); | error = listen(sock, 1); | ||||
ATF_REQUIRE_EQ_MSG(error, 0, "listen failed: %s", strerror(errno)); | ATF_REQUIRE_EQ_MSG(error, 0, "listen failed: %s", strerror(errno)); | ||||
memset(&server, 0, sizeof(server)); | |||||
error = getsockname(sock, &server, &len); | |||||
ATF_REQUIRE_EQ_MSG(error, 0, "getsockname failed: %s", strerror(errno)); | |||||
struct sockaddr_in *server_in = (struct sockaddr_in *)&server; | |||||
*port = ntohs(server_in->sin_port); | |||||
ngie: What if ports 6000-9000 are all consumed?
Also, style(9) bug:
```
for (i = 6000; i < 9000… | |||||
Not Done Inline ActionsI agree here we probably just need to use the anon port space even though it is rrs: I agree here we probably just need to use the anon port space even though it is
highly unlikely… | |||||
Done Inline ActionsIf ports from 6000-9000 are all consumed during a regression test, then yes having the test failing is a correct behavior to alert about something wrong. olivier: If ports from 6000-9000 are all consumed during a regression test, then yes having the test… | |||||
Not Done Inline ActionsI completely disagree: there's no guarantee that a test system will have all of those ports available. ngie: I completely disagree: there's no guarantee that a test system will have all of those ports… | |||||
Done Inline ActionsIf the code is using all ports from 6000 to 9000, yes I disagree too :-) olivier: If the code is using all ports from 6000 to 9000, yes I disagree too :-)
My goal here, was to… | |||||
return (sock); | return (sock); | ||||
} | } | ||||
Not Done Inline ActionsI don't think it's wise to try and resolve localhost 3000 times -- the value shouldn't change across iterations (recommendation: move name resolution out of the loop). Slow name resolution could potentially result in failed tests due to timeouts or failures to query the name info between iterations; it would definitely impact testing on OneFS, since we don't run a standard name server and it can be unreachable at a particular point in time depending on cluster state. ngie: I don't think it's wise to try and resolve localhost 3000 times -- the value shouldn't change… | |||||
Done Inline ActionsYes but because function resolve_localhost() is using the port, it's more complex than just moving the name resolution out of the loop. olivier: Yes but because function resolve_localhost() is using the port, it's more complex than just… | |||||
Not Done Inline Actionsnit: please fix indentation for lines 182 & 183 (second level indents are 4 spaces, not 2). ngie: nit: please fix indentation for lines 182 & 183 (second level indents are 4 spaces, not 2). | |||||
Not Done Inline ActionsPlease fix per style(9) and please fix res getting leaked on success: freeaddrinfo(res); if (error == 0) break; ngie: Please fix per style(9) and please fix `res` getting leaked on success:
```
freeaddrinfo(res)… | |||||
Context not available. | |||||
} | } | ||||
static int | static int | ||||
setup_tcp_server(int domain, int port) | setup_tcp_server(int domain, int *port) | ||||
{ | { | ||||
return (setup_server(domain, SOCK_STREAM, port)); | return (setup_server(domain, SOCK_STREAM, port)); | ||||
Context not available. | |||||
fd = open(SOURCE_FILE, O_RDONLY); | fd = open(SOURCE_FILE, O_RDONLY); | ||||
ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ||||
port = generate_random_port(__LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
server_pid = atf_utils_fork(); | server_pid = atf_utils_fork(); | ||||
Context not available. | |||||
"memcmp showed data mismatch: '%s' != '%s'", | "memcmp showed data mismatch: '%s' != '%s'", | ||||
DETERMINISTIC_PATTERN, shm_pointer); | DETERMINISTIC_PATTERN, shm_pointer); | ||||
port = generate_random_port(__LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
server_pid = atf_utils_fork(); | server_pid = atf_utils_fork(); | ||||
Context not available. | |||||
{ | { | ||||
int client_sock, error, fd, port, server_sock; | int client_sock, error, fd, port, server_sock; | ||||
port = generate_random_port(__LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
fd = -1; | fd = -1; | ||||
Context not available. | |||||
fd = open(SOURCE_FILE, O_RDONLY); | fd = open(SOURCE_FILE, O_RDONLY); | ||||
ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ||||
port = generate_random_port(i * __LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
server_pid = atf_utils_fork(); | server_pid = atf_utils_fork(); | ||||
Context not available. | |||||
hdtr.trl_cnt = 0; | hdtr.trl_cnt = 0; | ||||
} | } | ||||
port = generate_random_port(i * __LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
rc = asprintf(&pattern, "%s%s%s", | rc = asprintf(&pattern, "%s%s%s", | ||||
Context not available. | |||||
int client_sock, error, fd, port, server_sock; | int client_sock, error, fd, port, server_sock; | ||||
struct sf_hdtr *hdtr1, hdtr2, hdtr3; | struct sf_hdtr *hdtr1, hdtr2, hdtr3; | ||||
port = generate_random_port(__LINE__ + domain); | |||||
hdtr1 = (struct sf_hdtr*)-1; | hdtr1 = (struct sf_hdtr*)-1; | ||||
memset(&hdtr2, 0, sizeof(hdtr2)); | memset(&hdtr2, 0, sizeof(hdtr2)); | ||||
Context not available. | |||||
fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | ||||
ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ||||
server_sock = setup_tcp_server(domain, port); | server_sock = setup_tcp_server(domain, &port); | ||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
error = sendfile(fd, client_sock, 0, 0, hdtr1, NULL, SF_FLAGS(0, 0)); | error = sendfile(fd, client_sock, 0, 0, hdtr1, NULL, SF_FLAGS(0, 0)); | ||||
Not Done Inline Actionsstyle(9) bug: don't initialize the variable here. Do this instead (there's a similar issue on other touched lines that needs to be resolved): int client_sock, error, fd, port, server_sock; struct sf_hdtr *hdtr1, hdtr2, hdtr3; port = 0; ngie: style(9) bug: don't initialize the variable here. Do this instead (there's a similar issue on… | |||||
Not Done Inline ActionsStyle 9 does not prohibit the use of variable initializers. It says to be thoughtful about I do prefer that you keep the initialized variables on a separate line though. I.e. rrs: Style 9 does not prohibit the use of variable initializers. It says to be thoughtful about
its… | |||||
Context not available. | |||||
{ | { | ||||
int client_sock, error, fd, port, server_sock; | int client_sock, error, fd, port, server_sock; | ||||
port = generate_random_port(__LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | ||||
Context not available. | |||||
off_t sbytes; | off_t sbytes; | ||||
int client_sock, error, fd, port, server_sock; | int client_sock, error, fd, port, server_sock; | ||||
port = generate_random_port(__LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); | atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); | ||||
Context not available. | |||||
off_t *sbytes_p = (off_t*)-1; | off_t *sbytes_p = (off_t*)-1; | ||||
int client_sock, error, fd, port, server_sock; | int client_sock, error, fd, port, server_sock; | ||||
port = generate_random_port(__LINE__ + domain); | server_sock = setup_tcp_server(domain, &port); | ||||
server_sock = setup_tcp_server(domain, port); | |||||
client_sock = setup_tcp_client(domain, port); | client_sock = setup_tcp_client(domain, port); | ||||
atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); | atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); | ||||
Context not available. | |||||
{ | { | ||||
int client_sock, error, fd, port; | int client_sock, error, fd, port; | ||||
port = generate_random_port(__LINE__ + domain); | client_sock = setup_tcp_server(domain, &port); | ||||
client_sock = setup_tcp_server(domain, port); | |||||
fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | ||||
ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ||||
Context not available. | |||||
static void | static void | ||||
s_negative_udp_socket_test(int domain) | s_negative_udp_socket_test(int domain) | ||||
{ | { | ||||
int client_sock, error, fd, port; | int client_sock, error, fd; | ||||
port = generate_random_port(__LINE__ + domain); | client_sock = setup_client(domain, SOCK_DGRAM, 2424); | ||||
client_sock = setup_client(domain, SOCK_DGRAM, port); | |||||
fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | fd = open(SOURCE_FILE, O_CREAT|O_RDWR); | ||||
ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); | ||||
Context not available. |
What if ports 6000-9000 are all consumed?
Also, style(9) bug: