]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
nptl: Fix tst-cancel4 sendto tests
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 22 Feb 2018 18:47:33 +0000 (15:47 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 5 Mar 2018 21:09:08 +0000 (18:09 -0300)
Now that send might be implemented calling sendto syscall on Linux,
I am seeing some issue in some kernel configurations where tst-cancel4
sendto do not block as expected.

The socket used to force the syscall blocking is used with default
system configuration for buffer sending size, which might not be
suffice to force blocking.  This patch fixes it by explicit setting
buffer socket lower than the buffer size used.  It also enables sendto
cancellation tests to work in both ways (since internally send is
implemented routing to sendto on Linux kernel).

The patch also removes unrequired make rules on some archictures
for send/recv. The generic nptl Makefile already set the compiler flags
required on some architectures for correct unwinding and libc object
are not strictly required to support unwind (since pthread_cancel
requires linking against libpthread).

Checked on aarch64-linux-gnu and x86_64-linux-gnu. I also did a
sniff test with tst-cancel{4,5} on a simulated mips64-linux-gnu.

* nptl/tst-cancel4-common.h (set_socket_buffer): New function.
* nptl/tst-cancel4-common.c (do_test): Call set_socket_buffer
for socketpair endpoint.
* nptl/tst-cancel4.c (tf_send): Call set_socket_buffer and use
WRITE_BUFFER_SIZE as buffer size for sending socket.
(tf_sendto): Use SOCK_STREAM instead of SOCK_DGRAM and fix an
issue on system where send is implemented with sendto syscall.
* sysdeps/unix/sysv/linux/mips/mips64/Makefile [$(subdir) = socket]
(CFLAGS-recv.c, CFLAGS-send.c): Remove rules.
[$(subdir) = nptl] (CFLAGS-recv.c, CFLAGS-send.c): Likewise.
* sysdeps/unix/sysv/linux/riscv/rv64/Makefile: Remove file.

ChangeLog
nptl/tst-cancel4-common.c
nptl/tst-cancel4-common.h
nptl/tst-cancel4.c
sysdeps/unix/sysv/linux/mips/mips64/Makefile
sysdeps/unix/sysv/linux/riscv/rv64/Makefile [deleted file]

index f54496f8cb3875f93c6f7d577ddbdbc0caf1a848..92b86bf609db5af061d248a6d9e2cc4ff01bec96 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2018-03-03  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
+       * nptl/tst-cancel4-common.h (set_socket_buffer): New function.
+       * nptl/tst-cancel4-common.c (do_test): Call set_socket_buffer
+       for socketpair endpoint.
+       * nptl/tst-cancel4.c (tf_send): Call set_socket_buffer and use
+       WRITE_BUFFER_SIZE as buffer size for sending socket.
+       (tf_sendto): Use SOCK_STREAM instead of SOCK_DGRAM and fix an
+       issue on system where send is implemented with sendto syscall.
+       * sysdeps/unix/sysv/linux/mips/mips64/Makefile [$(subdir) = socket]
+       (CFLAGS-recv.c, CFLAGS-send.c): Remove rules.
+       [$(subdir) = nptl] (CFLAGS-recv.c, CFLAGS-send.c): Likewise.
+       * sysdeps/unix/sysv/linux/riscv/rv64/Makefile: Remove file.
+
        [BZ #21269]
        * sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
        * sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
index 5bc7e44ae2c532264ecccef53303b786d386f9b5..c6eee735dbfd9ba0c30775904e1b0996d9e24e2b 100644 (file)
 static int
 do_test (void)
 {
-  int val;
-  socklen_t len;
-
   if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
     {
       perror ("socketpair");
       exit (1);
     }
 
-  val = 1;
-  len = sizeof(val);
-  setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
-  if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
-    {
-      perror ("getsockopt");
-      exit (1);
-    }
-  if (val >= WRITE_BUFFER_SIZE)
-    {
-      puts ("minimum write buffer size too large");
-      exit (1);
-    }
-  setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
+  set_socket_buffer (fds[1]);
 
   if (mktemp (fifoname) == NULL)
     {
index a526c0cca12c41670e0c3f591110fc2bc29618cc..10cc4f36cea84e8ab7c094a091b3fafd3229917e 100644 (file)
@@ -62,6 +62,20 @@ static pthread_barrier_t b2;
 
 #define WRITE_BUFFER_SIZE 16384
 
+/* Set the send buffer of socket S to 1 byte so any send operation
+   done with WRITE_BUFFER_SIZE bytes will force syscall blocking.  */
+static void
+set_socket_buffer (int s)
+{
+  int val = 1;
+  socklen_t len = sizeof(val);
+
+  TEST_VERIFY_EXIT (setsockopt (s, SOL_SOCKET, SO_SNDBUF, &val,
+                   sizeof(val)) == 0);
+  TEST_VERIFY_EXIT (getsockopt (s, SOL_SOCKET, SO_SNDBUF, &val, &len) == 0);
+  TEST_VERIFY_EXIT (val < WRITE_BUFFER_SIZE);
+}
+
 /* Cleanup handling test.  */
 static int cl_called;
 
index 92a3d808bd05976aa395bcb91b318415d41b83e2..05325385b180e936e1b63e49763947bdbf658970 100644 (file)
@@ -726,6 +726,8 @@ tf_send (void *arg)
   if (tempfd2 == -1)
     FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
 
+  set_socket_buffer (tempfd2);
+
   if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
     FAIL_EXIT1 ("connect: %m");
 
@@ -738,8 +740,7 @@ tf_send (void *arg)
 
   pthread_cleanup_push (cl, NULL);
 
-  /* Very large block, so that the send call blocks.  */
-  char mem[700000];
+  char mem[WRITE_BUFFER_SIZE];
 
   send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
 
@@ -1230,16 +1231,11 @@ tf_msync (void *arg)
 static void *
 tf_sendto (void *arg)
 {
-  if (arg == NULL)
-    // XXX If somebody can provide a portable test case in which sendto()
-    // blocks we can enable this test to run in both rounds.
-    abort ();
-
   struct sockaddr_un sun;
 
-  tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
+  tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
   if (tempfd == -1)
-    FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
+    FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
 
   int tries = 0;
   do
@@ -1254,23 +1250,30 @@ tf_sendto (void *arg)
   while (bind (tempfd, (struct sockaddr *) &sun,
               offsetof (struct sockaddr_un, sun_path)
               + strlen (sun.sun_path) + 1) != 0);
-  tempfname = strdup (sun.sun_path);
 
-  tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
+  listen (tempfd, 5);
+
+  tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
   if (tempfd2 == -1)
-    FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
+    FAIL_EXIT1 ("socket (AF_UNIX, SOCK_STREAM, 0): %m");
 
-  xpthread_barrier_wait (&b2);
+  set_socket_buffer (tempfd2);
+
+  if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
+    FAIL_EXIT1 ("connect: %m");
+
+  unlink (sun.sun_path);
 
   xpthread_barrier_wait (&b2);
 
+  if (arg != NULL)
+    xpthread_barrier_wait (&b2);
+
   pthread_cleanup_push (cl, NULL);
 
-  char mem[1];
+  char mem[WRITE_BUFFER_SIZE];
 
-  sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
-         (struct sockaddr *) &sun,
-         offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
+  sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0, NULL, 0);
 
   pthread_cleanup_pop (0);
 
index b4fb190bba4e359a5fe88b8787a65c7991f67016..fcb48c0f566d4f11fa879b0bb923e140742e2dd2 100644 (file)
@@ -1,13 +1,3 @@
-ifeq ($(subdir),socket)
-CFLAGS-recv.c += -fexceptions
-CFLAGS-send.c += -fexceptions
-endif
-
-ifeq ($(subdir),nptl)
-CFLAGS-recv.c += -fexceptions
-CFLAGS-send.c += -fexceptions
-endif
-
 ifeq ($(subdir),signal)
 # sigaction.c defines static functions in asms and refers to them from
 # C code, resulting in "'restore_rt' used but never defined" (which
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/Makefile b/sysdeps/unix/sysv/linux/riscv/rv64/Makefile
deleted file mode 100644 (file)
index cb60d74..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-ifeq ($(subdir),socket)
-CFLAGS-recv.c += -fexceptions
-CFLAGS-send.c += -fexceptions
-endif