1 /* Copyright (C) 1998-2007, 2008, 2009 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 #include <sys/socket.h>
35 #include <not-cancel.h>
36 #include <nis/rpcsvc/nis.h>
37 #include <kernel-features.h>
39 #include "nscd-client.h"
42 /* Extra time we wait if the socket is still receiving data. This
43 value is in milliseconds. Note that the other side is nscd on the
44 local machine and it is already transmitting data. So the wait
45 time need not be long. */
46 #define EXTRA_RECEIVE_TIME 200
50 wait_on_socket (int sock
, long int usectmo
)
54 fds
[0].events
= POLLIN
| POLLERR
| POLLHUP
;
55 int n
= __poll (fds
, 1, usectmo
);
56 if (n
== -1 && __builtin_expect (errno
== EINTR
, 0))
58 /* Handle the case where the poll() call is interrupted by a
59 signal. We cannot just use TEMP_FAILURE_RETRY since it might
60 lead to infinite loops. */
62 (void) __gettimeofday (&now
, NULL
);
63 long int end
= now
.tv_sec
* 1000 + usectmo
+ (now
.tv_usec
+ 500) / 1000;
64 long int timeout
= usectmo
;
67 n
= __poll (fds
, 1, timeout
);
68 if (n
!= -1 || errno
!= EINTR
)
71 /* Recompute the timeout time. */
72 (void) __gettimeofday (&now
, NULL
);
73 timeout
= end
- (now
.tv_sec
* 1000 + (now
.tv_usec
+ 500) / 1000);
82 __readall (int fd
, void *buf
, size_t len
)
89 ret
= TEMP_FAILURE_RETRY (__read (fd
, buf
, n
));
92 if (__builtin_expect (ret
< 0 && errno
== EAGAIN
, 0)
93 /* The socket is still receiving data. Wait a bit more. */
94 && wait_on_socket (fd
, EXTRA_RECEIVE_TIME
) > 0)
99 buf
= (char *) buf
+ ret
;
103 return ret
< 0 ? ret
: len
- n
;
108 __readvall (int fd
, const struct iovec
*iov
, int iovcnt
)
110 ssize_t ret
= TEMP_FAILURE_RETRY (__readv (fd
, iov
, iovcnt
));
113 if (__builtin_expect (ret
== 0 || errno
!= EAGAIN
, 1))
114 /* A genuine error or no data to read. */
117 /* The data has not all yet been received. Do as if we have not
118 read anything yet. */
123 for (int i
= 0; i
< iovcnt
; ++i
)
124 total
+= iov
[i
].iov_len
;
128 struct iovec iov_buf
[iovcnt
];
131 struct iovec
*iovp
= memcpy (iov_buf
, iov
, iovcnt
* sizeof (*iov
));
134 while (iovp
->iov_len
<= r
)
140 iovp
->iov_base
= (char *) iovp
->iov_base
+ r
;
143 r
= TEMP_FAILURE_RETRY (__readv (fd
, iovp
, iovcnt
));
146 if (__builtin_expect (r
< 0 && errno
== EAGAIN
, 0)
147 /* The socket is still receiving data. Wait a bit more. */
148 && wait_on_socket (fd
, EXTRA_RECEIVE_TIME
) > 0)
164 open_socket (request_type type
, const char *key
, size_t keylen
)
169 # ifndef __ASSUME_SOCK_CLOEXEC
170 if (__have_sock_cloexec
>= 0)
173 sock
= __socket (PF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
174 # ifndef __ASSUME_SOCK_CLOEXEC
175 if (__have_sock_cloexec
== 0)
176 __have_sock_cloexec
= sock
!= -1 || errno
!= EINVAL
? 1 : -1;
180 #ifndef __ASSUME_SOCK_CLOEXEC
182 if (__have_sock_cloexec
< 0)
184 sock
= __socket (PF_UNIX
, SOCK_STREAM
, 0);
194 size_t real_sizeof_reqdata
= sizeof (request_header
) + keylen
;
196 #ifndef __ASSUME_SOCK_CLOEXEC
197 # ifdef SOCK_NONBLOCK
198 if (__have_sock_cloexec
< 0)
200 /* Make socket non-blocking. */
201 __fcntl (sock
, F_SETFL
, O_RDWR
| O_NONBLOCK
);
204 struct sockaddr_un sun
;
205 sun
.sun_family
= AF_UNIX
;
206 strcpy (sun
.sun_path
, _PATH_NSCDSOCKET
);
207 if (__connect (sock
, (struct sockaddr
*) &sun
, sizeof (sun
)) < 0
208 && errno
!= EINPROGRESS
)
211 reqdata
.req
.version
= NSCD_VERSION
;
212 reqdata
.req
.type
= type
;
213 reqdata
.req
.key_len
= keylen
;
215 memcpy (reqdata
.key
, key
, keylen
);
217 bool first_try
= true;
218 struct timeval tvend
;
219 /* Fake initializing tvend. */
220 asm ("" : "=m" (tvend
));
224 # define MSG_NOSIGNAL 0
226 ssize_t wres
= TEMP_FAILURE_RETRY (__send (sock
, &reqdata
,
229 if (__builtin_expect (wres
== (ssize_t
) real_sizeof_reqdata
, 1))
230 /* We managed to send the request. */
233 if (wres
!= -1 || errno
!= EAGAIN
)
234 /* Something is really wrong, no chance to continue. */
237 /* The daemon is busy wait for it. */
240 (void) __gettimeofday (&now
, NULL
);
243 tvend
.tv_usec
= now
.tv_usec
;
244 tvend
.tv_sec
= now
.tv_sec
+ 5;
249 to
= ((tvend
.tv_sec
- now
.tv_sec
) * 1000
250 + (tvend
.tv_usec
- now
.tv_usec
) / 1000);
252 struct pollfd fds
[1];
254 fds
[0].events
= POLLOUT
| POLLERR
| POLLHUP
;
255 if (__poll (fds
, 1, to
) <= 0)
256 /* The connection timed out or broke down. */
259 /* We try to write again. */
263 close_not_cancel_no_status (sock
);
270 __nscd_unmap (struct mapped_database
*mapped
)
272 assert (mapped
->counter
== 0);
273 __munmap ((void *) mapped
->head
, mapped
->mapsize
);
278 /* Try to get a file descriptor for the shared meory segment
279 containing the database. */
280 static struct mapped_database
*
281 get_mapping (request_type type
, const char *key
,
282 struct mapped_database
**mappedp
)
284 struct mapped_database
*result
= NO_MAPPING
;
286 const size_t keylen
= strlen (key
) + 1;
287 int saved_errno
= errno
;
290 char resdata
[keylen
];
292 /* Open a socket and send the request. */
293 int sock
= open_socket (type
, key
, keylen
);
297 /* Room for the data sent along with the file descriptor. We expect
298 the key name back. */
301 iov
[0].iov_base
= resdata
;
302 iov
[0].iov_len
= keylen
;
303 iov
[1].iov_base
= &mapsize
;
304 iov
[1].iov_len
= sizeof (mapsize
);
309 char bytes
[CMSG_SPACE (sizeof (int))];
311 struct msghdr msg
= { .msg_iov
= iov
, .msg_iovlen
= 2,
312 .msg_control
= buf
.bytes
,
313 .msg_controllen
= sizeof (buf
) };
314 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR (&msg
);
316 cmsg
->cmsg_level
= SOL_SOCKET
;
317 cmsg
->cmsg_type
= SCM_RIGHTS
;
318 cmsg
->cmsg_len
= CMSG_LEN (sizeof (int));
320 /* This access is well-aligned since BUF is correctly aligned for an
321 int and CMSG_DATA preserves this alignment. */
322 memset (CMSG_DATA (cmsg
), '\xff', sizeof (int));
324 msg
.msg_controllen
= cmsg
->cmsg_len
;
326 if (wait_on_socket (sock
, 5 * 1000) <= 0)
329 # ifndef MSG_CMSG_CLOEXEC
330 # define MSG_CMSG_CLOEXEC 0
332 ssize_t n
= TEMP_FAILURE_RETRY (__recvmsg (sock
, &msg
, MSG_CMSG_CLOEXEC
));
334 if (__builtin_expect (CMSG_FIRSTHDR (&msg
) == NULL
335 || (CMSG_FIRSTHDR (&msg
)->cmsg_len
336 != CMSG_LEN (sizeof (int))), 0))
339 int *ip
= (void *) CMSG_DATA (cmsg
);
342 if (__builtin_expect (n
!= keylen
&& n
!= keylen
+ sizeof (mapsize
), 0))
345 if (__builtin_expect (strcmp (resdata
, key
) != 0, 0))
348 if (__builtin_expect (n
== keylen
, 0))
351 if (__builtin_expect (fstat64 (mapfd
, &st
) != 0, 0)
352 || __builtin_expect (st
.st_size
< sizeof (struct database_pers_head
),
356 mapsize
= st
.st_size
;
359 /* The file is large enough, map it now. */
360 void *mapping
= __mmap (NULL
, mapsize
, PROT_READ
, MAP_SHARED
, mapfd
, 0);
361 if (__builtin_expect (mapping
!= MAP_FAILED
, 1))
363 /* Check whether the database is correct and up-to-date. */
364 struct database_pers_head
*head
= mapping
;
366 if (__builtin_expect (head
->version
!= DB_VERSION
, 0)
367 || __builtin_expect (head
->header_size
!= sizeof (*head
), 0)
368 /* Catch some misconfiguration. The server should catch
369 them now but some older versions did not. */
370 || __builtin_expect (head
->module
== 0, 0)
371 /* This really should not happen but who knows, maybe the update
373 || __builtin_expect (! head
->nscd_certainly_running
374 && (head
->timestamp
+ MAPPING_TIMEOUT
378 __munmap (mapping
, mapsize
);
382 size_t size
= (sizeof (*head
) + roundup (head
->module
* sizeof (ref_t
),
386 if (__builtin_expect (mapsize
< size
, 0))
389 /* Allocate a record for the mapping. */
390 struct mapped_database
*newp
= malloc (sizeof (*newp
));
392 /* Ugh, after all we went through the memory allocation failed. */
395 newp
->head
= mapping
;
396 newp
->data
= ((char *) mapping
+ head
->header_size
397 + roundup (head
->module
* sizeof (ref_t
), ALIGN
));
398 newp
->mapsize
= size
;
399 newp
->datasize
= head
->data_size
;
400 /* Set counter to 1 to show it is usable. */
411 __set_errno (saved_errno
);
412 #endif /* SCM_RIGHTS */
414 struct mapped_database
*oldval
= *mappedp
;
417 if (oldval
!= NULL
&& atomic_decrement_val (&oldval
->counter
) == 0)
418 __nscd_unmap (oldval
);
424 struct mapped_database
*
425 __nscd_get_map_ref (request_type type
, const char *name
,
426 volatile struct locked_map_ptr
*mapptr
, int *gc_cyclep
)
428 struct mapped_database
*cur
= mapptr
->mapped
;
429 if (cur
== NO_MAPPING
)
433 while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr
->lock
,
436 // XXX Best number of rounds?
437 if (__builtin_expect (++cnt
> 5, 0))
443 cur
= mapptr
->mapped
;
445 if (__builtin_expect (cur
!= NO_MAPPING
, 1))
447 /* If not mapped or timestamp not updated, request new map. */
449 || (cur
->head
->nscd_certainly_running
== 0
450 && cur
->head
->timestamp
+ MAPPING_TIMEOUT
< time (NULL
))
451 || cur
->head
->data_size
> cur
->datasize
)
452 cur
= get_mapping (type
, name
,
453 (struct mapped_database
**) &mapptr
->mapped
);
455 if (__builtin_expect (cur
!= NO_MAPPING
, 1))
457 if (__builtin_expect (((*gc_cyclep
= cur
->head
->gc_cycle
) & 1) != 0,
461 atomic_increment (&cur
->counter
);
471 /* Using sizeof (hashentry) is not always correct to determine the size of
472 the data structure as found in the nscd cache. The program could be
473 a 64-bit process and nscd could be a 32-bit process. In this case
474 sizeof (hashentry) would overestimate the size. The following is
475 the minimum size of such an entry, good enough for our tests here. */
476 #define MINIMUM_HASHENTRY_SIZE \
477 (offsetof (struct hashentry, dellist) + sizeof (int32_t))
480 /* Don't return const struct datahead *, as eventhough the record
481 is normally constant, it can change arbitrarily during nscd
482 garbage collection. */
484 __nscd_cache_search (request_type type
, const char *key
, size_t keylen
,
485 const struct mapped_database
*mapped
, size_t datalen
)
487 unsigned long int hash
= __nis_hash (key
, keylen
) % mapped
->head
->module
;
488 size_t datasize
= mapped
->datasize
;
490 ref_t trail
= mapped
->head
->array
[hash
];
491 trail
= atomic_forced_read (trail
);
493 size_t loop_cnt
= datasize
/ (MINIMUM_HASHENTRY_SIZE
494 + offsetof (struct datahead
, data
) / 2);
497 while (work
!= ENDREF
&& work
+ MINIMUM_HASHENTRY_SIZE
<= datasize
)
499 struct hashentry
*here
= (struct hashentry
*) (mapped
->data
+ work
);
500 ref_t here_key
, here_packet
;
502 #ifndef _STRING_ARCH_unaligned
503 /* Although during garbage collection when moving struct hashentry
504 records around we first copy from old to new location and then
505 adjust pointer from previous hashentry to it, there is no barrier
506 between those memory writes. It is very unlikely to hit it,
507 so check alignment only if a misaligned load can crash the
509 if ((uintptr_t) here
& (__alignof__ (*here
) - 1))
513 if (type
== here
->type
514 && keylen
== here
->len
515 && (here_key
= atomic_forced_read (here
->key
)) + keylen
<= datasize
516 && memcmp (key
, mapped
->data
+ here_key
, keylen
) == 0
517 && ((here_packet
= atomic_forced_read (here
->packet
))
518 + sizeof (struct datahead
) <= datasize
))
520 /* We found the entry. Increment the appropriate counter. */
522 = (struct datahead
*) (mapped
->data
+ here_packet
);
524 #ifndef _STRING_ARCH_unaligned
525 if ((uintptr_t) dh
& (__alignof__ (*dh
) - 1))
529 /* See whether we must ignore the entry or whether something
530 is wrong because garbage collection is in progress. */
532 && here_packet
+ dh
->allocsize
<= datasize
533 && (here_packet
+ offsetof (struct datahead
, data
) + datalen
538 work
= atomic_forced_read (here
->next
);
539 /* Prevent endless loops. This should never happen but perhaps
540 the database got corrupted, accidentally or deliberately. */
541 if (work
== trail
|| loop_cnt
-- == 0)
545 struct hashentry
*trailelem
;
546 trailelem
= (struct hashentry
*) (mapped
->data
+ trail
);
548 #ifndef _STRING_ARCH_unaligned
549 /* We have to redo the checks. Maybe the data changed. */
550 if ((uintptr_t) trailelem
& (__alignof__ (*trailelem
) - 1))
554 if (trail
+ MINIMUM_HASHENTRY_SIZE
> datasize
)
557 trail
= atomic_forced_read (trailelem
->next
);
566 /* Create a socket connected to a name. */
568 __nscd_open_socket (const char *key
, size_t keylen
, request_type type
,
569 void *response
, size_t responselen
)
571 /* This should never happen and it is something the nscd daemon
572 enforces, too. He it helps to limit the amount of stack
574 if (keylen
> MAXKEYLEN
)
577 int saved_errno
= errno
;
579 int sock
= open_socket (type
, key
, keylen
);
583 if (wait_on_socket (sock
, 5 * 1000) > 0)
585 ssize_t nbytes
= TEMP_FAILURE_RETRY (__read (sock
, response
,
587 if (nbytes
== (ssize_t
) responselen
)
591 close_not_cancel_no_status (sock
);
594 __set_errno (saved_errno
);