4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
33 static rwlock_t addrDB_rwlock
= DEFAULTRWLOCK
;
34 static nscd_db_t
*addrDB
= NULL
;
37 * internal structure representing a nscd internal address
39 typedef struct nscd_int_addr
{
40 int to_delete
; /* no longer valid */
43 nscd_seq_num_t seq_num
;
44 rwlock_t rwlock
; /* used to serialize get and destroy */
48 * FUNCTION: _nscd_create_int_addrDB
50 * Create the internal address database to keep track of the
51 * memory allocated by _nscd_alloc.
54 _nscd_create_int_addrDB()
58 char *me
= "_nscd_create_int_addrDB";
60 _NSCD_LOG(NSCD_LOG_INT_ADDR
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
61 (me
, "initializing the internal address database\n");
63 (void) rw_wrlock(&addrDB_rwlock
);
66 (void) rw_unlock(&addrDB_rwlock
);
70 ret
= _nscd_alloc_db(NSCD_DB_SIZE_LARGE
);
75 (void) rw_unlock(&addrDB_rwlock
);
81 * FUNCTION: _nscd_add_int_addr
83 * Add an address of 'type' to the internal address database.
89 nscd_seq_num_t seq_num
)
92 char buf
[2 * sizeof (ptr
) + 1];
93 nscd_db_entry_t
*db_entry
;
94 nscd_int_addr_t
*int_addr
;
97 return (NSCD_INVALID_ARGUMENT
);
99 (void) snprintf(buf
, sizeof (buf
), "%p", ptr
);
101 size
= sizeof (*int_addr
);
103 db_entry
= _nscd_alloc_db_entry(NSCD_DATA_ADDR
,
104 (const char *)buf
, size
, 1, 1);
105 if (db_entry
== NULL
)
106 return (NSCD_NO_MEMORY
);
108 int_addr
= (nscd_int_addr_t
*)*(db_entry
->data_array
);
110 int_addr
->type
= type
;
111 int_addr
->seq_num
= seq_num
;
112 (void) rwlock_init(&int_addr
->rwlock
, USYNC_THREAD
, NULL
);
114 (void) rw_wrlock(&addrDB_rwlock
);
115 (void) _nscd_add_db_entry(addrDB
, buf
, db_entry
,
116 NSCD_ADD_DB_ENTRY_FIRST
);
117 (void) rw_unlock(&addrDB_rwlock
);
119 return (NSCD_SUCCESS
);
123 * FUNCTION: _nscd_is_int_addr
125 * Check to see if an address can be found in the internal
126 * address database, if so, obtain a reader lock on the
127 * associated rw_lock. The caller needs to unlock it when
128 * done using the data.
133 nscd_seq_num_t seq_num
)
135 char *me
= "_nscd_is_int_addr";
136 char ptrstr
[1 + 2 * sizeof (ptr
)];
137 rwlock_t
*addr_rwlock
;
138 const nscd_db_entry_t
*db_entry
;
143 (void) snprintf(ptrstr
, sizeof (ptrstr
), "%p", ptr
);
145 (void) rw_rdlock(&addrDB_rwlock
);
147 db_entry
= _nscd_get_db_entry(addrDB
, NSCD_DATA_ADDR
,
148 (const char *)ptrstr
, NSCD_GET_FIRST_DB_ENTRY
, 0);
150 if (db_entry
!= NULL
) {
151 nscd_int_addr_t
*int_addr
;
153 int_addr
= (nscd_int_addr_t
*)*(db_entry
->data_array
);
154 addr_rwlock
= &int_addr
->rwlock
;
155 (void) rw_rdlock(addr_rwlock
);
158 * If the data is marked as to be deleted
159 * or the sequence number does not match,
162 if (int_addr
->to_delete
== 1 ||
163 int_addr
->seq_num
!= seq_num
) {
164 (void) rw_unlock(addr_rwlock
);
168 _NSCD_LOG(NSCD_LOG_INT_ADDR
, NSCD_LOG_LEVEL_DEBUG
)
169 (me
, "found %p, seq# = %lld\n", ptr
, int_addr
->seq_num
);
173 (void) rw_unlock(&addrDB_rwlock
);
175 return (addr_rwlock
);
179 * FUNCTION: _nscd_del_int_addr
181 * Delete an address from the internal address database.
186 nscd_seq_num_t seq_num
)
188 char *me
= "_nscd_del_int_addr";
189 char ptrstr
[1 + 2 * sizeof (ptr
)];
190 rwlock_t
*addr_rwlock
;
191 nscd_int_addr_t
*int_addr
;
192 const nscd_db_entry_t
*db_entry
;
197 _NSCD_LOG(NSCD_LOG_INT_ADDR
, NSCD_LOG_LEVEL_DEBUG
)
198 (me
, "deleting int addr %p (%d)\n", ptr
, seq_num
);
199 (void) snprintf(ptrstr
, sizeof (ptrstr
), "%p", ptr
);
201 (void) rw_rdlock(&addrDB_rwlock
);
203 * first find the db entry and make sure that
204 * no one is currently locking it. i.e.,
205 * no one is waiting to use the same address.
206 * If it is locked, rw_wrlock() will not return
207 * until it is unlocked.
209 db_entry
= _nscd_get_db_entry(addrDB
,
211 (const char *)ptrstr
,
212 NSCD_GET_FIRST_DB_ENTRY
, 0);
213 if (db_entry
!= NULL
) {
214 int_addr
= (nscd_int_addr_t
*)*(db_entry
->data_array
);
215 addr_rwlock
= &int_addr
->rwlock
;
216 (void) rw_wrlock(addr_rwlock
);
218 (void) rw_unlock(&addrDB_rwlock
);
221 (void) rw_unlock(&addrDB_rwlock
);
224 * delete the db entry if the sequence numbers match
226 if (int_addr
->seq_num
== seq_num
) {
227 (void) rw_wrlock(&addrDB_rwlock
);
228 (void) _nscd_delete_db_entry(addrDB
,
230 (const char *)ptrstr
,
231 NSCD_DEL_FIRST_DB_ENTRY
, 0);
232 (void) rw_unlock(&addrDB_rwlock
);
237 * FUNCTION: _nscd_destroy_int_addrDB
239 * Destroy the internal address database.
242 _nscd_destroy_int_addrDB()
244 (void) rw_wrlock(&addrDB_rwlock
);
245 _nscd_free_db(addrDB
);
247 (void) rw_unlock(&addrDB_rwlock
);