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.
24 * Copyright 2012 Milan Jurik. All rights reserved.
31 #include "nscd_door.h"
33 #include "nscd_admin.h"
35 extern nsc_ctx_t
*cache_ctx_p
[];
36 extern char *cache_name
[];
38 static nscd_admin_t admin_c
= { 0 };
39 static nscd_admin_mod_t admin_mod
= { 0 };
40 static mutex_t mod_lock
= DEFAULTMUTEX
;
44 _nscd_door_getadmin(void *outbuf
)
47 int data_size
= NSCD_N2N_DOOR_BUF_SIZE(admin_c
);
48 nss_pheader_t
*phdr
= (nss_pheader_t
*)outbuf
;
49 nscd_cfg_cache_t cfg_default
= NSCD_CFG_CACHE_DEFAULTS
;
52 * if size of buffer is not big enough, tell the caller to
53 * increase it to the size returned
55 if (phdr
->pbufsiz
< data_size
)
56 return (sizeof (admin_c
));
58 NSCD_SET_STATUS_SUCCESS(phdr
);
59 phdr
->data_off
= sizeof (nss_pheader_t
);
60 phdr
->data_len
= sizeof (admin_c
);
62 for (i
= 0; i
< CACHE_CTX_COUNT
; i
++) {
63 if (cache_ctx_p
[i
] != NULL
) {
64 (void) rw_rdlock(&cache_ctx_p
[i
]->cfg_rwlp
);
65 admin_c
.cache_cfg
[i
] = cache_ctx_p
[i
]->cfg
;
66 (void) rw_unlock(&cache_ctx_p
[i
]->cfg_rwlp
);
68 (void) mutex_lock(&cache_ctx_p
[i
]->stats_mutex
);
69 admin_c
.cache_stats
[i
] = cache_ctx_p
[i
]->stats
;
70 (void) mutex_unlock(&cache_ctx_p
[i
]->stats_mutex
);
72 admin_c
.cache_cfg
[i
] = cfg_default
;
73 (void) memset(&admin_c
.cache_stats
[i
], 0,
74 sizeof (admin_c
.cache_stats
[0]));
77 (void) memcpy(((char *)outbuf
) + phdr
->data_off
,
78 &admin_c
, sizeof (admin_c
));
84 _nscd_client_showstats()
86 (void) printf("nscd configuration:\n\n");
87 (void) printf("%10d server debug level\n", admin_c
.debug_level
);
88 (void) printf("\"%s\" is server log file\n", admin_c
.logfile
);
90 (void) nsc_info(NULL
, NULL
, admin_c
.cache_cfg
, admin_c
.cache_stats
);
95 _nscd_server_setadmin(nscd_admin_mod_t
*set
)
97 nscd_rc_t rc
= NSCD_ADMIN_FAIL_TO_SET
;
100 char *group
= "param-group-cache";
102 nscd_cfg_error_t
*err
= NULL
;
103 char *me
= "_nscd_server_setadmin";
108 /* one setadmin at a time */
109 (void) mutex_lock(&mod_lock
);
111 _NSCD_LOG_IF(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_DEBUG
) {
113 _nscd_logit(me
, "total_size = %d\n", set
->total_size
);
115 _nscd_logit(me
, "debug_level_set = %d, debug_level = %d\n",
116 set
->debug_level_set
, set
->debug_level
);
118 _nscd_logit(me
, "logfile_set = %d, logfile = %s\n",
119 set
->logfile_set
, *set
->logfile
== '\0' ?
122 _nscd_logit(me
, "cache_cfg_num = %d\n",
124 _nscd_logit(me
, "cache_flush_num = %d\n",
125 set
->cache_flush_num
);
132 if (set
->debug_level_set
== nscd_true
) {
133 if (_nscd_set_debug_level(set
->debug_level
)
136 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
137 (me
, "unable to set debug level %d\n",
142 admin_c
.debug_level
= set
->debug_level
;
145 if (set
->logfile_set
== nscd_true
) {
146 if (_nscd_set_log_file(set
->logfile
) != NSCD_SUCCESS
) {
148 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
149 (me
, "unable to set log file %s\n", set
->logfile
);
153 (void) strlcpy(admin_c
.logfile
, set
->logfile
,
158 * For caches to be changed
160 if (set
->cache_cfg_num
> CACHE_CTX_COUNT
) {
162 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
163 (me
, "number of caches (%d) to change out of bound %s\n",
169 for (i
= 0; i
< set
->cache_cfg_num
; i
++) {
171 nscd_cfg_cache_t
*new_cfg
;
173 j
= set
->cache_cfg_set
[i
];
174 new_cfg
= &set
->cache_cfg
[i
];
175 dbname
= cache_name
[j
];
176 if (cache_ctx_p
[j
] == NULL
) {
177 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
178 (me
, "unable to find cache context for %s\n",
182 rc
= _nscd_cfg_get_handle(group
, dbname
, &h
, NULL
);
183 if (rc
!= NSCD_SUCCESS
) {
184 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
185 (me
, "unable to get handle for < %s : %s >\n",
191 rc
= _nscd_cfg_set(h
, new_cfg
, &err
);
192 if (rc
!= NSCD_SUCCESS
) {
193 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
194 (me
, "unable to set admin data for < %s : %s >\n",
197 _nscd_cfg_free_handle(h
);
201 _nscd_cfg_free_handle(h
);
205 * For caches to be flushed
207 if (set
->cache_flush_num
> CACHE_CTX_COUNT
) {
209 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
210 (me
, "number of caches (%d) to flush out of bound %s\n",
211 set
->cache_flush_num
);
216 for (i
= 0; i
< set
->cache_flush_num
; i
++) {
219 j
= set
->cache_flush_set
[i
];
221 if (cache_ctx_p
[j
] == NULL
) {
222 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
223 (me
, "unable to find cache context for %s\n",
226 nsc_invalidate(cache_ctx_p
[j
], NULL
, NULL
);
232 (void) mutex_unlock(&mod_lock
);
239 _nscd_door_setadmin(void *buf
)
242 nss_pheader_t
*phdr
= (nss_pheader_t
*)buf
;
243 char *me
= "_nscd_door_setadmin";
245 rc
= _nscd_server_setadmin(NSCD_N2N_DOOR_DATA(nscd_admin_mod_t
, buf
));
246 if (rc
!= NSCD_SUCCESS
) {
247 _NSCD_LOG(NSCD_LOG_ADMIN
, NSCD_LOG_LEVEL_ERROR
)
248 (me
, "SETADMIN call failed\n");
250 NSCD_SET_N2N_STATUS(phdr
, NSS_NSCD_PRIV
, 0, rc
);
252 NSCD_SET_STATUS_SUCCESS(phdr
);
257 * for a database 'dbname', add config value 'val' of option 'opt'
258 * to the global admin_mod structure
261 _nscd_add_admin_mod(char *dbname
, char opt
,
262 char *val
, char *msg
, int msglen
) {
264 nscd_cfg_cache_t
*cfg
;
265 nscd_cfg_group_info_t gi
= NSCD_CFG_GROUP_INFO_CACHE
;
268 /* set initial admin_mod size; assume no cache config to set */
269 if (admin_mod
.total_size
== 0)
270 admin_mod
.total_size
= sizeof (admin_mod
) -
271 sizeof (admin_mod
.cache_cfg
);
273 /* global admin stuff */
274 if (opt
== 'l' || opt
== 'd') {
276 (void) strlcpy(admin_mod
.logfile
,
277 val
, NSCD_LOGFILE_LEN
);
278 admin_mod
.logfile_set
= nscd_true
;
280 admin_mod
.debug_level
= atoi(val
);
281 admin_mod
.debug_level_set
= nscd_true
;
286 /* options to be processed next requires cache name */
287 (void) strlcpy(dbn
, dbname
, sizeof (dbn
));
288 if ((cp
= strchr(dbn
, ',')) != NULL
)
290 i
= get_cache_idx(dbn
);
292 (void) snprintf(msg
, msglen
,
293 gettext("invalid cache name \"%s\""), dbn
);
299 admin_mod
.cache_flush_set
[admin_mod
.cache_flush_num
++] = i
;
303 /* options to be processed next requires a param value */
305 (void) snprintf(msg
, msglen
,
306 gettext("value missing after \"%s\""), dbn
);
310 /* try to use an existing cache_cfg in admin_mod */
311 for (j
= 0; j
< admin_mod
.cache_cfg_num
; j
++) {
312 if (admin_mod
.cache_cfg_set
[j
] == i
)
316 /* no existing one, set up another one */
317 if (j
== admin_mod
.cache_cfg_num
) {
318 admin_mod
.cache_cfg_set
[j
] = i
;
319 admin_mod
.cache_cfg_num
++;
320 admin_mod
.total_size
+= sizeof (admin_mod
.cache_cfg
[0]);
323 cfg
= &admin_mod
.cache_cfg
[j
];
324 cfg
->gi
.num_param
= gi
.num_param
;
331 _nscd_cfg_bitmap_set_nth(cfg
->gi
.bitmap
, 0);
332 if (strcmp(val
, "yes") == 0)
333 cfg
->enable
= nscd_true
;
334 else if (strcmp(val
, "no") == 0)
335 cfg
->enable
= nscd_false
;
337 (void) snprintf(msg
, msglen
,
338 gettext("\"yes\" or \"no\" not specified after \"%s\""), dbn
);
346 _nscd_cfg_bitmap_set_nth(cfg
->gi
.bitmap
, 3);
347 if (strcmp(val
, "yes") == 0)
348 cfg
->check_files
= nscd_true
;
349 else if (strcmp(val
, "no") == 0)
350 cfg
->check_files
= nscd_false
;
352 (void) snprintf(msg
, msglen
,
353 gettext("\"yes\" or \"no\" not specified after \"%s\""), dbn
);
359 /* positive time to live */
361 _nscd_cfg_bitmap_set_nth(cfg
->gi
.bitmap
, 5);
362 cfg
->pos_ttl
= atoi(val
);
366 /* negative time to live */
368 _nscd_cfg_bitmap_set_nth(cfg
->gi
.bitmap
, 6);
369 cfg
->neg_ttl
= atoi(val
);
375 _nscd_cfg_bitmap_set_nth(cfg
->gi
.bitmap
, 7);
376 cfg
->keephot
= atoi(val
);
384 _nscd_client_getadmin(char opt
)
390 callnum
= NSCD_GETPUADMIN
;
392 callnum
= NSCD_GETADMIN
;
394 (void) _nscd_doorcall_data(callnum
, NULL
, sizeof (admin_c
),
395 &admin_c
, sizeof (admin_c
), &phdr
);
397 if (NSCD_STATUS_IS_NOT_OK(&phdr
)) {
405 _nscd_client_setadmin()
407 return (_nscd_doorcall_data(NSCD_SETADMIN
, &admin_mod
,
408 sizeof (admin_mod
), NULL
, 0, NULL
));