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