xref: /titanic_51/usr/src/cmd/avs/sdbc/scmadm.c (revision 570de38f63910201fdd77246630b7aa8f9dc5661)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21*570de38fSSurya Prakki 
22fcf3ce44SJohn Forte /*
23*570de38fSSurya Prakki  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24fcf3ce44SJohn Forte  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27fcf3ce44SJohn Forte /*
28fcf3ce44SJohn Forte  * Utility for cache configuration
29fcf3ce44SJohn Forte  */
30fcf3ce44SJohn Forte #include <unistd.h>
31fcf3ce44SJohn Forte #include <stdio.h>
32fcf3ce44SJohn Forte #include <stdlib.h>
33fcf3ce44SJohn Forte #include <strings.h>
34fcf3ce44SJohn Forte #include <locale.h>
35fcf3ce44SJohn Forte #include <langinfo.h>
36fcf3ce44SJohn Forte #include <libintl.h>
37fcf3ce44SJohn Forte #include <time.h>
38fcf3ce44SJohn Forte #include <sys/nsctl/sd_bcache.h>
39fcf3ce44SJohn Forte #include <sys/wait.h>
40fcf3ce44SJohn Forte #include <errno.h>
41fcf3ce44SJohn Forte #include <signal.h>
42fcf3ce44SJohn Forte #include <sys/types.h>
43fcf3ce44SJohn Forte #include <fcntl.h>
44fcf3ce44SJohn Forte #include <stropts.h>
45fcf3ce44SJohn Forte #include <ctype.h>
46fcf3ce44SJohn Forte #include <libgen.h>
47fcf3ce44SJohn Forte 
48fcf3ce44SJohn Forte #include <sys/nsctl/sdbc_ioctl.h>
49fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
50fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
51fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
52fcf3ce44SJohn Forte #include <nsctl.h>
53fcf3ce44SJohn Forte 
54fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
55fcf3ce44SJohn Forte #define	STATS_PATH	"/usr/bin/sd_stats"
56fcf3ce44SJohn Forte 
57fcf3ce44SJohn Forte #define	_SD_FNAME	/* bring in function names from sd_trace.h */
58fcf3ce44SJohn Forte #include <sys/nsctl/sd_trace.h>
59fcf3ce44SJohn Forte #include <sys/syslog.h>
60fcf3ce44SJohn Forte 
61fcf3ce44SJohn Forte /*
62fcf3ce44SJohn Forte  * Since we no longer support nvram cards, the hints wrthru and nowrthru no
63fcf3ce44SJohn Forte  * longer serve any purpose, and the system will always be in wrthru mode.
64fcf3ce44SJohn Forte  * WRTHRU_HINTS, if defined still allows the setting and reporting of write
65fcf3ce44SJohn Forte  * hints.  This is defined by default on DEBUG builds.
66fcf3ce44SJohn Forte  */
67fcf3ce44SJohn Forte #ifdef DEBUG
68fcf3ce44SJohn Forte #define	WRTHRU_HINTS
69fcf3ce44SJohn Forte #endif
70fcf3ce44SJohn Forte 
71fcf3ce44SJohn Forte static int sdbc_max_devices = 0;
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte static char alert_file[200]  = "/dev/console";
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte /* Variables used to set up paramater block passed to kernel */
76fcf3ce44SJohn Forte static _sd_cache_param_t	user_level_conf;
77fcf3ce44SJohn Forte static int			myid;
78fcf3ce44SJohn Forte 
79fcf3ce44SJohn Forte static int		nodes_configured = 0;
80fcf3ce44SJohn Forte static int		minidsp = 0; /* Is it a sp10 */
81fcf3ce44SJohn Forte static int		forced_wrthru = -1; /* 0 clear, 1 set,-1 as is */
82fcf3ce44SJohn Forte static int		no_forced_wrthru = -1;
83fcf3ce44SJohn Forte static short		node_defined[MAX_SD_NODES];
84fcf3ce44SJohn Forte static short		nodes_conf[MAX_SD_NODES];
85fcf3ce44SJohn Forte 
86fcf3ce44SJohn Forte #define	USAGELEN	1024
87fcf3ce44SJohn Forte char stats_usage[USAGELEN+128];
88fcf3ce44SJohn Forte char scmadmUsage[USAGELEN];
89fcf3ce44SJohn Forte 
90fcf3ce44SJohn Forte static caddr_t progname;
91fcf3ce44SJohn Forte 
92fcf3ce44SJohn Forte 
93fcf3ce44SJohn Forte /*
94fcf3ce44SJohn Forte  * Functions exported for fwcadm.
95fcf3ce44SJohn Forte  */
96fcf3ce44SJohn Forte void enable_sdbc(void);
97fcf3ce44SJohn Forte void disable_sdbc(void);
98fcf3ce44SJohn Forte void sdbc_set_maxdev();
99fcf3ce44SJohn Forte 
100fcf3ce44SJohn Forte static void buildusage(char *);
101fcf3ce44SJohn Forte 
102fcf3ce44SJohn Forte void print_all_options(void);
103fcf3ce44SJohn Forte void get_cd_all(void);
104fcf3ce44SJohn Forte int toggle_flush(void);
105fcf3ce44SJohn Forte static void sd_gather_alert_dumps();
106fcf3ce44SJohn Forte static int get_cd(char *);
107fcf3ce44SJohn Forte static int get_hint(char *, int *, int *);
108fcf3ce44SJohn Forte static void check_and_set_mirrors(int, int);
109fcf3ce44SJohn Forte static void print_hint(const uint_t, const int);
110fcf3ce44SJohn Forte static char *get_device_name(char *arg);
111fcf3ce44SJohn Forte static void get_version();
112fcf3ce44SJohn Forte 
113fcf3ce44SJohn Forte extern struct tm *localtime_r(const time_t *, struct tm *);
114fcf3ce44SJohn Forte 
115fcf3ce44SJohn Forte #define	PRINT_CACHE_SZ_ERR(sz) {\
116fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext("\n%s: desired cache size (%d) "\
117fcf3ce44SJohn Forte 	    "set to system max (%d)\n"), \
118fcf3ce44SJohn Forte 	    progname, (sz), MAX_CACHE_SIZE); \
119fcf3ce44SJohn Forte 	spcs_log("sdbc", NULL, \
120fcf3ce44SJohn Forte 		gettext("desired cache size (%d) "\
121fcf3ce44SJohn Forte 		    "set to system max (%d)\n"), \
122fcf3ce44SJohn Forte 		(sz), MAX_CACHE_SIZE); \
123fcf3ce44SJohn Forte }
124fcf3ce44SJohn Forte 
125fcf3ce44SJohn Forte void
126fcf3ce44SJohn Forte sdbc_report_error(spcs_s_info_t *ustatus)
127fcf3ce44SJohn Forte {
128fcf3ce44SJohn Forte 	if (*ustatus != NULL) {
129fcf3ce44SJohn Forte 		spcs_s_report(*ustatus, stderr);
130fcf3ce44SJohn Forte 		spcs_s_ufree(ustatus);
131fcf3ce44SJohn Forte 	} else
132fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s\n", strerror(errno));
133fcf3ce44SJohn Forte }
134fcf3ce44SJohn Forte 
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte /*
137fcf3ce44SJohn Forte  * Return the per-cd hints for a cd.
138fcf3ce44SJohn Forte  *
139fcf3ce44SJohn Forte  * Since the global (no)wrthru and NSC_NOCACHE hints take precedence
140fcf3ce44SJohn Forte  * over the per-cd hints, get them as well and OR the whole lot
141fcf3ce44SJohn Forte  * together.
142fcf3ce44SJohn Forte  */
143fcf3ce44SJohn Forte static int
144fcf3ce44SJohn Forte get_cd_hint(const int cd)
145fcf3ce44SJohn Forte {
146fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
147fcf3ce44SJohn Forte 	int nodehint, cdhint;
148fcf3ce44SJohn Forte 
149fcf3ce44SJohn Forte 	nodehint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, 0, 0, 0, &ustats);
150fcf3ce44SJohn Forte 	if (nodehint == SPCS_S_ERROR) {
151fcf3ce44SJohn Forte 		(void) fprintf(stderr,
152fcf3ce44SJohn Forte 		    gettext("%s: get system options failed\n"), progname);
153fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
154fcf3ce44SJohn Forte 		exit(1);
155fcf3ce44SJohn Forte 	}
156fcf3ce44SJohn Forte 
157fcf3ce44SJohn Forte 	cdhint = SDBC_IOCTL(SDBC_GET_CD_HINT, cd, 0, 0, 0, 0, &ustats);
158fcf3ce44SJohn Forte 	if (cdhint == SPCS_S_ERROR) {
159fcf3ce44SJohn Forte 		(void) fprintf(stderr,
160fcf3ce44SJohn Forte 		    gettext("%s: get cd(%d) hint failed\n"), progname, cd);
161fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
162fcf3ce44SJohn Forte 		exit(1);
163fcf3ce44SJohn Forte 	}
164fcf3ce44SJohn Forte 
165fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
166fcf3ce44SJohn Forte 	nodehint &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU | NSC_NOCACHE);
167fcf3ce44SJohn Forte #else
168fcf3ce44SJohn Forte 	nodehint &= (NSC_NOCACHE);
169fcf3ce44SJohn Forte #endif
170fcf3ce44SJohn Forte 	if (nodehint) {
171fcf3ce44SJohn Forte 		/* set the top bit to mark it as a system override */
172fcf3ce44SJohn Forte 		nodehint |= 0x80000000;
173fcf3ce44SJohn Forte 	}
174fcf3ce44SJohn Forte 
175fcf3ce44SJohn Forte 	return (cdhint | nodehint);
176fcf3ce44SJohn Forte }
177fcf3ce44SJohn Forte 
178fcf3ce44SJohn Forte 
179fcf3ce44SJohn Forte 
180fcf3ce44SJohn Forte /*
181fcf3ce44SJohn Forte  * Check for a config.
182fcf3ce44SJohn Forte  *
183fcf3ce44SJohn Forte  * If no suitable config can be found, install the default config.
184fcf3ce44SJohn Forte  *
185fcf3ce44SJohn Forte  * Calling state:
186fcf3ce44SJohn Forte  *	libcfg locked (mode describes type of lock)
187fcf3ce44SJohn Forte  */
188fcf3ce44SJohn Forte static void
189fcf3ce44SJohn Forte convert_config(CFGFILE *cfg, CFGLOCK mode)
190fcf3ce44SJohn Forte {
191fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
192fcf3ce44SJohn Forte 	char *default_cfg = "128 64";
193fcf3ce44SJohn Forte 
194fcf3ce44SJohn Forte retry:
195fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, "scm.set1", buf, sizeof (buf)) >= 0) {
196fcf3ce44SJohn Forte 		/* config exists, return */
197fcf3ce44SJohn Forte 		return;
198fcf3ce44SJohn Forte 	}
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
201fcf3ce44SJohn Forte 
202fcf3ce44SJohn Forte #ifdef DEBUG
203fcf3ce44SJohn Forte 	(void) printf(gettext("%s: installing default config entry '%s'\n"),
204fcf3ce44SJohn Forte 	    progname, default_cfg);
205fcf3ce44SJohn Forte #endif
206fcf3ce44SJohn Forte 	if (mode != CFG_WRLOCK) {
207fcf3ce44SJohn Forte 		cfg_unlock(cfg);
208fcf3ce44SJohn Forte 		if (!cfg_lock(cfg, CFG_WRLOCK)) {
209fcf3ce44SJohn Forte 			(void) fprintf(stderr,
210fcf3ce44SJohn Forte 			    gettext("%s: unable to lock configuration: %s\n"),
211fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
212fcf3ce44SJohn Forte 			exit(1);
213fcf3ce44SJohn Forte 		}
214fcf3ce44SJohn Forte 		mode = CFG_WRLOCK;
215fcf3ce44SJohn Forte #ifdef DEBUG
216fcf3ce44SJohn Forte 		(void) printf(gettext("%s: upgraded lock, retrying\n"),
217fcf3ce44SJohn Forte 		    progname);
218fcf3ce44SJohn Forte #endif
219fcf3ce44SJohn Forte 		goto retry;
220fcf3ce44SJohn Forte 	}
221fcf3ce44SJohn Forte 
222fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, "scm", default_cfg, strlen(default_cfg)) < 0) {
223fcf3ce44SJohn Forte 		(void) fprintf(stderr,
224fcf3ce44SJohn Forte 		    gettext("%s: unable to write configuration: %s\n"),
225fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
226fcf3ce44SJohn Forte 		exit(1);
227fcf3ce44SJohn Forte 	}
228fcf3ce44SJohn Forte 
229fcf3ce44SJohn Forte 	if (!cfg_commit(cfg)) {
230fcf3ce44SJohn Forte 		(void) fprintf(stderr,
231fcf3ce44SJohn Forte 		    gettext("%s: unable to write to configuration: %s\n"),
232fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
233fcf3ce44SJohn Forte 	}
234fcf3ce44SJohn Forte 
235fcf3ce44SJohn Forte 	if (mode != CFG_WRLOCK) {
236fcf3ce44SJohn Forte 		if (!cfg_lock(cfg, mode)) {
237fcf3ce44SJohn Forte 			(void) fprintf(stderr,
238fcf3ce44SJohn Forte 			    gettext("%s: unable to relock configuration: %s\n"),
239fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
240fcf3ce44SJohn Forte 			exit(1);
241fcf3ce44SJohn Forte 		}
242fcf3ce44SJohn Forte 	}
243fcf3ce44SJohn Forte 
244fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
245fcf3ce44SJohn Forte }
246fcf3ce44SJohn Forte 
247fcf3ce44SJohn Forte 
248fcf3ce44SJohn Forte static int
249fcf3ce44SJohn Forte iscluster(void)
250fcf3ce44SJohn Forte {
251fcf3ce44SJohn Forte 	int rc;
252fcf3ce44SJohn Forte 
253fcf3ce44SJohn Forte 	rc = cfg_iscluster();
254fcf3ce44SJohn Forte 	if (rc == 0) {
255fcf3ce44SJohn Forte 		return (FALSE);
256fcf3ce44SJohn Forte 	} else if (rc > 0) {
257fcf3ce44SJohn Forte 		return (TRUE);
258fcf3ce44SJohn Forte 	} else {
259*570de38fSSurya Prakki 		(void) fprintf(stderr,
260*570de38fSSurya Prakki 		    gettext("%s: unable to ascertain environment\n"), progname);
261fcf3ce44SJohn Forte 		exit(1);
262fcf3ce44SJohn Forte 	}
263fcf3ce44SJohn Forte 
264fcf3ce44SJohn Forte 	/* NOTREACHED */
265fcf3ce44SJohn Forte }
266fcf3ce44SJohn Forte 
267fcf3ce44SJohn Forte 
268fcf3ce44SJohn Forte static void
269fcf3ce44SJohn Forte restore_hints()
270fcf3ce44SJohn Forte {
271fcf3ce44SJohn Forte 	CFGFILE *cfg;
272fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
273fcf3ce44SJohn Forte 	int setnumber;
274fcf3ce44SJohn Forte 	spcs_s_info_t ustatus;
275fcf3ce44SJohn Forte 	int cd;
276fcf3ce44SJohn Forte 
277fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
278fcf3ce44SJohn Forte 		(void) fprintf(stderr,
279fcf3ce44SJohn Forte 		    gettext("%s: unable to access configuration: %s\n"),
280fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
281fcf3ce44SJohn Forte 		exit(1);
282fcf3ce44SJohn Forte 	}
283fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_RDLOCK)) {
284fcf3ce44SJohn Forte 		(void) fprintf(stderr,
285fcf3ce44SJohn Forte 		    gettext("%s: unable to lock configuration: %s\n"),
286fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
287fcf3ce44SJohn Forte 		exit(1);
288fcf3ce44SJohn Forte 	}
289fcf3ce44SJohn Forte 
290fcf3ce44SJohn Forte 	for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) {
291fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "cache_hint.set%d.device",
292fcf3ce44SJohn Forte 		    setnumber);
293fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg,  key,  buf, sizeof (buf)) < 0) {
294fcf3ce44SJohn Forte 			/* error or not found */
295fcf3ce44SJohn Forte 			break;
296fcf3ce44SJohn Forte 		}
297fcf3ce44SJohn Forte 
298fcf3ce44SJohn Forte 		if (strcmp(buf, "system") == 0) {
299fcf3ce44SJohn Forte 			cd = -1;
300fcf3ce44SJohn Forte 		} else {
301fcf3ce44SJohn Forte 			cd = get_cd(buf);
302fcf3ce44SJohn Forte 			if (cd < 0)
303fcf3ce44SJohn Forte 				continue;
304fcf3ce44SJohn Forte 		}
305fcf3ce44SJohn Forte 
306fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "cache_hint.set%d.wrthru",
307fcf3ce44SJohn Forte 		    setnumber);
308fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg,  key,  buf, sizeof (buf)) < 0)
309fcf3ce44SJohn Forte 			continue;
310fcf3ce44SJohn Forte 
311fcf3ce44SJohn Forte 		if (atoi(buf) == 1) {
312fcf3ce44SJohn Forte 			if (cd == -1) {
313fcf3ce44SJohn Forte 				/* Node hint */
314fcf3ce44SJohn Forte 				if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_WRTHRU,
315fcf3ce44SJohn Forte 				    1, 0, 0, 0, &ustatus) == SPCS_S_ERROR) {
316fcf3ce44SJohn Forte 					(void) fprintf(stderr,
317fcf3ce44SJohn Forte 					    gettext("%s: set system "
318fcf3ce44SJohn Forte 					    "option failed\n"),
319fcf3ce44SJohn Forte 					    progname);
320fcf3ce44SJohn Forte 					sdbc_report_error(&ustatus);
321fcf3ce44SJohn Forte 					exit(1);
322fcf3ce44SJohn Forte 				}
323fcf3ce44SJohn Forte 			} else if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd,
324fcf3ce44SJohn Forte 			    NSC_WRTHRU, 1, 0, 0, &ustatus) == SPCS_S_ERROR) {
325fcf3ce44SJohn Forte 				(void) fprintf(stderr,
326fcf3ce44SJohn Forte 				    gettext("%s: set option failed\n"),
327fcf3ce44SJohn Forte 				    progname);
328fcf3ce44SJohn Forte 				sdbc_report_error(&ustatus);
329fcf3ce44SJohn Forte 				exit(1);
330fcf3ce44SJohn Forte 			}
331fcf3ce44SJohn Forte 		}
332fcf3ce44SJohn Forte 
333fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "cache_hint.set%d.nordcache",
334fcf3ce44SJohn Forte 		    setnumber);
335fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg,  key,  buf, sizeof (buf)) < 0)
336fcf3ce44SJohn Forte 			continue;
337fcf3ce44SJohn Forte 
338fcf3ce44SJohn Forte 		if (atoi(buf) == 1) {
339fcf3ce44SJohn Forte 			if (cd == -1) {
340fcf3ce44SJohn Forte 				/* Node hint */
341fcf3ce44SJohn Forte 				if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_NOCACHE,
342fcf3ce44SJohn Forte 				    1, 0, 0, 0, &ustatus) == SPCS_S_ERROR) {
343fcf3ce44SJohn Forte 					(void) fprintf(stderr,
344fcf3ce44SJohn Forte 					    gettext("%s: set system "
345fcf3ce44SJohn Forte 					    "option failed\n"),
346fcf3ce44SJohn Forte 					    progname);
347fcf3ce44SJohn Forte 					sdbc_report_error(&ustatus);
348fcf3ce44SJohn Forte 					exit(1);
349fcf3ce44SJohn Forte 				}
350fcf3ce44SJohn Forte 			} else if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, NSC_NOCACHE,
351fcf3ce44SJohn Forte 			    1, 0, 0, &ustatus) == SPCS_S_ERROR) {
352fcf3ce44SJohn Forte 				(void) fprintf(stderr,
353fcf3ce44SJohn Forte 				    gettext("%s: set option failed\n"),
354fcf3ce44SJohn Forte 				    progname);
355fcf3ce44SJohn Forte 				sdbc_report_error(&ustatus);
356fcf3ce44SJohn Forte 				exit(1);
357fcf3ce44SJohn Forte 			}
358fcf3ce44SJohn Forte 		}
359fcf3ce44SJohn Forte 	}
360fcf3ce44SJohn Forte 
361fcf3ce44SJohn Forte 	cfg_close(cfg);
362fcf3ce44SJohn Forte }
363fcf3ce44SJohn Forte 
364fcf3ce44SJohn Forte void
365fcf3ce44SJohn Forte sdbc_set_maxdev()
366fcf3ce44SJohn Forte {
367fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
368fcf3ce44SJohn Forte 
369fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices,
370fcf3ce44SJohn Forte 	    0, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
371fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: get maxfiles failed\n"),
372fcf3ce44SJohn Forte 		    progname);
373fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
374fcf3ce44SJohn Forte 		exit(1);
375fcf3ce44SJohn Forte 	}
376fcf3ce44SJohn Forte }
377fcf3ce44SJohn Forte 
378fcf3ce44SJohn Forte static void
379fcf3ce44SJohn Forte bitmapfs_print(void)
380fcf3ce44SJohn Forte {
381fcf3ce44SJohn Forte 	CFGFILE *cfg;
382fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
383fcf3ce44SJohn Forte 	int setnumber;
384fcf3ce44SJohn Forte 
385fcf3ce44SJohn Forte 	cfg = cfg_open(NULL);
386fcf3ce44SJohn Forte 	if (cfg == NULL) {
387fcf3ce44SJohn Forte 		(void) fprintf(stderr,
388fcf3ce44SJohn Forte 		    gettext("%s: unable to access configuration: %s\n"),
389fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
390fcf3ce44SJohn Forte 		exit(1);
391fcf3ce44SJohn Forte 	}
392fcf3ce44SJohn Forte 
393fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_RDLOCK)) {
394fcf3ce44SJohn Forte 		(void) fprintf(stderr,
395fcf3ce44SJohn Forte 		    gettext("%s: unable to lock configuration: %s\n"),
396fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
397fcf3ce44SJohn Forte 		exit(1);
398fcf3ce44SJohn Forte 	}
399fcf3ce44SJohn Forte 
400fcf3ce44SJohn Forte 	for (setnumber = 1; /*CSTYLED*/; setnumber++) {
401fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key),
402fcf3ce44SJohn Forte 		    "bitmaps.set%d.bitmap", setnumber);
403fcf3ce44SJohn Forte 		buf[0] = 0;
404fcf3ce44SJohn Forte 
405fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
406fcf3ce44SJohn Forte 			if (errno == ESRCH) {
407fcf3ce44SJohn Forte 				/* end of list */
408fcf3ce44SJohn Forte 				break;
409fcf3ce44SJohn Forte 			}
410fcf3ce44SJohn Forte 
411fcf3ce44SJohn Forte 			(void) fprintf(stderr,
412fcf3ce44SJohn Forte 			    gettext("%s: error reading configuration: %s\n"),
413fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
414fcf3ce44SJohn Forte 			exit(1);
415fcf3ce44SJohn Forte 		}
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 		(void) printf("%s\n", buf);
418fcf3ce44SJohn Forte 	}
419fcf3ce44SJohn Forte 
420fcf3ce44SJohn Forte 	cfg_close(cfg);
421fcf3ce44SJohn Forte }
422fcf3ce44SJohn Forte 
423fcf3ce44SJohn Forte 
424fcf3ce44SJohn Forte static void
425fcf3ce44SJohn Forte bitmapfs_delete(char *bitmapfs)
426fcf3ce44SJohn Forte {
427fcf3ce44SJohn Forte 	CFGFILE *cfg;
428fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
429fcf3ce44SJohn Forte 	int setnumber;
430fcf3ce44SJohn Forte 	int commit = 0;
431fcf3ce44SJohn Forte 
432fcf3ce44SJohn Forte 	cfg = cfg_open(NULL);
433fcf3ce44SJohn Forte 	if (cfg == NULL) {
434fcf3ce44SJohn Forte 		(void) fprintf(stderr,
435fcf3ce44SJohn Forte 		    gettext("%s: unable to access configuration: %s\n"),
436fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
437fcf3ce44SJohn Forte 		exit(1);
438fcf3ce44SJohn Forte 	}
439fcf3ce44SJohn Forte 
440fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_WRLOCK)) {
441fcf3ce44SJohn Forte 		(void) fprintf(stderr,
442fcf3ce44SJohn Forte 		    gettext("%s: unable to lock configuration: %s\n"),
443fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
444fcf3ce44SJohn Forte 		exit(1);
445fcf3ce44SJohn Forte 	}
446fcf3ce44SJohn Forte 
447fcf3ce44SJohn Forte 	for (setnumber = 1; /*CSTYLED*/; setnumber++) {
448fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key),
449fcf3ce44SJohn Forte 		    "bitmaps.set%d.bitmap", setnumber);
450fcf3ce44SJohn Forte 		buf[0] = 0;
451fcf3ce44SJohn Forte 
452fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
453fcf3ce44SJohn Forte 			if (errno == ESRCH) {
454fcf3ce44SJohn Forte 				/* end of list */
455fcf3ce44SJohn Forte 				(void) fprintf(stderr,
456fcf3ce44SJohn Forte 				    gettext("%s: %s not found "
457fcf3ce44SJohn Forte 				    "in configuration\n"),
458fcf3ce44SJohn Forte 				    progname, bitmapfs);
459fcf3ce44SJohn Forte 				break;
460fcf3ce44SJohn Forte 			}
461fcf3ce44SJohn Forte 
462fcf3ce44SJohn Forte 			(void) fprintf(stderr,
463fcf3ce44SJohn Forte 			    gettext("%s: error reading configuration: %s\n"),
464fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
465fcf3ce44SJohn Forte 			exit(1);
466fcf3ce44SJohn Forte 		}
467fcf3ce44SJohn Forte 
468fcf3ce44SJohn Forte 		if (strcmp(bitmapfs, buf) == 0) {
469fcf3ce44SJohn Forte 			(void) snprintf(key, sizeof (key),
470fcf3ce44SJohn Forte 			    "bitmaps.set%d", setnumber);
471fcf3ce44SJohn Forte 
472fcf3ce44SJohn Forte 			if (cfg_put_cstring(cfg, key, (char *)NULL, 0) < 0) {
473fcf3ce44SJohn Forte 				(void) fprintf(stderr,
474fcf3ce44SJohn Forte 				    gettext("%s: unable to delete %s "
475fcf3ce44SJohn Forte 				    "from configuration: %s\n"),
476fcf3ce44SJohn Forte 				    progname, bitmapfs, cfg_error(NULL));
477fcf3ce44SJohn Forte 			} else
478fcf3ce44SJohn Forte 				commit++;
479fcf3ce44SJohn Forte 
480fcf3ce44SJohn Forte 			break;
481fcf3ce44SJohn Forte 		}
482fcf3ce44SJohn Forte 	}
483fcf3ce44SJohn Forte 
484fcf3ce44SJohn Forte 	if (commit) {
485fcf3ce44SJohn Forte 		if (!cfg_commit(cfg)) {
486fcf3ce44SJohn Forte 			(void) fprintf(stderr,
487fcf3ce44SJohn Forte 			    gettext("%s: unable to write "
488fcf3ce44SJohn Forte 			    "to configuration: %s\n"),
489fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
490fcf3ce44SJohn Forte 		}
491fcf3ce44SJohn Forte 		commit = 0;
492fcf3ce44SJohn Forte 	}
493fcf3ce44SJohn Forte 
494fcf3ce44SJohn Forte 	cfg_close(cfg);
495fcf3ce44SJohn Forte }
496fcf3ce44SJohn Forte 
497fcf3ce44SJohn Forte 
498fcf3ce44SJohn Forte /*
499fcf3ce44SJohn Forte  * User visible configuration.
500fcf3ce44SJohn Forte  */
501fcf3ce44SJohn Forte 
502fcf3ce44SJohn Forte static const struct {
503fcf3ce44SJohn Forte 	const char *tag;	/* libcfg tag */
504fcf3ce44SJohn Forte 	const char *name;	/* user presented name */
505fcf3ce44SJohn Forte 	const char *help;	/* explanation string */
506fcf3ce44SJohn Forte } sdbc_cfg_options[] = {
507fcf3ce44SJohn Forte 	{ "thread", "nthreads", "number of threads" },
508fcf3ce44SJohn Forte 	{ "size", "cache_size", "total cache size" },
509fcf3ce44SJohn Forte #ifdef DEBUG
510fcf3ce44SJohn Forte 	{ "write_cache", "write_cache_size", "write cache size" },
511fcf3ce44SJohn Forte 	{ "fill_pattern", "fill_pattern", "debug fill pattern" },
512fcf3ce44SJohn Forte 	{ "reserved1", "reserved1", "unavailable, do not use" },
513fcf3ce44SJohn Forte 	{ "iobuf", "niobuf", "number of io buffers" },
514fcf3ce44SJohn Forte 	{ "tdemons", "ntdeamons", "number of sd_test daemons" },
515fcf3ce44SJohn Forte 	{ "forced_wrthru", "forced_wrthru", "override wrthru detection" },
516fcf3ce44SJohn Forte 	{ "no_forced_wrthru", "no_forced_wrthru", "override wrthru"},
517fcf3ce44SJohn Forte #endif
518fcf3ce44SJohn Forte 	{ NULL }
519fcf3ce44SJohn Forte };
520fcf3ce44SJohn Forte 
521fcf3ce44SJohn Forte 
522fcf3ce44SJohn Forte static int
523fcf3ce44SJohn Forte configure_sdbc(int argc, char *argv[], int optind)
524fcf3ce44SJohn Forte {
525fcf3ce44SJohn Forte 	CFGFILE *cfg;
526fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
527fcf3ce44SJohn Forte 	char *cp, option[CFG_MAX_BUF], value[CFG_MAX_BUF];
528fcf3ce44SJohn Forte 	const int opt_width = 20;
529fcf3ce44SJohn Forte 	int error, found, commit;
530fcf3ce44SJohn Forte 	int i;
531fcf3ce44SJohn Forte 
532fcf3ce44SJohn Forte 	error = commit = 0;
533fcf3ce44SJohn Forte 
534fcf3ce44SJohn Forte 	cfg = cfg_open(NULL);
535fcf3ce44SJohn Forte 	if (cfg == NULL) {
536fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s: unable to open configuration: %s",
537fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
538fcf3ce44SJohn Forte 		return (1);
539fcf3ce44SJohn Forte 	}
540fcf3ce44SJohn Forte 
541fcf3ce44SJohn Forte 	if (argc == optind) {
542fcf3ce44SJohn Forte 		/* display current user visible config */
543fcf3ce44SJohn Forte 
544fcf3ce44SJohn Forte 		if (!cfg_lock(cfg, CFG_RDLOCK)) {
545fcf3ce44SJohn Forte 			(void) fprintf(stderr,
546fcf3ce44SJohn Forte 			    gettext("%s: unable to lock configuration: %s\n"),
547fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
548fcf3ce44SJohn Forte 			error = 1;
549fcf3ce44SJohn Forte 			goto out;
550fcf3ce44SJohn Forte 		}
551fcf3ce44SJohn Forte 
552fcf3ce44SJohn Forte 		convert_config(cfg, CFG_RDLOCK);
553fcf3ce44SJohn Forte 
554fcf3ce44SJohn Forte 		for (i = 0; sdbc_cfg_options[i].tag != NULL; i++) {
555fcf3ce44SJohn Forte 			(void) snprintf(key, sizeof (key),
556fcf3ce44SJohn Forte 			    "scm.set1.%s", sdbc_cfg_options[i].tag);
557fcf3ce44SJohn Forte 			if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
558fcf3ce44SJohn Forte 				if (errno == ESRCH) {
559fcf3ce44SJohn Forte 					/* not found */
560*570de38fSSurya Prakki 					(void) strcpy(buf, "");
561fcf3ce44SJohn Forte 				} else {
562fcf3ce44SJohn Forte 					(void) fprintf(stderr,
563fcf3ce44SJohn Forte 					    gettext("%s: error reading "
564fcf3ce44SJohn Forte 					    "configuration: %s\n"),
565fcf3ce44SJohn Forte 					    progname, cfg_error(NULL));
566fcf3ce44SJohn Forte 					error = 1;
567fcf3ce44SJohn Forte 					goto out;
568fcf3ce44SJohn Forte 				}
569fcf3ce44SJohn Forte 			}
570fcf3ce44SJohn Forte 
571fcf3ce44SJohn Forte 			(void) printf("%-*s: %-*s /* %s */\n",
572fcf3ce44SJohn Forte 			    opt_width, sdbc_cfg_options[i].name,
573fcf3ce44SJohn Forte 			    opt_width, buf, sdbc_cfg_options[i].help);
574fcf3ce44SJohn Forte 		}
575fcf3ce44SJohn Forte 	} else {
576fcf3ce44SJohn Forte 		if (!cfg_lock(cfg, CFG_WRLOCK)) {
577fcf3ce44SJohn Forte 			(void) fprintf(stderr,
578fcf3ce44SJohn Forte 			    gettext("%s: unable to lock configuration: %s\n"),
579fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
580fcf3ce44SJohn Forte 			error = 1;
581fcf3ce44SJohn Forte 			goto out;
582fcf3ce44SJohn Forte 		}
583fcf3ce44SJohn Forte 
584fcf3ce44SJohn Forte 		convert_config(cfg, CFG_WRLOCK);
585fcf3ce44SJohn Forte 
586fcf3ce44SJohn Forte 		for (/*CSTYLED*/; optind < argc; optind++) {
587*570de38fSSurya Prakki 			(void) strncpy(option, argv[optind], sizeof (option));
588fcf3ce44SJohn Forte 			option[sizeof (option) - 1] = '\0';	/* terminate */
589fcf3ce44SJohn Forte 
590fcf3ce44SJohn Forte 			cp = strchr(option, '=');
591fcf3ce44SJohn Forte 			if (cp != NULL) {
592fcf3ce44SJohn Forte 				*cp = '\0';	/* terminate option */
593fcf3ce44SJohn Forte 				cp++;
594*570de38fSSurya Prakki 				(void) strncpy(value, cp, sizeof (value));
595fcf3ce44SJohn Forte 				value[sizeof (value) - 1] = '\0';
596fcf3ce44SJohn Forte 
597fcf3ce44SJohn Forte 				if (*value == '\0')
598*570de38fSSurya Prakki 					(void) strncpy(value, "-",
599*570de38fSSurya Prakki 					    sizeof (value));
600fcf3ce44SJohn Forte 			}
601fcf3ce44SJohn Forte 
602fcf3ce44SJohn Forte 			found = 0;
603fcf3ce44SJohn Forte 			for (i = 0; sdbc_cfg_options[i].tag != NULL; i++) {
604fcf3ce44SJohn Forte 				if (strcmp(option,
605fcf3ce44SJohn Forte 				    sdbc_cfg_options[i].name) == 0) {
606fcf3ce44SJohn Forte 					found = 1;
607fcf3ce44SJohn Forte 					break;
608fcf3ce44SJohn Forte 				}
609fcf3ce44SJohn Forte 			}
610fcf3ce44SJohn Forte 
611fcf3ce44SJohn Forte 			if (!found) {
612fcf3ce44SJohn Forte 				(void) fprintf(stderr,
613fcf3ce44SJohn Forte 				    gettext("%s: unknown configuration "
614fcf3ce44SJohn Forte 				    "parameter: %s\n"), progname, option);
615fcf3ce44SJohn Forte 				continue;
616fcf3ce44SJohn Forte 			}
617fcf3ce44SJohn Forte 
618fcf3ce44SJohn Forte 			(void) snprintf(key, sizeof (key),
619fcf3ce44SJohn Forte 			    "scm.set1.%s", sdbc_cfg_options[i].tag);
620fcf3ce44SJohn Forte 			if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
621fcf3ce44SJohn Forte 				(void) fprintf(stderr,
622fcf3ce44SJohn Forte 				    gettext("%s: error reading "
623fcf3ce44SJohn Forte 				    "configuration: %s\n"),
624fcf3ce44SJohn Forte 				    progname, cfg_error(NULL));
625fcf3ce44SJohn Forte 				error = 1;
626fcf3ce44SJohn Forte 				goto out;
627fcf3ce44SJohn Forte 			}
628fcf3ce44SJohn Forte 
629fcf3ce44SJohn Forte 			if (*buf == '\0')
630*570de38fSSurya Prakki 				(void) strncpy(buf, "<default>", sizeof (buf));
631fcf3ce44SJohn Forte 
632fcf3ce44SJohn Forte 			if (cp != NULL) {
633fcf3ce44SJohn Forte 				char *tmp;
634fcf3ce44SJohn Forte 				long val;
635fcf3ce44SJohn Forte 				/* set to new value */
636fcf3ce44SJohn Forte 
637fcf3ce44SJohn Forte 				if (strcmp(value, "-")) { /* default ? */
638fcf3ce44SJohn Forte 
639fcf3ce44SJohn Forte 					val = strtol(value, &tmp, 0);
640fcf3ce44SJohn Forte 					if (strcmp(value, tmp) == 0) {
641fcf3ce44SJohn Forte 						(void) fprintf(stderr,
642fcf3ce44SJohn Forte 						    gettext(
643fcf3ce44SJohn Forte 						    "%s: bad value (%s) "
644fcf3ce44SJohn Forte 						    "for option %s\n"),
645fcf3ce44SJohn Forte 						    progname, value, option);
646fcf3ce44SJohn Forte 						error = 1;
647fcf3ce44SJohn Forte 						goto out;
648fcf3ce44SJohn Forte 					}
649fcf3ce44SJohn Forte 
650fcf3ce44SJohn Forte 					/* make sure cache size is valid */
651fcf3ce44SJohn Forte 					if (strcmp(key, "scm.set1.size") == 0) {
652fcf3ce44SJohn Forte 						if (val > MAX_CACHE_SIZE) {
653fcf3ce44SJohn Forte 							PRINT_CACHE_SZ_ERR(val);
654fcf3ce44SJohn Forte 
655fcf3ce44SJohn Forte 							/*
656fcf3ce44SJohn Forte 							 * Overwrite the
657fcf3ce44SJohn Forte 							 * cache size with
658fcf3ce44SJohn Forte 							 * the maximum cache
659fcf3ce44SJohn Forte 							 * size.
660fcf3ce44SJohn Forte 							 */
661fcf3ce44SJohn Forte 							(void) snprintf(value,
662fcf3ce44SJohn Forte 							    sizeof (value),
663fcf3ce44SJohn Forte 							    "%ld",
664fcf3ce44SJohn Forte 							    (long)
665fcf3ce44SJohn Forte 							    MAX_CACHE_SIZE);
666fcf3ce44SJohn Forte 						}
667fcf3ce44SJohn Forte 					}
668fcf3ce44SJohn Forte 				}
669fcf3ce44SJohn Forte 
670fcf3ce44SJohn Forte 				if (cfg_put_cstring(cfg, key, value,
671fcf3ce44SJohn Forte 				    strlen(value)) < 0) {
672fcf3ce44SJohn Forte 					(void) fprintf(stderr,
673fcf3ce44SJohn Forte 					    gettext("\n%s: error writing "
674fcf3ce44SJohn Forte 					    "configuration: %s\n"),
675fcf3ce44SJohn Forte 					    progname, cfg_error(NULL));
676fcf3ce44SJohn Forte 					error = 1;
677fcf3ce44SJohn Forte 					goto out;
678fcf3ce44SJohn Forte 				}
679fcf3ce44SJohn Forte 
680fcf3ce44SJohn Forte 				(void) snprintf(buf, sizeof (buf),
681fcf3ce44SJohn Forte 				    "%s = %s", buf,
682fcf3ce44SJohn Forte 				    (strcmp(value, "-") == 0) ?
683fcf3ce44SJohn Forte 				    "<default>" : value);
684fcf3ce44SJohn Forte 
685fcf3ce44SJohn Forte 				commit = 1;
686fcf3ce44SJohn Forte 			}
687fcf3ce44SJohn Forte 
688fcf3ce44SJohn Forte 			(void) printf("%-*s: %-*s /* %s */\n",
689fcf3ce44SJohn Forte 			    opt_width, sdbc_cfg_options[i].name,
690fcf3ce44SJohn Forte 			    opt_width, buf, sdbc_cfg_options[i].help);
691fcf3ce44SJohn Forte 		} /* end command line args */
692fcf3ce44SJohn Forte 	}
693fcf3ce44SJohn Forte 
694fcf3ce44SJohn Forte out:
695fcf3ce44SJohn Forte 	if (commit) {
696fcf3ce44SJohn Forte 		if (!cfg_commit(cfg)) {
697fcf3ce44SJohn Forte 			(void) fprintf(stderr,
698fcf3ce44SJohn Forte 			    gettext("%s: unable to write "
699fcf3ce44SJohn Forte 			    "to configuration: %s\n"),
700fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
701fcf3ce44SJohn Forte 		}
702fcf3ce44SJohn Forte 		commit = 0;
703fcf3ce44SJohn Forte 
704fcf3ce44SJohn Forte 		(void) printf("\n%s\n",
705fcf3ce44SJohn Forte 		    gettext("Changed configuration parameters "
706fcf3ce44SJohn Forte 		    "will take effect when the cache is restarted"));
707fcf3ce44SJohn Forte 	}
708fcf3ce44SJohn Forte 
709fcf3ce44SJohn Forte 	cfg_close(cfg);
710fcf3ce44SJohn Forte 	return (error);
711fcf3ce44SJohn Forte }
712fcf3ce44SJohn Forte 
713fcf3ce44SJohn Forte 
714fcf3ce44SJohn Forte static char *
715fcf3ce44SJohn Forte cd_to_device(int cd)
716fcf3ce44SJohn Forte {
717fcf3ce44SJohn Forte 	static _sd_stats_t *cs_cur = NULL;
718fcf3ce44SJohn Forte 	spcs_s_info_t ustatus;
719fcf3ce44SJohn Forte 
720fcf3ce44SJohn Forte 	if (cs_cur == NULL) {
721fcf3ce44SJohn Forte 		cs_cur = malloc(sizeof (_sd_stats_t) +
722fcf3ce44SJohn Forte 		    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
723fcf3ce44SJohn Forte 
724fcf3ce44SJohn Forte 		if (cs_cur == NULL) {
725fcf3ce44SJohn Forte 			(void) fprintf(stderr, gettext("%s malloc: %s\n"),
726fcf3ce44SJohn Forte 			    progname, strerror(errno));
727fcf3ce44SJohn Forte 			exit(1);
728fcf3ce44SJohn Forte 		}
729fcf3ce44SJohn Forte 	}
730fcf3ce44SJohn Forte 
731fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0,
732fcf3ce44SJohn Forte 	    &ustatus) == SPCS_S_ERROR) {
733fcf3ce44SJohn Forte 		(void) fprintf(stderr,
734fcf3ce44SJohn Forte 		    gettext("%s: stats ioctl failed\n"), progname);
735fcf3ce44SJohn Forte 		sdbc_report_error(&ustatus);
736fcf3ce44SJohn Forte 		exit(1);
737fcf3ce44SJohn Forte 	}
738fcf3ce44SJohn Forte 	if (cs_cur->st_cachesize == 0 || cd >= cs_cur->st_count)
739fcf3ce44SJohn Forte 		return ("");
740fcf3ce44SJohn Forte 
741fcf3ce44SJohn Forte 	return (cs_cur->st_shared[cd].sh_filename);
742fcf3ce44SJohn Forte }
743fcf3ce44SJohn Forte 
744fcf3ce44SJohn Forte /*
745fcf3ce44SJohn Forte  * takes either either a string containing the cd or the device name, and
746fcf3ce44SJohn Forte  * returns the device name.
747fcf3ce44SJohn Forte  */
748fcf3ce44SJohn Forte static char *
749fcf3ce44SJohn Forte get_device_name(char *arg)
750fcf3ce44SJohn Forte {
751fcf3ce44SJohn Forte 	long cd = 0;
752fcf3ce44SJohn Forte 	char *device;
753fcf3ce44SJohn Forte 
754fcf3ce44SJohn Forte 	/* if the arg has a leading '/', assume it's a valid device name */
755fcf3ce44SJohn Forte 	if (!arg || *arg == '/') {
756fcf3ce44SJohn Forte 		return (arg);
757fcf3ce44SJohn Forte 	}
758fcf3ce44SJohn Forte 
759fcf3ce44SJohn Forte 	/* treat the "all" keyword as a valid device name */
760fcf3ce44SJohn Forte 	if (strcmp(arg, "all") == 0) {
761fcf3ce44SJohn Forte 		return (arg);
762fcf3ce44SJohn Forte 	}
763fcf3ce44SJohn Forte 
764fcf3ce44SJohn Forte 	/*
765fcf3ce44SJohn Forte 	 * Next, assume it's a cd, and try to convert it to an integer, and
766fcf3ce44SJohn Forte 	 * subsequently convert that cd to its corresponding device name.
767fcf3ce44SJohn Forte 	 *
768fcf3ce44SJohn Forte 	 * Since strtol returns 0 on failure, we need to make a special case
769fcf3ce44SJohn Forte 	 * for a cd of "0", which is valid.
770fcf3ce44SJohn Forte 	 */
771fcf3ce44SJohn Forte 	if (((cd = strtol(arg, (char **)NULL, 10)) > 0) ||
772fcf3ce44SJohn Forte 	    strcmp(arg, "0") == 0) {
773fcf3ce44SJohn Forte 		device = cd_to_device((int)cd);
774fcf3ce44SJohn Forte 
775fcf3ce44SJohn Forte 		/* cd_to_device returns NULL or "" on failure--check both */
776fcf3ce44SJohn Forte 		if (device && (strcmp(device, ""))) {
777fcf3ce44SJohn Forte 			/* it seems to be a valid device name */
778fcf3ce44SJohn Forte 			return (device);
779fcf3ce44SJohn Forte 		}
780fcf3ce44SJohn Forte 	}
781fcf3ce44SJohn Forte 
782fcf3ce44SJohn Forte 	return (NULL);
783fcf3ce44SJohn Forte }
784fcf3ce44SJohn Forte 
785fcf3ce44SJohn Forte static void
786fcf3ce44SJohn Forte remove_hint(char *device)
787fcf3ce44SJohn Forte {
788fcf3ce44SJohn Forte 	CFGFILE *cfg;
789fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
790fcf3ce44SJohn Forte 	int setnumber;
791fcf3ce44SJohn Forte 	int rc;
792fcf3ce44SJohn Forte 
793fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
794fcf3ce44SJohn Forte 		(void) fprintf(stderr,
795fcf3ce44SJohn Forte 		    gettext("%s: unable to access configuration: %s\n"),
796fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
797fcf3ce44SJohn Forte 		exit(1);
798fcf3ce44SJohn Forte 	}
799fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_WRLOCK)) {
800fcf3ce44SJohn Forte 		(void) fprintf(stderr,
801fcf3ce44SJohn Forte 		    gettext("%s: unable to lock configuration: %s\n"),
802fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
803fcf3ce44SJohn Forte 		exit(1);
804fcf3ce44SJohn Forte 	}
805fcf3ce44SJohn Forte 
806fcf3ce44SJohn Forte 	for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) {
807fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "cache_hint.set%d.device",
808fcf3ce44SJohn Forte 		    setnumber);
809fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg,  key,  buf, sizeof (buf)) < 0) {
810fcf3ce44SJohn Forte 			/* error or not found */
811fcf3ce44SJohn Forte 			break;
812fcf3ce44SJohn Forte 		}
813fcf3ce44SJohn Forte 
814fcf3ce44SJohn Forte 		if (strcmp(device, buf) != 0)
815fcf3ce44SJohn Forte 			continue;
816fcf3ce44SJohn Forte 
817fcf3ce44SJohn Forte 		/* remove config file entry */
818fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key),
819fcf3ce44SJohn Forte 		    "cache_hint.set%d", setnumber);
820fcf3ce44SJohn Forte 		rc = cfg_put_cstring(cfg, key, NULL, 0);
821fcf3ce44SJohn Forte 		if (rc < 0)
822fcf3ce44SJohn Forte 			(void) fprintf(stderr,
823fcf3ce44SJohn Forte 			    gettext("%s: unable to update configuration "
824fcf3ce44SJohn Forte 			    "storage: %s"),
825fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
826fcf3ce44SJohn Forte 		else if (!cfg_commit(cfg))
827fcf3ce44SJohn Forte 			(void) fprintf(stderr,
828fcf3ce44SJohn Forte 			    gettext("%s: unable to update configuration "
829fcf3ce44SJohn Forte 			    "storage: %s"),
830fcf3ce44SJohn Forte 			    progname, cfg_error(NULL));
831fcf3ce44SJohn Forte 		else
832fcf3ce44SJohn Forte 			(void) fprintf(stderr,
833fcf3ce44SJohn Forte 			    gettext("%s: persistent hint for %s"
834fcf3ce44SJohn Forte 			    " removed from configuration\n"),
835fcf3ce44SJohn Forte 			    progname, device);
836fcf3ce44SJohn Forte 		break;
837fcf3ce44SJohn Forte 	}
838fcf3ce44SJohn Forte 	cfg_close(cfg);
839fcf3ce44SJohn Forte }
840fcf3ce44SJohn Forte 
841fcf3ce44SJohn Forte 
842fcf3ce44SJohn Forte static void
843fcf3ce44SJohn Forte save_hint(int cd, int hint, int flag)
844fcf3ce44SJohn Forte {
845fcf3ce44SJohn Forte 	char device[NSC_MAXPATH];
846fcf3ce44SJohn Forte 	CFGFILE *cfg;
847fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
848fcf3ce44SJohn Forte 	int setnumber;
849fcf3ce44SJohn Forte 	int found;
850fcf3ce44SJohn Forte 	int rc;
851fcf3ce44SJohn Forte 
852fcf3ce44SJohn Forte 	if (hint != NSC_WRTHRU && hint != NSC_NOCACHE)
853fcf3ce44SJohn Forte 		return;
854fcf3ce44SJohn Forte 
855fcf3ce44SJohn Forte 	if (flag != 0 && flag != 1)
856fcf3ce44SJohn Forte 		return;
857fcf3ce44SJohn Forte 
858fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
859fcf3ce44SJohn Forte 		(void) fprintf(stderr,
860fcf3ce44SJohn Forte 		    gettext("%s: unable to access configuration: %s\n"),
861fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
862fcf3ce44SJohn Forte 		exit(1);
863fcf3ce44SJohn Forte 	}
864fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_WRLOCK)) {
865fcf3ce44SJohn Forte 		(void) fprintf(stderr,
866fcf3ce44SJohn Forte 		    gettext("%s: unable to lock configuration: %s\n"),
867fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
868fcf3ce44SJohn Forte 		exit(1);
869fcf3ce44SJohn Forte 	}
870fcf3ce44SJohn Forte 
871fcf3ce44SJohn Forte 	if (cd == -1)
872*570de38fSSurya Prakki 		(void) strcpy(device, "system");
873fcf3ce44SJohn Forte 	else
874*570de38fSSurya Prakki 		(void) strncpy(device, cd_to_device(cd), NSC_MAXPATH);
875fcf3ce44SJohn Forte 
876fcf3ce44SJohn Forte 	found = 0;
877fcf3ce44SJohn Forte 	for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) {
878fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "cache_hint.set%d.device",
879fcf3ce44SJohn Forte 		    setnumber);
880fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg,  key,  buf, sizeof (buf)) < 0) {
881fcf3ce44SJohn Forte 			/* error or not found */
882fcf3ce44SJohn Forte 			break;
883fcf3ce44SJohn Forte 		}
884fcf3ce44SJohn Forte 
885fcf3ce44SJohn Forte 		if (strcmp(device, buf) == 0) {
886fcf3ce44SJohn Forte 			found = 1;
887fcf3ce44SJohn Forte 			break;
888fcf3ce44SJohn Forte 		}
889fcf3ce44SJohn Forte 	}
890fcf3ce44SJohn Forte 
891fcf3ce44SJohn Forte 	if (found) {
892fcf3ce44SJohn Forte 		if (hint == NSC_WRTHRU)
893fcf3ce44SJohn Forte 			(void) snprintf(key, sizeof (key),
894fcf3ce44SJohn Forte 			    "cache_hint.set%d.wrthru", setnumber);
895fcf3ce44SJohn Forte 		else /* NSC_NOCACHE */
896fcf3ce44SJohn Forte 			(void) snprintf(key, sizeof (key),
897fcf3ce44SJohn Forte 			    "cache_hint.set%d.nordcache", setnumber);
898fcf3ce44SJohn Forte 		if (flag == 0)
899fcf3ce44SJohn Forte 			rc = cfg_put_cstring(cfg, key, "0", 1);
900fcf3ce44SJohn Forte 		else
901fcf3ce44SJohn Forte 			rc = cfg_put_cstring(cfg, key, "1", 1);
902fcf3ce44SJohn Forte 	} else {
903*570de38fSSurya Prakki 		(void) strncpy(buf, device, CFG_MAX_BUF);
904fcf3ce44SJohn Forte 		if (flag == 0)
905*570de38fSSurya Prakki 			(void) strncat(buf, " 0 0", CFG_MAX_BUF);
906fcf3ce44SJohn Forte 		else if (hint == NSC_WRTHRU)
907*570de38fSSurya Prakki 			(void) strncat(buf, " 1 0", CFG_MAX_BUF);
908fcf3ce44SJohn Forte 		else /* NSC_NOCACHE */
909*570de38fSSurya Prakki 			(void) strncat(buf, " 0 1", CFG_MAX_BUF);
910fcf3ce44SJohn Forte 		rc = cfg_put_cstring(cfg, "cache_hint", buf, sizeof (buf));
911fcf3ce44SJohn Forte 	}
912fcf3ce44SJohn Forte 
913fcf3ce44SJohn Forte 	if (rc < 0)
914fcf3ce44SJohn Forte 		(void) fprintf(stderr,
915fcf3ce44SJohn Forte 		    gettext("%s: unable to update configuration storage: %s"),
916fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
917fcf3ce44SJohn Forte 	else if (!cfg_commit(cfg))
918fcf3ce44SJohn Forte 		(void) fprintf(stderr,
919fcf3ce44SJohn Forte 		    gettext("%s: unable to update configuration storage: %s"),
920fcf3ce44SJohn Forte 		    progname, cfg_error(NULL));
921fcf3ce44SJohn Forte 	cfg_close(cfg);
922fcf3ce44SJohn Forte }
923fcf3ce44SJohn Forte 
924fcf3ce44SJohn Forte #ifdef lint
925fcf3ce44SJohn Forte int
926fcf3ce44SJohn Forte scmadm_lintmain(int argc, char *argv[])
927fcf3ce44SJohn Forte #else
928fcf3ce44SJohn Forte int
929fcf3ce44SJohn Forte main(int argc, char *argv[])
930fcf3ce44SJohn Forte #endif
931fcf3ce44SJohn Forte {
932fcf3ce44SJohn Forte 	int o = 0;
933fcf3ce44SJohn Forte 	int c;
934fcf3ce44SJohn Forte 	int errflg = 0;
935fcf3ce44SJohn Forte 	int hflag = 0;
936fcf3ce44SJohn Forte 	int qflag = 1;
937fcf3ce44SJohn Forte 	extern int optind;
938fcf3ce44SJohn Forte 	extern char *optarg;
939fcf3ce44SJohn Forte 	int cd;
940fcf3ce44SJohn Forte 	int hint;
941fcf3ce44SJohn Forte 	int flag;
942fcf3ce44SJohn Forte 	int optflag = 0;
943fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
944fcf3ce44SJohn Forte 	int Dopt, Lopt;
945fcf3ce44SJohn Forte 	int Oopt = 0;
946fcf3ce44SJohn Forte 	char *bitmapfs = NULL;
947fcf3ce44SJohn Forte 	const char *exclusive = gettext(
948fcf3ce44SJohn Forte 	    "-d, -e, -m, -o, -C, -D, -L, and -v "
949fcf3ce44SJohn Forte 	    "are mutually exclusive\n");
950fcf3ce44SJohn Forte 
951fcf3ce44SJohn Forte 	(void) setlocale(LC_ALL, "");
952fcf3ce44SJohn Forte 	(void) textdomain("scm");
953fcf3ce44SJohn Forte 
954fcf3ce44SJohn Forte 	progname = strdup(basename(argv[0]));
955fcf3ce44SJohn Forte 
956fcf3ce44SJohn Forte 	sdbc_set_maxdev();
957fcf3ce44SJohn Forte 
958fcf3ce44SJohn Forte 	buildusage(progname);
959fcf3ce44SJohn Forte 
960fcf3ce44SJohn Forte 	Dopt = Lopt = 0;
961fcf3ce44SJohn Forte 
962fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv,
963fcf3ce44SJohn Forte #ifdef DEBUG
964fcf3ce44SJohn Forte 	    "gi:t:S"
965fcf3ce44SJohn Forte #endif
966fcf3ce44SJohn Forte 	    "CD:LOa:devqhm:o:")) != EOF) {
967fcf3ce44SJohn Forte 
968fcf3ce44SJohn Forte 		switch (c) {
969fcf3ce44SJohn Forte 
970fcf3ce44SJohn Forte 		case 'D':
971fcf3ce44SJohn Forte 			if (optflag) {
972fcf3ce44SJohn Forte 				(void) fprintf(stderr, exclusive);
973fcf3ce44SJohn Forte 				goto usage;
974fcf3ce44SJohn Forte 			}
975fcf3ce44SJohn Forte 
976fcf3ce44SJohn Forte 			Dopt++;
977fcf3ce44SJohn Forte 			optflag++;
978fcf3ce44SJohn Forte 			bitmapfs = optarg;
979fcf3ce44SJohn Forte 			break;
980fcf3ce44SJohn Forte 
981fcf3ce44SJohn Forte 		case 'L':
982fcf3ce44SJohn Forte 			if (optflag) {
983fcf3ce44SJohn Forte 				(void) fprintf(stderr, exclusive);
984fcf3ce44SJohn Forte 				goto usage;
985fcf3ce44SJohn Forte 			}
986fcf3ce44SJohn Forte 
987fcf3ce44SJohn Forte 			Lopt++;
988fcf3ce44SJohn Forte 			optflag++;
989fcf3ce44SJohn Forte 			break;
990fcf3ce44SJohn Forte 
991fcf3ce44SJohn Forte #ifdef DEBUG
992fcf3ce44SJohn Forte 		case 'S':
993fcf3ce44SJohn Forte 			if (optflag) {
994fcf3ce44SJohn Forte 				(void) fprintf(stderr, exclusive);
995fcf3ce44SJohn Forte 				goto usage;
996fcf3ce44SJohn Forte 			}
997fcf3ce44SJohn Forte 
998fcf3ce44SJohn Forte 			if (putenv(stats_usage) != 0) {
999fcf3ce44SJohn Forte 				(void) fprintf(stderr,
1000fcf3ce44SJohn Forte 				    gettext("%s: unable to putenv()\n"),
1001fcf3ce44SJohn Forte 				    progname);
1002fcf3ce44SJohn Forte 				exit(1);
1003fcf3ce44SJohn Forte 			}
1004fcf3ce44SJohn Forte 
1005fcf3ce44SJohn Forte 			argv[1] = "scmadm";
1006fcf3ce44SJohn Forte 			if (execv(STATS_PATH, &argv[1]) == -1) {
1007fcf3ce44SJohn Forte 				(void) fprintf(stderr,
1008fcf3ce44SJohn Forte 				    gettext("%s: failed to execute " STATS_PATH
1009fcf3ce44SJohn Forte 					"\n"), progname);
1010fcf3ce44SJohn Forte 				(void) fprintf(stderr,
1011fcf3ce44SJohn Forte 				    gettext("Please be sure to copy sd_stats"
1012fcf3ce44SJohn Forte 					" from src/cmd/ns/sdbc in a development"
1013fcf3ce44SJohn Forte 					" workspace\n"));
1014fcf3ce44SJohn Forte 			}
1015fcf3ce44SJohn Forte 			exit(0);
1016fcf3ce44SJohn Forte 			break;
1017fcf3ce44SJohn Forte #endif
1018fcf3ce44SJohn Forte 		case 'a':
1019*570de38fSSurya Prakki 			(void) strcpy(alert_file, optarg);
1020fcf3ce44SJohn Forte 			break;
1021fcf3ce44SJohn Forte 		case 'q':
1022fcf3ce44SJohn Forte 			qflag++;
1023fcf3ce44SJohn Forte 			break;
1024fcf3ce44SJohn Forte 		case 'O': /* restore hints */
1025fcf3ce44SJohn Forte 			Oopt++;
1026fcf3ce44SJohn Forte 			break;
1027fcf3ce44SJohn Forte 		case 'C': /* configure */
1028fcf3ce44SJohn Forte 		case 'e': /* enable */
1029fcf3ce44SJohn Forte 		case 'd': /* disable */
1030fcf3ce44SJohn Forte 		case 'v': /* get version */
1031fcf3ce44SJohn Forte 		case 'o': /* get/set options */
1032fcf3ce44SJohn Forte 		case 'm': /* get cd map */
1033fcf3ce44SJohn Forte #ifdef DEBUG
1034fcf3ce44SJohn Forte 		case 't': /* trace */
1035fcf3ce44SJohn Forte 		case 'i': /* inject_ioerr */
1036fcf3ce44SJohn Forte 		case 'c': /* clear_ioerr */
1037fcf3ce44SJohn Forte 		case 'g': /* toggle_flush */
1038fcf3ce44SJohn Forte #endif
1039fcf3ce44SJohn Forte 			if (optflag) {
1040fcf3ce44SJohn Forte 				(void) fprintf(stderr,
1041fcf3ce44SJohn Forte #ifdef DEBUG
1042fcf3ce44SJohn Forte 				    "%s%s", gettext("-t, -i, -c, -g, "),
1043fcf3ce44SJohn Forte #endif
1044fcf3ce44SJohn Forte 				    exclusive);
1045fcf3ce44SJohn Forte 
1046fcf3ce44SJohn Forte 				errflg++;
1047fcf3ce44SJohn Forte 			}
1048fcf3ce44SJohn Forte 			optflag++;
1049fcf3ce44SJohn Forte 			o = c;
1050fcf3ce44SJohn Forte 			break;
1051fcf3ce44SJohn Forte 		case 'h':
1052fcf3ce44SJohn Forte 			hflag = 1;
1053fcf3ce44SJohn Forte 			break;
1054fcf3ce44SJohn Forte 		case '?':
1055fcf3ce44SJohn Forte 		default:
1056fcf3ce44SJohn Forte 			errflg++;
1057fcf3ce44SJohn Forte 			break;
1058fcf3ce44SJohn Forte 		}
1059fcf3ce44SJohn Forte 		if (errflg || hflag)
1060fcf3ce44SJohn Forte 			goto usage;
1061fcf3ce44SJohn Forte 	}
1062fcf3ce44SJohn Forte 
1063fcf3ce44SJohn Forte 	if (Oopt) {
1064fcf3ce44SJohn Forte 		/* Set hints saved in persistent configuration */
1065fcf3ce44SJohn Forte 		restore_hints();
1066fcf3ce44SJohn Forte 		exit(0);
1067fcf3ce44SJohn Forte 	}
1068fcf3ce44SJohn Forte 	if (Dopt || Lopt) {
1069fcf3ce44SJohn Forte 		/* bitmapfs control */
1070fcf3ce44SJohn Forte 
1071fcf3ce44SJohn Forte 		if (iscluster()) {
1072fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1073fcf3ce44SJohn Forte 			    gettext("%s: bitmap filesystems are not "
1074fcf3ce44SJohn Forte 			    "allowed in a cluster\n"), progname);
1075fcf3ce44SJohn Forte 			goto usage;
1076fcf3ce44SJohn Forte 		}
1077fcf3ce44SJohn Forte 
1078fcf3ce44SJohn Forte 		if ((Dopt + Lopt) > 1) {
1079fcf3ce44SJohn Forte 			(void) fprintf(stderr, gettext("-D and -L are"
1080fcf3ce44SJohn Forte 			    "mutually exclusive\n"));
1081fcf3ce44SJohn Forte 			goto usage;
1082fcf3ce44SJohn Forte 		}
1083fcf3ce44SJohn Forte 
1084fcf3ce44SJohn Forte 		if (Lopt)
1085fcf3ce44SJohn Forte 			bitmapfs_print();
1086fcf3ce44SJohn Forte 		else /* if (Dopt) */
1087fcf3ce44SJohn Forte 			bitmapfs_delete(bitmapfs);
1088fcf3ce44SJohn Forte 
1089fcf3ce44SJohn Forte 		exit(0);
1090fcf3ce44SJohn Forte 	}
1091fcf3ce44SJohn Forte 
1092fcf3ce44SJohn Forte 	if (!o) {
1093fcf3ce44SJohn Forte 		if (argc > 1)
1094fcf3ce44SJohn Forte 			goto usage;
1095fcf3ce44SJohn Forte 		(void) printf(gettext("%s: Printing all cd's and options:\n"),
1096fcf3ce44SJohn Forte 		    progname);
1097fcf3ce44SJohn Forte 		print_all_options();
1098fcf3ce44SJohn Forte 	}
1099fcf3ce44SJohn Forte 
1100fcf3ce44SJohn Forte 	/* Configure */
1101fcf3ce44SJohn Forte 	if (o == 'C') {
1102fcf3ce44SJohn Forte 		exit(configure_sdbc(argc, argv, optind));
1103fcf3ce44SJohn Forte 	}
1104fcf3ce44SJohn Forte 	/* enable */
1105fcf3ce44SJohn Forte 	if (o == 'e') {
1106fcf3ce44SJohn Forte 		enable_sdbc();
1107fcf3ce44SJohn Forte 		if (qflag == 0)
1108fcf3ce44SJohn Forte 			sd_gather_alert_dumps();
1109fcf3ce44SJohn Forte 		exit(0);
1110fcf3ce44SJohn Forte 	}
1111fcf3ce44SJohn Forte 	/* disable */
1112fcf3ce44SJohn Forte 	if (o == 'd') {
1113fcf3ce44SJohn Forte 		disable_sdbc();
1114fcf3ce44SJohn Forte 		exit(0);
1115fcf3ce44SJohn Forte 	}
1116fcf3ce44SJohn Forte 	/* get version */
1117fcf3ce44SJohn Forte 	if (o == 'v') {
1118fcf3ce44SJohn Forte 		get_version();
1119fcf3ce44SJohn Forte 		exit(0);
1120fcf3ce44SJohn Forte 	}
1121fcf3ce44SJohn Forte 	/* node_hint or cd_hint */
1122fcf3ce44SJohn Forte 	if (o == 'o') {
1123fcf3ce44SJohn Forte 		if (!(strcoll(optarg, "system"))) {  /* node_hint */
1124fcf3ce44SJohn Forte 			if ((optind - 1) == (argc - 1)) {  /* get */
1125fcf3ce44SJohn Forte 				if ((hint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0,
1126fcf3ce44SJohn Forte 				    0, 0, 0, &ustats)) == SPCS_S_ERROR) {
1127fcf3ce44SJohn Forte 					(void) fprintf(stderr,
1128fcf3ce44SJohn Forte 					    gettext("%s: get system "
1129fcf3ce44SJohn Forte 					    "options failed\n"),
1130fcf3ce44SJohn Forte 					    progname);
1131fcf3ce44SJohn Forte 					sdbc_report_error(&ustats);
1132fcf3ce44SJohn Forte 					exit(1);
1133fcf3ce44SJohn Forte 				}
1134fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
1135fcf3ce44SJohn Forte 				(void) printf(gettext("System Status: "));
1136fcf3ce44SJohn Forte 				print_hint(hint, 1);
1137fcf3ce44SJohn Forte #endif
1138fcf3ce44SJohn Forte 				(void) printf(gettext("System Options: "));
1139fcf3ce44SJohn Forte 				print_hint(hint, 0);
1140fcf3ce44SJohn Forte 				exit(0);
1141fcf3ce44SJohn Forte 			} else {  /* set, clear */
1142fcf3ce44SJohn Forte 				if (get_hint(argv[optind], &hint, &flag) == -1)
1143fcf3ce44SJohn Forte 					goto usage;
1144fcf3ce44SJohn Forte 				if (hint == -1) {
1145fcf3ce44SJohn Forte 					/* remove hint from config */
1146fcf3ce44SJohn Forte 					remove_hint("system");
1147fcf3ce44SJohn Forte 					exit(0);
1148fcf3ce44SJohn Forte 				}
1149fcf3ce44SJohn Forte 
1150fcf3ce44SJohn Forte 				if (SDBC_IOCTL(SDBC_SET_NODE_HINT, hint, flag,
1151fcf3ce44SJohn Forte 				    0, 0, 0, &ustats) == SPCS_S_ERROR) {
1152fcf3ce44SJohn Forte 					(void) fprintf(stderr,
1153fcf3ce44SJohn Forte 					    gettext("%s: set system "
1154fcf3ce44SJohn Forte 					    "option failed\n"),
1155fcf3ce44SJohn Forte 					    progname);
1156fcf3ce44SJohn Forte 					sdbc_report_error(&ustats);
1157fcf3ce44SJohn Forte 					exit(1);
1158fcf3ce44SJohn Forte 				}
1159fcf3ce44SJohn Forte 				save_hint(-1, hint, flag);
1160fcf3ce44SJohn Forte 				(void) printf(gettext("%s: System option %s"
1161fcf3ce44SJohn Forte 				    " now set.\n"), progname, argv[optind]);
1162fcf3ce44SJohn Forte 				exit(0);
1163fcf3ce44SJohn Forte 			}
1164fcf3ce44SJohn Forte 		} else {  /* cd_hint */
1165fcf3ce44SJohn Forte 			cd = get_cd(optarg);
1166fcf3ce44SJohn Forte 			if ((optind - 1) == (argc - 1)) {  /* get */
1167fcf3ce44SJohn Forte 				if (cd < 0) {
1168fcf3ce44SJohn Forte 					(void) fprintf(stderr,
1169fcf3ce44SJohn Forte 					    gettext("%s: device %s not "
1170fcf3ce44SJohn Forte 					    "found\n"),
1171fcf3ce44SJohn Forte 					    progname, optarg);
1172fcf3ce44SJohn Forte 					exit(1);
1173fcf3ce44SJohn Forte 				}
1174fcf3ce44SJohn Forte 				hint = get_cd_hint(cd);
1175fcf3ce44SJohn Forte 				(void) printf(gettext("%s: cd(%d) Current "
1176fcf3ce44SJohn Forte 				    "options are: "), progname, cd);
1177fcf3ce44SJohn Forte 				print_hint(hint, 0);
1178fcf3ce44SJohn Forte 				exit(0);
1179fcf3ce44SJohn Forte 			} else { /* set, clear */
1180fcf3ce44SJohn Forte 				if (get_hint(argv[optind], &hint, &flag) == -1)
1181fcf3ce44SJohn Forte 					goto usage;
1182fcf3ce44SJohn Forte 				if (hint == -1) {
1183fcf3ce44SJohn Forte 					/* remove hint from config */
1184fcf3ce44SJohn Forte 					if (cd < 0)
1185fcf3ce44SJohn Forte 						remove_hint(optarg);
1186fcf3ce44SJohn Forte 					else
1187fcf3ce44SJohn Forte 						remove_hint(cd_to_device(cd));
1188fcf3ce44SJohn Forte 					exit(0);
1189fcf3ce44SJohn Forte 				}
1190fcf3ce44SJohn Forte 				if (cd < 0) {
1191fcf3ce44SJohn Forte 					(void) fprintf(stderr,
1192fcf3ce44SJohn Forte 					    gettext("%s: device %s not "
1193fcf3ce44SJohn Forte 					    "found\n"),
1194fcf3ce44SJohn Forte 					    progname, optarg);
1195fcf3ce44SJohn Forte 					exit(1);
1196fcf3ce44SJohn Forte 				}
1197fcf3ce44SJohn Forte 
1198fcf3ce44SJohn Forte 				if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, hint,
1199fcf3ce44SJohn Forte 				    flag, 0, 0, &ustats) == SPCS_S_ERROR) {
1200fcf3ce44SJohn Forte 					(void) fprintf(stderr,
1201fcf3ce44SJohn Forte 					    gettext("%s: set option "
1202fcf3ce44SJohn Forte 					    "failed\n"), progname);
1203fcf3ce44SJohn Forte 					sdbc_report_error(&ustats);
1204fcf3ce44SJohn Forte 					exit(1);
1205fcf3ce44SJohn Forte 				}
1206fcf3ce44SJohn Forte 				save_hint(cd, hint, flag);
1207fcf3ce44SJohn Forte 				(void) printf(gettext("%s: cd %d option %s now"
1208fcf3ce44SJohn Forte 				    " set.\n"), progname, cd, argv[optind]);
1209fcf3ce44SJohn Forte 				exit(0);
1210fcf3ce44SJohn Forte 			}
1211fcf3ce44SJohn Forte 		}
1212fcf3ce44SJohn Forte 	}
1213fcf3ce44SJohn Forte 
1214fcf3ce44SJohn Forte 	if (o == 'm') {   /* "get_cd" = map */
1215fcf3ce44SJohn Forte 		char *dev_name;
1216fcf3ce44SJohn Forte 
1217fcf3ce44SJohn Forte 		if (!(strcoll(optarg, "all"))) /* all */
1218fcf3ce44SJohn Forte 			(void) get_cd_all();
1219fcf3ce44SJohn Forte 		else {
1220fcf3ce44SJohn Forte 			cd = get_cd(optarg);
1221fcf3ce44SJohn Forte 			if (cd < 0) {
1222fcf3ce44SJohn Forte 				(void) fprintf(stderr,
1223fcf3ce44SJohn Forte 				    gettext("%s: device or cd %s not found\n"),
1224fcf3ce44SJohn Forte 				    progname, optarg);
1225fcf3ce44SJohn Forte 				exit(1);
1226fcf3ce44SJohn Forte 			}
1227fcf3ce44SJohn Forte 
1228fcf3ce44SJohn Forte 			if ((dev_name = get_device_name(optarg)) == NULL) {
1229fcf3ce44SJohn Forte 				(void) fprintf(stderr, gettext(
1230fcf3ce44SJohn Forte 				    "%s: device for cd %d not found\n"),
1231fcf3ce44SJohn Forte 				    progname, cd);
1232fcf3ce44SJohn Forte 				exit(1);
1233fcf3ce44SJohn Forte 			}
1234fcf3ce44SJohn Forte 
1235fcf3ce44SJohn Forte 			(void) printf(gettext("%s: diskname %s; cd %d\n"),
1236fcf3ce44SJohn Forte 			    progname, dev_name, cd);
1237fcf3ce44SJohn Forte 			exit(0);
1238fcf3ce44SJohn Forte 		}
1239fcf3ce44SJohn Forte 	}
1240fcf3ce44SJohn Forte 
1241fcf3ce44SJohn Forte #ifdef DEBUG
1242fcf3ce44SJohn Forte 	if (o == 't') { /* "trace" */
1243fcf3ce44SJohn Forte 		int flag, value;
1244fcf3ce44SJohn Forte 		_sdtr_table_t tt;
1245fcf3ce44SJohn Forte 		if ((optind+1) != (argc-1))
1246fcf3ce44SJohn Forte 			goto usage;
1247fcf3ce44SJohn Forte 		cd = get_cd(argv[optind]);
1248fcf3ce44SJohn Forte 		if (cd < 0) {
1249fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1250fcf3ce44SJohn Forte 			    gettext("%s: device or cd %s not found\n"),
1251fcf3ce44SJohn Forte 			    progname, argv[optind]);
1252fcf3ce44SJohn Forte 			exit(1);
1253fcf3ce44SJohn Forte 		}
1254fcf3ce44SJohn Forte 
1255fcf3ce44SJohn Forte 		value = strtol(argv[optind+1], 0, 0);
1256fcf3ce44SJohn Forte 		if (!(strcoll(optarg, gettext("size")))) {
1257fcf3ce44SJohn Forte 			flag = SD_SET_SIZE;
1258fcf3ce44SJohn Forte 			tt.tt_max = value;
1259fcf3ce44SJohn Forte 		} else if (!(strcoll(optarg, gettext("mask")))) {
1260fcf3ce44SJohn Forte 			flag = SD_SET_MASK;
1261fcf3ce44SJohn Forte 			tt.tt_mask = value;
1262fcf3ce44SJohn Forte 		} else if (!(strcoll(optarg, gettext("lbolt")))) {
1263fcf3ce44SJohn Forte 			flag = SD_SET_LBOLT;
1264fcf3ce44SJohn Forte 			tt.tt_lbolt = value;
1265fcf3ce44SJohn Forte 		} else if (!(strcoll(optarg, gettext("good")))) {
1266fcf3ce44SJohn Forte 			flag = SD_SET_GOOD;
1267fcf3ce44SJohn Forte 			tt.tt_good = value;
1268fcf3ce44SJohn Forte 		} else	goto usage;
1269fcf3ce44SJohn Forte 
1270fcf3ce44SJohn Forte 		if (SDBC_IOCTL(SDBC_ADUMP, (long)cd, &tt, NULL, 0L,
1271fcf3ce44SJohn Forte 		    (long)flag, &ustats) == SPCS_S_ERROR) {
1272fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1273fcf3ce44SJohn Forte 			    gettext("%s: trace %s failed\n"),
1274fcf3ce44SJohn Forte 			    progname, optarg);
1275fcf3ce44SJohn Forte 			sdbc_report_error(&ustats);
1276fcf3ce44SJohn Forte 			exit(1);
1277fcf3ce44SJohn Forte 		}
1278fcf3ce44SJohn Forte 		(void) printf(gettext("%s: trace %s processed\n"),
1279fcf3ce44SJohn Forte 		    progname, optarg);
1280fcf3ce44SJohn Forte 		if (cd != -1)
1281fcf3ce44SJohn Forte 			(void) printf(gettext(" cd %d; size %d; mask 0x%04x; "
1282fcf3ce44SJohn Forte 			    "lbolt %d; good %d;\n"),
1283fcf3ce44SJohn Forte 			    cd, tt.tt_max, tt.tt_mask,
1284fcf3ce44SJohn Forte 			    tt.tt_lbolt, tt.tt_good);
1285fcf3ce44SJohn Forte 		exit(0);
1286fcf3ce44SJohn Forte 	}
1287fcf3ce44SJohn Forte 
1288fcf3ce44SJohn Forte 	if (o == 'i') { /* "inject_ioerr" */
1289fcf3ce44SJohn Forte 		int ioj_err = EIO;
1290fcf3ce44SJohn Forte 		int cd;
1291fcf3ce44SJohn Forte 		int ioj_cnt = 0;
1292fcf3ce44SJohn Forte 
1293fcf3ce44SJohn Forte 		/* a cd of "-1" represents all devices */
1294fcf3ce44SJohn Forte 		if (strcmp(optarg, "-1") == 0) {
1295fcf3ce44SJohn Forte 			cd = -1;
1296fcf3ce44SJohn Forte 		} else if ((cd = get_cd(optarg)) < 0) {
1297fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1298fcf3ce44SJohn Forte 			    gettext("%s: device or cd %s not found\n"),
1299fcf3ce44SJohn Forte 			    progname, optarg);
1300fcf3ce44SJohn Forte 			exit(1);
1301fcf3ce44SJohn Forte 		}
1302fcf3ce44SJohn Forte 		if (argc == 4)
1303fcf3ce44SJohn Forte 			ioj_err = strtol(argv[optind], 0, 0);
1304fcf3ce44SJohn Forte 		if (argc == 5)
1305fcf3ce44SJohn Forte 			ioj_cnt = strtol(argv[optind+1], 0, 0);
1306fcf3ce44SJohn Forte 
1307fcf3ce44SJohn Forte 		if (SDBC_IOCTL(SDBC_INJ_IOERR, cd, ioj_err, ioj_cnt, 0, 0,
1308fcf3ce44SJohn Forte 		    &ustats) == SPCS_S_ERROR)  {
1309fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1310fcf3ce44SJohn Forte 			    gettext("%s: i/o error injection for cd %s "
1311fcf3ce44SJohn Forte 			    "failed\n"), progname, optarg);
1312fcf3ce44SJohn Forte 			sdbc_report_error(&ustats);
1313fcf3ce44SJohn Forte 			exit(1);
1314fcf3ce44SJohn Forte 		}
1315fcf3ce44SJohn Forte 		(void) printf(gettext("%s: i/o error injection cd %d errno %d "
1316fcf3ce44SJohn Forte 		    "processed\n"), progname, cd, ioj_err);
1317fcf3ce44SJohn Forte 		exit(0);
1318fcf3ce44SJohn Forte 	}
1319fcf3ce44SJohn Forte 
1320fcf3ce44SJohn Forte 	if (o == 'c') { /* "clear_ioerr" */
1321fcf3ce44SJohn Forte 		int cd;
1322fcf3ce44SJohn Forte 
1323fcf3ce44SJohn Forte 		/* a cd of "-1" represents all devices */
1324fcf3ce44SJohn Forte 		if (strcmp(optarg, "-1") == 0) {
1325fcf3ce44SJohn Forte 			cd = -1;
1326fcf3ce44SJohn Forte 		} else if ((cd = get_cd(optarg)) < 0) {
1327fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1328fcf3ce44SJohn Forte 			    gettext("%s: device or cd %s not found\n"),
1329fcf3ce44SJohn Forte 			    progname, optarg);
1330fcf3ce44SJohn Forte 			exit(1);
1331fcf3ce44SJohn Forte 		}
1332fcf3ce44SJohn Forte 
1333fcf3ce44SJohn Forte 		if (SDBC_IOCTL(SDBC_CLR_IOERR, cd, 0, 0, 0, 0, &ustats)
1334fcf3ce44SJohn Forte 		    == SPCS_S_ERROR) {
1335fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1336fcf3ce44SJohn Forte 			    gettext("%s: i/o error clear %s failed\n"),
1337fcf3ce44SJohn Forte 			    progname, optarg);
1338fcf3ce44SJohn Forte 			sdbc_report_error(&ustats);
1339fcf3ce44SJohn Forte 			exit(1);
1340fcf3ce44SJohn Forte 		}
1341fcf3ce44SJohn Forte 		(void) printf(gettext("%s: i/o error clear for cd %d "
1342fcf3ce44SJohn Forte 		    "processed\n"), progname, cd);
1343fcf3ce44SJohn Forte 		exit(0);
1344fcf3ce44SJohn Forte 	}
1345fcf3ce44SJohn Forte 
1346fcf3ce44SJohn Forte 	if (o == 'g') { /* "toggle_flush" */
1347fcf3ce44SJohn Forte 		flag = toggle_flush();
1348fcf3ce44SJohn Forte 		(void) printf(gettext("%s: sdbc cache flush now %s\n"),
1349fcf3ce44SJohn Forte 		    progname, flag ? "on" : "off");
1350fcf3ce44SJohn Forte 		exit(0);
1351fcf3ce44SJohn Forte 	}
1352fcf3ce44SJohn Forte #endif /* DEBUG */
1353fcf3ce44SJohn Forte 
1354fcf3ce44SJohn Forte 	return (0);
1355fcf3ce44SJohn Forte usage:
1356fcf3ce44SJohn Forte 	(void) fprintf(stderr, "%s\n", scmadmUsage);
1357fcf3ce44SJohn Forte 	if (hflag) {
1358fcf3ce44SJohn Forte 		return (0);
1359fcf3ce44SJohn Forte 	}
1360fcf3ce44SJohn Forte 	return (1);
1361fcf3ce44SJohn Forte }
1362fcf3ce44SJohn Forte 
1363fcf3ce44SJohn Forte 
1364fcf3ce44SJohn Forte #define	addusage(f__)	\
1365*570de38fSSurya Prakki 	(void) strncat(scmadmUsage, f__, sizeof (scmadmUsage));
1366fcf3ce44SJohn Forte 
1367fcf3ce44SJohn Forte #define	addusage1(f__, a__)	\
1368fcf3ce44SJohn Forte 	(void) snprintf(fmt, sizeof (fmt), "%s%s", scmadmUsage, f__);	\
1369fcf3ce44SJohn Forte 	(void) snprintf(scmadmUsage, sizeof (scmadmUsage), fmt, a__);
1370fcf3ce44SJohn Forte 
1371fcf3ce44SJohn Forte #define	addusage2(f__, a__, b__)	\
1372fcf3ce44SJohn Forte 	(void) snprintf(fmt, sizeof (fmt), "%s%s", scmadmUsage, f__);	\
1373fcf3ce44SJohn Forte 	(void) snprintf(scmadmUsage, sizeof (scmadmUsage), fmt, a__, b__);
1374fcf3ce44SJohn Forte 
1375fcf3ce44SJohn Forte static void
1376fcf3ce44SJohn Forte buildusage(char *p)
1377fcf3ce44SJohn Forte {
1378fcf3ce44SJohn Forte 	char fmt[USAGELEN];
1379fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
1380fcf3ce44SJohn Forte 	char *hints_str = "[nordcache|rdcache|wrthru|nowrthru|forget]\n";
1381fcf3ce44SJohn Forte #else
1382fcf3ce44SJohn Forte 	char *hints_str = "[nordcache|rdcache|forget]\n";
1383fcf3ce44SJohn Forte #endif
1384fcf3ce44SJohn Forte 
1385fcf3ce44SJohn Forte 	bzero(scmadmUsage, sizeof (scmadmUsage));
1386fcf3ce44SJohn Forte 	bzero(fmt, sizeof (fmt));
1387fcf3ce44SJohn Forte 
1388fcf3ce44SJohn Forte 	addusage(gettext("Usage :\n"));
1389fcf3ce44SJohn Forte 	addusage1(gettext("\t%s\n"), p);
1390fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -h\n"), p);
1391fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -e\n"), p);
1392fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -d\n"), p);
1393fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -v\n"), p);
1394fcf3ce44SJohn Forte 	addusage1(gettext("\t%s {-L | -D bitmapfs}\n"), p);
1395fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -C [parameter[=[value]] ...]\n"), p);
1396fcf3ce44SJohn Forte 	addusage2(gettext("\t%s -o system %s"), p, hints_str);
1397fcf3ce44SJohn Forte 	addusage2(gettext("\t%s -o <cd> %s"), p, hints_str);
1398fcf3ce44SJohn Forte 	addusage2(gettext("\t%s -o <diskname> %s"), p, hints_str);
1399fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -m {<cd>|<diskname>|all}\n"), p);
1400fcf3ce44SJohn Forte #ifdef DEBUG
1401fcf3ce44SJohn Forte 	addusage1(gettext(
1402fcf3ce44SJohn Forte 	    "\t%s -S [-Mz] [-d delay_time] [-l logfile] [-r range]\n"), p);
1403fcf3ce44SJohn Forte 	addusage1(gettext(
1404fcf3ce44SJohn Forte 	    "\t%s -t {size|mask|lbolt|good} <cd|diskname> <value>\n"), p);
1405fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -g\n"), p);
1406fcf3ce44SJohn Forte 	addusage1(gettext(
1407fcf3ce44SJohn Forte 	    "\t%s -i {cd|diskname|-1 for all} [errno [countdown]]\n"), p);
1408fcf3ce44SJohn Forte 	addusage1(gettext("\t%s -c {cd|diskname|-1 for all}\n"), p);
1409fcf3ce44SJohn Forte 	addusage(gettext("\nt = trace\tg = toggle_flush\ti = inject ioerr\n"
1410fcf3ce44SJohn Forte 	    "c = clear ioerr\tS = stats\n"));
1411fcf3ce44SJohn Forte #endif /* DEBUG */
1412fcf3ce44SJohn Forte 	addusage(gettext(
1413fcf3ce44SJohn Forte 	    "e = enable\td = disable\tv=version\to = get/ set options\n"));
1414fcf3ce44SJohn Forte 	addusage(gettext(
1415fcf3ce44SJohn Forte 	    "m = get cd map\n"));
1416fcf3ce44SJohn Forte 	addusage1(gettext(
1417fcf3ce44SJohn Forte 	    "note: cd is a cache descriptor integer in the range [0-%d]\n"),
1418fcf3ce44SJohn Forte 	    sdbc_max_devices - 1);
1419fcf3ce44SJohn Forte 	addusage(gettext(
1420fcf3ce44SJohn Forte 	    "      bitmapfs is a block device or filesystem mount point\n"));
1421fcf3ce44SJohn Forte 
1422fcf3ce44SJohn Forte #ifdef DEBUG
1423fcf3ce44SJohn Forte 	(void) snprintf(stats_usage, sizeof (stats_usage),
1424fcf3ce44SJohn Forte 	    "SD_STATS_USAGE=%s", scmadmUsage);
1425fcf3ce44SJohn Forte #endif
1426fcf3ce44SJohn Forte }
1427fcf3ce44SJohn Forte 
1428fcf3ce44SJohn Forte static int
1429fcf3ce44SJohn Forte get_hint(char *str,  int *hint, int *flag)
1430fcf3ce44SJohn Forte {
1431fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
1432fcf3ce44SJohn Forte 	if (!(strcoll(str, gettext("wrthru")))) {
1433fcf3ce44SJohn Forte 		*hint = NSC_WRTHRU;
1434fcf3ce44SJohn Forte 		*flag = 1;
1435fcf3ce44SJohn Forte 		return (0);
1436fcf3ce44SJohn Forte 	} else if (!(strcoll(str, gettext("nowrthru")))) {
1437fcf3ce44SJohn Forte 		*hint =  NSC_WRTHRU;
1438fcf3ce44SJohn Forte 		*flag = 0;
1439fcf3ce44SJohn Forte 		return (0);
1440fcf3ce44SJohn Forte 	} else
1441fcf3ce44SJohn Forte #endif
1442fcf3ce44SJohn Forte 	if (!(strcoll(str, gettext("nordcache")))) {
1443fcf3ce44SJohn Forte 		*hint = NSC_NOCACHE;
1444fcf3ce44SJohn Forte 		*flag = 1;
1445fcf3ce44SJohn Forte 		return (0);
1446fcf3ce44SJohn Forte 	} else if (!(strcoll(str, gettext("rdcache")))) {
1447fcf3ce44SJohn Forte 		*hint = NSC_NOCACHE;
1448fcf3ce44SJohn Forte 		*flag = 0;
1449fcf3ce44SJohn Forte 		return (0);
1450fcf3ce44SJohn Forte 	} else if (!(strcoll(str, gettext("forget")))) {
1451fcf3ce44SJohn Forte 		*hint = -1;
1452fcf3ce44SJohn Forte 		*flag = 0;
1453fcf3ce44SJohn Forte 		return (0);
1454fcf3ce44SJohn Forte 	}
1455fcf3ce44SJohn Forte 	return (-1);
1456fcf3ce44SJohn Forte }
1457fcf3ce44SJohn Forte 
1458fcf3ce44SJohn Forte /*ARGSUSED*/
1459fcf3ce44SJohn Forte void
1460fcf3ce44SJohn Forte print_hint(const uint_t type, const int status)
1461fcf3ce44SJohn Forte {
1462fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
1463fcf3ce44SJohn Forte 	if (status) {
1464fcf3ce44SJohn Forte 		if (type & NSC_FORCED_WRTHRU) {
1465fcf3ce44SJohn Forte 			(void) printf(gettext("Fast Writes Overridden\n"));
1466fcf3ce44SJohn Forte 		} else {
1467fcf3ce44SJohn Forte 			/* if (type & NSC_NO_FORCED_WRTHRU) */
1468fcf3ce44SJohn Forte 			(void) printf(gettext("default\n"));
1469fcf3ce44SJohn Forte 		}
1470fcf3ce44SJohn Forte 	} else {
1471fcf3ce44SJohn Forte 		(void) printf("%swrthru, %srdcache",
1472fcf3ce44SJohn Forte 		    (type & (NSC_FORCED_WRTHRU|NSC_WRTHRU)) ? "" : "no",
1473fcf3ce44SJohn Forte 		    (type & NSC_NOCACHE) ? "no" : "");
1474fcf3ce44SJohn Forte #else
1475fcf3ce44SJohn Forte 	{
1476fcf3ce44SJohn Forte 		(void) printf("%srdcache", (type & NSC_NOCACHE) ? "no" : "");
1477fcf3ce44SJohn Forte #endif
1478fcf3ce44SJohn Forte 
1479fcf3ce44SJohn Forte 		if (type & 0x80000000)
1480fcf3ce44SJohn Forte 			(void) printf(" (overridden by system)");
1481fcf3ce44SJohn Forte 
1482fcf3ce44SJohn Forte 		(void) printf("\n");
1483fcf3ce44SJohn Forte 	}
1484fcf3ce44SJohn Forte }
1485fcf3ce44SJohn Forte 
1486fcf3ce44SJohn Forte /*
1487fcf3ce44SJohn Forte  * Read the configuration via libcfg
1488fcf3ce44SJohn Forte  */
1489fcf3ce44SJohn Forte 
1490fcf3ce44SJohn Forte int
1491fcf3ce44SJohn Forte get_cache_config()
1492fcf3ce44SJohn Forte {
1493fcf3ce44SJohn Forte 	int i;
1494fcf3ce44SJohn Forte 	int sysid;
1495fcf3ce44SJohn Forte 	CFGFILE *cfg;
1496fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
1497fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
1498fcf3ce44SJohn Forte 
1499fcf3ce44SJohn Forte 
1500fcf3ce44SJohn Forte 	if ((cfg = cfg_open(NULL)) == NULL) {
1501fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1502fcf3ce44SJohn Forte 		    gettext("Cannot open configuration file\n"));
1503fcf3ce44SJohn Forte 		exit(1);
1504fcf3ce44SJohn Forte 	}
1505fcf3ce44SJohn Forte 
1506fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, CFG_RDLOCK)) {
1507fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1508fcf3ce44SJohn Forte 		    gettext("Cannot lock configuration file\n"));
1509fcf3ce44SJohn Forte 		exit(1);
1510fcf3ce44SJohn Forte 	}
1511fcf3ce44SJohn Forte 
1512fcf3ce44SJohn Forte 	convert_config(cfg, CFG_RDLOCK);
1513fcf3ce44SJohn Forte 	(void) memset((char *)&user_level_conf, 0, sizeof (_sd_cache_param_t));
1514fcf3ce44SJohn Forte 
1515fcf3ce44SJohn Forte 	/* Get the system ID */
1516fcf3ce44SJohn Forte 	if (nsc_getsystemid(&sysid) < 0) {
1517fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1518fcf3ce44SJohn Forte 		    gettext("%s Unable to obtain subsystem ID: %s\n"),
1519fcf3ce44SJohn Forte 		    progname, strerror(errno));
1520fcf3ce44SJohn Forte 		exit(1);
1521fcf3ce44SJohn Forte 	}
1522fcf3ce44SJohn Forte 	myid = sysid;
1523fcf3ce44SJohn Forte 
1524fcf3ce44SJohn Forte 	user_level_conf.blk_size = 8192;	/* DEFAULT */
1525fcf3ce44SJohn Forte 	user_level_conf.procs = 16;	/* DEFAULT */
1526fcf3ce44SJohn Forte 	user_level_conf.reserved1 = RESERVED1_DEFAULTS;
1527fcf3ce44SJohn Forte 
1528fcf3ce44SJohn Forte 	bzero(buf, CFG_MAX_BUF);
1529fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.thread");
1530fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1531fcf3ce44SJohn Forte 		user_level_conf.threads = atoi(buf);
1532fcf3ce44SJohn Forte 	} else
1533fcf3ce44SJohn Forte 		user_level_conf.threads = 128;	/* DEFAULT */
1534fcf3ce44SJohn Forte 
1535fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.tdemons");
1536fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1537fcf3ce44SJohn Forte 		user_level_conf.test_demons = atoi(buf);
1538fcf3ce44SJohn Forte 	}
1539fcf3ce44SJohn Forte 
1540fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.write_cache");
1541fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1542fcf3ce44SJohn Forte 		user_level_conf.write_cache = atoi(buf);
1543fcf3ce44SJohn Forte 	}
1544fcf3ce44SJohn Forte 
1545fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.size");
1546fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1547fcf3ce44SJohn Forte 		/*
1548fcf3ce44SJohn Forte 		 * We need to run strtol for backwards compatibility in 3.2.
1549fcf3ce44SJohn Forte 		 * A workaround for this bug was put in 3.2 which allowed
1550fcf3ce44SJohn Forte 		 * customers to set the cache size up to 1024 if it was
1551fcf3ce44SJohn Forte 		 * specified in hexadecimal. Decimal still had the limit
1552fcf3ce44SJohn Forte 		 * of 128.  This change treats them both identically.
1553fcf3ce44SJohn Forte 		 */
1554fcf3ce44SJohn Forte 		user_level_conf.cache_mem[0] = (int)strtol(buf, NULL, 0);
1555fcf3ce44SJohn Forte 		if (user_level_conf.cache_mem[0] > MAX_CACHE_SIZE) {
1556fcf3ce44SJohn Forte 			(void) fprintf(stderr, gettext(
1557fcf3ce44SJohn Forte 			    "The cache size of %ld is larger than "
1558fcf3ce44SJohn Forte 			    "the system maximum of %ld.\nUse \"scmadm -C "
1559fcf3ce44SJohn Forte 			    "cache_size=<size>\" to set the size to a proper "
1560fcf3ce44SJohn Forte 			    "value.\n"),
1561fcf3ce44SJohn Forte 			    user_level_conf.cache_mem[0], MAX_CACHE_SIZE);
1562fcf3ce44SJohn Forte 			user_level_conf.cache_mem[0] = MAX_CACHE_SIZE;
1563fcf3ce44SJohn Forte 		}
1564fcf3ce44SJohn Forte 	}
1565fcf3ce44SJohn Forte 
1566fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.iobuf");
1567fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1568fcf3ce44SJohn Forte 		user_level_conf.iobuf = atoi(buf);
1569fcf3ce44SJohn Forte 	}
1570fcf3ce44SJohn Forte 
1571fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.fill_pattern");
1572fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1573fcf3ce44SJohn Forte 		user_level_conf.fill_pattern = atoi(buf);
1574fcf3ce44SJohn Forte 		user_level_conf.gen_pattern = 1;
1575fcf3ce44SJohn Forte 	}
1576fcf3ce44SJohn Forte 
1577fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.no_forced_wrthru");
1578fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1579fcf3ce44SJohn Forte 		no_forced_wrthru = atoi(buf);
1580fcf3ce44SJohn Forte 	}
1581fcf3ce44SJohn Forte 
1582fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.forced_wrthru");
1583fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1584fcf3ce44SJohn Forte 		forced_wrthru = atoi(buf);
1585fcf3ce44SJohn Forte 	}
1586fcf3ce44SJohn Forte 
1587fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "scm.set1.reserved1");
1588fcf3ce44SJohn Forte 	if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) {
1589fcf3ce44SJohn Forte 		user_level_conf.reserved1 = atoi(buf);
1590fcf3ce44SJohn Forte 	}
1591fcf3ce44SJohn Forte 
1592fcf3ce44SJohn Forte 	cfg_close(cfg);
1593fcf3ce44SJohn Forte 
1594fcf3ce44SJohn Forte 	/*
1595fcf3ce44SJohn Forte 	 * use the default minidsp configuration if no
1596fcf3ce44SJohn Forte 	 * node/mirror/remote-mirror/cluster line is in the sd.cf file
1597fcf3ce44SJohn Forte 	 */
1598fcf3ce44SJohn Forte 	if (nodes_configured == 0)
1599fcf3ce44SJohn Forte 		check_and_set_mirrors(myid, _SD_NO_HOST);
1600fcf3ce44SJohn Forte 
1601fcf3ce44SJohn Forte 
1602fcf3ce44SJohn Forte 	/* Check if our sysid was defined */
1603fcf3ce44SJohn Forte 	if (!node_defined[myid]) {
1604fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1605fcf3ce44SJohn Forte 		    gettext("This node(%d) is not defined in config.\n"), myid);
1606fcf3ce44SJohn Forte 		exit(1);
1607fcf3ce44SJohn Forte 	}
1608fcf3ce44SJohn Forte 
1609fcf3ce44SJohn Forte 	/*
1610fcf3ce44SJohn Forte 	 * Save off number of nodes so we can calculate the point-to-point
1611fcf3ce44SJohn Forte 	 * segements.  Code in kernel currently supports MAX_SD_NODES
1612fcf3ce44SJohn Forte 	 */
1613fcf3ce44SJohn Forte 	if ((user_level_conf.num_nodes = nodes_configured) >
1614fcf3ce44SJohn Forte 	    MAX_SD_NODES) {
1615fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1616fcf3ce44SJohn Forte 		    gettext("Cache can support only %d nodes(%d).\n"),
1617fcf3ce44SJohn Forte 		    MAX_SD_NODES, nodes_configured);
1618fcf3ce44SJohn Forte 		exit(1);
1619fcf3ce44SJohn Forte 	}
1620fcf3ce44SJohn Forte 
1621fcf3ce44SJohn Forte 	if ((nodes_configured % 2) && !minidsp) {
1622fcf3ce44SJohn Forte 		if (nodes_configured == 1)
1623fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1624fcf3ce44SJohn Forte 			    gettext("Only one node configured, "
1625fcf3ce44SJohn Forte 			    "mirror node must be %d\n"), _SD_NO_HOST);
1626fcf3ce44SJohn Forte 		else
1627fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1628fcf3ce44SJohn Forte 			    gettext("Cannot configure odd number of nodes.\n"));
1629fcf3ce44SJohn Forte 		exit(1);
1630fcf3ce44SJohn Forte 	}
1631fcf3ce44SJohn Forte 
1632fcf3ce44SJohn Forte 
1633fcf3ce44SJohn Forte 	/* Pass List of Nodes Configured to Cache */
1634fcf3ce44SJohn Forte 	for (i = 0; i < nodes_configured; i++)
1635fcf3ce44SJohn Forte 		user_level_conf.nodes_conf[i] = nodes_conf[i];
1636fcf3ce44SJohn Forte 
1637fcf3ce44SJohn Forte 	/* Place magic number in user_level_conf.  Kernel will test for it */
1638fcf3ce44SJohn Forte 	user_level_conf.magic = _SD_MAGIC;
1639fcf3ce44SJohn Forte 	(void) sleep(1);
1640fcf3ce44SJohn Forte 	return (0);
1641fcf3ce44SJohn Forte }
1642fcf3ce44SJohn Forte 
1643fcf3ce44SJohn Forte _sdtr_t hdr;
1644fcf3ce44SJohn Forte 
1645fcf3ce44SJohn Forte /* function name string */
1646fcf3ce44SJohn Forte char *
1647fcf3ce44SJohn Forte _sd_fname(int f)
1648fcf3ce44SJohn Forte {
1649fcf3ce44SJohn Forte 	int fn = f & ST_FUNC;
1650fcf3ce44SJohn Forte 	static char c[8];
1651fcf3ce44SJohn Forte 	char *s;
1652fcf3ce44SJohn Forte 
1653fcf3ce44SJohn Forte 	if (f & ST_BCACHE)
1654fcf3ce44SJohn Forte 		s = _bcache_fname[fn];
1655fcf3ce44SJohn Forte 	else if (f & ST_BSUB)
1656fcf3ce44SJohn Forte 		s = _bsub_fname[fn];
1657fcf3ce44SJohn Forte 	else if (f & ST_IO)
1658fcf3ce44SJohn Forte 		s = _io_fname[fn];
1659fcf3ce44SJohn Forte 	else if (f & ST_STATS)
1660fcf3ce44SJohn Forte 		s = _stats_fname[fn];
1661fcf3ce44SJohn Forte 	else if (f & ST_CCIO)
1662fcf3ce44SJohn Forte 		s = _ccio_fname[fn];
1663fcf3ce44SJohn Forte 	else if (f & ST_FT)
1664fcf3ce44SJohn Forte 		s = _ft_fname[fn];
1665fcf3ce44SJohn Forte 	else if (f & ST_INFO)
1666fcf3ce44SJohn Forte 		s = _info_fname[fn];
1667fcf3ce44SJohn Forte 	if (!s)
1668fcf3ce44SJohn Forte 		(void) sprintf(s = c, "0x%04x", f & 0xffff);
1669fcf3ce44SJohn Forte 	return (s);
1670fcf3ce44SJohn Forte }
1671fcf3ce44SJohn Forte 
1672fcf3ce44SJohn Forte int alerts = 0;
1673fcf3ce44SJohn Forte 
1674fcf3ce44SJohn Forte /*
1675fcf3ce44SJohn Forte  * Background daemon to wait for alert (on any device)
1676fcf3ce44SJohn Forte  * Writes the traces to "sd_alert.CD.NUM",
1677fcf3ce44SJohn Forte  * and writes an information message to the alert_file.
1678fcf3ce44SJohn Forte  */
1679fcf3ce44SJohn Forte 
1680fcf3ce44SJohn Forte void
1681fcf3ce44SJohn Forte sd_gather_alert_dumps()
1682fcf3ce44SJohn Forte {
1683fcf3ce44SJohn Forte 	_sdtr_table_t tt;
1684fcf3ce44SJohn Forte 	_sdtr_t *buf;
1685fcf3ce44SJohn Forte 	int cd, count, size, flag;
1686fcf3ce44SJohn Forte 	char filename[64];
1687fcf3ce44SJohn Forte 	int fd;
1688fcf3ce44SJohn Forte 	time_t tloc;
1689fcf3ce44SJohn Forte 	struct tm tm_storage;
1690fcf3ce44SJohn Forte 	struct tm *tm_ptr;
1691fcf3ce44SJohn Forte 	char timebuf[80];
1692fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
1693fcf3ce44SJohn Forte 
1694fcf3ce44SJohn Forte 	/* fork and detach daemon */
1695fcf3ce44SJohn Forte 	if (fork())
1696fcf3ce44SJohn Forte 		exit(0);
1697fcf3ce44SJohn Forte 	(void) close(0);
1698fcf3ce44SJohn Forte 	fd = open(alert_file, O_WRONLY|O_APPEND|O_CREAT, 0644);
1699fcf3ce44SJohn Forte 	if (fd == -1)
1700fcf3ce44SJohn Forte 		fd = open("/dev/console", O_WRONLY);
1701fcf3ce44SJohn Forte 	if (fd != -1) {
1702fcf3ce44SJohn Forte 		(void) dup2(fd, 1);
1703fcf3ce44SJohn Forte 		(void) dup2(fd, 2);
1704fcf3ce44SJohn Forte 		(void) close(fd);
1705fcf3ce44SJohn Forte 	}
1706fcf3ce44SJohn Forte 	(void) setsid();
1707fcf3ce44SJohn Forte 
1708fcf3ce44SJohn Forte 	size = 10000;
1709fcf3ce44SJohn Forte 	if (size < user_level_conf.trace_size)
1710fcf3ce44SJohn Forte 		size = user_level_conf.trace_size;
1711fcf3ce44SJohn Forte 
1712fcf3ce44SJohn Forte 	buf = (_sdtr_t *)malloc(size * sizeof (_sdtr_t));
1713fcf3ce44SJohn Forte 	if (!buf) {
1714fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s malloc: %s\n"),
1715fcf3ce44SJohn Forte 		    progname, strerror(errno));
1716fcf3ce44SJohn Forte 		exit(1);
1717fcf3ce44SJohn Forte 	}
1718fcf3ce44SJohn Forte 	tloc = time(NULL);
1719fcf3ce44SJohn Forte 	tm_ptr = (struct tm *)localtime_r(&tloc, &tm_storage);
1720fcf3ce44SJohn Forte 
1721fcf3ce44SJohn Forte loop:
1722fcf3ce44SJohn Forte 	cd = SDT_ANY_CD;		/* any device */
1723fcf3ce44SJohn Forte 	flag = SD_ALERT_WAIT;	/* block for alert */
1724fcf3ce44SJohn Forte 	if ((count = SDBC_IOCTL(SDBC_ADUMP, cd, &tt, buf, size,
1725fcf3ce44SJohn Forte 	    flag, &ustats)) == SPCS_S_ERROR) {
1726fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: sd_adump\n"), progname);
1727fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
1728fcf3ce44SJohn Forte 		if (errno == EIDRM) {
1729fcf3ce44SJohn Forte 			(void) strftime(timebuf, 80, "%x %X", tm_ptr);
1730fcf3ce44SJohn Forte 			(void) fprintf(stderr,
1731fcf3ce44SJohn Forte 			    gettext("%s: cache deconfigured at %s\n"),
1732fcf3ce44SJohn Forte 			    progname, timebuf);
1733fcf3ce44SJohn Forte 			exit(0);
1734fcf3ce44SJohn Forte 		}
1735fcf3ce44SJohn Forte 		if (errno == ENOSYS)
1736fcf3ce44SJohn Forte 			exit(0);
1737fcf3ce44SJohn Forte 		exit(errno);
1738fcf3ce44SJohn Forte 	}
1739fcf3ce44SJohn Forte 	if (count == 0)
1740fcf3ce44SJohn Forte 		goto loop;
1741fcf3ce44SJohn Forte 	cd = tt.tt_cd;
1742fcf3ce44SJohn Forte 	(void) sprintf(filename, "%s.%d.%d", "sd_alert", cd, alerts++);
1743fcf3ce44SJohn Forte 	if ((fd = open(filename, O_CREAT | O_RDWR, 0444)) == -1) {
1744fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: open: %s\n"),
1745fcf3ce44SJohn Forte 		    progname, strerror(errno));
1746fcf3ce44SJohn Forte 		exit(errno);
1747fcf3ce44SJohn Forte 	}
1748fcf3ce44SJohn Forte 	/*
1749fcf3ce44SJohn Forte 	 * write header to identify device, write entries
1750fcf3ce44SJohn Forte 	 */
1751fcf3ce44SJohn Forte 	hdr.t_func = SDF_CD;
1752fcf3ce44SJohn Forte 	hdr.t_len = count;
1753fcf3ce44SJohn Forte 	hdr.t_ret = tt.tt_cd;
1754fcf3ce44SJohn Forte 	if (write(fd, &hdr, sizeof (_sdtr_t)) == -1) {
1755fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: write: %s\n"),
1756fcf3ce44SJohn Forte 		    progname, strerror(errno));
1757fcf3ce44SJohn Forte 		exit(errno);
1758fcf3ce44SJohn Forte 	}
1759fcf3ce44SJohn Forte 
1760fcf3ce44SJohn Forte 	if (write(fd, buf, sizeof (_sdtr_t)*count) == -1) {
1761fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: write: %s\n"),
1762fcf3ce44SJohn Forte 		    progname, strerror(errno));
1763fcf3ce44SJohn Forte 		exit(errno);
1764fcf3ce44SJohn Forte 	}
1765fcf3ce44SJohn Forte 	(void) close(fd);
1766fcf3ce44SJohn Forte 
1767fcf3ce44SJohn Forte 	(void) strftime(timebuf, 80, "%x %X", tm_ptr);
1768fcf3ce44SJohn Forte 	(void) printf("sd alert trace dump %s at %s\n", filename, timebuf);
1769fcf3ce44SJohn Forte 	goto loop;
1770fcf3ce44SJohn Forte }
1771fcf3ce44SJohn Forte 
1772fcf3ce44SJohn Forte 
1773fcf3ce44SJohn Forte 
1774fcf3ce44SJohn Forte /*
1775fcf3ce44SJohn Forte  * print list of configured cd's, diskname, options and global options
1776fcf3ce44SJohn Forte  */
1777fcf3ce44SJohn Forte void
1778fcf3ce44SJohn Forte print_all_options()
1779fcf3ce44SJohn Forte {
1780fcf3ce44SJohn Forte 	static _sd_stats_t *cs_cur;
1781fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
1782fcf3ce44SJohn Forte 	int cd;
1783fcf3ce44SJohn Forte 	int hint;
1784fcf3ce44SJohn Forte 	char *s1 = "device name";
1785fcf3ce44SJohn Forte 	char *s2 = "option";
1786fcf3ce44SJohn Forte 	char fn[19];
1787fcf3ce44SJohn Forte 	int len;
1788fcf3ce44SJohn Forte 
1789fcf3ce44SJohn Forte 	/* No corresponding free because this function exits */
1790fcf3ce44SJohn Forte 	cs_cur = malloc(sizeof (_sd_stats_t) +
1791fcf3ce44SJohn Forte 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
1792fcf3ce44SJohn Forte 	if (cs_cur == NULL) {
1793fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s malloc: %s\n"),
1794fcf3ce44SJohn Forte 		    progname, strerror(errno));
1795fcf3ce44SJohn Forte 		exit(1);
1796fcf3ce44SJohn Forte 	}
1797fcf3ce44SJohn Forte 
1798fcf3ce44SJohn Forte 	/* node hints */
1799fcf3ce44SJohn Forte 	if ((hint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, 0, 0, 0,
1800fcf3ce44SJohn Forte 	    &ustats)) == SPCS_S_ERROR) {
1801fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1802fcf3ce44SJohn Forte 		    gettext("%s: get system option failed\n"),
1803fcf3ce44SJohn Forte 		    progname);
1804fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
1805fcf3ce44SJohn Forte 		exit(1);
1806fcf3ce44SJohn Forte 	}
1807fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
1808fcf3ce44SJohn Forte 	(void) printf(gettext("System Status: "));
1809fcf3ce44SJohn Forte 	print_hint(hint, 1);
1810fcf3ce44SJohn Forte #endif
1811fcf3ce44SJohn Forte 	(void) printf(gettext("System Options: "));
1812fcf3ce44SJohn Forte 	print_hint(hint, 0);
1813fcf3ce44SJohn Forte 
1814fcf3ce44SJohn Forte 	/* get cds */
1815fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats)
1816fcf3ce44SJohn Forte 	    == SPCS_S_ERROR) {
1817fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1818fcf3ce44SJohn Forte 		    gettext("%s: get_cd failed in print_all options\n"),
1819fcf3ce44SJohn Forte 		    progname);
1820fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
1821fcf3ce44SJohn Forte 		exit(1);
1822fcf3ce44SJohn Forte 	}
1823fcf3ce44SJohn Forte 	if (cs_cur->st_cachesize == 0)
1824fcf3ce44SJohn Forte 		(void) printf(gettext("Cache is disabled\n"));
1825fcf3ce44SJohn Forte 	else if (cs_cur->st_count == 0)
1826fcf3ce44SJohn Forte 		(void) printf(gettext("No devices are configured\n"));
1827fcf3ce44SJohn Forte 	else {
1828fcf3ce44SJohn Forte 		(void) printf(
1829fcf3ce44SJohn Forte 		    gettext("\nConfigured cd's, disknames and options: \n"));
1830fcf3ce44SJohn Forte 		(void) printf(gettext("cd\t%-28s\t%-20s\n"), s1, s2);
1831fcf3ce44SJohn Forte 		for (cd = 0; cd < cs_cur->st_count; cd++) {
1832fcf3ce44SJohn Forte 			if (cs_cur->st_shared[cd].sh_alloc) {
1833fcf3ce44SJohn Forte 				hint = get_cd_hint(cd);
1834fcf3ce44SJohn Forte 				if ((len =
1835fcf3ce44SJohn Forte 				    strlen(cs_cur->st_shared[cd].sh_filename))
1836fcf3ce44SJohn Forte 				    > 23) {
1837*570de38fSSurya Prakki 					(void) strcpy(fn, "...");
1838*570de38fSSurya Prakki 					(void) strcat(fn,
1839fcf3ce44SJohn Forte 					    cs_cur->st_shared[cd].sh_filename +
1840fcf3ce44SJohn Forte 					    len - 20);
1841fcf3ce44SJohn Forte 				} else {
1842*570de38fSSurya Prakki 					(void) strcpy(fn,
1843fcf3ce44SJohn Forte 					    cs_cur->st_shared[cd].sh_filename);
1844fcf3ce44SJohn Forte 				}
1845fcf3ce44SJohn Forte 
1846fcf3ce44SJohn Forte 				(void) printf(gettext("%d\t%-28.*s\t"), cd,
1847fcf3ce44SJohn Forte 				    NSC_MAXPATH, fn);
1848fcf3ce44SJohn Forte 
1849fcf3ce44SJohn Forte 				print_hint(hint, 0);
1850fcf3ce44SJohn Forte 			}
1851fcf3ce44SJohn Forte 		}
1852fcf3ce44SJohn Forte 	}
1853fcf3ce44SJohn Forte 	exit(0);
1854fcf3ce44SJohn Forte }
1855fcf3ce44SJohn Forte 
1856fcf3ce44SJohn Forte 
1857fcf3ce44SJohn Forte /*
1858fcf3ce44SJohn Forte  * cache device -- lookup names and cache descriptors of all configured devices
1859fcf3ce44SJohn Forte  */
1860fcf3ce44SJohn Forte void
1861fcf3ce44SJohn Forte get_cd_all()
1862fcf3ce44SJohn Forte {
1863fcf3ce44SJohn Forte 	static _sd_stats_t *cs_cur;
1864fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
1865fcf3ce44SJohn Forte 	int cd;
1866fcf3ce44SJohn Forte 	char fn[19];
1867fcf3ce44SJohn Forte 	int len;
1868fcf3ce44SJohn Forte 
1869fcf3ce44SJohn Forte 	/* No corresponding free because this function exits */
1870fcf3ce44SJohn Forte 	cs_cur = malloc(sizeof (_sd_stats_t) +
1871fcf3ce44SJohn Forte 	    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
1872fcf3ce44SJohn Forte 	if (cs_cur == NULL) {
1873fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s malloc: %s\n"),
1874fcf3ce44SJohn Forte 		    progname, strerror(errno));
1875fcf3ce44SJohn Forte 		exit(1);
1876fcf3ce44SJohn Forte 	}
1877fcf3ce44SJohn Forte 
1878fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats)
1879fcf3ce44SJohn Forte 	    == SPCS_S_ERROR) {
1880fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: get_cd_all"),
1881fcf3ce44SJohn Forte 		    progname);
1882fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
1883fcf3ce44SJohn Forte 		exit(1);
1884fcf3ce44SJohn Forte 	}
1885fcf3ce44SJohn Forte 	if (cs_cur->st_cachesize == 0)
1886fcf3ce44SJohn Forte 		(void) printf(gettext("Cache is disabled\n"));
1887fcf3ce44SJohn Forte 	else if (cs_cur->st_count == 0)
1888fcf3ce44SJohn Forte 		(void) printf(gettext("No devices are configured\n"));
1889fcf3ce44SJohn Forte 	else {
1890fcf3ce44SJohn Forte 		(void) printf(gettext("\tcd\tdevice name\n"));
1891fcf3ce44SJohn Forte 		for (cd = 0; cd < cs_cur->st_count; cd++) {
1892fcf3ce44SJohn Forte 			if (cs_cur->st_shared[cd].sh_alloc) {
1893fcf3ce44SJohn Forte 				if ((len = strlen(
1894fcf3ce44SJohn Forte 				    cs_cur->st_shared[cd].sh_filename)) > 15) {
1895*570de38fSSurya Prakki 					(void) strcpy(fn, "...");
1896*570de38fSSurya Prakki 					(void) strcat(fn,
1897fcf3ce44SJohn Forte 					    cs_cur->st_shared[cd].sh_filename +
1898fcf3ce44SJohn Forte 					    len - 12);
1899fcf3ce44SJohn Forte 				} else {
1900*570de38fSSurya Prakki 					(void) strcpy(fn,
1901fcf3ce44SJohn Forte 					    cs_cur->st_shared[cd].sh_filename);
1902fcf3ce44SJohn Forte 				}
1903fcf3ce44SJohn Forte 				(void) printf(gettext("\t%d\t%s\n"),
1904fcf3ce44SJohn Forte 				    cd, fn);
1905fcf3ce44SJohn Forte 			}
1906fcf3ce44SJohn Forte 		}
1907fcf3ce44SJohn Forte 	}
1908fcf3ce44SJohn Forte 	exit(0);
1909fcf3ce44SJohn Forte }
1910fcf3ce44SJohn Forte 
1911fcf3ce44SJohn Forte /*
1912fcf3ce44SJohn Forte  * cache device -- specified by number or lookup name
1913fcf3ce44SJohn Forte  */
1914fcf3ce44SJohn Forte static int
1915fcf3ce44SJohn Forte get_cd(char *s)
1916fcf3ce44SJohn Forte {
1917fcf3ce44SJohn Forte 	static _sd_stats_t *cs_cur = NULL;
1918fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
1919fcf3ce44SJohn Forte 	int cd, arg_cd = -1;
1920fcf3ce44SJohn Forte 
1921fcf3ce44SJohn Forte 	if (cs_cur == NULL) {
1922fcf3ce44SJohn Forte 		/*
1923fcf3ce44SJohn Forte 		 * No corresponding free because the memory is reused
1924fcf3ce44SJohn Forte 		 * every time the function is called.
1925fcf3ce44SJohn Forte 		 */
1926fcf3ce44SJohn Forte 		cs_cur = malloc(sizeof (_sd_stats_t) +
1927fcf3ce44SJohn Forte 		    (sdbc_max_devices - 1) * sizeof (_sd_shared_t));
1928fcf3ce44SJohn Forte 		if (cs_cur == NULL) {
1929fcf3ce44SJohn Forte 			(void) fprintf(stderr, gettext("%s malloc: %s\n"),
1930fcf3ce44SJohn Forte 			    progname, strerror(errno));
1931fcf3ce44SJohn Forte 			exit(1);
1932fcf3ce44SJohn Forte 		}
1933fcf3ce44SJohn Forte 	}
1934fcf3ce44SJohn Forte 
1935fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats)
1936fcf3ce44SJohn Forte 	    == SPCS_S_ERROR) {
1937fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: get_cd\n"), progname);
1938fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
1939fcf3ce44SJohn Forte 		exit(1);
1940fcf3ce44SJohn Forte 	}
1941fcf3ce44SJohn Forte 	if (cs_cur->st_cachesize == 0) {
1942fcf3ce44SJohn Forte 		(void) printf(gettext("Cache is disabled\n"));
1943fcf3ce44SJohn Forte 		exit(0);
1944fcf3ce44SJohn Forte 	}
1945fcf3ce44SJohn Forte 
1946fcf3ce44SJohn Forte 	if (*s != '/') {
1947fcf3ce44SJohn Forte 		/*
1948fcf3ce44SJohn Forte 		 * Since strtol returns 0 on failure, we need to make a
1949fcf3ce44SJohn Forte 		 * special case for a cd of "0", which is valid.
1950fcf3ce44SJohn Forte 		 *
1951fcf3ce44SJohn Forte 		 * This case also deals with the difference between
1952fcf3ce44SJohn Forte 		 * scmadm -o system and scmadm -o 0
1953fcf3ce44SJohn Forte 		 */
1954fcf3ce44SJohn Forte 		if (((int)strtol(s, (char **)NULL, 10) == 0) &&
1955fcf3ce44SJohn Forte 		    strcmp(s, "0"))
1956fcf3ce44SJohn Forte 			return (-1);
1957fcf3ce44SJohn Forte 
1958fcf3ce44SJohn Forte 		/*
1959fcf3ce44SJohn Forte 		 * Only return failure at this point, in order to allow
1960fcf3ce44SJohn Forte 		 * checking arg_cd against st_count later on.
1961fcf3ce44SJohn Forte 		 */
1962fcf3ce44SJohn Forte 		if ((arg_cd = strtol(s, 0, 0)) < 0) {
1963fcf3ce44SJohn Forte 			return (arg_cd);
1964fcf3ce44SJohn Forte 		}
1965fcf3ce44SJohn Forte 	}
1966fcf3ce44SJohn Forte 
1967fcf3ce44SJohn Forte 	/* make sure the cd passed as an argument is alloc'd and < st_count */
1968fcf3ce44SJohn Forte 	if (arg_cd >= 0) {
1969fcf3ce44SJohn Forte 		return (((arg_cd < cs_cur->st_count) &&
1970fcf3ce44SJohn Forte 		    (cs_cur->st_shared[arg_cd].sh_alloc)) ? arg_cd : -1);
1971fcf3ce44SJohn Forte 	}
1972fcf3ce44SJohn Forte 
1973fcf3ce44SJohn Forte 	for (cd = 0; cd < cs_cur->st_count; cd++) {
1974fcf3ce44SJohn Forte 		if (cs_cur->st_shared[cd].sh_alloc &&
1975fcf3ce44SJohn Forte 		    strcmp(s, cs_cur->st_shared[cd].sh_filename) == 0)
1976fcf3ce44SJohn Forte 			return (cd);
1977fcf3ce44SJohn Forte 	}
1978fcf3ce44SJohn Forte 	return (-1);
1979fcf3ce44SJohn Forte }
1980fcf3ce44SJohn Forte 
1981fcf3ce44SJohn Forte void
1982fcf3ce44SJohn Forte check_and_set_mirrors(int node, int mirror)
1983fcf3ce44SJohn Forte {
1984fcf3ce44SJohn Forte 
1985fcf3ce44SJohn Forte 	if (minidsp) {
1986fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1987fcf3ce44SJohn Forte 		    gettext("%s: minidsp defined. "
1988fcf3ce44SJohn Forte 		    "Cannot define other nodes.\n"),
1989fcf3ce44SJohn Forte 		    progname);
1990fcf3ce44SJohn Forte 		exit(1);
1991fcf3ce44SJohn Forte 	}
1992fcf3ce44SJohn Forte 
1993fcf3ce44SJohn Forte 	if (mirror == _SD_NO_HOST) {
1994fcf3ce44SJohn Forte 		minidsp++;
1995fcf3ce44SJohn Forte 	} else if ((!(node % 2) && !(node == mirror - 1)) ||
1996fcf3ce44SJohn Forte 	    (((node % 2) && !(node == mirror + 1)))) {
1997fcf3ce44SJohn Forte 		(void) fprintf(stderr,
1998fcf3ce44SJohn Forte 		    gettext("%s: Node and Mirror identification values "
1999fcf3ce44SJohn Forte 		    "must be consecutive\n"
2000fcf3ce44SJohn Forte 		    "starting at an even number (Node = %d Mirror = %d)\n"),
2001fcf3ce44SJohn Forte 		    progname, node, mirror);
2002fcf3ce44SJohn Forte 		exit(1);
2003fcf3ce44SJohn Forte 	}
2004fcf3ce44SJohn Forte 
2005fcf3ce44SJohn Forte 	node_defined[node]++;
2006fcf3ce44SJohn Forte 
2007fcf3ce44SJohn Forte 	nodes_conf[nodes_configured] = node;
2008fcf3ce44SJohn Forte 	nodes_configured++;
2009fcf3ce44SJohn Forte 
2010fcf3ce44SJohn Forte 	if (node == myid) {
2011fcf3ce44SJohn Forte 		user_level_conf.mirror_host  = mirror;
2012fcf3ce44SJohn Forte 	}
2013fcf3ce44SJohn Forte }
2014fcf3ce44SJohn Forte 
2015fcf3ce44SJohn Forte char *mem_string =
2016fcf3ce44SJohn Forte 	"%-8s Structures use approx. %8d bytes (%5d pages) of memory\n";
2017fcf3ce44SJohn Forte 
2018fcf3ce44SJohn Forte void
2019fcf3ce44SJohn Forte enable_sdbc()
2020fcf3ce44SJohn Forte {
2021fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
2022fcf3ce44SJohn Forte 
2023fcf3ce44SJohn Forte 	if (get_cache_config()) {
2024fcf3ce44SJohn Forte 		(void) fprintf(stderr,
2025fcf3ce44SJohn Forte 		    gettext("%s: unable to read configuration file\n"),
2026fcf3ce44SJohn Forte 		    progname);
2027fcf3ce44SJohn Forte 		exit(1);
2028fcf3ce44SJohn Forte 	}
2029fcf3ce44SJohn Forte 
2030fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_ENABLE, &user_level_conf, 0, 0, 0, 0,
2031fcf3ce44SJohn Forte 	    &ustats) == SPCS_S_ERROR) {
2032fcf3ce44SJohn Forte 		(void) fprintf(stderr, gettext("%s: cache enable failed\n"),
2033fcf3ce44SJohn Forte 		    progname);
2034fcf3ce44SJohn Forte 		spcs_log("scm", &ustats, gettext("%s cache enable failed"),
2035fcf3ce44SJohn Forte 		    progname);
2036fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
2037fcf3ce44SJohn Forte 		exit(1);
2038fcf3ce44SJohn Forte 	}
2039fcf3ce44SJohn Forte 	spcs_log("scm", NULL, gettext("%s cache enable succeeded"),
2040fcf3ce44SJohn Forte 	    progname);
2041fcf3ce44SJohn Forte #ifdef DEBUG
2042fcf3ce44SJohn Forte 	(void) printf(gettext("%s: cache has been configured\n"), progname);
2043fcf3ce44SJohn Forte #endif
2044fcf3ce44SJohn Forte #ifdef WRTHRU_HINTS
2045fcf3ce44SJohn Forte 	if (iscluster()) {
2046fcf3ce44SJohn Forte 		/* Must writethru on a cluster, even if nvram configured */
2047fcf3ce44SJohn Forte 		forced_wrthru = 1;
2048fcf3ce44SJohn Forte 	}
2049fcf3ce44SJohn Forte 
2050fcf3ce44SJohn Forte 	if (minidsp && forced_wrthru != -1) {
2051fcf3ce44SJohn Forte 		/* Have minidsp with forced_wrthru hint. Set / Clear hint */
2052fcf3ce44SJohn Forte 		if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_FORCED_WRTHRU,
2053fcf3ce44SJohn Forte 		    forced_wrthru, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
2054fcf3ce44SJohn Forte 			(void) fprintf(stderr,
2055fcf3ce44SJohn Forte 			    gettext("%s: set/clear forced_wrthru failed\n"),
2056fcf3ce44SJohn Forte 			    progname);
2057fcf3ce44SJohn Forte 			sdbc_report_error(&ustats);
2058fcf3ce44SJohn Forte 		} else if (forced_wrthru) {
2059fcf3ce44SJohn Forte 			(void) printf(gettext("%s: Node option forced_wrthru "
2060fcf3ce44SJohn Forte 			    "now set.\n"), progname);
2061fcf3ce44SJohn Forte 		} else {
2062fcf3ce44SJohn Forte 			(void) printf(gettext("%s: Node option forced_wrthru "
2063fcf3ce44SJohn Forte 			    "now cleared.\n"), progname);
2064fcf3ce44SJohn Forte 		}
2065fcf3ce44SJohn Forte 	}
2066fcf3ce44SJohn Forte 	if (no_forced_wrthru != -1) {
2067fcf3ce44SJohn Forte 		if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_NO_FORCED_WRTHRU,
2068fcf3ce44SJohn Forte 		    no_forced_wrthru, 0, 0, 0, &ustats) == SPCS_S_ERROR) {
2069fcf3ce44SJohn Forte 			(void) fprintf(stderr,
2070fcf3ce44SJohn Forte 			    gettext("%s: set/clear no_forced_wrthru "
2071fcf3ce44SJohn Forte 			    "failed\n"), progname);
2072fcf3ce44SJohn Forte 			sdbc_report_error(&ustats);
2073fcf3ce44SJohn Forte 		} else if (no_forced_wrthru) {
2074fcf3ce44SJohn Forte 			(void) printf(gettext("%s: Node option no_forced_wrthru"
2075fcf3ce44SJohn Forte 			    " now set.\n"), progname);
2076fcf3ce44SJohn Forte 		} else {
2077fcf3ce44SJohn Forte 			(void) printf(gettext("%s: Node option no_forced_wrthru"
2078fcf3ce44SJohn Forte 			    " now cleared.\n"), progname);
2079fcf3ce44SJohn Forte 		}
2080fcf3ce44SJohn Forte 	}
2081fcf3ce44SJohn Forte #endif
2082fcf3ce44SJohn Forte 
2083fcf3ce44SJohn Forte 	/* do scmadm -O to cater for manual cache disable then enable */
2084fcf3ce44SJohn Forte 	restore_hints();
2085fcf3ce44SJohn Forte }
2086fcf3ce44SJohn Forte 
2087fcf3ce44SJohn Forte void
2088fcf3ce44SJohn Forte disable_sdbc()
2089fcf3ce44SJohn Forte {
2090fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
2091fcf3ce44SJohn Forte 
2092fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_DISABLE, 0, 0, 0, 0, 0, &ustats) != SPCS_S_OK) {
2093fcf3ce44SJohn Forte 		/*
2094fcf3ce44SJohn Forte 		 * If it wasn't already enabled, don't appear to fail
2095fcf3ce44SJohn Forte 		 * or users of this program might think the cache is
2096fcf3ce44SJohn Forte 		 * configured, when it actually isn't.
2097fcf3ce44SJohn Forte 		 */
2098fcf3ce44SJohn Forte 		if (errno != SDBC_EDISABLE) {
2099fcf3ce44SJohn Forte 			spcs_log("scm", &ustats,
2100fcf3ce44SJohn Forte 			    gettext("%s cache disable failed"), progname);
2101fcf3ce44SJohn Forte 			sdbc_report_error(&ustats);
2102fcf3ce44SJohn Forte 			exit(1);
2103fcf3ce44SJohn Forte 		}
2104fcf3ce44SJohn Forte 	}
2105fcf3ce44SJohn Forte #ifdef DEBUG
2106fcf3ce44SJohn Forte 	(void) printf(gettext("%s: cache has been deconfigured\n"), progname);
2107fcf3ce44SJohn Forte #endif
2108fcf3ce44SJohn Forte 	spcs_log("scm", NULL, gettext("%s cache disable succeeded"),
2109fcf3ce44SJohn Forte 	    progname);
2110fcf3ce44SJohn Forte }
2111fcf3ce44SJohn Forte 
2112fcf3ce44SJohn Forte static void
2113fcf3ce44SJohn Forte get_version()
2114fcf3ce44SJohn Forte {
2115fcf3ce44SJohn Forte 	cache_version_t version;
2116fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
2117fcf3ce44SJohn Forte 
2118fcf3ce44SJohn Forte 	if (SDBC_IOCTL(SDBC_VERSION, &version, 0, 0, 0, 0, &ustats) ==
2119fcf3ce44SJohn Forte 	    SPCS_S_ERROR) {
2120fcf3ce44SJohn Forte 		(void) fprintf(stderr,
2121fcf3ce44SJohn Forte 		    gettext("%s: get cache version failed\n"), progname);
2122fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
2123fcf3ce44SJohn Forte 		exit(1);
2124fcf3ce44SJohn Forte 	}
2125fcf3ce44SJohn Forte #ifdef DEBUG
2126fcf3ce44SJohn Forte 	(void) printf(gettext("Cache version %d.%d.%d.%d\n"),
2127fcf3ce44SJohn Forte 	    version.major, version.minor, version.micro, version.baseline);
2128fcf3ce44SJohn Forte #else
2129fcf3ce44SJohn Forte 	if (version.micro) {
2130fcf3ce44SJohn Forte 		(void) printf(gettext("Cache version %d.%d.%d\n"),
2131fcf3ce44SJohn Forte 		    version.major, version.minor, version.micro);
2132fcf3ce44SJohn Forte 	} else {
2133fcf3ce44SJohn Forte 		(void) printf(gettext("Cache version %d.%d\n"),
2134fcf3ce44SJohn Forte 		    version.major, version.minor);
2135fcf3ce44SJohn Forte 	}
2136fcf3ce44SJohn Forte #endif
2137fcf3ce44SJohn Forte }
2138fcf3ce44SJohn Forte 
2139fcf3ce44SJohn Forte #ifdef DEBUG
2140fcf3ce44SJohn Forte int
2141fcf3ce44SJohn Forte toggle_flush(void)
2142fcf3ce44SJohn Forte {
2143fcf3ce44SJohn Forte 	int rc;
2144fcf3ce44SJohn Forte 	spcs_s_info_t ustats;
2145fcf3ce44SJohn Forte 
2146fcf3ce44SJohn Forte 	if ((rc = SDBC_IOCTL(SDBC_TOGGLE_FLUSH, 0, 0, 0,
2147fcf3ce44SJohn Forte 	    0, 0, &ustats)) == SPCS_S_ERROR) {
2148fcf3ce44SJohn Forte 		(void) fprintf(stderr,
2149fcf3ce44SJohn Forte 		    gettext("%s: toggle sdbc cache flush failed\n"),
2150fcf3ce44SJohn Forte 		    progname);
2151fcf3ce44SJohn Forte 		sdbc_report_error(&ustats);
2152fcf3ce44SJohn Forte 		exit(1);
2153fcf3ce44SJohn Forte 	}
2154fcf3ce44SJohn Forte 	return (rc);
2155fcf3ce44SJohn Forte }
2156fcf3ce44SJohn Forte #endif
2157