2121#include <poll.h>
2222#include <signal.h>
2323#include <sys/ioctl.h>
24- #include <linux/sockios.h>
2524#include <linux/time64.h>
2625
2726#include "vsock_test_zerocopy.h"
@@ -1280,7 +1279,7 @@ static void test_unsent_bytes_server(const struct test_opts *opts, int type)
12801279static void test_unsent_bytes_client (const struct test_opts * opts , int type )
12811280{
12821281 unsigned char buf [MSG_BUF_IOCTL_LEN ];
1283- int ret , fd , sock_bytes_unsent ;
1282+ int fd ;
12841283
12851284 fd = vsock_connect (opts -> peer_cid , opts -> peer_port , type );
12861285 if (fd < 0 ) {
@@ -1297,22 +1296,12 @@ static void test_unsent_bytes_client(const struct test_opts *opts, int type)
12971296 /* SIOCOUTQ isn't guaranteed to instantly track sent data. Even though
12981297 * the "RECEIVED" message means that the other side has received the
12991298 * data, there can be a delay in our kernel before updating the "unsent
1300- * bytes" counter. Repeat SIOCOUTQ until it returns 0.
1299+ * bytes" counter. vsock_wait_sent() will repeat SIOCOUTQ until it
1300+ * returns 0.
13011301 */
1302- timeout_begin (TIMEOUT );
1303- do {
1304- ret = ioctl (fd , SIOCOUTQ , & sock_bytes_unsent );
1305- if (ret < 0 ) {
1306- if (errno == EOPNOTSUPP ) {
1307- fprintf (stderr , "Test skipped, SIOCOUTQ not supported.\n" );
1308- break ;
1309- }
1310- perror ("ioctl" );
1311- exit (EXIT_FAILURE );
1312- }
1313- timeout_check ("SIOCOUTQ" );
1314- } while (sock_bytes_unsent != 0 );
1315- timeout_end ();
1302+ if (!vsock_wait_sent (fd ))
1303+ fprintf (stderr , "Test skipped, SIOCOUTQ not supported.\n" );
1304+
13161305 close (fd );
13171306}
13181307
@@ -1824,10 +1813,6 @@ static void test_stream_connect_retry_server(const struct test_opts *opts)
18241813
18251814static void test_stream_linger_client (const struct test_opts * opts )
18261815{
1827- struct linger optval = {
1828- .l_onoff = 1 ,
1829- .l_linger = 1
1830- };
18311816 int fd ;
18321817
18331818 fd = vsock_stream_connect (opts -> peer_cid , opts -> peer_port );
@@ -1836,15 +1821,58 @@ static void test_stream_linger_client(const struct test_opts *opts)
18361821 exit (EXIT_FAILURE );
18371822 }
18381823
1839- if (setsockopt (fd , SOL_SOCKET , SO_LINGER , & optval , sizeof (optval ))) {
1840- perror ("setsockopt(SO_LINGER)" );
1824+ enable_so_linger (fd , 1 );
1825+ close (fd );
1826+ }
1827+
1828+ static void test_stream_linger_server (const struct test_opts * opts )
1829+ {
1830+ int fd ;
1831+
1832+ fd = vsock_stream_accept (VMADDR_CID_ANY , opts -> peer_port , NULL );
1833+ if (fd < 0 ) {
1834+ perror ("accept" );
18411835 exit (EXIT_FAILURE );
18421836 }
18431837
1838+ vsock_wait_remote_close (fd );
18441839 close (fd );
18451840}
18461841
1847- static void test_stream_linger_server (const struct test_opts * opts )
1842+ /* Half of the default to not risk timing out the control channel */
1843+ #define LINGER_TIMEOUT (TIMEOUT / 2)
1844+
1845+ static void test_stream_nolinger_client (const struct test_opts * opts )
1846+ {
1847+ bool waited ;
1848+ time_t ns ;
1849+ int fd ;
1850+
1851+ fd = vsock_stream_connect (opts -> peer_cid , opts -> peer_port );
1852+ if (fd < 0 ) {
1853+ perror ("connect" );
1854+ exit (EXIT_FAILURE );
1855+ }
1856+
1857+ enable_so_linger (fd , LINGER_TIMEOUT );
1858+ send_byte (fd , 1 , 0 ); /* Left unread to expose incorrect behaviour. */
1859+ waited = vsock_wait_sent (fd );
1860+
1861+ ns = current_nsec ();
1862+ close (fd );
1863+ ns = current_nsec () - ns ;
1864+
1865+ if (!waited ) {
1866+ fprintf (stderr , "Test skipped, SIOCOUTQ not supported.\n" );
1867+ } else if (DIV_ROUND_UP (ns , NSEC_PER_SEC ) >= LINGER_TIMEOUT ) {
1868+ fprintf (stderr , "Unexpected lingering\n" );
1869+ exit (EXIT_FAILURE );
1870+ }
1871+
1872+ control_writeln ("DONE" );
1873+ }
1874+
1875+ static void test_stream_nolinger_server (const struct test_opts * opts )
18481876{
18491877 int fd ;
18501878
@@ -1854,7 +1882,7 @@ static void test_stream_linger_server(const struct test_opts *opts)
18541882 exit (EXIT_FAILURE );
18551883 }
18561884
1857- vsock_wait_remote_close ( fd );
1885+ control_expectln ( "DONE" );
18581886 close (fd );
18591887}
18601888
@@ -2018,6 +2046,11 @@ static struct test_case test_cases[] = {
20182046 .run_client = test_stream_linger_client ,
20192047 .run_server = test_stream_linger_server ,
20202048 },
2049+ {
2050+ .name = "SOCK_STREAM SO_LINGER close() on unread" ,
2051+ .run_client = test_stream_nolinger_client ,
2052+ .run_server = test_stream_nolinger_server ,
2053+ },
20212054 {},
20222055};
20232056
0 commit comments