View | Details | Raw Unified | Return to bug 14906 | Differences between
and this patch

Collapse All | Expand All

(-)a/ChangeLog (+22 lines)
Lines 1-5 Link Here
1
2015-02-17  Carlos O'Donell  <carlos@redhat.com>
1
2015-02-17  Carlos O'Donell  <carlos@redhat.com>
2
2
3
	[BZ #14906]
4
	* nscd/cache.c (prune_cache): Use TRACED_FILE.
5
	* nscd/connections.c [HAVE_INOTIFY] (install_watches): New function.
6
	(register_traced_file): Call install_watches. Don't set unused mtime.
7
	(invalidate_cache): Call install_watches.
8
	(inotify_check_files): Don't inline. Handle watching parent
9
	directories and configuration file movement in and out.
10
	(handle_inotify_events): New function.
11
	(main_loop_poll): Call handle_inotify_events.
12
	(main_loop_epoll): Likewise.
13
	* nscd/nscd.h: Define TRACED_FILE, TRACED_DIR, and PATH_MAX.
14
	(struct traced_file): Remove unused mtime. Use array of inotify fds.
15
	Add parent directory, and basename.
16
	(init_traced_file): New inline function.
17
	(define_traced_file): New macro.
18
	* nss/nss_db/db-init.c: Use define_traced_file.
19
	(_nss_db_init): Use init_traced_file.
20
	* nss/nss_files/files-init.c: Use define_traced_file.
21
	(_nss_files_init): Use init_traced_file.
22
23
2015-02-17  Carlos O'Donell  <carlos@redhat.com>
24
3
	* dl-reloc.c: Inlucde libc-internal.h.
25
	* dl-reloc.c: Inlucde libc-internal.h.
4
	(_dl_try_allocate_static_tls): Call ALIGN_UP.
26
	(_dl_try_allocate_static_tls): Call ALIGN_UP.
5
	(_dl_relocate_object): Call ALIGN_UP, ALIGN_DOWN, and PTR_ALIGN_DOWN.
27
	(_dl_relocate_object): Call ALIGN_UP, ALIGN_DOWN, and PTR_ALIGN_DOWN.
(-)a/nscd/cache.c (-1 / +1 lines)
Lines 272-278 prune_cache (struct database_dyn *table, time_t now, int fd) Link Here
272
      while (runp != NULL)
272
      while (runp != NULL)
273
	{
273
	{
274
#ifdef HAVE_INOTIFY
274
#ifdef HAVE_INOTIFY
275
	  if (runp->inotify_descr == -1)
275
	  if (runp->inotify_descr[TRACED_FILE] == -1)
276
#endif
276
#endif
277
	    {
277
	    {
278
	      struct stat64 st;
278
	      struct stat64 st;
(-)a/nscd/connections.c (-91 / +228 lines)
Lines 957-962 cannot change socket to nonblocking mode: %s"), Link Here
957
    finish_drop_privileges ();
957
    finish_drop_privileges ();
958
}
958
}
959
959
960
#ifdef HAVE_INOTIFY
961
#define TRACED_FILE_MASK (IN_DELETE_SELF | IN_CLOSE_WRITE | IN_MOVE_SELF)
962
#define TRACED_DIR_MASK (IN_DELETE_SELF | IN_CREATE | IN_MOVED_TO | IN_MOVE_SELF)
963
void
964
install_watches (struct traced_file *finfo)
965
{
966
  /* If we have inotify support use it exclusively with no fallback
967
     to stat.  This is a design decision to make the implementation
968
     sipmler.  Either we use fstat for the file name or we use inotify
969
     for both the file and parent directory.  */
970
  if (finfo->inotify_descr[TRACED_FILE] < 0)
971
    finfo->inotify_descr[TRACED_FILE] = inotify_add_watch (inotify_fd,
972
							   finfo->fname,
973
							   TRACED_FILE_MASK);
974
  if (finfo->inotify_descr[TRACED_FILE] < 0)
975
    {
976
      dbg_log (_("failed to add watch to file `%s': %s"),
977
		 finfo->fname, strerror (errno));
978
      return;
979
    }
980
  dbg_log (_("watching registered file `%s` (%d)"),
981
	   finfo->fname, finfo->inotify_descr[TRACED_FILE]);
982
  /* Additionally listen for IN_CREATE events in the files parent
983
     directory.  We do this because the file to be watched might be
984
     deleted and then added back again.  When it is added back again
985
     we must re-add the watch.  We must also cover IN_MOVED_TO to
986
     detect a file being moved into the directory.  */
987
  if (finfo->inotify_descr[TRACED_DIR] < 0)
988
    finfo->inotify_descr[TRACED_DIR] = inotify_add_watch (inotify_fd,
989
							  finfo->dname,
990
							  TRACED_DIR_MASK);
991
  if (finfo->inotify_descr[TRACED_DIR] < 0)
992
    {
993
      dbg_log (_("failed to add watch to directory `%s': %s"),
994
		 finfo->fname, strerror (errno));
995
      return;
996
    }
997
  dbg_log (_("watching registered directory `%s` (%d)"),
998
	   finfo->dname, finfo->inotify_descr[TRACED_DIR]);
999
}
1000
#endif
960
1001
961
/* Register the file in FINFO as a traced file for the database DBS[DBIX].
1002
/* Register the file in FINFO as a traced file for the database DBS[DBIX].
962
1003
Lines 985-1010 register_traced_file (size_t dbidx, struct traced_file *finfo) Link Here
985
	     finfo->fname, dbnames[dbidx]);
1026
	     finfo->fname, dbnames[dbidx]);
986
1027
987
#ifdef HAVE_INOTIFY
1028
#ifdef HAVE_INOTIFY
988
  if (inotify_fd < 0
1029
  install_watches (finfo);
989
      || (finfo->inotify_descr = inotify_add_watch (inotify_fd, finfo->fname,
990
						    IN_DELETE_SELF
991
						    | IN_MODIFY)) < 0)
992
#endif
1030
#endif
993
    {
994
      /* We need the modification date of the file.  */
995
      struct stat64 st;
996
997
      if (stat64 (finfo->fname, &st) < 0)
998
	{
999
	  /* We cannot stat() the file, disable file checking.  */
1000
	  dbg_log (_("cannot stat() file `%s': %s"),
1001
		   finfo->fname, strerror (errno));
1002
	  return;
1003
	}
1004
1005
      finfo->inotify_descr = -1;
1006
      finfo->mtime = st.st_mtime;
1007
    }
1008
1031
1009
  /* Queue up the file name.  */
1032
  /* Queue up the file name.  */
1010
  finfo->next = dbs[dbidx].traced_files;
1033
  finfo->next = dbs[dbidx].traced_files;
Lines 1033-1045 invalidate_cache (char *key, int fd) Link Here
1033
	  {
1056
	  {
1034
	    struct traced_file *runp = dbs[hstdb].traced_files;
1057
	    struct traced_file *runp = dbs[hstdb].traced_files;
1035
	    while (runp != NULL)
1058
	    while (runp != NULL)
1036
	      if (runp->call_res_init)
1059
	      {
1037
		{
1060
#ifdef HAVE_INOTIFY
1038
		  res_init ();
1061
		/* During an invalidation we try to reload the traced
1039
		  break;
1062
		   file watches.  This allows the user to re-sync if
1040
		}
1063
		   inotify events were lost.  */
1041
	      else
1064
		install_watches (runp);
1065
#endif
1066
		if (runp->call_res_init)
1067
		  {
1068
		    res_init ();
1069
		    break;
1070
		  }
1042
		runp = runp->next;
1071
		runp = runp->next;
1072
	      }
1043
	  }
1073
	  }
1044
	break;
1074
	break;
1045
    }
1075
    }
Lines 1884-1890 union __inev Link Here
1884
   registered with a database then mark that database as requiring its cache
1914
   registered with a database then mark that database as requiring its cache
1885
   to be cleared. We indicate the cache needs clearing by setting
1915
   to be cleared. We indicate the cache needs clearing by setting
1886
   TO_CLEAR[DBCNT] to true for the matching database.  */
1916
   TO_CLEAR[DBCNT] to true for the matching database.  */
1887
static inline void
1917
static void
1888
inotify_check_files (bool *to_clear, union __inev *inev)
1918
inotify_check_files (bool *to_clear, union __inev *inev)
1889
{
1919
{
1890
  /* Check which of the files changed.  */
1920
  /* Check which of the files changed.  */
Lines 1894-1909 inotify_check_files (bool *to_clear, union __inev *inev) Link Here
1894
1924
1895
      while (finfo != NULL)
1925
      while (finfo != NULL)
1896
	{
1926
	{
1897
	  /* Inotify event watch descriptor matches.  */
1927
	  /* The configuration file was moved or deleted.
1898
	  if (finfo->inotify_descr == inev->i.wd)
1928
	     We stop watching it at that point, and reinitialize.  */
1929
	  if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd
1930
	      && ((inev->i.mask & IN_MOVE_SELF)
1931
		  || (inev->i.mask & IN_DELETE_SELF)
1932
		  || (inev->i.mask & IN_IGNORED)))
1933
	    {
1934
	      int ret;
1935
	      bool moved = (inev->i.mask & IN_MOVE_SELF) != 0;
1936
	      dbg_log (_("registered file `%s` was %s, removing watch"),
1937
		       finfo->fname, moved ? "moved" : "deleted");
1938
	      /* File was moved out, remove the watch.  Watches are
1939
		 automatically removed when the file is deleted.  */
1940
	      if (moved)
1941
		{
1942
		  ret = inotify_rm_watch (inotify_fd, inev->i.wd);
1943
		  if (ret < 0)
1944
		    dbg_log (_("failed to remove file watch `%s`: %s"),
1945
			     finfo->fname, strerror (errno));
1946
		}
1947
	      finfo->inotify_descr[TRACED_FILE] = -1;
1948
	      to_clear[dbcnt] = true;
1949
	      if (finfo->call_res_init)
1950
	        res_init ();
1951
	      return;
1952
	    }
1953
	  /* The configuration file was open for writing and has just closed.
1954
	     We reset the cache and reinitialize.  */
1955
	  if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd)
1899
	    {
1956
	    {
1900
	      /* Mark cache as needing to be cleared and reinitialize.  */
1957
	      /* Mark cache as needing to be cleared and reinitialize.  */
1958
	      dbg_log (_("registered file `%s` was written to"), finfo->fname);
1901
	      to_clear[dbcnt] = true;
1959
	      to_clear[dbcnt] = true;
1902
	      if (finfo->call_res_init)
1960
	      if (finfo->call_res_init)
1903
	        res_init ();
1961
	        res_init ();
1904
	      return;
1962
	      return;
1905
	    }
1963
	    }
1964
	  /* The parent directory was moved or deleted.  There is no coming
1965
	     back from this.  We do not track the parent of the parent, and
1966
	     once this happens we trigger one last invalidation.  You must
1967
	     restart nscd to track subsequent changes.   We track this to
1968
	     do one last robust re-initialization and then we're done.  */
1969
	  if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd
1970
	      && ((inev->i.mask & IN_DELETE_SELF)
1971
		  || (inev->i.mask & IN_MOVE_SELF)
1972
		  || (inev->i.mask & IN_IGNORED)))
1973
	    {
1974
	      bool moved = (inev->i.mask & IN_MOVE_SELF) != 0;
1975
	      /* The directory watch may have already been removed
1976
		 but we don't know so we just remove it again and
1977
		 ignore the error.  Then we remove the file watch.
1978
		 Note: watches are automatically removed for deleted
1979
		 files.  */
1980
	      if (moved)
1981
		inotify_rm_watch (inotify_fd, inev->i.wd);
1982
	      if (finfo->inotify_descr[TRACED_FILE] != -1)
1983
		{
1984
		  dbg_log (_("registered parent directory `%s` was %s, removing watch on `%s`"),
1985
			   finfo->dname, moved ? "moved" : "deleted", finfo->fname);
1986
		  if (inotify_rm_watch (inotify_fd, finfo->inotify_descr[TRACED_FILE]) < 0)
1987
		    dbg_log (_("failed to remove file watch `%s`: %s"),
1988
			     finfo->dname, strerror (errno));
1989
		}
1990
	      finfo->inotify_descr[TRACED_FILE] = -1;
1991
	      finfo->inotify_descr[TRACED_DIR] = -1;
1992
	      to_clear[dbcnt] = true;
1993
	      if (finfo->call_res_init)
1994
	        res_init ();
1995
	      /* Continue to the next entry since this might be the
1996
		 parent directory for multiple registered files and
1997
		 we want to remove watches for all registered files.  */
1998
	      continue;
1999
	    }
2000
	  /* The parent directory had a create or moved to event.  */
2001
	  if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd
2002
	      && strcmp (inev->i.name, finfo->sfname) == 0)
2003
	    {
2004
	      /* We detected a directory change.  We look for the creation
2005
		 of the file we are tracking or the move of the same file
2006
		 into the directory.  */
2007
	      int ret;
2008
	      dbg_log (_("registered file `%s` was %s, adding watch"),
2009
		       finfo->fname,
2010
		       inev->i.mask & IN_CREATE ? "created" : "moved into place");
2011
	      /* File was moved in or created.  Regenerate the watch.  */
2012
	      if (finfo->inotify_descr[TRACED_FILE] != -1)
2013
		{
2014
		  ret = inotify_rm_watch (inotify_fd,
2015
					  finfo->inotify_descr[TRACED_FILE]);
2016
		  if (ret < 0)
2017
		    dbg_log (_("failed to remove file watch `%s`: %s"),
2018
			     finfo->fname, strerror (errno));
2019
		}
2020
2021
	      ret = inotify_add_watch (inotify_fd,
2022
				       finfo->fname,
2023
				       TRACED_FILE_MASK);
2024
	      if (ret < 0)
2025
		dbg_log (_("failed to add file watch `%s`: %s"),
2026
			 finfo->fname, strerror (errno));
2027
2028
	      finfo->inotify_descr[TRACED_FILE] = ret;
1906
2029
2030
	      /* The file is new or moved so mark cache as needing to
2031
		 be cleared and reinitialize.  */
2032
	      to_clear[dbcnt] = true;
2033
	      if (finfo->call_res_init)
2034
		res_init ();
2035
2036
	      /* Done re-adding the watch.  Don't return, we may still
2037
		 have other files in this same directory, same watch
2038
		 descriptor, and need to process them.  */
2039
	    }
1907
	  finfo = finfo->next;
2040
	  finfo = finfo->next;
1908
        }
2041
        }
1909
    }
2042
    }
Lines 1925-1930 clear_db_cache (bool *to_clear) Link Here
1925
      }
2058
      }
1926
}
2059
}
1927
2060
2061
int
2062
handle_inotify_events (void)
2063
{
2064
  bool to_clear[lastdb] = { false, };
2065
  union __inev inev;
2066
2067
  /* Read all inotify events for files registered via
2068
     register_traced_file().  */
2069
  while (1)
2070
    {
2071
      /* Potentially read multiple events into buf.  */
2072
      ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd,
2073
					     &inev.buf,
2074
					     sizeof (inev)));
2075
      if (nb < (ssize_t) sizeof (struct inotify_event))
2076
	{
2077
	  /* Not even 1 event.  */
2078
	  if (__glibc_unlikely (nb == -1 && errno != EAGAIN))
2079
	    return -1;
2080
	  /* Done reading events that are ready.  */
2081
	  break;
2082
	}
2083
      /* Process all events.  The normal inotify interface delivers
2084
	 complete events on a read and never a partial event.  */
2085
      char *eptr = &inev.buf[0];
2086
      ssize_t count;
2087
      while (1)
2088
	{
2089
	  /* Check which of the files changed.  */
2090
	  inotify_check_files (to_clear, &inev);
2091
	  count = sizeof (struct inotify_event) + inev.i.len;
2092
	  eptr += count;
2093
	  nb -= count;
2094
	  if (nb >= (ssize_t) sizeof (struct inotify_event))
2095
	    memcpy (&inev, eptr, nb);
2096
	  else
2097
	    break;
2098
	}
2099
      continue;
2100
    }
2101
  /* Actually perform the cache clearing.  */
2102
  clear_db_cache (to_clear);
2103
  return 0;
2104
}
2105
1928
#endif
2106
#endif
1929
2107
1930
static void
2108
static void
Lines 2031-2072 main_loop_poll (void) Link Here
2031
	    {
2209
	    {
2032
	      if (conns[1].revents != 0)
2210
	      if (conns[1].revents != 0)
2033
		{
2211
		{
2034
		  bool to_clear[lastdb] = { false, };
2212
		  int ret;
2035
		  union __inev inev;
2213
		  ret = handle_inotify_events ();
2036
2214
		  if (ret == -1)
2037
		  /* Read all inotify events for files registered via
2038
		     register_traced_file().  */
2039
		  while (1)
2040
		    {
2215
		    {
2041
		      ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
2216
		      /* Something went wrong when reading the inotify
2042
							     sizeof (inev)));
2217
			 data.  Better disable inotify.  */
2043
		      if (nb < (ssize_t) sizeof (struct inotify_event))
2218
		      dbg_log (_("disabled inotify after read error %d"), errno);
2044
			{
2219
		      conns[1].fd = -1;
2045
			  if (__builtin_expect (nb == -1 && errno != EAGAIN,
2220
		      firstfree = 1;
2046
						0))
2221
		      if (nused == 2)
2047
			    {
2222
			nused = 1;
2048
			      /* Something went wrong when reading the inotify
2223
		      close (inotify_fd);
2049
				 data.  Better disable inotify.  */
2224
		      inotify_fd = -1;
2050
			      dbg_log (_("\
2051
disabled inotify after read error %d"),
2052
				       errno);
2053
			      conns[1].fd = -1;
2054
			      firstfree = 1;
2055
			      if (nused == 2)
2056
				nused = 1;
2057
			      close (inotify_fd);
2058
			      inotify_fd = -1;
2059
			    }
2060
			  break;
2061
			}
2062
2063
		      /* Check which of the files changed.  */
2064
		      inotify_check_files (to_clear, &inev);
2065
		    }
2225
		    }
2066
2067
		  /* Actually perform the cache clearing.  */
2068
		  clear_db_cache (to_clear);
2069
2070
		  --n;
2226
		  --n;
2071
		}
2227
		}
2072
2228
Lines 2234-2270 main_loop_epoll (int efd) Link Here
2234
# ifdef HAVE_INOTIFY
2390
# ifdef HAVE_INOTIFY
2235
	else if (revs[cnt].data.fd == inotify_fd)
2391
	else if (revs[cnt].data.fd == inotify_fd)
2236
	  {
2392
	  {
2237
	    bool to_clear[lastdb] = { false, };
2393
	    int ret;
2238
	    union __inev inev;
2394
	    ret = handle_inotify_events ();
2239
2395
	    if (ret == -1)
2240
	    /* Read all inotify events for files registered via
2241
	       register_traced_file().  */
2242
	    while (1)
2243
	      {
2396
	      {
2244
		ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
2397
		/* Something went wrong when reading the inotify
2245
						 sizeof (inev)));
2398
		   data.  Better disable inotify.  */
2246
		if (nb < (ssize_t) sizeof (struct inotify_event))
2399
		dbg_log (_("disabled inotify after read error %d"), errno);
2247
		  {
2400
		(void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd, NULL);
2248
		    if (__glibc_unlikely (nb == -1 && errno != EAGAIN))
2401
		close (inotify_fd);
2249
		      {
2402
		inotify_fd = -1;
2250
			/* Something went wrong when reading the inotify
2403
		break;
2251
			   data.  Better disable inotify.  */
2252
			dbg_log (_("disabled inotify after read error %d"),
2253
				 errno);
2254
			(void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd,
2255
					  NULL);
2256
			close (inotify_fd);
2257
			inotify_fd = -1;
2258
		      }
2259
		    break;
2260
		  }
2261
2262
		/* Check which of the files changed.  */
2263
		inotify_check_files(to_clear, &inev);
2264
	      }
2404
	      }
2265
2266
	    /* Actually perform the cache clearing.  */
2267
	    clear_db_cache (to_clear);
2268
	  }
2405
	  }
2269
# endif
2406
# endif
2270
# ifdef HAVE_NETLINK
2407
# ifdef HAVE_NETLINK
(-)a/nscd/nscd.h (-4 / +51 lines)
Lines 61-77 typedef enum Link Here
61
   80% of the thread stack size.  */
61
   80% of the thread stack size.  */
62
#define MAX_STACK_USE ((8 * NSCD_THREAD_STACKSIZE) / 10)
62
#define MAX_STACK_USE ((8 * NSCD_THREAD_STACKSIZE) / 10)
63
63
64
64
/* Records the file registered per database that when changed
65
/* Registered filename used to fill database.  */
65
   or modified requires invalidating the database.  */
66
struct traced_file
66
struct traced_file
67
{
67
{
68
  time_t mtime;
68
  /* Support multiple registered files per database.  */
69
  struct traced_file *next;
69
  struct traced_file *next;
70
  int call_res_init;
70
  int call_res_init;
71
  int inotify_descr;
71
  /* Requires Inotify support to do anything useful.  */
72
#define TRACED_FILE	0
73
#define TRACED_DIR	1
74
  int inotify_descr[2];
75
# ifndef PATH_MAX
76
#  define PATH_MAX 1024
77
# endif
78
  /* The parent directory is used to scan for creation/deletion.  */
79
  char dname[PATH_MAX];
80
  /* Just the name of the file with no directory component.  */
81
  char *sfname;
82
  /* The full-path name of the registered file.  */
72
  char fname[];
83
  char fname[];
73
};
84
};
74
85
86
/* Initialize a `struct traced_file`.  As input we need the name
87
   of the file, and if invalidation requires calling res_init.
88
   If CRINIT is 1 then res_init will be called after invalidation
89
   or if the traced file is changed in any way, otherwise it will
90
   not.  */
91
static inline void
92
init_traced_file(struct traced_file *file, const char *fname, int crinit)
93
{
94
   char *dname;
95
   file->inotify_descr[TRACED_FILE] = -1;
96
   file->inotify_descr[TRACED_DIR] = -1;
97
   strcpy (file->fname, fname);
98
   /* Compute the parent directory name and store a copy.  The copy makes
99
      it much faster to add/remove watches while nscd is running instead
100
      of computing this over and over again in a temp buffer.  */
101
   file->dname[0] = '\0';
102
   dname = strrchr (fname, '/');
103
   if (dname != NULL)
104
     {
105
       size_t len = (size_t)(dname - fname);
106
       if (len > sizeof (file->dname))
107
	 abort ();
108
       strncpy (file->dname, file->fname, len);
109
       file->dname[len] = '\0';
110
     }
111
   /* The basename is the name just after the last forward slash.  */
112
   file->sfname = &dname[1];
113
   file->call_res_init = crinit;
114
}
115
116
#define define_traced_file(id, filename) 			\
117
static union							\
118
{								\
119
  struct traced_file file;					\
120
  char buf[sizeof (struct traced_file) + sizeof (filename)];	\
121
} id##_traced_file;
75
122
76
/* Structure describing dynamic part of one database.  */
123
/* Structure describing dynamic part of one database.  */
77
struct database_dyn
124
struct database_dyn
(-)a/nss/nss_db/db-init.c (-19 / +9 lines)
Lines 22-56 Link Here
22
#include <nscd/nscd.h>
22
#include <nscd/nscd.h>
23
#include <string.h>
23
#include <string.h>
24
24
25
static union
25
#define PWD_FILENAME (_PATH_VARDB "passwd.db")
26
{
26
define_traced_file (pwd, PWD_FILENAME);
27
  struct traced_file file;
28
  char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "passwd.db")];
29
} pwd_traced_file;
30
31
static union
32
{
33
  struct traced_file file;
34
  char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "group.db")];
35
} grp_traced_file;
36
27
37
static union
28
#define GRP_FILENAME (_PATH_VARDB "group.db")
38
{
29
define_traced_file (grp, GRP_FILENAME);
39
  struct traced_file file;
40
  char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "services.db")];
41
} serv_traced_file;
42
30
31
#define SERV_FILENAME (_PATH_VARDB "services.db")
32
define_traced_file (serv, SERV_FILENAME);
43
33
44
void
34
void
45
_nss_db_init (void (*cb) (size_t, struct traced_file *))
35
_nss_db_init (void (*cb) (size_t, struct traced_file *))
46
{
36
{
47
  strcpy (pwd_traced_file.file.fname,_PATH_VARDB  "passwd.db");
37
  init_traced_file (&pwd_traced_file.file, PWD_FILENAME, 0);
48
  cb (pwddb, &pwd_traced_file.file);
38
  cb (pwddb, &pwd_traced_file.file);
49
39
50
  strcpy (grp_traced_file.file.fname, _PATH_VARDB "group.db");
40
  init_traced_file (&grp_traced_file.file, GRP_FILENAME, 0);
51
  cb (grpdb, &grp_traced_file.file);
41
  cb (grpdb, &grp_traced_file.file);
52
42
53
  strcpy (serv_traced_file.file.fname, _PATH_VARDB "services.db");
43
  init_traced_file (&serv_traced_file.file, SERV_FILENAME, 0);
54
  cb (servdb, &serv_traced_file.file);
44
  cb (servdb, &serv_traced_file.file);
55
}
45
}
56
46
(-)a/nss/nss_files/files-init.c (-25 / +21 lines)
Lines 21-67 Link Here
21
#include <string.h>
21
#include <string.h>
22
#include <nscd/nscd.h>
22
#include <nscd/nscd.h>
23
23
24
#define PWD_FILENAME "/etc/passwd"
25
define_traced_file (pwd, PWD_FILENAME);
24
26
25
#define TF(id, filename, ...)					\
27
#define GRP_FILENAME "/etc/group"
26
static union							\
28
define_traced_file (grp, GRP_FILENAME);
27
{								\
28
  struct traced_file file;					\
29
  char buf[sizeof (struct traced_file) + sizeof (filename)];	\
30
} id##_traced_file =						\
31
  {								\
32
    .file =							\
33
    {								\
34
      __VA_ARGS__						\
35
    }								\
36
  }
37
38
TF (pwd, "/etc/passwd");
39
TF (grp, "/etc/group");
40
TF (hst, "/etc/hosts");
41
TF (resolv, "/etc/resolv.conf", .call_res_init = 1);
42
TF (serv, "/etc/services");
43
TF (netgr, "/etc/netgroup");
44
29
30
#define HST_FILENAME "/etc/hosts"
31
define_traced_file (hst, HST_FILENAME);
32
33
#define RESOLV_FILENAME "/etc/resolv.conf"
34
define_traced_file (resolv, RESOLV_FILENAME);
35
36
#define SERV_FILENAME "/etc/services"
37
define_traced_file (serv, SERV_FILENAME);
38
39
#define NETGR_FILENAME "/etc/netgroup"
40
define_traced_file (netgr, NETGR_FILENAME);
45
41
46
void
42
void
47
_nss_files_init (void (*cb) (size_t, struct traced_file *))
43
_nss_files_init (void (*cb) (size_t, struct traced_file *))
48
{
44
{
49
  strcpy (pwd_traced_file.file.fname, "/etc/passwd");
45
  init_traced_file (&pwd_traced_file.file, PWD_FILENAME, 0);
50
  cb (pwddb, &pwd_traced_file.file);
46
  cb (pwddb, &pwd_traced_file.file);
51
47
52
  strcpy (grp_traced_file.file.fname, "/etc/group");
48
  init_traced_file (&grp_traced_file.file, GRP_FILENAME, 0);
53
  cb (grpdb, &grp_traced_file.file);
49
  cb (grpdb, &grp_traced_file.file);
54
50
55
  strcpy (hst_traced_file.file.fname, "/etc/hosts");
51
  init_traced_file (&hst_traced_file.file, HST_FILENAME, 0);
56
  cb (hstdb, &hst_traced_file.file);
52
  cb (hstdb, &hst_traced_file.file);
57
53
58
  strcpy (resolv_traced_file.file.fname, "/etc/resolv.conf");
54
  init_traced_file (&resolv_traced_file.file, RESOLV_FILENAME, 1);
59
  cb (hstdb, &resolv_traced_file.file);
55
  cb (hstdb, &resolv_traced_file.file);
60
56
61
  strcpy (serv_traced_file.file.fname, "/etc/services");
57
  init_traced_file (&serv_traced_file.file, SERV_FILENAME, 0);
62
  cb (servdb, &serv_traced_file.file);
58
  cb (servdb, &serv_traced_file.file);
63
59
64
  strcpy (netgr_traced_file.file.fname, "/etc/netgroup");
60
  init_traced_file (&netgr_traced_file.file, NETGR_FILENAME, 0);
65
  cb (netgrdb, &netgr_traced_file.file);
61
  cb (netgrdb, &netgr_traced_file.file);
66
}
62
}
67
63

Return to bug 14906