Remove 'grp' and merge into 'nss' and 'posix'

Message ID 20230629113408.724726-1-arjun@redhat.com
State New
Headers
Series Remove 'grp' and merge into 'nss' and 'posix' |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_check--master-arm fail Testing failed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed

Commit Message

Arjun Shankar June 29, 2023, 11:34 a.m. UTC
  The majority of grp routines are entry points for nss functionality.
This commit removes the 'grp' subdirectory and moves all nss-relevant
functionality and all tests to 'nss', and the 'setgroups' stub into
'posix' (alongside the 'getgroups' stub).  References to grp/ are
accordingly changed.  In addition, compat-initgroups.c, a fallback
implementation of initgroups is renamed to initgroups-fallback.c so that
the build system does not confuse it for nss_compat/compat-initgroups.c.

Build time improves very slightly; e.g. down from an average of 45.5s to
44.5s on an 8-thread mobile x86_64 CPU.
---
This is a follow up to a discussion I started a few weeks ago:
Avoiding dlopen in statically linked applications that use nss [#27959]:
https://sourceware.org/pipermail/libc-alpha/2023-May/148682.html

Regarding consolidating nss code across the source tree, I had said:

> Therefore, if my understanding of the situation is correct, this new
> statically linked library will need to have more bits from nss
> including all public functions available for name resolution in order
> for it to work. I expect this would also mean moving code from various
> places in the glibc source tree into nss/ (e.g. pwd/, resolv/, grp/
> etc.) so that they can then be included in the new library.

Florian noted that he is not opposed to it even though it's not actually
necessary:

> I'm not opposed to this change (moving pwd, grp, gethostbyname,
> getaddrinfo etc. into nss/) as a general simplification and build
> speedup.  It's actually unrelated to the static NSS changes.

If this patch (or a version of it) reaches consensus, I'll follow up with
more patches and then tackle the static linking issue.
---
 Makeconfig                                    |  2 +-
 grp/Makefile                                  | 70 -------------------
 grp/Versions                                  | 34 ---------
 include/grp-merge.h                           |  2 +-
 include/grp.h                                 |  2 +-
 nscd/initgrcache.c                            |  2 +-
 nss/Makefile                                  | 48 +++++++++++--
 nss/Versions                                  | 30 ++++++++
 {grp => nss}/fgetgrent.c                      |  0
 {grp => nss}/fgetgrent_r.c                    |  0
 {grp => nss}/getgrent.c                       |  0
 {grp => nss}/getgrent_r.c                     |  0
 {grp => nss}/getgrgid.c                       |  0
 {grp => nss}/getgrgid_r.c                     |  0
 {grp => nss}/getgrnam.c                       |  0
 {grp => nss}/getgrnam_r.c                     |  0
 {grp => nss}/grp-merge.c                      |  0
 {grp => nss}/grp-merge.h                      |  0
 {grp => nss}/grp.h                            |  0
 .../initgroups-fallback.c                     |  0
 {grp => nss}/initgroups.c                     |  2 +-
 {grp => nss}/putgrent.c                       |  0
 {grp => nss}/testgrp.c                        |  0
 {grp => nss}/tst-initgroups1.c                |  0
 {grp => nss}/tst-initgroups1.root/etc/group   |  0
 .../tst-initgroups1.root/etc/nsswitch.conf    |  0
 {grp => nss}/tst-initgroups1.root/etc/passwd  |  0
 {grp => nss}/tst-initgroups2.c                |  0
 {grp => nss}/tst-initgroups2.root/etc/group   |  0
 .../tst-initgroups2.root/etc/nsswitch.conf    |  0
 {grp => nss}/tst-initgroups2.root/etc/passwd  |  0
 {grp => nss}/tst-putgrent.c                   |  0
 {grp => nss}/tst_fgetgrent.c                  |  0
 {grp => nss}/tst_fgetgrent.sh                 | 10 +--
 posix/Makefile                                |  1 +
 posix/Versions                                |  2 +-
 {grp => posix}/setgroups.c                    |  0
 scripts/update-copyrights                     |  2 +-
 38 files changed, 87 insertions(+), 120 deletions(-)
 delete mode 100644 grp/Makefile
 delete mode 100644 grp/Versions
 rename {grp => nss}/fgetgrent.c (100%)
 rename {grp => nss}/fgetgrent_r.c (100%)
 rename {grp => nss}/getgrent.c (100%)
 rename {grp => nss}/getgrent_r.c (100%)
 rename {grp => nss}/getgrgid.c (100%)
 rename {grp => nss}/getgrgid_r.c (100%)
 rename {grp => nss}/getgrnam.c (100%)
 rename {grp => nss}/getgrnam_r.c (100%)
 rename {grp => nss}/grp-merge.c (100%)
 rename {grp => nss}/grp-merge.h (100%)
 rename {grp => nss}/grp.h (100%)
 rename grp/compat-initgroups.c => nss/initgroups-fallback.c (100%)
 rename {grp => nss}/initgroups.c (99%)
 rename {grp => nss}/putgrent.c (100%)
 rename {grp => nss}/testgrp.c (100%)
 rename {grp => nss}/tst-initgroups1.c (100%)
 rename {grp => nss}/tst-initgroups1.root/etc/group (100%)
 rename {grp => nss}/tst-initgroups1.root/etc/nsswitch.conf (100%)
 rename {grp => nss}/tst-initgroups1.root/etc/passwd (100%)
 rename {grp => nss}/tst-initgroups2.c (100%)
 rename {grp => nss}/tst-initgroups2.root/etc/group (100%)
 rename {grp => nss}/tst-initgroups2.root/etc/nsswitch.conf (100%)
 rename {grp => nss}/tst-initgroups2.root/etc/passwd (100%)
 rename {grp => nss}/tst-putgrent.c (100%)
 rename {grp => nss}/tst_fgetgrent.c (100%)
 rename {grp => nss}/tst_fgetgrent.sh (76%)
 rename {grp => posix}/setgroups.c (100%)
  

Comments

DJ Delorie June 29, 2023, 9:26 p.m. UTC | #1
Arjun Shankar via Libc-alpha <libc-alpha@sourceware.org> writes:
> This commit removes the 'grp' subdirectory and moves all nss-relevant
> functionality and all tests to 'nss', and the 'setgroups' stub into

Reviewing it as a "just a move" patch, then.

LGTM.
Reviewed-by: DJ Delorie <dj@redhat.com>

> -	      grp pwd posix io termios resource misc socket sysvipc gmon    \
> +	          pwd posix io termios resource misc socket sysvipc gmon        \

Removes grp, ok.

> diff --git a/grp/Makefile b/grp/Makefile
> deleted file mode 100644

Ok.

> diff --git a/grp/Versions b/grp/Versions
> deleted file mode 100644

Ok.

> -#include <grp/grp-merge.h>
> +#include <nss/grp-merge.h>

Ok.

> -#include <grp/grp.h>
> +#include <nss/grp.h>

Ok.

> -#include "../grp/compat-initgroups.c"
> +#include "../nss/initgroups-fallback.c"

Ok.

> diff --git a/nss/Makefile b/nss/Makefile
> -headers			:= nss.h
> +headers			:= nss.h grp.h

Ok.

> +# grp routines:
> +routines += \
> +  fgetgrent \
> +  fgetgrent_r \
> +  getgrent \
> +  getgrent_r \
> +  getgrgid \
> +  getgrgid_r \
> +  getgrnam \
> +  getgrnam_r \
> +  grp-merge \
> +  initgroups \
> +  putgrent \
> +  # routines

Ok.  Missing setgroups, which goes elsewhere.

> +ifeq ($(have-thread-library),yes)
> +CFLAGS-fgetgrent.c += -fexceptions
> +CFLAGS-fgetgrent_r.c += -fexceptions $(libio-mtsafe)
> +CFLAGS-getgrent.c += -fexceptions
> +CFLAGS-getgrent_r.c += -fexceptions
> +CFLAGS-getgrgid.c += -fexceptions
> +CFLAGS-getgrgid_r.c += -fexceptions
> +CFLAGS-getgrnam.c += -fexceptions
> +CFLAGS-getgrnam_r.c += -fexceptions
> +CFLAGS-initgroups.c += -fexceptions
> +CFLAGS-putgrent.c += -fexceptions $(libio-mtsafe)
> +endif

Ok.

> @@ -61,6 +89,7 @@ tests := \
>    bug17079 \
>    test-digits-dots \
>    test-netdb \
> +  testgrp \
>    tst-nss-getpwent \
>    tst-nss-hash \
>    tst-nss-test1 \
> @@ -68,11 +97,14 @@ tests := \
>    tst-nss-test4 \
>    tst-nss-test5 \
>    tst-nss-test_errno \
> -# tests
> +  tst-putgrent \
> +  # tests

Ok.

>  xtests = bug-erange
>  
>  tests-container := \
> +  tst-initgroups1 \
> +  tst-initgroups2 \
>    tst-nss-compat1 \
>    tst-nss-db-endgrent \
>    tst-nss-db-endpwent \
> @@ -81,15 +113,23 @@ tests-container := \
>    tst-nss-test3 \
>    tst-reload1 \
>    tst-reload2 \
> -# tests-container
> +  # tests-container

Ok.

> -# Tests which need libdl
>  ifeq (yes,$(build-shared))
> +# Tests which need libdl
>  tests += tst-nss-files-hosts-erange
>  tests += tst-nss-files-hosts-multi
>  tests += tst-nss-files-hosts-getent
>  tests += tst-nss-files-alias-leak
>  tests += tst-nss-files-alias-truncated
> +# tst_fgetgrent currently only works with shared libraries
> +test-srcs :=  tst_fgetgrent
> +ifeq ($(run-built-tests),yes)
> +tests-special += $(objpfx)tst_fgetgrent.out
> +$(objpfx)tst_fgetgrent.out: tst_fgetgrent.sh $(objpfx)tst_fgetgrent
> +	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
> +	$(evaluate-test)
> +endif
>  endif

Ok.

> diff --git a/nss/Versions b/nss/Versions
> index e551524aa9..5401829911 100644
> --- a/nss/Versions
> +++ b/nss/Versions
> @@ -5,10 +5,38 @@ libc {
>      # Functions exported as no-op compat symbols.
>      __nss_passwd_lookup; __nss_group_lookup; __nss_hosts_lookup; __nss_next;
>      __nss_database_lookup;
> +
> +    # e*
> +    endgrent;
> +
> +    # f*
> +    fgetgrent; fgetgrent_r;
> +
> +    # g*
> +    getgrent; getgrent_r; getgrgid; getgrgid_r; getgrnam; getgrnam_r;
> +    getgroups;
> +
> +    # i*
> +    initgroups;
> +
> +    # s*
> +    setgrent;
> +  }
> +  GLIBC_2.1 {
> +    # p*
> +    putgrent;
> +  }
> +  GLIBC_2.1.2 {
> +    # g*
> +    getgrent_r; getgrgid_r; getgrnam_r;
>    }
>    GLIBC_2.2.2 {
>      __nss_hostname_digits_dots;
>    }
> +  GLIBC_2.2.4 {
> +    # g*
> +    getgrouplist;
> +  }
>    GLIBC_2.27 {
>    }
>    GLIBC_PRIVATE {
> @@ -107,6 +135,8 @@ libc {
>      _nss_files_initgroups_dyn;
>  
>      _nss_files_init;
> +
> +    __merge_grp; __copy_grp;
>    }
>  }

Ok.

> diff --git a/grp/fgetgrent.c b/nss/fgetgrent.c
> similarity index 100%
> rename from grp/fgetgrent.c
> rename to nss/fgetgrent.c
> diff --git a/grp/fgetgrent_r.c b/nss/fgetgrent_r.c
> similarity index 100%
> rename from grp/fgetgrent_r.c
> rename to nss/fgetgrent_r.c
> diff --git a/grp/getgrent.c b/nss/getgrent.c
> similarity index 100%
> rename from grp/getgrent.c
> rename to nss/getgrent.c
> diff --git a/grp/getgrent_r.c b/nss/getgrent_r.c
> similarity index 100%
> rename from grp/getgrent_r.c
> rename to nss/getgrent_r.c
> diff --git a/grp/getgrgid.c b/nss/getgrgid.c
> similarity index 100%
> rename from grp/getgrgid.c
> rename to nss/getgrgid.c
> diff --git a/grp/getgrgid_r.c b/nss/getgrgid_r.c
> similarity index 100%
> rename from grp/getgrgid_r.c
> rename to nss/getgrgid_r.c
> diff --git a/grp/getgrnam.c b/nss/getgrnam.c
> similarity index 100%
> rename from grp/getgrnam.c
> rename to nss/getgrnam.c
> diff --git a/grp/getgrnam_r.c b/nss/getgrnam_r.c
> similarity index 100%
> rename from grp/getgrnam_r.c
> rename to nss/getgrnam_r.c
> diff --git a/grp/grp-merge.c b/nss/grp-merge.c
> similarity index 100%
> rename from grp/grp-merge.c
> rename to nss/grp-merge.c
> diff --git a/grp/grp-merge.h b/nss/grp-merge.h
> similarity index 100%
> rename from grp/grp-merge.h
> rename to nss/grp-merge.h
> diff --git a/grp/grp.h b/nss/grp.h
> similarity index 100%
> rename from grp/grp.h
> rename to nss/grp.h
> diff --git a/grp/compat-initgroups.c b/nss/initgroups-fallback.c
> similarity index 100%
> rename from grp/compat-initgroups.c
> rename to nss/initgroups-fallback.c

Ok.

> diff --git a/grp/initgroups.c b/nss/initgroups.c
> similarity index 99%
> rename from grp/initgroups.c
> rename to nss/initgroups.c
> index 2ebd623d7b..e803cecebc 100644
> --- a/grp/initgroups.c
> +++ b/nss/initgroups.c
> @@ -39,7 +39,7 @@ typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
>  static bool use_initgroups_entry;
>  
>  
> -#include "compat-initgroups.c"
> +#include "initgroups-fallback.c"

Ok.

> diff --git a/grp/putgrent.c b/nss/putgrent.c
> similarity index 100%
> rename from grp/putgrent.c
> rename to nss/putgrent.c
> diff --git a/grp/testgrp.c b/nss/testgrp.c
> similarity index 100%
> rename from grp/testgrp.c
> rename to nss/testgrp.c
> diff --git a/grp/tst-initgroups1.c b/nss/tst-initgroups1.c
> similarity index 100%
> rename from grp/tst-initgroups1.c
> rename to nss/tst-initgroups1.c
> diff --git a/grp/tst-initgroups1.root/etc/group b/nss/tst-initgroups1.root/etc/group
> similarity index 100%
> rename from grp/tst-initgroups1.root/etc/group
> rename to nss/tst-initgroups1.root/etc/group
> diff --git a/grp/tst-initgroups1.root/etc/nsswitch.conf b/nss/tst-initgroups1.root/etc/nsswitch.conf
> similarity index 100%
> rename from grp/tst-initgroups1.root/etc/nsswitch.conf
> rename to nss/tst-initgroups1.root/etc/nsswitch.conf
> diff --git a/grp/tst-initgroups1.root/etc/passwd b/nss/tst-initgroups1.root/etc/passwd
> similarity index 100%
> rename from grp/tst-initgroups1.root/etc/passwd
> rename to nss/tst-initgroups1.root/etc/passwd
> diff --git a/grp/tst-initgroups2.c b/nss/tst-initgroups2.c
> similarity index 100%
> rename from grp/tst-initgroups2.c
> rename to nss/tst-initgroups2.c
> diff --git a/grp/tst-initgroups2.root/etc/group b/nss/tst-initgroups2.root/etc/group
> similarity index 100%
> rename from grp/tst-initgroups2.root/etc/group
> rename to nss/tst-initgroups2.root/etc/group
> diff --git a/grp/tst-initgroups2.root/etc/nsswitch.conf b/nss/tst-initgroups2.root/etc/nsswitch.conf
> similarity index 100%
> rename from grp/tst-initgroups2.root/etc/nsswitch.conf
> rename to nss/tst-initgroups2.root/etc/nsswitch.conf
> diff --git a/grp/tst-initgroups2.root/etc/passwd b/nss/tst-initgroups2.root/etc/passwd
> similarity index 100%
> rename from grp/tst-initgroups2.root/etc/passwd
> rename to nss/tst-initgroups2.root/etc/passwd
> diff --git a/grp/tst-putgrent.c b/nss/tst-putgrent.c
> similarity index 100%
> rename from grp/tst-putgrent.c
> rename to nss/tst-putgrent.c
> diff --git a/grp/tst_fgetgrent.c b/nss/tst_fgetgrent.c
> similarity index 100%
> rename from grp/tst_fgetgrent.c
> rename to nss/tst_fgetgrent.c

Ok.

> diff --git a/grp/tst_fgetgrent.sh b/nss/tst_fgetgrent.sh
> similarity index 76%
> rename from grp/tst_fgetgrent.sh
> rename to nss/tst_fgetgrent.sh
> index 1775a6bc61..fb6b0c4179 100644
> --- a/grp/tst_fgetgrent.sh
> +++ b/nss/tst_fgetgrent.sh
> @@ -21,20 +21,20 @@ set -e
>  common_objpfx=$1; shift
>  test_program_prefix=$1; shift
>  
> -testout=${common_objpfx}/grp/tst_fgetgrent.out
> +testout=${common_objpfx}/nss/tst_fgetgrent.out

Ok.

>  result=0
>  
>  ${test_program_prefix} \
> -${common_objpfx}grp/tst_fgetgrent 0 > ${testout} || result=1
> +${common_objpfx}nss/tst_fgetgrent 0 > ${testout} || result=1

Ok.

>  ${test_program_prefix} \
> -${common_objpfx}grp/tst_fgetgrent 1 >> ${testout} || result=1
> +${common_objpfx}nss/tst_fgetgrent 1 >> ${testout} || result=1

Ok.

>  ${test_program_prefix} \
> -${common_objpfx}grp/tst_fgetgrent 2 >> ${testout} || result=1
> +${common_objpfx}nss/tst_fgetgrent 2 >> ${testout} || result=1

Ok.

>  ${test_program_prefix} \
> -${common_objpfx}grp/tst_fgetgrent 3 >> ${testout} || result=1
> +${common_objpfx}nss/tst_fgetgrent 3 >> ${testout} || result=1

Ok.

> diff --git a/posix/Makefile b/posix/Makefile
> index ad43cbdec6..39caa95ec2 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -135,6 +135,7 @@ routines := \
>    sched_sets \
>    sched_yield \
>    setgid \
> +  setgroups \
>    setpgid \
>    setpgrp \
>    setresgid \

Ok.

> diff --git a/posix/Versions b/posix/Versions
> -               setpgid; setpgrp; setsid; setuid; sleep; sysconf;
> +    setgroups; setpgid; setpgrp; setsid; setuid; sleep; sysconf;

Ok.

> diff --git a/grp/setgroups.c b/posix/setgroups.c
> -    grp/initgroups.c | misc/bits/stab.def | posix/regex.h \
> +    nss/initgroups.c | misc/bits/stab.def | posix/regex.h \

Ok.
  

Patch

diff --git a/Makeconfig b/Makeconfig
index 2514db35f6..6e767feaf4 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1328,7 +1328,7 @@  endif
 # dependencies and generate sorted-subdirs dynamically.
 all-subdirs = csu assert ctype locale intl catgets math setjmp signal	    \
 	      stdlib stdio-common libio malloc string wcsmbs time dirent    \
-	      grp pwd posix io termios resource misc socket sysvipc gmon    \
+	      pwd posix io termios resource misc socket sysvipc gmon        \
 	      gnulib iconv iconvdata wctype manual shadow gshadow po argp   \
 	      localedata timezone rt conform debug mathvec support	    \
 	      dlfcn elf
diff --git a/grp/Makefile b/grp/Makefile
deleted file mode 100644
index 38006fb5c3..0000000000
--- a/grp/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@ 
-# Copyright (C) 1991-2023 Free Software Foundation, Inc.
-# This file is part of the GNU C Library.
-
-# The GNU C Library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-
-# The GNU C Library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-
-# You should have received a copy of the GNU Lesser General Public
-# License along with the GNU C Library; if not, see
-# <https://www.gnu.org/licenses/>.
-
-#
-#	Sub-makefile for grp portion of the library.
-#
-subdir	:= grp
-
-include ../Makeconfig
-
-headers := grp.h
-
-routines := fgetgrent initgroups setgroups \
-	    getgrent getgrgid getgrnam putgrent \
-	    getgrent_r getgrgid_r getgrnam_r fgetgrent_r \
-	    grp-merge
-
-tests := testgrp tst-putgrent
-
-tests-container = \
-	tst-initgroups1 \
-	tst-initgroups2
-
-ifeq (yes,$(build-shared))
-test-srcs :=  tst_fgetgrent
-ifeq ($(run-built-tests),yes)
-tests-special += $(objpfx)tst_fgetgrent.out
-endif
-endif
-
-
-include ../Rules
-
-ifeq ($(have-thread-library),yes)
-
-CFLAGS-getgrgid_r.c += -fexceptions
-CFLAGS-getgrnam_r.c += -fexceptions
-CFLAGS-getgrent_r.c += -fexceptions
-CFLAGS-getgrent.c += -fexceptions
-CFLAGS-fgetgrent.c += -fexceptions
-CFLAGS-fgetgrent_r.c += -fexceptions $(libio-mtsafe)
-CFLAGS-putgrent.c += -fexceptions $(libio-mtsafe)
-CFLAGS-initgroups.c += -fexceptions
-CFLAGS-getgrgid.c += -fexceptions
-
-endif
-
-ifeq ($(run-built-tests),yes)
-# tst_fgetgrent currently only works with shared libraries
-ifeq (yes,$(build-shared))
-$(objpfx)tst_fgetgrent.out: tst_fgetgrent.sh $(objpfx)tst_fgetgrent
-	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
-	$(evaluate-test)
-
-endif
-endif
diff --git a/grp/Versions b/grp/Versions
deleted file mode 100644
index 096caa47c5..0000000000
--- a/grp/Versions
+++ /dev/null
@@ -1,34 +0,0 @@ 
-libc {
-  GLIBC_2.0 {
-    # e*
-    endgrent;
-
-    # f*
-    fgetgrent; fgetgrent_r;
-
-    # g*
-    getgrent; getgrent_r; getgrgid; getgrgid_r; getgrnam; getgrnam_r;
-    getgroups;
-
-    # i*
-    initgroups;
-
-    # s*
-    setgrent; setgroups;
-  }
-  GLIBC_2.1 {
-    # p*
-    putgrent;
-  }
-  GLIBC_2.1.2 {
-    # g*
-    getgrent_r; getgrgid_r; getgrnam_r;
-  }
-  GLIBC_2.2.4 {
-    # g*
-    getgrouplist;
-  }
-  GLIBC_PRIVATE {
-    __merge_grp; __copy_grp;
-  }
-}
diff --git a/include/grp-merge.h b/include/grp-merge.h
index 331ac20ea9..fc9a25df01 100644
--- a/include/grp-merge.h
+++ b/include/grp-merge.h
@@ -1,5 +1,5 @@ 
 #ifndef _GRP_MERGE_H
-#include <grp/grp-merge.h>
+#include <nss/grp-merge.h>
 
 libc_hidden_proto (__copy_grp)
 libc_hidden_proto (__merge_grp)
diff --git a/include/grp.h b/include/grp.h
index 2cd2475534..96b98a3cde 100644
--- a/include/grp.h
+++ b/include/grp.h
@@ -1,5 +1,5 @@ 
 #ifndef _GRP_H
-#include <grp/grp.h>
+#include <nss/grp.h>
 
 #ifndef _ISOMAC
 libc_hidden_proto (setgroups)
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index be44951bd6..8d8e1c2dbf 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -45,7 +45,7 @@  static const initgr_response_header notfound =
 };
 
 
-#include "../grp/compat-initgroups.c"
+#include "../nss/initgroups-fallback.c"
 
 
 static time_t
diff --git a/nss/Makefile b/nss/Makefile
index 3a9ea065ac..9536310a46 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -22,7 +22,7 @@  subdir	:= nss
 
 include ../Makeconfig
 
-headers			:= nss.h
+headers			:= nss.h grp.h
 
 # This is the trivial part which goes into libc itself.
 routines		= nsswitch getnssent getnssent_r digits_dots \
@@ -34,6 +34,34 @@  routines		= nsswitch getnssent getnssent_r digits_dots \
 			  nss_action_parse nss_database nss_files_data \
 			  nss_files_functions
 
+# grp routines:
+routines += \
+  fgetgrent \
+  fgetgrent_r \
+  getgrent \
+  getgrent_r \
+  getgrgid \
+  getgrgid_r \
+  getgrnam \
+  getgrnam_r \
+  grp-merge \
+  initgroups \
+  putgrent \
+  # routines
+
+ifeq ($(have-thread-library),yes)
+CFLAGS-fgetgrent.c += -fexceptions
+CFLAGS-fgetgrent_r.c += -fexceptions $(libio-mtsafe)
+CFLAGS-getgrent.c += -fexceptions
+CFLAGS-getgrent_r.c += -fexceptions
+CFLAGS-getgrgid.c += -fexceptions
+CFLAGS-getgrgid_r.c += -fexceptions
+CFLAGS-getgrnam.c += -fexceptions
+CFLAGS-getgrnam_r.c += -fexceptions
+CFLAGS-initgroups.c += -fexceptions
+CFLAGS-putgrent.c += -fexceptions $(libio-mtsafe)
+endif
+
 # These are the databases that go through nss dispatch.
 # Caution: if you add a database here, you must add its real name
 # in databases.def, too.
@@ -61,6 +89,7 @@  tests := \
   bug17079 \
   test-digits-dots \
   test-netdb \
+  testgrp \
   tst-nss-getpwent \
   tst-nss-hash \
   tst-nss-test1 \
@@ -68,11 +97,14 @@  tests := \
   tst-nss-test4 \
   tst-nss-test5 \
   tst-nss-test_errno \
-# tests
+  tst-putgrent \
+  # tests
 
 xtests = bug-erange
 
 tests-container := \
+  tst-initgroups1 \
+  tst-initgroups2 \
   tst-nss-compat1 \
   tst-nss-db-endgrent \
   tst-nss-db-endpwent \
@@ -81,15 +113,23 @@  tests-container := \
   tst-nss-test3 \
   tst-reload1 \
   tst-reload2 \
-# tests-container
+  # tests-container
 
-# Tests which need libdl
 ifeq (yes,$(build-shared))
+# Tests which need libdl
 tests += tst-nss-files-hosts-erange
 tests += tst-nss-files-hosts-multi
 tests += tst-nss-files-hosts-getent
 tests += tst-nss-files-alias-leak
 tests += tst-nss-files-alias-truncated
+# tst_fgetgrent currently only works with shared libraries
+test-srcs :=  tst_fgetgrent
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)tst_fgetgrent.out
+$(objpfx)tst_fgetgrent.out: tst_fgetgrent.sh $(objpfx)tst_fgetgrent
+	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
+	$(evaluate-test)
+endif
 endif
 
 # If we have a thread library then we can test cancellation against
diff --git a/nss/Versions b/nss/Versions
index e551524aa9..5401829911 100644
--- a/nss/Versions
+++ b/nss/Versions
@@ -5,10 +5,38 @@  libc {
     # Functions exported as no-op compat symbols.
     __nss_passwd_lookup; __nss_group_lookup; __nss_hosts_lookup; __nss_next;
     __nss_database_lookup;
+
+    # e*
+    endgrent;
+
+    # f*
+    fgetgrent; fgetgrent_r;
+
+    # g*
+    getgrent; getgrent_r; getgrgid; getgrgid_r; getgrnam; getgrnam_r;
+    getgroups;
+
+    # i*
+    initgroups;
+
+    # s*
+    setgrent;
+  }
+  GLIBC_2.1 {
+    # p*
+    putgrent;
+  }
+  GLIBC_2.1.2 {
+    # g*
+    getgrent_r; getgrgid_r; getgrnam_r;
   }
   GLIBC_2.2.2 {
     __nss_hostname_digits_dots;
   }
+  GLIBC_2.2.4 {
+    # g*
+    getgrouplist;
+  }
   GLIBC_2.27 {
   }
   GLIBC_PRIVATE {
@@ -107,6 +135,8 @@  libc {
     _nss_files_initgroups_dyn;
 
     _nss_files_init;
+
+    __merge_grp; __copy_grp;
   }
 }
 
diff --git a/grp/fgetgrent.c b/nss/fgetgrent.c
similarity index 100%
rename from grp/fgetgrent.c
rename to nss/fgetgrent.c
diff --git a/grp/fgetgrent_r.c b/nss/fgetgrent_r.c
similarity index 100%
rename from grp/fgetgrent_r.c
rename to nss/fgetgrent_r.c
diff --git a/grp/getgrent.c b/nss/getgrent.c
similarity index 100%
rename from grp/getgrent.c
rename to nss/getgrent.c
diff --git a/grp/getgrent_r.c b/nss/getgrent_r.c
similarity index 100%
rename from grp/getgrent_r.c
rename to nss/getgrent_r.c
diff --git a/grp/getgrgid.c b/nss/getgrgid.c
similarity index 100%
rename from grp/getgrgid.c
rename to nss/getgrgid.c
diff --git a/grp/getgrgid_r.c b/nss/getgrgid_r.c
similarity index 100%
rename from grp/getgrgid_r.c
rename to nss/getgrgid_r.c
diff --git a/grp/getgrnam.c b/nss/getgrnam.c
similarity index 100%
rename from grp/getgrnam.c
rename to nss/getgrnam.c
diff --git a/grp/getgrnam_r.c b/nss/getgrnam_r.c
similarity index 100%
rename from grp/getgrnam_r.c
rename to nss/getgrnam_r.c
diff --git a/grp/grp-merge.c b/nss/grp-merge.c
similarity index 100%
rename from grp/grp-merge.c
rename to nss/grp-merge.c
diff --git a/grp/grp-merge.h b/nss/grp-merge.h
similarity index 100%
rename from grp/grp-merge.h
rename to nss/grp-merge.h
diff --git a/grp/grp.h b/nss/grp.h
similarity index 100%
rename from grp/grp.h
rename to nss/grp.h
diff --git a/grp/compat-initgroups.c b/nss/initgroups-fallback.c
similarity index 100%
rename from grp/compat-initgroups.c
rename to nss/initgroups-fallback.c
diff --git a/grp/initgroups.c b/nss/initgroups.c
similarity index 99%
rename from grp/initgroups.c
rename to nss/initgroups.c
index 2ebd623d7b..e803cecebc 100644
--- a/grp/initgroups.c
+++ b/nss/initgroups.c
@@ -39,7 +39,7 @@  typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
 static bool use_initgroups_entry;
 
 
-#include "compat-initgroups.c"
+#include "initgroups-fallback.c"
 
 
 static int
diff --git a/grp/putgrent.c b/nss/putgrent.c
similarity index 100%
rename from grp/putgrent.c
rename to nss/putgrent.c
diff --git a/grp/testgrp.c b/nss/testgrp.c
similarity index 100%
rename from grp/testgrp.c
rename to nss/testgrp.c
diff --git a/grp/tst-initgroups1.c b/nss/tst-initgroups1.c
similarity index 100%
rename from grp/tst-initgroups1.c
rename to nss/tst-initgroups1.c
diff --git a/grp/tst-initgroups1.root/etc/group b/nss/tst-initgroups1.root/etc/group
similarity index 100%
rename from grp/tst-initgroups1.root/etc/group
rename to nss/tst-initgroups1.root/etc/group
diff --git a/grp/tst-initgroups1.root/etc/nsswitch.conf b/nss/tst-initgroups1.root/etc/nsswitch.conf
similarity index 100%
rename from grp/tst-initgroups1.root/etc/nsswitch.conf
rename to nss/tst-initgroups1.root/etc/nsswitch.conf
diff --git a/grp/tst-initgroups1.root/etc/passwd b/nss/tst-initgroups1.root/etc/passwd
similarity index 100%
rename from grp/tst-initgroups1.root/etc/passwd
rename to nss/tst-initgroups1.root/etc/passwd
diff --git a/grp/tst-initgroups2.c b/nss/tst-initgroups2.c
similarity index 100%
rename from grp/tst-initgroups2.c
rename to nss/tst-initgroups2.c
diff --git a/grp/tst-initgroups2.root/etc/group b/nss/tst-initgroups2.root/etc/group
similarity index 100%
rename from grp/tst-initgroups2.root/etc/group
rename to nss/tst-initgroups2.root/etc/group
diff --git a/grp/tst-initgroups2.root/etc/nsswitch.conf b/nss/tst-initgroups2.root/etc/nsswitch.conf
similarity index 100%
rename from grp/tst-initgroups2.root/etc/nsswitch.conf
rename to nss/tst-initgroups2.root/etc/nsswitch.conf
diff --git a/grp/tst-initgroups2.root/etc/passwd b/nss/tst-initgroups2.root/etc/passwd
similarity index 100%
rename from grp/tst-initgroups2.root/etc/passwd
rename to nss/tst-initgroups2.root/etc/passwd
diff --git a/grp/tst-putgrent.c b/nss/tst-putgrent.c
similarity index 100%
rename from grp/tst-putgrent.c
rename to nss/tst-putgrent.c
diff --git a/grp/tst_fgetgrent.c b/nss/tst_fgetgrent.c
similarity index 100%
rename from grp/tst_fgetgrent.c
rename to nss/tst_fgetgrent.c
diff --git a/grp/tst_fgetgrent.sh b/nss/tst_fgetgrent.sh
similarity index 76%
rename from grp/tst_fgetgrent.sh
rename to nss/tst_fgetgrent.sh
index 1775a6bc61..fb6b0c4179 100644
--- a/grp/tst_fgetgrent.sh
+++ b/nss/tst_fgetgrent.sh
@@ -21,20 +21,20 @@  set -e
 common_objpfx=$1; shift
 test_program_prefix=$1; shift
 
-testout=${common_objpfx}/grp/tst_fgetgrent.out
+testout=${common_objpfx}/nss/tst_fgetgrent.out
 
 result=0
 
 ${test_program_prefix} \
-${common_objpfx}grp/tst_fgetgrent 0 > ${testout} || result=1
+${common_objpfx}nss/tst_fgetgrent 0 > ${testout} || result=1
 
 ${test_program_prefix} \
-${common_objpfx}grp/tst_fgetgrent 1 >> ${testout} || result=1
+${common_objpfx}nss/tst_fgetgrent 1 >> ${testout} || result=1
 
 ${test_program_prefix} \
-${common_objpfx}grp/tst_fgetgrent 2 >> ${testout} || result=1
+${common_objpfx}nss/tst_fgetgrent 2 >> ${testout} || result=1
 
 ${test_program_prefix} \
-${common_objpfx}grp/tst_fgetgrent 3 >> ${testout} || result=1
+${common_objpfx}nss/tst_fgetgrent 3 >> ${testout} || result=1
 
 exit $result
diff --git a/posix/Makefile b/posix/Makefile
index ad43cbdec6..39caa95ec2 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -135,6 +135,7 @@  routines := \
   sched_sets \
   sched_yield \
   setgid \
+  setgroups \
   setpgid \
   setpgrp \
   setresgid \
diff --git a/posix/Versions b/posix/Versions
index 3753810864..2eedbc3e79 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -53,7 +53,7 @@  libc {
     sched_get_priority_max; sched_get_priority_min; sched_getparam;
     sched_getscheduler; sched_rr_get_interval; sched_setparam;
     sched_setscheduler; sched_yield; setegid; seteuid; setgid;
-    setpgid; setpgrp; setsid; setuid; sleep; sysconf;
+    setgroups; setpgid; setpgrp; setsid; setuid; sleep; sysconf;
 
     # t*
     times;
diff --git a/grp/setgroups.c b/posix/setgroups.c
similarity index 100%
rename from grp/setgroups.c
rename to posix/setgroups.c
diff --git a/scripts/update-copyrights b/scripts/update-copyrights
index f6ef6fa33b..a582fa1476 100755
--- a/scripts/update-copyrights
+++ b/scripts/update-copyrights
@@ -65,7 +65,7 @@  for f in $files; do
 	"$update_script" "$f"
       fi
       ;;
-    grp/initgroups.c | misc/bits/stab.def | posix/regex.h \
+    nss/initgroups.c | misc/bits/stab.def | posix/regex.h \
       | sysdeps/wordsize-32/divdi3.c)
       # Pre-1991 gaps in copyright years, so cannot use a single range.
       UPDATE_COPYRIGHT_USE_INTERVALS=1 "$update_script" "$f"