ca483c
Partial backport of the sendfile removal.  This backport only
ca483c
updates nscd/netgroupcache.c, to avoid future conflicts.
ca483c
ca483c
commit 8c78faa9ef5c6cae455739f162e4b9d690e32eca
ca483c
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
ca483c
Date:   Wed May 16 10:51:15 2018 -0300
ca483c
ca483c
    Fix concurrent changes on nscd aware files (BZ #23178)
ca483c
    
ca483c
    As indicated by BZ#23178, concurrent access on some files read by nscd
ca483c
    may result non expected data send through service requisition.  This is
ca483c
    due 'sendfile' Linux implementation where for sockets with zero-copy
ca483c
    support, callers must ensure the transferred portions of the the file
ca483c
    reffered by input file descriptor remain unmodified until the reader
ca483c
    on the other end of socket has consumed the transferred data.
ca483c
    
ca483c
    I could not find any explicit documentation stating this behaviour on
ca483c
    Linux kernel documentation.  However man-pages sendfile entry [1] states
ca483c
    in NOTES the aforementioned remark.  It was initially pushed on man-pages
ca483c
    with an explicit testcase [2] that shows changing the file used in
ca483c
    'sendfile' call prior the socket input data consumption results in
ca483c
    previous data being lost.
ca483c
    
ca483c
    From commit message it stated on tested Linux version (3.15) only TCP
ca483c
    socket showed this issues, however on recent kernels (4.4) I noticed the
ca483c
    same behaviour for local sockets as well.
ca483c
    
ca483c
    Since sendfile on HURD is a read/write operation and the underlying
ca483c
    issue on Linux, the straightforward fix is just remove sendfile use
ca483c
    altogether.  I am really skeptical it is hitting some hotstop (there
ca483c
    are indication over internet that sendfile is helpfull only for large
ca483c
    files, more than 10kb) here to justify that extra code complexity or
ca483c
    to pursuit other possible fix (through memory or file locks for
ca483c
    instance, which I am not sure it is doable).
ca483c
    
ca483c
    Checked on x86_64-linux-gnu.
ca483c
    
ca483c
            [BZ #23178]
ca483c
            * nscd/nscd-client.h (sendfileall): Remove prototype.
ca483c
            * nscd/connections.c [HAVE_SENDFILE] (sendfileall): Remove function.
ca483c
            (handle_request): Use writeall instead of sendfileall.
ca483c
            * nscd/aicache.c (addhstaiX): Likewise.
ca483c
            * nscd/grpcache.c (cache_addgr): Likewise.
ca483c
            * nscd/hstcache.c (cache_addhst): Likewise.
ca483c
            * nscd/initgrcache.c (addinitgroupsX): Likewise.
ca483c
            * nscd/netgroupcache.c (addgetnetgrentX, addinnetgrX): Likewise.
ca483c
            * nscd/pwdcache.c (cache_addpw): Likewise.
ca483c
            * nscd/servicescache.c (cache_addserv): Likewise.
ca483c
            * sysdeps/unix/sysv/linux/Makefile [$(subdir) == nscd]
ca483c
            (sysdep-CFLAGS): Remove -DHAVE_SENDFILE.
ca483c
            * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_SENDFILE):
ca483c
            Remove define.
ca483c
    
ca483c
    [1] http://man7.org/linux/man-pages/man2/sendfile.2.html
ca483c
    [2] https://github.com/mkerrisk/man-pages/commit/7b6a3299776b5c1c4f169a591434a855d50c68b4#diff-efd6af3a70f0f07c578e85b51e83b3c3
ca483c
ca483c
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
ca483c
index 4fce79283a9badb3..7ee0c284ed58d1e3 100644
ca483c
--- a/nscd/netgroupcache.c
ca483c
+++ b/nscd/netgroupcache.c
ca483c
@@ -415,33 +415,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
ca483c
 	 since while inserting this thread might block and so would
ca483c
 	 unnecessarily let the receiver wait.  */
ca483c
     writeout:
ca483c
-#ifdef HAVE_SENDFILE
ca483c
-      if (__builtin_expect (db->mmap_used, 1) && cacheable)
ca483c
-	{
ca483c
-	  assert (db->wr_fd != -1);
ca483c
-	  assert ((char *) &dataset->resp > (char *) db->data);
ca483c
-	  assert ((char *) dataset - (char *) db->head + total
ca483c
-		  <= (sizeof (struct database_pers_head)
ca483c
-		      + db->head->module * sizeof (ref_t)
ca483c
-		      + db->head->data_size));
ca483c
-# ifndef __ASSUME_SENDFILE
ca483c
-	  ssize_t written =
ca483c
-# endif
ca483c
-	    sendfileall (fd, db->wr_fd, (char *) &dataset->resp
ca483c
-			 - (char *) db->head, dataset->head.recsize);
ca483c
-# ifndef __ASSUME_SENDFILE
ca483c
-	  if (written == -1 && errno == ENOSYS)
ca483c
-	    goto use_write;
ca483c
-# endif
ca483c
-	}
ca483c
-      else
ca483c
-#endif
ca483c
-	{
ca483c
-#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
ca483c
-	use_write:
ca483c
-#endif
ca483c
-	  writeall (fd, &dataset->resp, dataset->head.recsize);
ca483c
-	}
ca483c
+      writeall (fd, &dataset->resp, dataset->head.recsize);
ca483c
     }
ca483c
 
ca483c
   if (cacheable)
ca483c
@@ -596,36 +570,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
ca483c
       /* We write the dataset before inserting it to the database
ca483c
 	 since while inserting this thread might block and so would
ca483c
 	 unnecessarily let the receiver wait.  */
ca483c
-       assert (fd != -1);
ca483c
+      assert (fd != -1);
ca483c
 
ca483c
-#ifdef HAVE_SENDFILE
ca483c
-      if (__builtin_expect (db->mmap_used, 1) && cacheable)
ca483c
-	{
ca483c
-	  assert (db->wr_fd != -1);
ca483c
-	  assert ((char *) &dataset->resp > (char *) db->data);
ca483c
-	  assert ((char *) dataset - (char *) db->head + sizeof (*dataset)
ca483c
-		  <= (sizeof (struct database_pers_head)
ca483c
-		      + db->head->module * sizeof (ref_t)
ca483c
-		      + db->head->data_size));
ca483c
-# ifndef __ASSUME_SENDFILE
ca483c
-	  ssize_t written =
ca483c
-# endif
ca483c
-	    sendfileall (fd, db->wr_fd,
ca483c
-			 (char *) &dataset->resp - (char *) db->head,
ca483c
-			 sizeof (innetgroup_response_header));
ca483c
-# ifndef __ASSUME_SENDFILE
ca483c
-	  if (written == -1 && errno == ENOSYS)
ca483c
-	    goto use_write;
ca483c
-# endif
ca483c
-	}
ca483c
-      else
ca483c
-#endif
ca483c
-	{
ca483c
-#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
ca483c
-	use_write:
ca483c
-#endif
ca483c
-	  writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
ca483c
-	}
ca483c
+      writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
ca483c
     }
ca483c
 
ca483c
   if (cacheable)