xref: /titanic_44/usr/src/cmd/avs/sv/svadm.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 #include <sys/types.h>
27*fcf3ce44SJohn Forte #include <sys/stat.h>
28*fcf3ce44SJohn Forte #include <sys/mkdev.h>
29*fcf3ce44SJohn Forte #include <sys/param.h>
30*fcf3ce44SJohn Forte #include <sys/wait.h>
31*fcf3ce44SJohn Forte #include <fcntl.h>
32*fcf3ce44SJohn Forte #include <stdarg.h>
33*fcf3ce44SJohn Forte #include <stdlib.h>
34*fcf3ce44SJohn Forte #include <strings.h>
35*fcf3ce44SJohn Forte #include <errno.h>
36*fcf3ce44SJohn Forte #include <stdio.h>
37*fcf3ce44SJohn Forte #include <locale.h>
38*fcf3ce44SJohn Forte #include <unistd.h>
39*fcf3ce44SJohn Forte #include <search.h>
40*fcf3ce44SJohn Forte #include <libgen.h>
41*fcf3ce44SJohn Forte #include <nsctl.h>
42*fcf3ce44SJohn Forte 
43*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
44*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_u.h>
45*fcf3ce44SJohn Forte #include <sys/unistat/spcs_errors.h>
46*fcf3ce44SJohn Forte 
47*fcf3ce44SJohn Forte #include <sys/nsctl/sv.h>
48*fcf3ce44SJohn Forte #include <sys/nsctl/sv_impl.h>
49*fcf3ce44SJohn Forte 
50*fcf3ce44SJohn Forte #include <sys/nsctl/cfg.h>
51*fcf3ce44SJohn Forte #include <sys/nsctl/nsc_hash.h>
52*fcf3ce44SJohn Forte 
53*fcf3ce44SJohn Forte #include "../sv/svadm.h"
54*fcf3ce44SJohn Forte 
55*fcf3ce44SJohn Forte 
56*fcf3ce44SJohn Forte static int sv_max_devices;
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte 
59*fcf3ce44SJohn Forte /*
60*fcf3ce44SJohn Forte  * support for the special cluster tag "local" to be used with -C in a
61*fcf3ce44SJohn Forte  * cluster for local volumes.
62*fcf3ce44SJohn Forte  */
63*fcf3ce44SJohn Forte 
64*fcf3ce44SJohn Forte #define	SV_LOCAL_TAG	"local"
65*fcf3ce44SJohn Forte 
66*fcf3ce44SJohn Forte static int sv_islocal;
67*fcf3ce44SJohn Forte 
68*fcf3ce44SJohn Forte /*
69*fcf3ce44SJohn Forte  * libcfg access.
70*fcf3ce44SJohn Forte  */
71*fcf3ce44SJohn Forte 
72*fcf3ce44SJohn Forte static CFGFILE *cfg;		/* libcfg file pointer */
73*fcf3ce44SJohn Forte static int cfg_changed;		/* set to 1 if we need to commit changes */
74*fcf3ce44SJohn Forte 
75*fcf3ce44SJohn Forte static char *cfg_cluster_tag;	/* local cluster tag */
76*fcf3ce44SJohn Forte 
77*fcf3ce44SJohn Forte static char *implicit_tag;	/* implicit cluster tag */
78*fcf3ce44SJohn Forte 
79*fcf3ce44SJohn Forte 
80*fcf3ce44SJohn Forte /*
81*fcf3ce44SJohn Forte  * Print width for print_sv() output.
82*fcf3ce44SJohn Forte  */
83*fcf3ce44SJohn Forte 
84*fcf3ce44SJohn Forte #define	STATWIDTH	(SV_MAXPATH / 2)
85*fcf3ce44SJohn Forte 
86*fcf3ce44SJohn Forte /*
87*fcf3ce44SJohn Forte  * Pathnames.
88*fcf3ce44SJohn Forte  */
89*fcf3ce44SJohn Forte 
90*fcf3ce44SJohn Forte static const caddr_t sv_rpath = SV_DEVICE;
91*fcf3ce44SJohn Forte 
92*fcf3ce44SJohn Forte /*
93*fcf3ce44SJohn Forte  * Functions.
94*fcf3ce44SJohn Forte  */
95*fcf3ce44SJohn Forte 
96*fcf3ce44SJohn Forte static int read_config_file(const caddr_t, sv_name_t []);
97*fcf3ce44SJohn Forte static int enable_dev(sv_name_t *);
98*fcf3ce44SJohn Forte static int disable_dev(const caddr_t);
99*fcf3ce44SJohn Forte static void error(spcs_s_info_t *, caddr_t, ...);
100*fcf3ce44SJohn Forte static void create_cfg_hash();
101*fcf3ce44SJohn Forte static int find_in_hash(char *path);
102*fcf3ce44SJohn Forte static void destroy_hashtable();
103*fcf3ce44SJohn Forte static void remove_from_cfgfile(char *path, int setnumber);
104*fcf3ce44SJohn Forte 
105*fcf3ce44SJohn Forte static caddr_t program;
106*fcf3ce44SJohn Forte 
107*fcf3ce44SJohn Forte static void
sv_cfg_open(CFGLOCK mode)108*fcf3ce44SJohn Forte sv_cfg_open(CFGLOCK mode)
109*fcf3ce44SJohn Forte {
110*fcf3ce44SJohn Forte 	if (cfg != NULL)
111*fcf3ce44SJohn Forte 		return;
112*fcf3ce44SJohn Forte 
113*fcf3ce44SJohn Forte 	cfg = cfg_open(NULL);
114*fcf3ce44SJohn Forte 	if (cfg == NULL) {
115*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to access the configuration"));
116*fcf3ce44SJohn Forte 		/* NOTREACHED */
117*fcf3ce44SJohn Forte 	}
118*fcf3ce44SJohn Forte 
119*fcf3ce44SJohn Forte 	if (cfg_cluster_tag && *cfg_cluster_tag) {
120*fcf3ce44SJohn Forte 		cfg_resource(cfg, cfg_cluster_tag);
121*fcf3ce44SJohn Forte 	} else {
122*fcf3ce44SJohn Forte 		cfg_resource(cfg, NULL);
123*fcf3ce44SJohn Forte 	}
124*fcf3ce44SJohn Forte 	if (!cfg_lock(cfg, mode)) {
125*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to lock the configuration"));
126*fcf3ce44SJohn Forte 		/* NOTREACHED */
127*fcf3ce44SJohn Forte 	}
128*fcf3ce44SJohn Forte }
129*fcf3ce44SJohn Forte 
130*fcf3ce44SJohn Forte 
131*fcf3ce44SJohn Forte static void
sv_cfg_close(void)132*fcf3ce44SJohn Forte sv_cfg_close(void)
133*fcf3ce44SJohn Forte {
134*fcf3ce44SJohn Forte 	if (cfg == NULL)
135*fcf3ce44SJohn Forte 		return;
136*fcf3ce44SJohn Forte 
137*fcf3ce44SJohn Forte 	if (cfg_changed) {
138*fcf3ce44SJohn Forte 		(void) cfg_commit(cfg);
139*fcf3ce44SJohn Forte 		cfg_changed = 0;
140*fcf3ce44SJohn Forte 	}
141*fcf3ce44SJohn Forte 
142*fcf3ce44SJohn Forte 	cfg_close(cfg);
143*fcf3ce44SJohn Forte 	cfg = NULL;
144*fcf3ce44SJohn Forte }
145*fcf3ce44SJohn Forte 
146*fcf3ce44SJohn Forte 
147*fcf3ce44SJohn Forte 
148*fcf3ce44SJohn Forte static void
usage(void)149*fcf3ce44SJohn Forte usage(void)
150*fcf3ce44SJohn Forte {
151*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext("usage:\n"));
152*fcf3ce44SJohn Forte 
153*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
154*fcf3ce44SJohn Forte 	    "\t%s -h                                 help\n"), program);
155*fcf3ce44SJohn Forte 
156*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
157*fcf3ce44SJohn Forte 	    "\t%s [-C tag]                           display status\n"),
158*fcf3ce44SJohn Forte 	    program);
159*fcf3ce44SJohn Forte 
160*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
161*fcf3ce44SJohn Forte 	    "\t%s [-C tag] -i                        display "
162*fcf3ce44SJohn Forte 	    "extended status\n"), program);
163*fcf3ce44SJohn Forte 
164*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
165*fcf3ce44SJohn Forte 	    "\t%s [-C tag] -v                        display "
166*fcf3ce44SJohn Forte 	    "version number\n"), program);
167*fcf3ce44SJohn Forte 
168*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
169*fcf3ce44SJohn Forte 	    "\t%s [-C tag] -e { -f file | volume }   enable\n"), program);
170*fcf3ce44SJohn Forte 
171*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
172*fcf3ce44SJohn Forte 	    "\t%s [-C tag] -d { -f file | volume }   disable\n"), program);
173*fcf3ce44SJohn Forte 
174*fcf3ce44SJohn Forte 	(void) fprintf(stderr, gettext(
175*fcf3ce44SJohn Forte 	    "\t%s [-C tag] -r { -f file | volume }   reconfigure\n"), program);
176*fcf3ce44SJohn Forte 
177*fcf3ce44SJohn Forte 	sv_cfg_close();
178*fcf3ce44SJohn Forte }
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte static void
message(caddr_t prefix,spcs_s_info_t * status,caddr_t string,va_list ap)181*fcf3ce44SJohn Forte message(caddr_t prefix, spcs_s_info_t *status, caddr_t string, va_list ap)
182*fcf3ce44SJohn Forte {
183*fcf3ce44SJohn Forte 	(void) fprintf(stderr, "%s: %s: ", program, prefix);
184*fcf3ce44SJohn Forte 	(void) vfprintf(stderr, string, ap);
185*fcf3ce44SJohn Forte 	(void) fprintf(stderr, "\n");
186*fcf3ce44SJohn Forte 
187*fcf3ce44SJohn Forte 	if (status) {
188*fcf3ce44SJohn Forte 		spcs_s_report(*status, stderr);
189*fcf3ce44SJohn Forte 		spcs_s_ufree(status);
190*fcf3ce44SJohn Forte 	}
191*fcf3ce44SJohn Forte }
192*fcf3ce44SJohn Forte 
193*fcf3ce44SJohn Forte 
194*fcf3ce44SJohn Forte static void
error(spcs_s_info_t * status,caddr_t string,...)195*fcf3ce44SJohn Forte error(spcs_s_info_t *status, caddr_t string, ...)
196*fcf3ce44SJohn Forte {
197*fcf3ce44SJohn Forte 	va_list ap;
198*fcf3ce44SJohn Forte 	va_start(ap, string);
199*fcf3ce44SJohn Forte 
200*fcf3ce44SJohn Forte 	message(gettext("error"), status, string, ap);
201*fcf3ce44SJohn Forte 
202*fcf3ce44SJohn Forte 	va_end(ap);
203*fcf3ce44SJohn Forte 
204*fcf3ce44SJohn Forte 	sv_cfg_close();
205*fcf3ce44SJohn Forte 	exit(1);
206*fcf3ce44SJohn Forte }
207*fcf3ce44SJohn Forte 
208*fcf3ce44SJohn Forte 
209*fcf3ce44SJohn Forte static void
warn(spcs_s_info_t * status,caddr_t string,...)210*fcf3ce44SJohn Forte warn(spcs_s_info_t *status, caddr_t string, ...)
211*fcf3ce44SJohn Forte {
212*fcf3ce44SJohn Forte 	va_list ap;
213*fcf3ce44SJohn Forte 	va_start(ap, string);
214*fcf3ce44SJohn Forte 
215*fcf3ce44SJohn Forte 	message(gettext("warning"), status, string, ap);
216*fcf3ce44SJohn Forte 
217*fcf3ce44SJohn Forte 	va_end(ap);
218*fcf3ce44SJohn Forte }
219*fcf3ce44SJohn Forte 
220*fcf3ce44SJohn Forte 
221*fcf3ce44SJohn Forte static void
sv_get_maxdevs(void)222*fcf3ce44SJohn Forte sv_get_maxdevs(void)
223*fcf3ce44SJohn Forte {
224*fcf3ce44SJohn Forte 	sv_name_t svn[1];
225*fcf3ce44SJohn Forte 	sv_list_t svl;
226*fcf3ce44SJohn Forte 	int fd;
227*fcf3ce44SJohn Forte 
228*fcf3ce44SJohn Forte 	if (sv_max_devices > 0)
229*fcf3ce44SJohn Forte 		return;
230*fcf3ce44SJohn Forte 
231*fcf3ce44SJohn Forte 	fd = open(sv_rpath, O_RDONLY);
232*fcf3ce44SJohn Forte 	if (fd < 0)
233*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to open %s: %s"),
234*fcf3ce44SJohn Forte 			sv_rpath, strerror(errno));
235*fcf3ce44SJohn Forte 
236*fcf3ce44SJohn Forte 	bzero(&svl, sizeof (svl));
237*fcf3ce44SJohn Forte 	bzero(&svn[0], sizeof (svn));
238*fcf3ce44SJohn Forte 
239*fcf3ce44SJohn Forte 	svl.svl_names = &svn[0];
240*fcf3ce44SJohn Forte 	svl.svl_error = spcs_s_ucreate();
241*fcf3ce44SJohn Forte 
242*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_LIST, &svl) < 0) {
243*fcf3ce44SJohn Forte 		(void) close(fd);
244*fcf3ce44SJohn Forte 		error(&svl.svl_error, gettext("unable to get max devs"));
245*fcf3ce44SJohn Forte 	}
246*fcf3ce44SJohn Forte 
247*fcf3ce44SJohn Forte 	spcs_s_ufree(&svl.svl_error);
248*fcf3ce44SJohn Forte 	sv_max_devices = svl.svl_maxdevs;
249*fcf3ce44SJohn Forte 
250*fcf3ce44SJohn Forte 	(void) close(fd);
251*fcf3ce44SJohn Forte }
252*fcf3ce44SJohn Forte 
253*fcf3ce44SJohn Forte 
254*fcf3ce44SJohn Forte static sv_name_t *
sv_alloc_svnames(void)255*fcf3ce44SJohn Forte sv_alloc_svnames(void)
256*fcf3ce44SJohn Forte {
257*fcf3ce44SJohn Forte 	sv_name_t *svn = NULL;
258*fcf3ce44SJohn Forte 
259*fcf3ce44SJohn Forte 	sv_get_maxdevs();
260*fcf3ce44SJohn Forte 
261*fcf3ce44SJohn Forte 	svn = calloc(sv_max_devices, sizeof (*svn));
262*fcf3ce44SJohn Forte 	if (svn == NULL) {
263*fcf3ce44SJohn Forte 		error(NULL, "unable to allocate %ld bytes of memory",
264*fcf3ce44SJohn Forte 		    sv_max_devices * sizeof (*svn));
265*fcf3ce44SJohn Forte 	}
266*fcf3ce44SJohn Forte 
267*fcf3ce44SJohn Forte 	return (svn);
268*fcf3ce44SJohn Forte }
269*fcf3ce44SJohn Forte 
270*fcf3ce44SJohn Forte 
271*fcf3ce44SJohn Forte static void
sv_check_dgislocal(char * dgname)272*fcf3ce44SJohn Forte sv_check_dgislocal(char *dgname)
273*fcf3ce44SJohn Forte {
274*fcf3ce44SJohn Forte 	char *othernode;
275*fcf3ce44SJohn Forte 	int rc;
276*fcf3ce44SJohn Forte 
277*fcf3ce44SJohn Forte 	/*
278*fcf3ce44SJohn Forte 	 * check where this disk service is mastered
279*fcf3ce44SJohn Forte 	 */
280*fcf3ce44SJohn Forte 
281*fcf3ce44SJohn Forte 	rc = cfg_dgname_islocal(dgname, &othernode);
282*fcf3ce44SJohn Forte 	if (rc < 0) {
283*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to find "
284*fcf3ce44SJohn Forte 		    "disk service, %s: %s"), dgname, strerror(errno));
285*fcf3ce44SJohn Forte 	}
286*fcf3ce44SJohn Forte 
287*fcf3ce44SJohn Forte 	if (rc == 0) {
288*fcf3ce44SJohn Forte 		error(NULL, gettext("disk service, %s, is "
289*fcf3ce44SJohn Forte 		    "active on node \"%s\"\nPlease re-issue "
290*fcf3ce44SJohn Forte 		    "the command on that node"), dgname, othernode);
291*fcf3ce44SJohn Forte 	}
292*fcf3ce44SJohn Forte }
293*fcf3ce44SJohn Forte 
294*fcf3ce44SJohn Forte 
295*fcf3ce44SJohn Forte /*
296*fcf3ce44SJohn Forte  * Carry out cluster based checks for a specified volume, or just
297*fcf3ce44SJohn Forte  * global options.
298*fcf3ce44SJohn Forte  */
299*fcf3ce44SJohn Forte static void
sv_check_cluster(char * path)300*fcf3ce44SJohn Forte sv_check_cluster(char *path)
301*fcf3ce44SJohn Forte {
302*fcf3ce44SJohn Forte 	char dgname[CFG_MAX_BUF];
303*fcf3ce44SJohn Forte 	static int sv_iscluster = -1;	/* set to 1 if running in a cluster */
304*fcf3ce44SJohn Forte 
305*fcf3ce44SJohn Forte 	/*
306*fcf3ce44SJohn Forte 	 * Find out if we are running in a cluster
307*fcf3ce44SJohn Forte 	 */
308*fcf3ce44SJohn Forte 	if (sv_iscluster == -1) {
309*fcf3ce44SJohn Forte 		if ((sv_iscluster = cfg_iscluster()) < 0) {
310*fcf3ce44SJohn Forte 			error(NULL, gettext("unable to ascertain environment"));
311*fcf3ce44SJohn Forte 		}
312*fcf3ce44SJohn Forte 	}
313*fcf3ce44SJohn Forte 
314*fcf3ce44SJohn Forte 	if (!sv_iscluster && cfg_cluster_tag != NULL) {
315*fcf3ce44SJohn Forte 		error(NULL, gettext("-C is not valid when not in a cluster"));
316*fcf3ce44SJohn Forte 	}
317*fcf3ce44SJohn Forte 
318*fcf3ce44SJohn Forte 	if (!sv_iscluster || sv_islocal || path == NULL) {
319*fcf3ce44SJohn Forte 		return;
320*fcf3ce44SJohn Forte 	}
321*fcf3ce44SJohn Forte 
322*fcf3ce44SJohn Forte 
323*fcf3ce44SJohn Forte 	/*
324*fcf3ce44SJohn Forte 	 * Cluster-only checks on pathname
325*fcf3ce44SJohn Forte 	 */
326*fcf3ce44SJohn Forte 	if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) {
327*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to determine "
328*fcf3ce44SJohn Forte 		    "disk group name for %s"), path);
329*fcf3ce44SJohn Forte 		return;
330*fcf3ce44SJohn Forte 	}
331*fcf3ce44SJohn Forte 
332*fcf3ce44SJohn Forte 	if (cfg_cluster_tag != NULL) {
333*fcf3ce44SJohn Forte 		/*
334*fcf3ce44SJohn Forte 		 * Do dgislocal check now in case path did not contain
335*fcf3ce44SJohn Forte 		 * a dgname.
336*fcf3ce44SJohn Forte 		 *
337*fcf3ce44SJohn Forte 		 * E.g. adding a /dev/did/ device to a disk service.
338*fcf3ce44SJohn Forte 		 */
339*fcf3ce44SJohn Forte 
340*fcf3ce44SJohn Forte 		sv_check_dgislocal(cfg_cluster_tag);
341*fcf3ce44SJohn Forte 	}
342*fcf3ce44SJohn Forte 
343*fcf3ce44SJohn Forte 	if (strcmp(dgname, "") == 0)
344*fcf3ce44SJohn Forte 		return;		/* NULL dgname is valid */
345*fcf3ce44SJohn Forte 
346*fcf3ce44SJohn Forte 	if (cfg_cluster_tag == NULL) {
347*fcf3ce44SJohn Forte 		/*
348*fcf3ce44SJohn Forte 		 * Implicitly set the cluster tag to dgname
349*fcf3ce44SJohn Forte 		 */
350*fcf3ce44SJohn Forte 
351*fcf3ce44SJohn Forte 		sv_check_dgislocal(dgname);
352*fcf3ce44SJohn Forte 
353*fcf3ce44SJohn Forte 		if (implicit_tag) {
354*fcf3ce44SJohn Forte 			free(implicit_tag);
355*fcf3ce44SJohn Forte 			implicit_tag = NULL;
356*fcf3ce44SJohn Forte 		}
357*fcf3ce44SJohn Forte 
358*fcf3ce44SJohn Forte 		implicit_tag = strdup(dgname);
359*fcf3ce44SJohn Forte 		if (implicit_tag == NULL) {
360*fcf3ce44SJohn Forte 			error(NULL,
361*fcf3ce44SJohn Forte 			    gettext("unable to allocate memory "
362*fcf3ce44SJohn Forte 			    "for cluster tag"));
363*fcf3ce44SJohn Forte 		}
364*fcf3ce44SJohn Forte 	} else {
365*fcf3ce44SJohn Forte 		/*
366*fcf3ce44SJohn Forte 		 * Check dgname and cluster tag from -C are the same.
367*fcf3ce44SJohn Forte 		 */
368*fcf3ce44SJohn Forte 
369*fcf3ce44SJohn Forte 		if (strcmp(dgname, cfg_cluster_tag) != 0) {
370*fcf3ce44SJohn Forte 			error(NULL,
371*fcf3ce44SJohn Forte 			    gettext("-C (%s) does not match disk group "
372*fcf3ce44SJohn Forte 			    "name (%s) for %s"), cfg_cluster_tag,
373*fcf3ce44SJohn Forte 			    dgname, path);
374*fcf3ce44SJohn Forte 		}
375*fcf3ce44SJohn Forte 
376*fcf3ce44SJohn Forte 		/*
377*fcf3ce44SJohn Forte 		 * sv_check_dgislocal(cfg_cluster_tag) was called above.
378*fcf3ce44SJohn Forte 		 */
379*fcf3ce44SJohn Forte 	}
380*fcf3ce44SJohn Forte }
381*fcf3ce44SJohn Forte 
382*fcf3ce44SJohn Forte 
383*fcf3ce44SJohn Forte static void
print_version(void)384*fcf3ce44SJohn Forte print_version(void)
385*fcf3ce44SJohn Forte {
386*fcf3ce44SJohn Forte 	sv_version_t svv;
387*fcf3ce44SJohn Forte 	int fd;
388*fcf3ce44SJohn Forte 
389*fcf3ce44SJohn Forte 	bzero(&svv, sizeof (svv));
390*fcf3ce44SJohn Forte 	svv.svv_error = spcs_s_ucreate();
391*fcf3ce44SJohn Forte 
392*fcf3ce44SJohn Forte 	fd = open(sv_rpath, O_RDONLY);
393*fcf3ce44SJohn Forte 	if (fd < 0) {
394*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to open %s: %s"),
395*fcf3ce44SJohn Forte 			sv_rpath, strerror(errno));
396*fcf3ce44SJohn Forte 		return;
397*fcf3ce44SJohn Forte 	}
398*fcf3ce44SJohn Forte 
399*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_VERSION, &svv) != 0) {
400*fcf3ce44SJohn Forte 		error(&svv.svv_error,
401*fcf3ce44SJohn Forte 		    gettext("unable to read the version number"));
402*fcf3ce44SJohn Forte 		/* NOTREACHED */
403*fcf3ce44SJohn Forte 	}
404*fcf3ce44SJohn Forte 
405*fcf3ce44SJohn Forte 	spcs_s_ufree(&svv.svv_error);
406*fcf3ce44SJohn Forte #ifdef DEBUG
407*fcf3ce44SJohn Forte 	(void) printf(gettext("Storage Volume version %d.%d.%d.%d\n"),
408*fcf3ce44SJohn Forte 	    svv.svv_major_rev, svv.svv_minor_rev,
409*fcf3ce44SJohn Forte 	    svv.svv_micro_rev, svv.svv_baseline_rev);
410*fcf3ce44SJohn Forte #else
411*fcf3ce44SJohn Forte 	if (svv.svv_micro_rev) {
412*fcf3ce44SJohn Forte 		(void) printf(gettext("Storage Volume version %d.%d.%d\n"),
413*fcf3ce44SJohn Forte 		    svv.svv_major_rev, svv.svv_minor_rev, svv.svv_micro_rev);
414*fcf3ce44SJohn Forte 	} else {
415*fcf3ce44SJohn Forte 		(void) printf(gettext("Storage Volume version %d.%d\n"),
416*fcf3ce44SJohn Forte 		    svv.svv_major_rev, svv.svv_minor_rev);
417*fcf3ce44SJohn Forte 	}
418*fcf3ce44SJohn Forte #endif
419*fcf3ce44SJohn Forte 
420*fcf3ce44SJohn Forte 	(void) close(fd);
421*fcf3ce44SJohn Forte }
422*fcf3ce44SJohn Forte 
423*fcf3ce44SJohn Forte int
main(int argc,char * argv[])424*fcf3ce44SJohn Forte main(int argc, char *argv[])
425*fcf3ce44SJohn Forte {
426*fcf3ce44SJohn Forte 	extern int optind;
427*fcf3ce44SJohn Forte 	extern char *optarg;
428*fcf3ce44SJohn Forte 	char *conf_file = NULL;
429*fcf3ce44SJohn Forte 	int enable, disable, compare, print, version;
430*fcf3ce44SJohn Forte 	int opt, Cflag, fflag, iflag;
431*fcf3ce44SJohn Forte 	int rc;
432*fcf3ce44SJohn Forte 
433*fcf3ce44SJohn Forte 	(void) setlocale(LC_ALL, "");
434*fcf3ce44SJohn Forte 	(void) textdomain("svadm");
435*fcf3ce44SJohn Forte 
436*fcf3ce44SJohn Forte 	program = strdup(basename(argv[0]));
437*fcf3ce44SJohn Forte 
438*fcf3ce44SJohn Forte 	Cflag = fflag = iflag = 0;
439*fcf3ce44SJohn Forte 	compare = enable = disable = version = 0;
440*fcf3ce44SJohn Forte 
441*fcf3ce44SJohn Forte 	print = 1;
442*fcf3ce44SJohn Forte 
443*fcf3ce44SJohn Forte 	while ((opt = getopt(argc, argv, "C:def:hirv")) != EOF) {
444*fcf3ce44SJohn Forte 		switch (opt) {
445*fcf3ce44SJohn Forte 
446*fcf3ce44SJohn Forte 		case 'C':
447*fcf3ce44SJohn Forte 			if (Cflag) {
448*fcf3ce44SJohn Forte 				warn(NULL,
449*fcf3ce44SJohn Forte 				    gettext("-C specified multiple times"));
450*fcf3ce44SJohn Forte 				usage();
451*fcf3ce44SJohn Forte 				exit(2);
452*fcf3ce44SJohn Forte 				/* NOTREACHED */
453*fcf3ce44SJohn Forte 			}
454*fcf3ce44SJohn Forte 
455*fcf3ce44SJohn Forte 			Cflag++;
456*fcf3ce44SJohn Forte 			cfg_cluster_tag = optarg;
457*fcf3ce44SJohn Forte 			break;
458*fcf3ce44SJohn Forte 
459*fcf3ce44SJohn Forte 		case 'e':
460*fcf3ce44SJohn Forte 			print = 0;
461*fcf3ce44SJohn Forte 			enable++;
462*fcf3ce44SJohn Forte 			break;
463*fcf3ce44SJohn Forte 
464*fcf3ce44SJohn Forte 		case 'd':
465*fcf3ce44SJohn Forte 			print = 0;
466*fcf3ce44SJohn Forte 			disable++;
467*fcf3ce44SJohn Forte 			break;
468*fcf3ce44SJohn Forte 
469*fcf3ce44SJohn Forte 		case 'f':
470*fcf3ce44SJohn Forte 			fflag++;
471*fcf3ce44SJohn Forte 			conf_file = optarg;
472*fcf3ce44SJohn Forte 			break;
473*fcf3ce44SJohn Forte 
474*fcf3ce44SJohn Forte 		case 'i':
475*fcf3ce44SJohn Forte 			iflag++;
476*fcf3ce44SJohn Forte 			break;
477*fcf3ce44SJohn Forte 
478*fcf3ce44SJohn Forte 		case 'r':
479*fcf3ce44SJohn Forte 			/* Compare running system with sv.cf */
480*fcf3ce44SJohn Forte 			print = 0;
481*fcf3ce44SJohn Forte 			compare++;
482*fcf3ce44SJohn Forte 			break;
483*fcf3ce44SJohn Forte 
484*fcf3ce44SJohn Forte 		case 'v':
485*fcf3ce44SJohn Forte 			print = 0;
486*fcf3ce44SJohn Forte 			version++;
487*fcf3ce44SJohn Forte 			break;
488*fcf3ce44SJohn Forte 
489*fcf3ce44SJohn Forte 		case 'h':
490*fcf3ce44SJohn Forte 			usage();
491*fcf3ce44SJohn Forte 			exit(0);
492*fcf3ce44SJohn Forte 
493*fcf3ce44SJohn Forte 		default:
494*fcf3ce44SJohn Forte 			usage();
495*fcf3ce44SJohn Forte 			exit(2);
496*fcf3ce44SJohn Forte 			/* NOTREACHED */
497*fcf3ce44SJohn Forte 		}
498*fcf3ce44SJohn Forte 	}
499*fcf3ce44SJohn Forte 
500*fcf3ce44SJohn Forte 
501*fcf3ce44SJohn Forte 	/*
502*fcf3ce44SJohn Forte 	 * Usage checks
503*fcf3ce44SJohn Forte 	 */
504*fcf3ce44SJohn Forte 
505*fcf3ce44SJohn Forte 	if ((enable + disable + compare) > 1) {
506*fcf3ce44SJohn Forte 		warn(NULL, gettext("-d, -e and -r are mutually exclusive"));
507*fcf3ce44SJohn Forte 		usage();
508*fcf3ce44SJohn Forte 		exit(2);
509*fcf3ce44SJohn Forte 	}
510*fcf3ce44SJohn Forte 
511*fcf3ce44SJohn Forte 	if (fflag && (print || version)) {
512*fcf3ce44SJohn Forte 		warn(NULL, gettext("-f is only valid with -d, -e or -r"));
513*fcf3ce44SJohn Forte 		usage();
514*fcf3ce44SJohn Forte 		exit(2);
515*fcf3ce44SJohn Forte 	}
516*fcf3ce44SJohn Forte 
517*fcf3ce44SJohn Forte 	if (fflag && optind != argc) {
518*fcf3ce44SJohn Forte 		usage();
519*fcf3ce44SJohn Forte 		exit(2);
520*fcf3ce44SJohn Forte 	}
521*fcf3ce44SJohn Forte 
522*fcf3ce44SJohn Forte 	if (print || version) {
523*fcf3ce44SJohn Forte 		/* check for no more args */
524*fcf3ce44SJohn Forte 
525*fcf3ce44SJohn Forte 		if (optind != argc) {
526*fcf3ce44SJohn Forte 			usage();
527*fcf3ce44SJohn Forte 			exit(2);
528*fcf3ce44SJohn Forte 		}
529*fcf3ce44SJohn Forte 	} else {
530*fcf3ce44SJohn Forte 		/* check for inline args */
531*fcf3ce44SJohn Forte 
532*fcf3ce44SJohn Forte 		if (!fflag && (argc - optind) != 1) {
533*fcf3ce44SJohn Forte 			usage();
534*fcf3ce44SJohn Forte 			exit(2);
535*fcf3ce44SJohn Forte 		}
536*fcf3ce44SJohn Forte 	}
537*fcf3ce44SJohn Forte 
538*fcf3ce44SJohn Forte 	if (!print && iflag) {
539*fcf3ce44SJohn Forte 		usage();
540*fcf3ce44SJohn Forte 		exit(2);
541*fcf3ce44SJohn Forte 	}
542*fcf3ce44SJohn Forte 
543*fcf3ce44SJohn Forte 
544*fcf3ce44SJohn Forte 	/*
545*fcf3ce44SJohn Forte 	 * Check for the special cluster tag and convert into the
546*fcf3ce44SJohn Forte 	 * internal representation.
547*fcf3ce44SJohn Forte 	 */
548*fcf3ce44SJohn Forte 
549*fcf3ce44SJohn Forte 	if (cfg_cluster_tag != NULL &&
550*fcf3ce44SJohn Forte 	    strcmp(cfg_cluster_tag, SV_LOCAL_TAG) == 0) {
551*fcf3ce44SJohn Forte 		cfg_cluster_tag = "-";
552*fcf3ce44SJohn Forte 		sv_islocal = 1;
553*fcf3ce44SJohn Forte 	}
554*fcf3ce44SJohn Forte 
555*fcf3ce44SJohn Forte 
556*fcf3ce44SJohn Forte 	/*
557*fcf3ce44SJohn Forte 	 * Process commands
558*fcf3ce44SJohn Forte 	 */
559*fcf3ce44SJohn Forte 
560*fcf3ce44SJohn Forte 	if (optind != argc) {
561*fcf3ce44SJohn Forte 		/* deal with inline volume argument */
562*fcf3ce44SJohn Forte 
563*fcf3ce44SJohn Forte 		rc = 0;
564*fcf3ce44SJohn Forte 		if (enable)
565*fcf3ce44SJohn Forte 			rc = enable_one_sv(argv[optind]);
566*fcf3ce44SJohn Forte 		else if (disable)
567*fcf3ce44SJohn Forte 			rc = disable_one_sv(argv[optind]);
568*fcf3ce44SJohn Forte 		else /* if (compare) */
569*fcf3ce44SJohn Forte 			compare_one_sv(argv[optind]);
570*fcf3ce44SJohn Forte 
571*fcf3ce44SJohn Forte 		if (rc != 0)
572*fcf3ce44SJohn Forte 			return (1);
573*fcf3ce44SJohn Forte 
574*fcf3ce44SJohn Forte 		return (0);
575*fcf3ce44SJohn Forte 	}
576*fcf3ce44SJohn Forte 
577*fcf3ce44SJohn Forte 	rc = 0;
578*fcf3ce44SJohn Forte 	if (enable)
579*fcf3ce44SJohn Forte 		rc = enable_sv(conf_file);
580*fcf3ce44SJohn Forte 	else if (disable)
581*fcf3ce44SJohn Forte 		rc = disable_sv(conf_file);
582*fcf3ce44SJohn Forte 	else if (compare)
583*fcf3ce44SJohn Forte 		compare_sv(conf_file);
584*fcf3ce44SJohn Forte 	else if (print)
585*fcf3ce44SJohn Forte 		print_sv(iflag);
586*fcf3ce44SJohn Forte 	else /* if (version) */
587*fcf3ce44SJohn Forte 		print_version();
588*fcf3ce44SJohn Forte 
589*fcf3ce44SJohn Forte 	if (rc != 0)
590*fcf3ce44SJohn Forte 		return (1);
591*fcf3ce44SJohn Forte 
592*fcf3ce44SJohn Forte 	return (0);
593*fcf3ce44SJohn Forte }
594*fcf3ce44SJohn Forte 
595*fcf3ce44SJohn Forte 
596*fcf3ce44SJohn Forte 
597*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
598*fcf3ce44SJohn Forte static int
enable_sv(char * conf_file)599*fcf3ce44SJohn Forte enable_sv(char *conf_file)
600*fcf3ce44SJohn Forte {
601*fcf3ce44SJohn Forte 	int index;
602*fcf3ce44SJohn Forte 	sv_name_t *svn;
603*fcf3ce44SJohn Forte 	int cnt;
604*fcf3ce44SJohn Forte 	int rc, ret;
605*fcf3ce44SJohn Forte 
606*fcf3ce44SJohn Forte 	svn = sv_alloc_svnames();
607*fcf3ce44SJohn Forte 
608*fcf3ce44SJohn Forte 	index = read_config_file(conf_file, svn);
609*fcf3ce44SJohn Forte 
610*fcf3ce44SJohn Forte 	rc = ret = 0;
611*fcf3ce44SJohn Forte 
612*fcf3ce44SJohn Forte 	for (cnt = 0; cnt < index; cnt++) {
613*fcf3ce44SJohn Forte 
614*fcf3ce44SJohn Forte 		/*
615*fcf3ce44SJohn Forte 		 * Check for more data.
616*fcf3ce44SJohn Forte 		 */
617*fcf3ce44SJohn Forte 		if (svn[cnt].svn_path[0] == '\0') {
618*fcf3ce44SJohn Forte 			/*
619*fcf3ce44SJohn Forte 			 * This was set when reading sv.conf.  After the last
620*fcf3ce44SJohn Forte 			 * line svn_path was set to \0, so we are finished.
621*fcf3ce44SJohn Forte 			 * We shouldn't get here, but put this in just in
622*fcf3ce44SJohn Forte 			 * case.
623*fcf3ce44SJohn Forte 			 */
624*fcf3ce44SJohn Forte 			break;
625*fcf3ce44SJohn Forte 		}
626*fcf3ce44SJohn Forte 		rc = enable_dev(&svn[cnt]);
627*fcf3ce44SJohn Forte 		if (rc && !ret)
628*fcf3ce44SJohn Forte 			ret = rc;
629*fcf3ce44SJohn Forte 	}
630*fcf3ce44SJohn Forte 
631*fcf3ce44SJohn Forte 	sv_cfg_close();
632*fcf3ce44SJohn Forte 
633*fcf3ce44SJohn Forte 	return (ret);
634*fcf3ce44SJohn Forte }
635*fcf3ce44SJohn Forte 
636*fcf3ce44SJohn Forte 
637*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
638*fcf3ce44SJohn Forte static int
enable_one_sv(caddr_t path)639*fcf3ce44SJohn Forte enable_one_sv(caddr_t path)
640*fcf3ce44SJohn Forte {
641*fcf3ce44SJohn Forte 	sv_name_t svn;
642*fcf3ce44SJohn Forte 	int rc;
643*fcf3ce44SJohn Forte 
644*fcf3ce44SJohn Forte 	sv_get_maxdevs();
645*fcf3ce44SJohn Forte 
646*fcf3ce44SJohn Forte 	bzero(&svn, sizeof (svn));
647*fcf3ce44SJohn Forte 	(void) strncpy(svn.svn_path, path, sizeof (svn.svn_path));
648*fcf3ce44SJohn Forte 	svn.svn_mode = (NSC_DEVICE | NSC_CACHE);
649*fcf3ce44SJohn Forte 
650*fcf3ce44SJohn Forte 	/* force NULL termination */
651*fcf3ce44SJohn Forte 	svn.svn_path[sizeof (svn.svn_path) - 1] = '\0';
652*fcf3ce44SJohn Forte 
653*fcf3ce44SJohn Forte 	rc = enable_dev(&svn);
654*fcf3ce44SJohn Forte 	sv_cfg_close();
655*fcf3ce44SJohn Forte 
656*fcf3ce44SJohn Forte 	return (rc);
657*fcf3ce44SJohn Forte }
658*fcf3ce44SJohn Forte 
659*fcf3ce44SJohn Forte 
660*fcf3ce44SJohn Forte static int
enable_dev(sv_name_t * svn)661*fcf3ce44SJohn Forte enable_dev(sv_name_t *svn)
662*fcf3ce44SJohn Forte {
663*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
664*fcf3ce44SJohn Forte 	struct stat stb;
665*fcf3ce44SJohn Forte 	sv_conf_t svc;
666*fcf3ce44SJohn Forte 	int fd;
667*fcf3ce44SJohn Forte 	int sev;
668*fcf3ce44SJohn Forte 	int rc;
669*fcf3ce44SJohn Forte 	char *lcltag;
670*fcf3ce44SJohn Forte 	char *altname;
671*fcf3ce44SJohn Forte 
672*fcf3ce44SJohn Forte 	sv_check_cluster(svn->svn_path);
673*fcf3ce44SJohn Forte 	sv_cfg_open(CFG_WRLOCK);
674*fcf3ce44SJohn Forte 
675*fcf3ce44SJohn Forte 	bzero(&svc, sizeof (svc));
676*fcf3ce44SJohn Forte 
677*fcf3ce44SJohn Forte 	if (stat(svn->svn_path, &stb) != 0) {
678*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to access %s: %s"),
679*fcf3ce44SJohn Forte 			svn->svn_path, strerror(errno));
680*fcf3ce44SJohn Forte 		return (1);
681*fcf3ce44SJohn Forte 	}
682*fcf3ce44SJohn Forte 
683*fcf3ce44SJohn Forte 	if (!S_ISCHR(stb.st_mode)) {
684*fcf3ce44SJohn Forte 		warn(NULL, gettext("%s is not a character device - ignored"),
685*fcf3ce44SJohn Forte 		    svn->svn_path);
686*fcf3ce44SJohn Forte 		return (1);
687*fcf3ce44SJohn Forte 	}
688*fcf3ce44SJohn Forte 
689*fcf3ce44SJohn Forte 	svc.svc_major = major(stb.st_rdev);
690*fcf3ce44SJohn Forte 	svc.svc_minor = minor(stb.st_rdev);
691*fcf3ce44SJohn Forte 	(void) strncpy(svc.svc_path, svn->svn_path, sizeof (svc.svc_path));
692*fcf3ce44SJohn Forte 
693*fcf3ce44SJohn Forte 	fd = open(sv_rpath, O_RDONLY);
694*fcf3ce44SJohn Forte 	if (fd < 0) {
695*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to open %s: %s"),
696*fcf3ce44SJohn Forte 			svn->svn_path, strerror(errno));
697*fcf3ce44SJohn Forte 		return (1);
698*fcf3ce44SJohn Forte 	}
699*fcf3ce44SJohn Forte 
700*fcf3ce44SJohn Forte 	svc.svc_flag = svn->svn_mode;
701*fcf3ce44SJohn Forte 	svc.svc_error = spcs_s_ucreate();
702*fcf3ce44SJohn Forte 
703*fcf3ce44SJohn Forte 	/* first, check for duplicates */
704*fcf3ce44SJohn Forte 	rc = cfg_get_canonical_name(cfg, svn->svn_path, &altname);
705*fcf3ce44SJohn Forte 	if (rc < 0) {
706*fcf3ce44SJohn Forte 		spcs_log("sv", NULL, gettext("Unable to parse config file"));
707*fcf3ce44SJohn Forte 		warn(NULL, gettext("Unable to parse config file"));
708*fcf3ce44SJohn Forte 		(void) close(fd);
709*fcf3ce44SJohn Forte 		return (1);
710*fcf3ce44SJohn Forte 	}
711*fcf3ce44SJohn Forte 	if (rc) {
712*fcf3ce44SJohn Forte 		error(NULL, gettext("'%s' has already been configured as "
713*fcf3ce44SJohn Forte 		    "'%s'.  Re-enter command with the latter name."),
714*fcf3ce44SJohn Forte 		    svn->svn_path, altname);
715*fcf3ce44SJohn Forte 	}
716*fcf3ce44SJohn Forte 
717*fcf3ce44SJohn Forte 	/* secondly, try to insert it into the dsvol config */
718*fcf3ce44SJohn Forte 	if (implicit_tag && *implicit_tag) {
719*fcf3ce44SJohn Forte 		lcltag = implicit_tag;
720*fcf3ce44SJohn Forte 	} else if (cfg_cluster_tag && *cfg_cluster_tag) {
721*fcf3ce44SJohn Forte 		lcltag = cfg_cluster_tag;
722*fcf3ce44SJohn Forte 	} else {
723*fcf3ce44SJohn Forte 		lcltag = "-";
724*fcf3ce44SJohn Forte 	}
725*fcf3ce44SJohn Forte 	rc = cfg_add_user(cfg, svn->svn_path, lcltag, "sv");
726*fcf3ce44SJohn Forte 	if (CFG_USER_ERR == rc) {
727*fcf3ce44SJohn Forte 		spcs_log("sv", NULL,
728*fcf3ce44SJohn Forte 		    gettext("%s: unable to put %s into dsvol cfg"),
729*fcf3ce44SJohn Forte 		    program, svn->svn_path);
730*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to put %s into dsvol cfg"),
731*fcf3ce44SJohn Forte 		    svn->svn_path);
732*fcf3ce44SJohn Forte 		(void) close(fd);
733*fcf3ce44SJohn Forte 		return (1);
734*fcf3ce44SJohn Forte 	}
735*fcf3ce44SJohn Forte 	cfg_changed = 1;
736*fcf3ce44SJohn Forte 
737*fcf3ce44SJohn Forte 	if (CFG_USER_OK == rc) {
738*fcf3ce44SJohn Forte 		/* success */
739*fcf3ce44SJohn Forte 		(void) close(fd);
740*fcf3ce44SJohn Forte 		return (0);
741*fcf3ce44SJohn Forte 	}
742*fcf3ce44SJohn Forte 
743*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) {
744*fcf3ce44SJohn Forte 		if ((CFG_USER_REPEAT == rc) && (SV_EENABLED == errno)) {
745*fcf3ce44SJohn Forte 			/* it's ok -- we were just double-checking */
746*fcf3ce44SJohn Forte 			(void) close(fd);
747*fcf3ce44SJohn Forte 			return (0);
748*fcf3ce44SJohn Forte 		}
749*fcf3ce44SJohn Forte 
750*fcf3ce44SJohn Forte 		spcs_log("sv", &svc.svc_error,
751*fcf3ce44SJohn Forte 		    gettext("%s: unable to enable %s"),
752*fcf3ce44SJohn Forte 		    program, svn->svn_path);
753*fcf3ce44SJohn Forte 
754*fcf3ce44SJohn Forte 		warn(&svc.svc_error, gettext("unable to enable %s"),
755*fcf3ce44SJohn Forte 			svn->svn_path);
756*fcf3ce44SJohn Forte 
757*fcf3ce44SJohn Forte 		/* remove it from dsvol, if we're the ones who put it in */
758*fcf3ce44SJohn Forte 		if (CFG_USER_FIRST == rc) {
759*fcf3ce44SJohn Forte 			(void) cfg_rem_user(cfg, svn->svn_path, lcltag, "sv");
760*fcf3ce44SJohn Forte 		}
761*fcf3ce44SJohn Forte 		(void) close(fd);
762*fcf3ce44SJohn Forte 		return (1);
763*fcf3ce44SJohn Forte 	}
764*fcf3ce44SJohn Forte 
765*fcf3ce44SJohn Forte 	spcs_log("sv", NULL, gettext("%s: enabled %s"),
766*fcf3ce44SJohn Forte 	    program, svn->svn_path);
767*fcf3ce44SJohn Forte 
768*fcf3ce44SJohn Forte 	if (implicit_tag != NULL) {
769*fcf3ce44SJohn Forte #ifdef DEBUG
770*fcf3ce44SJohn Forte 		if (cfg_cluster_tag != NULL) {
771*fcf3ce44SJohn Forte 			error(NULL,
772*fcf3ce44SJohn Forte 			    gettext("enable_dev: -C %s AND implicit_tag %s!"),
773*fcf3ce44SJohn Forte 			    cfg_cluster_tag, implicit_tag);
774*fcf3ce44SJohn Forte 		}
775*fcf3ce44SJohn Forte #endif
776*fcf3ce44SJohn Forte 
777*fcf3ce44SJohn Forte 		(void) snprintf(buf, sizeof (buf), "%s - %s",
778*fcf3ce44SJohn Forte 		    svc.svc_path, implicit_tag);
779*fcf3ce44SJohn Forte 	} else {
780*fcf3ce44SJohn Forte 		(void) strcpy(buf, svc.svc_path);
781*fcf3ce44SJohn Forte 	}
782*fcf3ce44SJohn Forte 
783*fcf3ce44SJohn Forte 	rc = 0;
784*fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, "sv", buf, sizeof (buf)) < 0) {
785*fcf3ce44SJohn Forte 		warn(NULL,
786*fcf3ce44SJohn Forte 		    gettext("unable to add %s to configuration storage: %s"),
787*fcf3ce44SJohn Forte 		    svc.svc_path, cfg_error(&sev));
788*fcf3ce44SJohn Forte 		rc = 1;
789*fcf3ce44SJohn Forte 	}
790*fcf3ce44SJohn Forte 
791*fcf3ce44SJohn Forte 	cfg_changed = 1;
792*fcf3ce44SJohn Forte 	spcs_s_ufree(&svc.svc_error);
793*fcf3ce44SJohn Forte 	(void) close(fd);
794*fcf3ce44SJohn Forte 
795*fcf3ce44SJohn Forte 	return (rc);
796*fcf3ce44SJohn Forte }
797*fcf3ce44SJohn Forte 
798*fcf3ce44SJohn Forte 
799*fcf3ce44SJohn Forte /*
800*fcf3ce44SJohn Forte  * This routine parses the config file passed in via conf_file and
801*fcf3ce44SJohn Forte  * stores the data in the svn array.  The return value is the number
802*fcf3ce44SJohn Forte  * of entries read from conf_file.  If an error occurs the error()
803*fcf3ce44SJohn Forte  * routine is called (which exits the program).
804*fcf3ce44SJohn Forte  */
805*fcf3ce44SJohn Forte static int
read_config_file(const caddr_t conf_file,sv_name_t svn[])806*fcf3ce44SJohn Forte read_config_file(const caddr_t conf_file, sv_name_t svn[])
807*fcf3ce44SJohn Forte {
808*fcf3ce44SJohn Forte 	char line[1024], rdev[1024], junk[1024];
809*fcf3ce44SJohn Forte 	struct stat stb;
810*fcf3ce44SJohn Forte 	int lineno;
811*fcf3ce44SJohn Forte 	int cnt, i;
812*fcf3ce44SJohn Forte 	int index = 0;		/* Current location in svn array	*/
813*fcf3ce44SJohn Forte 	sv_name_t *cur_svn;	/* Pointer to svn[index]		*/
814*fcf3ce44SJohn Forte 	FILE *fp;
815*fcf3ce44SJohn Forte 
816*fcf3ce44SJohn Forte 	if (access(conf_file, R_OK) != 0 ||
817*fcf3ce44SJohn Forte 	    stat(conf_file, &stb) != 0 ||
818*fcf3ce44SJohn Forte 	    !S_ISREG(stb.st_mode)) {
819*fcf3ce44SJohn Forte 		error(NULL, gettext("cannot read config file %s"), conf_file);
820*fcf3ce44SJohn Forte 	}
821*fcf3ce44SJohn Forte 
822*fcf3ce44SJohn Forte 	if ((fp = fopen(conf_file, "r")) == NULL) {
823*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to open config file %s: %s"),
824*fcf3ce44SJohn Forte 			conf_file, strerror(errno));
825*fcf3ce44SJohn Forte 	}
826*fcf3ce44SJohn Forte 
827*fcf3ce44SJohn Forte 	lineno = 0;
828*fcf3ce44SJohn Forte 
829*fcf3ce44SJohn Forte 	while (fgets(line, sizeof (line), fp) != NULL) {
830*fcf3ce44SJohn Forte 		lineno++;
831*fcf3ce44SJohn Forte 
832*fcf3ce44SJohn Forte 		i = strlen(line);
833*fcf3ce44SJohn Forte 
834*fcf3ce44SJohn Forte 		if (i < 1)
835*fcf3ce44SJohn Forte 			continue;
836*fcf3ce44SJohn Forte 
837*fcf3ce44SJohn Forte 		if (line[i-1] == '\n')
838*fcf3ce44SJohn Forte 			line[i-1] = '\0';
839*fcf3ce44SJohn Forte 		else if (i == (sizeof (line) - 1)) {
840*fcf3ce44SJohn Forte 			warn(NULL, gettext(
841*fcf3ce44SJohn Forte 		"line %d: line too long -- should be less than %d characters"),
842*fcf3ce44SJohn Forte 				lineno, (sizeof (line) - 1));
843*fcf3ce44SJohn Forte 			warn(NULL, gettext("line %d: ignored"), lineno);
844*fcf3ce44SJohn Forte 		}
845*fcf3ce44SJohn Forte 
846*fcf3ce44SJohn Forte 		/*
847*fcf3ce44SJohn Forte 		 * check for comment line.
848*fcf3ce44SJohn Forte 		 */
849*fcf3ce44SJohn Forte 		if (line[0] == '#')
850*fcf3ce44SJohn Forte 			continue;
851*fcf3ce44SJohn Forte 
852*fcf3ce44SJohn Forte 		cnt = sscanf(line, "%s %s", rdev, junk);
853*fcf3ce44SJohn Forte 
854*fcf3ce44SJohn Forte 		if (cnt != 1 && cnt != 2) {
855*fcf3ce44SJohn Forte 			if (cnt > 0) {
856*fcf3ce44SJohn Forte 				warn(NULL, gettext("line %d: invalid format"),
857*fcf3ce44SJohn Forte 					lineno);
858*fcf3ce44SJohn Forte 				warn(NULL, gettext("line %d: ignored"), lineno);
859*fcf3ce44SJohn Forte 			}
860*fcf3ce44SJohn Forte 			continue;
861*fcf3ce44SJohn Forte 		}
862*fcf3ce44SJohn Forte 
863*fcf3ce44SJohn Forte 		rdev[sizeof (rdev) - 1] = '\0';
864*fcf3ce44SJohn Forte 
865*fcf3ce44SJohn Forte 		cur_svn = &svn[index];  /* For easier reading below */
866*fcf3ce44SJohn Forte 
867*fcf3ce44SJohn Forte 		if (strlen(rdev) >= sizeof (cur_svn->svn_path)) {
868*fcf3ce44SJohn Forte 			warn(NULL, gettext(
869*fcf3ce44SJohn Forte 		"line %d: raw device name (%s) longer than %d characters"),
870*fcf3ce44SJohn Forte 				lineno, rdev,
871*fcf3ce44SJohn Forte 				(sizeof (cur_svn->svn_path) - 1));
872*fcf3ce44SJohn Forte 			warn(NULL, gettext("line %d: ignored"), lineno);
873*fcf3ce44SJohn Forte 			continue;
874*fcf3ce44SJohn Forte 		}
875*fcf3ce44SJohn Forte 
876*fcf3ce44SJohn Forte 		(void) strcpy(cur_svn->svn_path, rdev);
877*fcf3ce44SJohn Forte 		cur_svn->svn_mode = (NSC_DEVICE | NSC_CACHE);
878*fcf3ce44SJohn Forte 
879*fcf3ce44SJohn Forte 		index++;
880*fcf3ce44SJohn Forte 	}
881*fcf3ce44SJohn Forte 
882*fcf3ce44SJohn Forte 	/* Set the last path to NULL */
883*fcf3ce44SJohn Forte 	svn[index].svn_path[0] = '\0';
884*fcf3ce44SJohn Forte 
885*fcf3ce44SJohn Forte 	(void) fclose(fp);
886*fcf3ce44SJohn Forte 
887*fcf3ce44SJohn Forte 	return (index);
888*fcf3ce44SJohn Forte }
889*fcf3ce44SJohn Forte 
890*fcf3ce44SJohn Forte 
891*fcf3ce44SJohn Forte /*
892*fcf3ce44SJohn Forte  * Disable the device from the kernel configuration.
893*fcf3ce44SJohn Forte  *
894*fcf3ce44SJohn Forte  * RETURN:
895*fcf3ce44SJohn Forte  *   0 on success
896*fcf3ce44SJohn Forte  *   non-zero on failure.
897*fcf3ce44SJohn Forte  *
898*fcf3ce44SJohn Forte  * Failures are reported to the user.
899*fcf3ce44SJohn Forte  */
900*fcf3ce44SJohn Forte static int
disable_dev(const caddr_t path)901*fcf3ce44SJohn Forte disable_dev(const caddr_t path)
902*fcf3ce44SJohn Forte {
903*fcf3ce44SJohn Forte 	struct stat stb;
904*fcf3ce44SJohn Forte 	sv_conf_t svc;
905*fcf3ce44SJohn Forte 	int fd;
906*fcf3ce44SJohn Forte 
907*fcf3ce44SJohn Forte 	sv_check_cluster(path);
908*fcf3ce44SJohn Forte 
909*fcf3ce44SJohn Forte 	if (stat(path, &stb) < 0) {
910*fcf3ce44SJohn Forte 		svc.svc_major = (major_t)-1;
911*fcf3ce44SJohn Forte 		svc.svc_minor = (minor_t)-1;
912*fcf3ce44SJohn Forte 	} else {
913*fcf3ce44SJohn Forte 		svc.svc_major = major(stb.st_rdev);
914*fcf3ce44SJohn Forte 		svc.svc_minor = minor(stb.st_rdev);
915*fcf3ce44SJohn Forte 	}
916*fcf3ce44SJohn Forte 
917*fcf3ce44SJohn Forte 	if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
918*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to open %s: %s"),
919*fcf3ce44SJohn Forte 			sv_rpath, strerror(errno));
920*fcf3ce44SJohn Forte 		return (-1);
921*fcf3ce44SJohn Forte 	}
922*fcf3ce44SJohn Forte 
923*fcf3ce44SJohn Forte 	(void) strcpy(svc.svc_path, path);
924*fcf3ce44SJohn Forte 	svc.svc_error = spcs_s_ucreate();
925*fcf3ce44SJohn Forte 
926*fcf3ce44SJohn Forte 	/*
927*fcf3ce44SJohn Forte 	 * Issue the ioctl to attempt to disable this device.  Note that all
928*fcf3ce44SJohn Forte 	 * the libdscfg details are handled elsewhere.
929*fcf3ce44SJohn Forte 	 */
930*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_DISABLE, &svc) < 0) {
931*fcf3ce44SJohn Forte 		if (errno != SV_EDISABLED) {
932*fcf3ce44SJohn Forte 			spcs_log("sv", &svc.svc_error,
933*fcf3ce44SJohn Forte 					gettext("%s: unable to disable %s"),
934*fcf3ce44SJohn Forte 					program, path);
935*fcf3ce44SJohn Forte 
936*fcf3ce44SJohn Forte 			warn(&svc.svc_error,
937*fcf3ce44SJohn Forte 					gettext("unable to disable %s"), path);
938*fcf3ce44SJohn Forte 			(void) close(fd);
939*fcf3ce44SJohn Forte 			return (-1);
940*fcf3ce44SJohn Forte 		}
941*fcf3ce44SJohn Forte 	}
942*fcf3ce44SJohn Forte 
943*fcf3ce44SJohn Forte 	spcs_log("sv", NULL, gettext("%s: disabled %s"), program, path);
944*fcf3ce44SJohn Forte 
945*fcf3ce44SJohn Forte 	spcs_s_ufree(&svc.svc_error);
946*fcf3ce44SJohn Forte 	(void) close(fd);
947*fcf3ce44SJohn Forte 
948*fcf3ce44SJohn Forte 	return (0);
949*fcf3ce44SJohn Forte }
950*fcf3ce44SJohn Forte 
951*fcf3ce44SJohn Forte 
952*fcf3ce44SJohn Forte static void
print_cluster_tag(const int setnumber)953*fcf3ce44SJohn Forte print_cluster_tag(const int setnumber)
954*fcf3ce44SJohn Forte {
955*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF];
956*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
957*fcf3ce44SJohn Forte 
958*fcf3ce44SJohn Forte 	bzero(buf, sizeof (buf));
959*fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber);
960*fcf3ce44SJohn Forte 
961*fcf3ce44SJohn Forte 	(void) cfg_get_cstring(cfg, key, buf, sizeof (buf));
962*fcf3ce44SJohn Forte 
963*fcf3ce44SJohn Forte 	if (*buf != '\0') {
964*fcf3ce44SJohn Forte 		if (strcmp(buf, "-") == 0) {
965*fcf3ce44SJohn Forte 			(void) printf(" [%s]", gettext("local to node"));
966*fcf3ce44SJohn Forte 		} else {
967*fcf3ce44SJohn Forte 			(void) printf(" [%s: %s]", gettext("cluster"), buf);
968*fcf3ce44SJohn Forte 		}
969*fcf3ce44SJohn Forte 	}
970*fcf3ce44SJohn Forte }
971*fcf3ce44SJohn Forte 
972*fcf3ce44SJohn Forte 
973*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
974*fcf3ce44SJohn Forte static void
print_sv(int verbose)975*fcf3ce44SJohn Forte print_sv(int verbose)
976*fcf3ce44SJohn Forte {
977*fcf3ce44SJohn Forte 	sv_name_t *svn, *svn_system;	/* Devices in system */
978*fcf3ce44SJohn Forte 	sv_list_t svl_system;
979*fcf3ce44SJohn Forte 	int fd, i;
980*fcf3ce44SJohn Forte 	int setnumber;
981*fcf3ce44SJohn Forte 
982*fcf3ce44SJohn Forte 	sv_check_cluster(NULL);
983*fcf3ce44SJohn Forte 	sv_cfg_open(CFG_RDLOCK);
984*fcf3ce44SJohn Forte 
985*fcf3ce44SJohn Forte 	svn_system = sv_alloc_svnames();
986*fcf3ce44SJohn Forte 
987*fcf3ce44SJohn Forte 	if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
988*fcf3ce44SJohn Forte 		(void) printf(gettext("unable to open %s: %s"),
989*fcf3ce44SJohn Forte 			sv_rpath, strerror(errno));
990*fcf3ce44SJohn Forte 		return;
991*fcf3ce44SJohn Forte 	}
992*fcf3ce44SJohn Forte 
993*fcf3ce44SJohn Forte 	/* Grab the system list from the driver */
994*fcf3ce44SJohn Forte 	svl_system.svl_count = sv_max_devices;
995*fcf3ce44SJohn Forte 	svl_system.svl_names = &svn_system[0];
996*fcf3ce44SJohn Forte 	svl_system.svl_error = spcs_s_ucreate();
997*fcf3ce44SJohn Forte 
998*fcf3ce44SJohn Forte 	if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) {
999*fcf3ce44SJohn Forte 		error(&svl_system.svl_error, gettext("unable to get list"));
1000*fcf3ce44SJohn Forte 	}
1001*fcf3ce44SJohn Forte 
1002*fcf3ce44SJohn Forte 	spcs_s_ufree(&svl_system.svl_error);
1003*fcf3ce44SJohn Forte 	(void) close(fd);
1004*fcf3ce44SJohn Forte 
1005*fcf3ce44SJohn Forte 	/*
1006*fcf3ce44SJohn Forte 	 * We build a hashmap out of the entries from the config file to make
1007*fcf3ce44SJohn Forte 	 * searching faster. We end up taking a performance hit when the # of
1008*fcf3ce44SJohn Forte 	 * volumes is small, but for larger configurations it's a
1009*fcf3ce44SJohn Forte 	 * HUGE improvement.
1010*fcf3ce44SJohn Forte 	 */
1011*fcf3ce44SJohn Forte 
1012*fcf3ce44SJohn Forte 	/* build the hashtable */
1013*fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
1014*fcf3ce44SJohn Forte 	create_cfg_hash();
1015*fcf3ce44SJohn Forte 
1016*fcf3ce44SJohn Forte 	/*
1017*fcf3ce44SJohn Forte 	 * For each volume found from the kernel, print out
1018*fcf3ce44SJohn Forte 	 * info about it from the kernel.
1019*fcf3ce44SJohn Forte 	 */
1020*fcf3ce44SJohn Forte 	for (i = 0; i < svl_system.svl_count; i++) {
1021*fcf3ce44SJohn Forte 		if (*svn_system[i].svn_path == '\0') {
1022*fcf3ce44SJohn Forte 			break;
1023*fcf3ce44SJohn Forte 		}
1024*fcf3ce44SJohn Forte 
1025*fcf3ce44SJohn Forte 		svn = &svn_system[i];
1026*fcf3ce44SJohn Forte 		if (svn->svn_mode == 0) {
1027*fcf3ce44SJohn Forte #ifdef DEBUG
1028*fcf3ce44SJohn Forte 			(void) printf(gettext("%s [kernel guard]\n"),
1029*fcf3ce44SJohn Forte 			    svn->svn_path);
1030*fcf3ce44SJohn Forte #endif
1031*fcf3ce44SJohn Forte 			continue;
1032*fcf3ce44SJohn Forte 		}
1033*fcf3ce44SJohn Forte 		/* get sv entry from the hashtable */
1034*fcf3ce44SJohn Forte 		if ((setnumber = find_in_hash(svn->svn_path)) != -1) {
1035*fcf3ce44SJohn Forte 			(void) printf("%-*s", STATWIDTH, svn->svn_path);
1036*fcf3ce44SJohn Forte 
1037*fcf3ce44SJohn Forte 			if (verbose) {
1038*fcf3ce44SJohn Forte 				print_cluster_tag(setnumber);
1039*fcf3ce44SJohn Forte 			}
1040*fcf3ce44SJohn Forte 
1041*fcf3ce44SJohn Forte 			(void) printf("\n");
1042*fcf3ce44SJohn Forte 
1043*fcf3ce44SJohn Forte 		} else {
1044*fcf3ce44SJohn Forte 			/*
1045*fcf3ce44SJohn Forte 			 * We didn't find the entry in the hashtable.  Let
1046*fcf3ce44SJohn Forte 			 * the user know that the persistent storage is
1047*fcf3ce44SJohn Forte 			 * inconsistent with the kernel configuration.
1048*fcf3ce44SJohn Forte 			 */
1049*fcf3ce44SJohn Forte 			if (cfg_cluster_tag == NULL)
1050*fcf3ce44SJohn Forte 				warn(NULL, gettext(
1051*fcf3ce44SJohn Forte 					"%s is configured, but not in the "
1052*fcf3ce44SJohn Forte 					"config storage"), svn->svn_path);
1053*fcf3ce44SJohn Forte 		}
1054*fcf3ce44SJohn Forte 	}
1055*fcf3ce44SJohn Forte 
1056*fcf3ce44SJohn Forte 	/* free up the hashtable */
1057*fcf3ce44SJohn Forte 	destroy_hashtable();
1058*fcf3ce44SJohn Forte 
1059*fcf3ce44SJohn Forte 	sv_cfg_close();
1060*fcf3ce44SJohn Forte }
1061*fcf3ce44SJohn Forte 
1062*fcf3ce44SJohn Forte 
1063*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
1064*fcf3ce44SJohn Forte static int
disable_sv(char * conf_file)1065*fcf3ce44SJohn Forte disable_sv(char *conf_file)
1066*fcf3ce44SJohn Forte {
1067*fcf3ce44SJohn Forte 	sv_name_t *svn, *svn_system;	/* Devices in system */
1068*fcf3ce44SJohn Forte 	sv_list_t svl_system;
1069*fcf3ce44SJohn Forte 	int fd, i, setnumber;
1070*fcf3ce44SJohn Forte 	int rc, ret;
1071*fcf3ce44SJohn Forte 
1072*fcf3ce44SJohn Forte 	svn_system = sv_alloc_svnames();
1073*fcf3ce44SJohn Forte 
1074*fcf3ce44SJohn Forte 	rc = ret = 0;
1075*fcf3ce44SJohn Forte 
1076*fcf3ce44SJohn Forte 	if (conf_file == NULL) {
1077*fcf3ce44SJohn Forte 		if ((fd = open(sv_rpath, O_RDONLY)) < 0) {
1078*fcf3ce44SJohn Forte 			(void) printf(gettext("unable to open %s: %s"),
1079*fcf3ce44SJohn Forte 				sv_rpath, strerror(errno));
1080*fcf3ce44SJohn Forte 			return (1);
1081*fcf3ce44SJohn Forte 		}
1082*fcf3ce44SJohn Forte 
1083*fcf3ce44SJohn Forte 		/* Grab the system list from the driver */
1084*fcf3ce44SJohn Forte 		svl_system.svl_count = sv_max_devices;
1085*fcf3ce44SJohn Forte 		svl_system.svl_names = &svn_system[0];
1086*fcf3ce44SJohn Forte 		svl_system.svl_error = spcs_s_ucreate();
1087*fcf3ce44SJohn Forte 
1088*fcf3ce44SJohn Forte 		if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) {
1089*fcf3ce44SJohn Forte 			error(&(svl_system.svl_error),
1090*fcf3ce44SJohn Forte 					gettext("unable to get list"));
1091*fcf3ce44SJohn Forte 		}
1092*fcf3ce44SJohn Forte 
1093*fcf3ce44SJohn Forte 		spcs_s_ufree(&(svl_system.svl_error));
1094*fcf3ce44SJohn Forte 		(void) close(fd);
1095*fcf3ce44SJohn Forte 	} else {
1096*fcf3ce44SJohn Forte 		svl_system.svl_count = read_config_file(conf_file, svn_system);
1097*fcf3ce44SJohn Forte 	}
1098*fcf3ce44SJohn Forte 
1099*fcf3ce44SJohn Forte 
1100*fcf3ce44SJohn Forte 	for (i = 0; i < svl_system.svl_count; i++) {
1101*fcf3ce44SJohn Forte 		if (*svn_system[i].svn_path == '\0')
1102*fcf3ce44SJohn Forte 			break;
1103*fcf3ce44SJohn Forte 
1104*fcf3ce44SJohn Forte 		svn = &svn_system[i];
1105*fcf3ce44SJohn Forte 
1106*fcf3ce44SJohn Forte 		sv_check_cluster(svn->svn_path);
1107*fcf3ce44SJohn Forte 		sv_cfg_open(CFG_WRLOCK);
1108*fcf3ce44SJohn Forte 		create_cfg_hash();
1109*fcf3ce44SJohn Forte 		rc = 0;
1110*fcf3ce44SJohn Forte 		if ((setnumber = find_in_hash(svn->svn_path)) != -1) {
1111*fcf3ce44SJohn Forte 			if ((rc = disable_dev(svn->svn_path)) != -1) {
1112*fcf3ce44SJohn Forte 				remove_from_cfgfile(svn->svn_path, setnumber);
1113*fcf3ce44SJohn Forte 			} else if (errno == SV_ENODEV) {
1114*fcf3ce44SJohn Forte 				remove_from_cfgfile(svn->svn_path, setnumber);
1115*fcf3ce44SJohn Forte 			}
1116*fcf3ce44SJohn Forte 		} else {
1117*fcf3ce44SJohn Forte 			/* warn the user that we didn't find it in cfg file */
1118*fcf3ce44SJohn Forte 			warn(NULL, gettext(
1119*fcf3ce44SJohn Forte 				"%s was not found in the config storage"),
1120*fcf3ce44SJohn Forte 				svn->svn_path);
1121*fcf3ce44SJohn Forte 			/* try to disable anyway */
1122*fcf3ce44SJohn Forte 			(void) disable_dev(svn->svn_path);
1123*fcf3ce44SJohn Forte 			rc = 1;
1124*fcf3ce44SJohn Forte 		}
1125*fcf3ce44SJohn Forte 
1126*fcf3ce44SJohn Forte 		sv_cfg_close();
1127*fcf3ce44SJohn Forte 		destroy_hashtable();
1128*fcf3ce44SJohn Forte 
1129*fcf3ce44SJohn Forte 		if (rc && !ret)
1130*fcf3ce44SJohn Forte 			ret = rc;
1131*fcf3ce44SJohn Forte 	}
1132*fcf3ce44SJohn Forte 
1133*fcf3ce44SJohn Forte 	return (ret);
1134*fcf3ce44SJohn Forte }
1135*fcf3ce44SJohn Forte 
1136*fcf3ce44SJohn Forte 
1137*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
1138*fcf3ce44SJohn Forte static int
disable_one_sv(char * path)1139*fcf3ce44SJohn Forte disable_one_sv(char *path)
1140*fcf3ce44SJohn Forte {
1141*fcf3ce44SJohn Forte 	int setnumber;
1142*fcf3ce44SJohn Forte 	int rc;
1143*fcf3ce44SJohn Forte 
1144*fcf3ce44SJohn Forte 	sv_get_maxdevs();
1145*fcf3ce44SJohn Forte 	sv_check_cluster(path);
1146*fcf3ce44SJohn Forte 	sv_cfg_open(CFG_WRLOCK);
1147*fcf3ce44SJohn Forte 
1148*fcf3ce44SJohn Forte 	create_cfg_hash();
1149*fcf3ce44SJohn Forte 	if ((setnumber = find_in_hash(path)) != -1) {
1150*fcf3ce44SJohn Forte 		/* remove from kernel */
1151*fcf3ce44SJohn Forte 		if ((rc = disable_dev(path)) == 0) {
1152*fcf3ce44SJohn Forte 			/* remove the cfgline */
1153*fcf3ce44SJohn Forte 			remove_from_cfgfile(path, setnumber);
1154*fcf3ce44SJohn Forte 		} else if (errno == SV_ENODEV) {
1155*fcf3ce44SJohn Forte 			remove_from_cfgfile(path, setnumber);
1156*fcf3ce44SJohn Forte 		}
1157*fcf3ce44SJohn Forte 	} else {
1158*fcf3ce44SJohn Forte 		/* warn the user that we didn't find it in cfg file */
1159*fcf3ce44SJohn Forte 		warn(NULL,
1160*fcf3ce44SJohn Forte 		    gettext("%s was not found in the config storage"), path);
1161*fcf3ce44SJohn Forte 		/* still attempt to remove */
1162*fcf3ce44SJohn Forte 		(void) disable_dev(path);
1163*fcf3ce44SJohn Forte 		rc = 1;
1164*fcf3ce44SJohn Forte 	}
1165*fcf3ce44SJohn Forte 	destroy_hashtable();
1166*fcf3ce44SJohn Forte 
1167*fcf3ce44SJohn Forte 	sv_cfg_close();
1168*fcf3ce44SJohn Forte 	return (rc);
1169*fcf3ce44SJohn Forte }
1170*fcf3ce44SJohn Forte 
1171*fcf3ce44SJohn Forte 
1172*fcf3ce44SJohn Forte static void
compare_tag(char * path)1173*fcf3ce44SJohn Forte compare_tag(char *path)
1174*fcf3ce44SJohn Forte {
1175*fcf3ce44SJohn Forte 	char buf[CFG_MAX_BUF], vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF];
1176*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
1177*fcf3ce44SJohn Forte 	int found, setnumber, i;
1178*fcf3ce44SJohn Forte 	char *tag;
1179*fcf3ce44SJohn Forte 
1180*fcf3ce44SJohn Forte 	sv_check_cluster(path);
1181*fcf3ce44SJohn Forte 	cfg_resource(cfg, (char *)NULL);	/* reset */
1182*fcf3ce44SJohn Forte 	cfg_rewind(cfg, CFG_SEC_CONF);
1183*fcf3ce44SJohn Forte 
1184*fcf3ce44SJohn Forte #ifdef DEBUG
1185*fcf3ce44SJohn Forte 	if (cfg_cluster_tag != NULL && implicit_tag != NULL) {
1186*fcf3ce44SJohn Forte 		error(NULL, gettext("compare_tag: -C %s AND implicit_tag %s!"),
1187*fcf3ce44SJohn Forte 		    cfg_cluster_tag, implicit_tag);
1188*fcf3ce44SJohn Forte 	}
1189*fcf3ce44SJohn Forte #endif
1190*fcf3ce44SJohn Forte 
1191*fcf3ce44SJohn Forte 	if (cfg_cluster_tag != NULL)
1192*fcf3ce44SJohn Forte 		tag = cfg_cluster_tag;
1193*fcf3ce44SJohn Forte 	else if (implicit_tag != NULL)
1194*fcf3ce44SJohn Forte 		tag = implicit_tag;
1195*fcf3ce44SJohn Forte 	else
1196*fcf3ce44SJohn Forte 		tag = "-";
1197*fcf3ce44SJohn Forte 
1198*fcf3ce44SJohn Forte 	found = 0;
1199*fcf3ce44SJohn Forte 	for (i = 0; i < sv_max_devices; i++) {
1200*fcf3ce44SJohn Forte 		setnumber = i + 1;
1201*fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "sv.set%d", setnumber);
1202*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) {
1203*fcf3ce44SJohn Forte 			break;
1204*fcf3ce44SJohn Forte 		}
1205*fcf3ce44SJohn Forte 
1206*fcf3ce44SJohn Forte 		if (sscanf(buf, "%s - %s", vol, cnode) != 2) {
1207*fcf3ce44SJohn Forte 			continue;
1208*fcf3ce44SJohn Forte 		}
1209*fcf3ce44SJohn Forte 
1210*fcf3ce44SJohn Forte 		if (strcmp(path, vol) == 0) {
1211*fcf3ce44SJohn Forte 			found = 1;
1212*fcf3ce44SJohn Forte 			break;
1213*fcf3ce44SJohn Forte 		}
1214*fcf3ce44SJohn Forte 	}
1215*fcf3ce44SJohn Forte 
1216*fcf3ce44SJohn Forte 	if (!found) {
1217*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to find %s in the configuration"),
1218*fcf3ce44SJohn Forte 		    path);
1219*fcf3ce44SJohn Forte 		return;
1220*fcf3ce44SJohn Forte 	}
1221*fcf3ce44SJohn Forte 
1222*fcf3ce44SJohn Forte 	/* have name match, compare cnode to new tag */
1223*fcf3ce44SJohn Forte 
1224*fcf3ce44SJohn Forte 	if (strcmp(tag, cnode) == 0) {
1225*fcf3ce44SJohn Forte 		/* cluster tags match */
1226*fcf3ce44SJohn Forte 		return;
1227*fcf3ce44SJohn Forte 	}
1228*fcf3ce44SJohn Forte 
1229*fcf3ce44SJohn Forte 	/* need to change the cluster tag */
1230*fcf3ce44SJohn Forte 
1231*fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber);
1232*fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, key, tag, strlen(tag)) < 0) {
1233*fcf3ce44SJohn Forte 		warn(NULL,
1234*fcf3ce44SJohn Forte 		    gettext("unable to change cluster tag for %s"), path);
1235*fcf3ce44SJohn Forte 		return;
1236*fcf3ce44SJohn Forte 	}
1237*fcf3ce44SJohn Forte 
1238*fcf3ce44SJohn Forte 	cfg_changed = 1;
1239*fcf3ce44SJohn Forte 
1240*fcf3ce44SJohn Forte 	/* change "-" tags to "" for display purposes */
1241*fcf3ce44SJohn Forte 
1242*fcf3ce44SJohn Forte 	if (strcmp(tag, "-") == 0)
1243*fcf3ce44SJohn Forte 		tag = "";
1244*fcf3ce44SJohn Forte 
1245*fcf3ce44SJohn Forte 	if (strcmp(cnode, "-") == 0)
1246*fcf3ce44SJohn Forte 		(void) strcpy(cnode, "");
1247*fcf3ce44SJohn Forte 
1248*fcf3ce44SJohn Forte 	(void) printf(
1249*fcf3ce44SJohn Forte 	    gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\"\n"),
1250*fcf3ce44SJohn Forte 	    program, path, cnode, tag);
1251*fcf3ce44SJohn Forte 
1252*fcf3ce44SJohn Forte 	spcs_log("sv", NULL,
1253*fcf3ce44SJohn Forte 	    gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\""),
1254*fcf3ce44SJohn Forte 	    program, path, cnode, tag);
1255*fcf3ce44SJohn Forte }
1256*fcf3ce44SJohn Forte 
1257*fcf3ce44SJohn Forte 
1258*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
1259*fcf3ce44SJohn Forte static void
compare_sv(char * conf_file)1260*fcf3ce44SJohn Forte compare_sv(char *conf_file)
1261*fcf3ce44SJohn Forte {
1262*fcf3ce44SJohn Forte 	sv_name_t *svn_config;		/* Devices in config file */
1263*fcf3ce44SJohn Forte 	sv_name_t *svn_system;		/* Devices in system */
1264*fcf3ce44SJohn Forte 	sv_name_t *enable;		/* Devices that need enabled */
1265*fcf3ce44SJohn Forte 	sv_list_t svl_system;
1266*fcf3ce44SJohn Forte 	int config_cnt;
1267*fcf3ce44SJohn Forte 	int sys_cnt = 0;
1268*fcf3ce44SJohn Forte 	int setnumber, i, j;
1269*fcf3ce44SJohn Forte 	int index = 0;	/* Index in enable[] */
1270*fcf3ce44SJohn Forte 	int found;
1271*fcf3ce44SJohn Forte 	int fd0;
1272*fcf3ce44SJohn Forte 
1273*fcf3ce44SJohn Forte 	svn_config = sv_alloc_svnames();
1274*fcf3ce44SJohn Forte 	svn_system = sv_alloc_svnames();
1275*fcf3ce44SJohn Forte 	enable = sv_alloc_svnames();
1276*fcf3ce44SJohn Forte 
1277*fcf3ce44SJohn Forte 	bzero(svn_system, sizeof (svn_system));
1278*fcf3ce44SJohn Forte 	bzero(&svl_system, sizeof (svl_system));
1279*fcf3ce44SJohn Forte 	bzero(enable, sizeof (enable));
1280*fcf3ce44SJohn Forte 
1281*fcf3ce44SJohn Forte 	/*
1282*fcf3ce44SJohn Forte 	 * Read the configuration file
1283*fcf3ce44SJohn Forte 	 * The return value is the number of entries
1284*fcf3ce44SJohn Forte 	 */
1285*fcf3ce44SJohn Forte 	config_cnt = read_config_file(conf_file, svn_config);
1286*fcf3ce44SJohn Forte 
1287*fcf3ce44SJohn Forte 	if ((fd0 = open(sv_rpath, O_RDONLY)) < 0)
1288*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to open %s: %s"),
1289*fcf3ce44SJohn Forte 			sv_rpath, strerror(errno));
1290*fcf3ce44SJohn Forte 
1291*fcf3ce44SJohn Forte 	/* Grab the system list from the driver */
1292*fcf3ce44SJohn Forte 	svl_system.svl_count = sv_max_devices;
1293*fcf3ce44SJohn Forte 	svl_system.svl_names = &svn_system[0];
1294*fcf3ce44SJohn Forte 	svl_system.svl_error = spcs_s_ucreate();
1295*fcf3ce44SJohn Forte 
1296*fcf3ce44SJohn Forte 	if (ioctl(fd0, SVIOC_LIST, &svl_system) < 0) {
1297*fcf3ce44SJohn Forte 		error(&svl_system.svl_error, gettext("unable to get list"));
1298*fcf3ce44SJohn Forte 	}
1299*fcf3ce44SJohn Forte 
1300*fcf3ce44SJohn Forte 	spcs_s_ufree(&svl_system.svl_error);
1301*fcf3ce44SJohn Forte 	(void) close(fd0);
1302*fcf3ce44SJohn Forte 
1303*fcf3ce44SJohn Forte 	/*
1304*fcf3ce44SJohn Forte 	 * Count the number of devices in the system.
1305*fcf3ce44SJohn Forte 	 * The last entry in the array has '\0' for a path name.
1306*fcf3ce44SJohn Forte 	 */
1307*fcf3ce44SJohn Forte 	for (j = 0; j < sv_max_devices; j++) {
1308*fcf3ce44SJohn Forte 		if (svn_system[j].svn_path[0] != '\0') {
1309*fcf3ce44SJohn Forte 			sys_cnt++;
1310*fcf3ce44SJohn Forte 		} else {
1311*fcf3ce44SJohn Forte 			break;
1312*fcf3ce44SJohn Forte 		}
1313*fcf3ce44SJohn Forte 	}
1314*fcf3ce44SJohn Forte 	/*
1315*fcf3ce44SJohn Forte 	 * Compare the configuration array with the system array.
1316*fcf3ce44SJohn Forte 	 * Mark any differences and disable conflicting devices.
1317*fcf3ce44SJohn Forte 	 */
1318*fcf3ce44SJohn Forte 	for (i = 0; i < config_cnt; i++) {
1319*fcf3ce44SJohn Forte 		found = 0;
1320*fcf3ce44SJohn Forte 		for (j = 0; j < sys_cnt; j++) {
1321*fcf3ce44SJohn Forte 			if (svn_system[j].svn_path[0] == '\0' ||
1322*fcf3ce44SJohn Forte 			    svn_system[j].svn_mode == 0)
1323*fcf3ce44SJohn Forte 				continue;
1324*fcf3ce44SJohn Forte 
1325*fcf3ce44SJohn Forte 			/*  Check to see if path matches */
1326*fcf3ce44SJohn Forte 			if (strcmp(svn_system[j].svn_path,
1327*fcf3ce44SJohn Forte 			    svn_config[i].svn_path) == 0) {
1328*fcf3ce44SJohn Forte 				/*  Found a match  */
1329*fcf3ce44SJohn Forte 				svn_system[j].svn_path[0] = '\0';
1330*fcf3ce44SJohn Forte 				found++;
1331*fcf3ce44SJohn Forte 				break;
1332*fcf3ce44SJohn Forte 			}
1333*fcf3ce44SJohn Forte 		}
1334*fcf3ce44SJohn Forte 
1335*fcf3ce44SJohn Forte 		if (!found) {
1336*fcf3ce44SJohn Forte 			/* Minor number not in system  = > enable device */
1337*fcf3ce44SJohn Forte 			enable[index].svn_mode = svn_config[i].svn_mode;
1338*fcf3ce44SJohn Forte 			(void) strcpy(enable[index].svn_path,
1339*fcf3ce44SJohn Forte 			    svn_config[i].svn_path);
1340*fcf3ce44SJohn Forte 			index++;
1341*fcf3ce44SJohn Forte 		}
1342*fcf3ce44SJohn Forte 	}
1343*fcf3ce44SJohn Forte 
1344*fcf3ce44SJohn Forte 	/* Disable any devices that weren't in the config file */
1345*fcf3ce44SJohn Forte 	for (j = 0; j < sys_cnt; j++) {
1346*fcf3ce44SJohn Forte 		sv_check_cluster(NULL);
1347*fcf3ce44SJohn Forte 		sv_cfg_open(CFG_WRLOCK);
1348*fcf3ce44SJohn Forte 		create_cfg_hash();
1349*fcf3ce44SJohn Forte 		if (svn_system[j].svn_path[0] != '\0' &&
1350*fcf3ce44SJohn Forte 		    svn_system[j].svn_mode != 0) {
1351*fcf3ce44SJohn Forte 			(void) printf(gettext("%s: disabling sv: %s\n"),
1352*fcf3ce44SJohn Forte 			    program, svn_system[j].svn_path);
1353*fcf3ce44SJohn Forte 			if (disable_dev(svn_system[j].svn_path) == 0) {
1354*fcf3ce44SJohn Forte 				setnumber =
1355*fcf3ce44SJohn Forte 					find_in_hash(svn_system[j].svn_path);
1356*fcf3ce44SJohn Forte 				if (setnumber != -1) {
1357*fcf3ce44SJohn Forte 					/* the volume was found in cfg store */
1358*fcf3ce44SJohn Forte 					remove_from_cfgfile(
1359*fcf3ce44SJohn Forte 					svn_system[j].svn_path, setnumber);
1360*fcf3ce44SJohn Forte 				}
1361*fcf3ce44SJohn Forte 			}
1362*fcf3ce44SJohn Forte 		}
1363*fcf3ce44SJohn Forte 		sv_cfg_close();
1364*fcf3ce44SJohn Forte 		destroy_hashtable();
1365*fcf3ce44SJohn Forte 	}
1366*fcf3ce44SJohn Forte 
1367*fcf3ce44SJohn Forte 	while (index) {
1368*fcf3ce44SJohn Forte 		/*
1369*fcf3ce44SJohn Forte 		 * Config file doesn't match system => enable the devices
1370*fcf3ce44SJohn Forte 		 * in enable[]
1371*fcf3ce44SJohn Forte 		 */
1372*fcf3ce44SJohn Forte 		index--;
1373*fcf3ce44SJohn Forte 		(void) printf(gettext("%s: enabling new sv: %s\n"),
1374*fcf3ce44SJohn Forte 		    program, enable[index].svn_path);
1375*fcf3ce44SJohn Forte 		(void) enable_dev(&enable[index]);
1376*fcf3ce44SJohn Forte 	}
1377*fcf3ce44SJohn Forte 
1378*fcf3ce44SJohn Forte 	/*
1379*fcf3ce44SJohn Forte 	 * Search for entries where the cluster tag has changed.
1380*fcf3ce44SJohn Forte 	 */
1381*fcf3ce44SJohn Forte 	sv_check_cluster(NULL);
1382*fcf3ce44SJohn Forte 	sv_cfg_open(CFG_WRLOCK);
1383*fcf3ce44SJohn Forte 
1384*fcf3ce44SJohn Forte 	for (i = 0; i < sv_max_devices; i++) {
1385*fcf3ce44SJohn Forte 		if (svn_config[i].svn_path[0] == '\0')
1386*fcf3ce44SJohn Forte 			break;
1387*fcf3ce44SJohn Forte 
1388*fcf3ce44SJohn Forte 		compare_tag(svn_config[i].svn_path);
1389*fcf3ce44SJohn Forte 	}
1390*fcf3ce44SJohn Forte 
1391*fcf3ce44SJohn Forte 	sv_cfg_close();
1392*fcf3ce44SJohn Forte }
1393*fcf3ce44SJohn Forte 
1394*fcf3ce44SJohn Forte 
1395*fcf3ce44SJohn Forte /*
1396*fcf3ce44SJohn Forte  * We assume that the volume is already enabled and we can only
1397*fcf3ce44SJohn Forte  * be changing the cluster tag.  Anything else is an error.
1398*fcf3ce44SJohn Forte  */
1399*fcf3ce44SJohn Forte /* LINT - not static as fwcadm uses it */
1400*fcf3ce44SJohn Forte static void
compare_one_sv(char * path)1401*fcf3ce44SJohn Forte compare_one_sv(char *path)
1402*fcf3ce44SJohn Forte {
1403*fcf3ce44SJohn Forte 	sv_get_maxdevs();
1404*fcf3ce44SJohn Forte 	sv_check_cluster(NULL);
1405*fcf3ce44SJohn Forte 	sv_cfg_open(CFG_WRLOCK);
1406*fcf3ce44SJohn Forte 
1407*fcf3ce44SJohn Forte 	compare_tag(path);
1408*fcf3ce44SJohn Forte 
1409*fcf3ce44SJohn Forte 	sv_cfg_close();
1410*fcf3ce44SJohn Forte }
1411*fcf3ce44SJohn Forte 
1412*fcf3ce44SJohn Forte /*
1413*fcf3ce44SJohn Forte  * Read all sets from the libdscfg configuration file, and store everything in
1414*fcf3ce44SJohn Forte  * the hashfile.
1415*fcf3ce44SJohn Forte  *
1416*fcf3ce44SJohn Forte  * We assume that the config file has been opened & rewound for us.  We store
1417*fcf3ce44SJohn Forte  * the volume name as the key, and the setnumber where we found it as the data.
1418*fcf3ce44SJohn Forte  *
1419*fcf3ce44SJohn Forte  * The caller can pass in a pointer to the maximum number of volumes, or
1420*fcf3ce44SJohn Forte  * a pointer to NULL, specifying we want 'all' the volumes.  The table is
1421*fcf3ce44SJohn Forte  * searched using find_in_hash.
1422*fcf3ce44SJohn Forte  */
1423*fcf3ce44SJohn Forte static void
create_cfg_hash()1424*fcf3ce44SJohn Forte create_cfg_hash()
1425*fcf3ce44SJohn Forte {
1426*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY], buf[CFG_MAX_BUF];
1427*fcf3ce44SJohn Forte 	char vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF];
1428*fcf3ce44SJohn Forte 	int setnumber;
1429*fcf3ce44SJohn Forte 	ENTRY item;
1430*fcf3ce44SJohn Forte 
1431*fcf3ce44SJohn Forte 	if (hcreate((size_t)sv_max_devices) == 0)
1432*fcf3ce44SJohn Forte 		error(NULL, gettext("unable to create hash table"));
1433*fcf3ce44SJohn Forte 
1434*fcf3ce44SJohn Forte 	for (setnumber = 1; /* CSTYLED */; setnumber++) {
1435*fcf3ce44SJohn Forte 		(void) snprintf(key, sizeof (key), "sv.set%d", setnumber);
1436*fcf3ce44SJohn Forte 		if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0)
1437*fcf3ce44SJohn Forte 			break;
1438*fcf3ce44SJohn Forte 
1439*fcf3ce44SJohn Forte 		if (sscanf(buf, "%s - %s", vol, cnode) != 2) {
1440*fcf3ce44SJohn Forte 			continue;
1441*fcf3ce44SJohn Forte 		}
1442*fcf3ce44SJohn Forte 
1443*fcf3ce44SJohn Forte 		item.key = strdup(vol);
1444*fcf3ce44SJohn Forte 		item.data = (void *)setnumber;
1445*fcf3ce44SJohn Forte 		if (hsearch(item, ENTER) == NULL) {
1446*fcf3ce44SJohn Forte 			error(NULL,
1447*fcf3ce44SJohn Forte 			    gettext("unable to add entry to hash table"));
1448*fcf3ce44SJohn Forte 		}
1449*fcf3ce44SJohn Forte 	}
1450*fcf3ce44SJohn Forte }
1451*fcf3ce44SJohn Forte 
1452*fcf3ce44SJohn Forte /*
1453*fcf3ce44SJohn Forte  * Function to search the hash for a specific volume.  If it is found,
1454*fcf3ce44SJohn Forte  * we return the set number.  If it isn't found, we return -1
1455*fcf3ce44SJohn Forte  */
1456*fcf3ce44SJohn Forte static int
find_in_hash(char * path)1457*fcf3ce44SJohn Forte find_in_hash(char *path)
1458*fcf3ce44SJohn Forte {
1459*fcf3ce44SJohn Forte 	ENTRY *found_entry, item;
1460*fcf3ce44SJohn Forte 	int retval = -1;
1461*fcf3ce44SJohn Forte 
1462*fcf3ce44SJohn Forte 	item.key = path;
1463*fcf3ce44SJohn Forte 
1464*fcf3ce44SJohn Forte 	if ((found_entry = hsearch(item, FIND)) != NULL) {
1465*fcf3ce44SJohn Forte 		retval = (int)found_entry->data;
1466*fcf3ce44SJohn Forte 	}
1467*fcf3ce44SJohn Forte 
1468*fcf3ce44SJohn Forte 	return (retval);
1469*fcf3ce44SJohn Forte }
1470*fcf3ce44SJohn Forte 
1471*fcf3ce44SJohn Forte /*
1472*fcf3ce44SJohn Forte  * Just a wrapper to destory the hashtable.  At some point in the future we
1473*fcf3ce44SJohn Forte  * might want to do something more....  For instance, verify that the cfg
1474*fcf3ce44SJohn Forte  * database and the kernel configuration match (?)  Just an idea.
1475*fcf3ce44SJohn Forte  */
1476*fcf3ce44SJohn Forte static void
destroy_hashtable()1477*fcf3ce44SJohn Forte destroy_hashtable()
1478*fcf3ce44SJohn Forte {
1479*fcf3ce44SJohn Forte 	hdestroy();
1480*fcf3ce44SJohn Forte }
1481*fcf3ce44SJohn Forte 
1482*fcf3ce44SJohn Forte /*
1483*fcf3ce44SJohn Forte  * This function will remove a particular set from the config file.
1484*fcf3ce44SJohn Forte  *
1485*fcf3ce44SJohn Forte  * We make a whole host of assumptions:
1486*fcf3ce44SJohn Forte  *   o the hashfile is up to date;
1487*fcf3ce44SJohn Forte  *   o The config file has been opened with a WRLOCK for us.
1488*fcf3ce44SJohn Forte  */
1489*fcf3ce44SJohn Forte static void
remove_from_cfgfile(char * path,int setnumber)1490*fcf3ce44SJohn Forte remove_from_cfgfile(char *path, int setnumber)
1491*fcf3ce44SJohn Forte {
1492*fcf3ce44SJohn Forte 	char key[CFG_MAX_KEY];
1493*fcf3ce44SJohn Forte 	int sev;
1494*fcf3ce44SJohn Forte 	char *lcltag;
1495*fcf3ce44SJohn Forte 
1496*fcf3ce44SJohn Forte 	/* attempt to remove the volume from config storage */
1497*fcf3ce44SJohn Forte 	(void) snprintf(key, sizeof (key), "sv.set%d", setnumber);
1498*fcf3ce44SJohn Forte 	if (cfg_put_cstring(cfg, key, NULL, 0) < 0) {
1499*fcf3ce44SJohn Forte 		warn(NULL, gettext("unable to remove %s from "
1500*fcf3ce44SJohn Forte 		    "config storage: %s"), path, cfg_error(&sev));
1501*fcf3ce44SJohn Forte 	} else {
1502*fcf3ce44SJohn Forte 		if (implicit_tag && *implicit_tag) {
1503*fcf3ce44SJohn Forte 			lcltag = implicit_tag;
1504*fcf3ce44SJohn Forte 		} else if (cfg_cluster_tag && *cfg_cluster_tag) {
1505*fcf3ce44SJohn Forte 			lcltag = cfg_cluster_tag;
1506*fcf3ce44SJohn Forte 		} else {
1507*fcf3ce44SJohn Forte 			lcltag = "-";
1508*fcf3ce44SJohn Forte 		}
1509*fcf3ce44SJohn Forte 		if (cfg_rem_user(cfg, path, lcltag, "sv") != CFG_USER_LAST) {
1510*fcf3ce44SJohn Forte 			warn(NULL, gettext("unable to remove %s from dsvol"),
1511*fcf3ce44SJohn Forte 			    path);
1512*fcf3ce44SJohn Forte 		}
1513*fcf3ce44SJohn Forte 		cfg_changed = 1;
1514*fcf3ce44SJohn Forte 	}
1515*fcf3ce44SJohn Forte }
1516