This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] libc.so: Replace nscd_hash.os with libc-nscd_hash.os [BZ #22459]


Here's an updated patch which doesn't make __nss_has part of the ABI. The alternative nscd implementation, unscd, does not use maps, so it does not need to replicate the exact same hash function as glibc.

Thanks,
Florian
Subject: [PATCH] nss: Export nscd hash function as __nss_hash [BZ #22459]
To: libc-alpha@sourceware.org

2017-11-23  Florian Weimer  <fweimer@redhat.com>

	[BZ #22459]
	Export nscd hash function as __nss_hash.
	* include/nss.h (__nss_hash): Declare.
	* nis/nis_hash.c (__nis_hash): Call __nss_hash.  Turn into compat
	symbol.
	* nscd/Makefile (aux, nscd-modules): Remove nscd_hash.
	* nscd/cache.c (cache_search, cache_add): Call __nss_hash instead
	of __nscd_hash.
	* nscd/nscd_helper.c (__nscd_cache_search): Likewise.
	* nscd/nscd_hash.h, nscd/nscd_hash.c: Remove files.
	* nss/Makefiles (routines): Add nss_hash.
	* nss/Versions (GLIBC_PRIVATE): Export __nss_hash.
	* nss/nss_hash.c: Rename from nis/nis_hash.c.
	(__nss_hash): Rename from __nis_hash.  Define hidden alias.
	* nis/rpcsvc/nislib.h (__nis_hash): Remove declaration.

diff --git a/include/nss.h b/include/nss.h
index 5f29de7f84..c5b7c04c82 100644
--- a/include/nss.h
+++ b/include/nss.h
@@ -1,9 +1,12 @@
 #ifndef _NSS_H
 #include <nss/nss.h>
 
-# ifndef _ISOMAC
+#ifndef _ISOMAC
 
-#define NSS_INVALID_FIELD_CHARACTERS ":\n"
+# include <stddef.h>
+# include <stdint.h>
+
+# define NSS_INVALID_FIELD_CHARACTERS ":\n"
 extern const char __nss_invalid_field_characters[] attribute_hidden;
 
 _Bool __nss_valid_field (const char *value) attribute_hidden;
@@ -11,5 +14,10 @@ _Bool __nss_valid_list_field (char **list)  attribute_hidden;
 const char *__nss_rewrite_field (const char *value, char **to_be_freed)
   attribute_hidden;
 
-# endif /* !_ISOMAC */
+/* Compute a hash value for LENGTH bytes starting at KEY.  This is the
+   hash function used by the nscd for the cache mapping files.  */
+uint32_t __nss_hash (const void *__key, size_t __length);
+libc_hidden_proto (__nss_hash)
+
+#endif /* !_ISOMAC */
 #endif /* _NSS_H */
diff --git a/nis/nis_hash.c b/nis/nis_hash.c
index cc42ac8911..5dba1cba0f 100644
--- a/nis/nis_hash.c
+++ b/nis/nis_hash.c
@@ -1,6 +1,6 @@
-/* Copyright (c) 1997-2017 Free Software Foundation, Inc.
+/* Forward __nis_hash calls to __nss_hash, for ABI compatibility.
+   Copyright (c) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,61 +16,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stdint.h>
-#include <rpcsvc/nis.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libnsl, GLIBC_2_1, GLIBC_2_27)
+
+# include <nss.h>
 
-/* This is from libc/db/hash/hash_func.c, hash3 is static there */
-/*
- * This is INCREDIBLY ugly, but fast.  We break the string up into 8 byte
- * units.  On the first time through the loop we get the "leftover bytes"
- * (strlen % 8).  On every other iteration, we perform 8 HASHC's so we handle
- * all 8 bytes.  Essentially, this saves us 7 cmp & branch instructions.  If
- * this routine is heavily used enough, it's worth the ugly coding.
- *
- * OZ's original sdbm hash
- */
 uint32_t
 __nis_hash (const void *keyarg, size_t len)
 {
-  const u_char *key;
-  size_t loop;
-  uint32_t h;
-
-#define HASHC   h = *key++ + 65599 * h
-
-  h = 0;
-  key = keyarg;
-  if (len > 0)
-    {
-      loop = (len + 8 - 1) >> 3;
-      switch (len & (8 - 1))
-	{
-	case 0:
-	  do {
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 7:
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 6:
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 5:
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 4:
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 3:
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 2:
-	    HASHC;
-	    /* FALLTHROUGH */
-	  case 1:
-	    HASHC;
-	  } while (--loop);
-	}
-    }
-  return h;
+  return __nss_hash (keyarg, len);
 }
+
+compat_symbol (libnsl, __nis_hash, __nis_hash, GLIBC_2_1);
+
+#endif
diff --git a/nis/rpcsvc/nislib.h b/nis/rpcsvc/nislib.h
index 52fbba4b8f..ad22c9c767 100644
--- a/nis/rpcsvc/nislib.h
+++ b/nis/rpcsvc/nislib.h
@@ -244,7 +244,6 @@ extern uint32_t __nis_default_ttl (char *) __THROW;
 extern unsigned int __nis_default_access (char *, unsigned int) __THROW;
 extern fd_result *__nis_finddirectory (directory_obj *, const_nis_name) __THROW;
 extern void __free_fdresult (fd_result *) __THROW;
-extern uint32_t __nis_hash (const void *__keyarg, size_t __len) __THROW;
 
 /* NIS+ cache locking */
 extern int __nis_lock_cache (void) __THROW;
diff --git a/nscd/Makefile b/nscd/Makefile
index 095f3e53d4..85e1c387d7 100644
--- a/nscd/Makefile
+++ b/nscd/Makefile
@@ -25,7 +25,7 @@ include ../Makeconfig
 ifneq ($(use-nscd),no)
 routines := nscd_getpw_r nscd_getgr_r nscd_gethst_r nscd_getai \
 	    nscd_initgroups nscd_getserv_r nscd_netgroup
-aux	:= nscd_helper nscd_hash
+aux	:= nscd_helper
 endif
 
 # To find xmalloc.c
@@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
 		getsrvbynm_r getsrvbypt_r servicescache \
 		dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
 		xmalloc xstrdup aicache initgrcache gai res_hconf \
-		netgroupcache nscd_hash
+		netgroupcache
 
 ifeq ($(build-nscd)$(have-thread-library),yesyes)
 
diff --git a/nscd/cache.c b/nscd/cache.c
index 4a17c3371b..72c73d31d3 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -29,10 +29,10 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/uio.h>
+#include <nss.h>
 
 #include "nscd.h"
 #include "dbg_log.h"
-#include "nscd_hash.h"
 
 
 /* Wrapper functions with error checking for standard functions.  */
@@ -74,7 +74,7 @@ struct datahead *
 cache_search (request_type type, const void *key, size_t len,
 	      struct database_dyn *table, uid_t owner)
 {
-  unsigned long int hash = __nscd_hash (key, len) % table->head->module;
+  unsigned long int hash = __nss_hash (key, len) % table->head->module;
 
   unsigned long int nsearched = 0;
   struct datahead *result = NULL;
@@ -153,7 +153,7 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
 	       first ? _(" (first)") : "");
     }
 
-  unsigned long int hash = __nscd_hash (key, len) % table->head->module;
+  unsigned long int hash = __nss_hash (key, len) % table->head->module;
   struct hashentry *newp;
 
   newp = mempool_alloc (table, sizeof (struct hashentry), 0);
diff --git a/nscd/nscd_hash.c b/nscd/nscd_hash.c
deleted file mode 100644
index 1572af616a..0000000000
--- a/nscd/nscd_hash.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2017 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
-   <http://www.gnu.org/licenses/>.  */
-
-#define __nis_hash __nscd_hash
-#include <nis/nis_hash.c>
diff --git a/nscd/nscd_hash.h b/nscd/nscd_hash.h
deleted file mode 100644
index e56d71015c..0000000000
--- a/nscd/nscd_hash.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (C) 2017 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
-   <http://www.gnu.org/licenses/>.  */
-
-#include <stdint.h>
-
-extern uint32_t __nscd_hash (const void *__keyarg, size_t __len)
-  attribute_hidden;
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index a42a4a7da5..ac04a2f572 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -36,10 +36,9 @@
 #include <sys/un.h>
 #include <not-cancel.h>
 #include <kernel-features.h>
+#include <nss.h>
 
 #include "nscd-client.h"
-#include "nscd_hash.h"
-
 
 /* Extra time we wait if the socket is still receiving data.  This
    value is in milliseconds.  Note that the other side is nscd on the
@@ -451,7 +450,7 @@ struct datahead *
 __nscd_cache_search (request_type type, const char *key, size_t keylen,
 		     const struct mapped_database *mapped, size_t datalen)
 {
-  unsigned long int hash = __nscd_hash (key, keylen) % mapped->head->module;
+  unsigned long int hash = __nss_hash (key, keylen) % mapped->head->module;
   size_t datasize = mapped->datasize;
 
   ref_t trail = mapped->head->array[hash];
diff --git a/nss/Makefile b/nss/Makefile
index 26952112c1..f9ecea56a0 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -28,7 +28,7 @@ headers			:= nss.h
 routines		= nsswitch getnssent getnssent_r digits_dots \
 			  valid_field valid_list_field rewrite_field \
 			  $(addsuffix -lookup,$(databases)) \
-			  compat-lookup
+			  compat-lookup nss_hash
 
 # These are the databases that go through nss dispatch.
 # Caution: if you add a database here, you must add its real name
diff --git a/nss/Versions b/nss/Versions
index 7694998f1d..db8c887720 100644
--- a/nss/Versions
+++ b/nss/Versions
@@ -15,6 +15,7 @@ libc {
 
     __nss_passwd_lookup2; __nss_group_lookup2; __nss_hosts_lookup2;
     __nss_services_lookup2; __nss_next2; __nss_lookup;
+    __nss_hash;
   }
 }
 
diff --git a/nss/nss_hash.c b/nss/nss_hash.c
new file mode 100644
index 0000000000..aff11a9ef0
--- /dev/null
+++ b/nss/nss_hash.c
@@ -0,0 +1,77 @@
+/* Copyright (c) 1997-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
+
+   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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <nss.h>
+
+/* This is from libc/db/hash/hash_func.c, hash3 is static there */
+/*
+ * This is INCREDIBLY ugly, but fast.  We break the string up into 8 byte
+ * units.  On the first time through the loop we get the "leftover bytes"
+ * (strlen % 8).  On every other iteration, we perform 8 HASHC's so we handle
+ * all 8 bytes.  Essentially, this saves us 7 cmp & branch instructions.  If
+ * this routine is heavily used enough, it's worth the ugly coding.
+ *
+ * OZ's original sdbm hash
+ */
+uint32_t
+__nss_hash (const void *keyarg, size_t len)
+{
+  const unsigned char *key;
+  size_t loop;
+  uint32_t h;
+
+#define HASHC   h = *key++ + 65599 * h
+
+  h = 0;
+  key = keyarg;
+  if (len > 0)
+    {
+      loop = (len + 8 - 1) >> 3;
+      switch (len & (8 - 1))
+	{
+	case 0:
+	  do {
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 7:
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 6:
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 5:
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 4:
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 3:
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 2:
+	    HASHC;
+	    /* FALLTHROUGH */
+	  case 1:
+	    HASHC;
+	  } while (--loop);
+	}
+    }
+  return h;
+}
+
+libc_hidden_def (__nss_hash)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]