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