xref: /onnv-gate/usr/src/cmd/avs/ncall/ncalladm.c (revision 7836:4e95154b5b7a)
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 <strings.h>
29*7836SJohn.Forte@Sun.COM #include <stdlib.h>
30*7836SJohn.Forte@Sun.COM #include <unistd.h>
31*7836SJohn.Forte@Sun.COM #include <errno.h>
32*7836SJohn.Forte@Sun.COM #include <stdio.h>
33*7836SJohn.Forte@Sun.COM #include <locale.h>
34*7836SJohn.Forte@Sun.COM #include <fcntl.h>
35*7836SJohn.Forte@Sun.COM #include <libgen.h>
36*7836SJohn.Forte@Sun.COM 
37*7836SJohn.Forte@Sun.COM #include <sys/nsctl/cfg.h>
38*7836SJohn.Forte@Sun.COM #include <sys/ncall/ncall.h>
39*7836SJohn.Forte@Sun.COM 
40*7836SJohn.Forte@Sun.COM static CFGFILE *cfg;
41*7836SJohn.Forte@Sun.COM static int cfg_changed;
42*7836SJohn.Forte@Sun.COM static char *progname;
43*7836SJohn.Forte@Sun.COM static ncall_node_t *getnodelist(int, int *, int *);
44*7836SJohn.Forte@Sun.COM 
45*7836SJohn.Forte@Sun.COM 
46*7836SJohn.Forte@Sun.COM static void
usage(int exitstat)47*7836SJohn.Forte@Sun.COM usage(int exitstat)
48*7836SJohn.Forte@Sun.COM {
49*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("usage:\n"));
50*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       %s -d\n"), progname);
51*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       %s -e\n"), progname);
52*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       %s -h\n"), progname);
53*7836SJohn.Forte@Sun.COM #ifdef DEBUG
54*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       %s -c [nodeid <nodeid>]\n"),
55*7836SJohn.Forte@Sun.COM 	    progname);
56*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       %s -i\n"), progname);
57*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       %s -p <host>\n"), progname);
58*7836SJohn.Forte@Sun.COM #endif
59*7836SJohn.Forte@Sun.COM 
60*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("where:\n"));
61*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       -d    disable ncall\n"));
62*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       -e    enable ncall core\n"));
63*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       -h    this help message\n"));
64*7836SJohn.Forte@Sun.COM #ifdef DEBUG
65*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr,
66*7836SJohn.Forte@Sun.COM 	    gettext("       -c    set or print ncall configuration\n"));
67*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       -i    ncall information\n"));
68*7836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, gettext("       -p    ncall ping <host>\n"));
69*7836SJohn.Forte@Sun.COM #endif
70*7836SJohn.Forte@Sun.COM 
71*7836SJohn.Forte@Sun.COM 	exit(exitstat);
72*7836SJohn.Forte@Sun.COM }
73*7836SJohn.Forte@Sun.COM 
74*7836SJohn.Forte@Sun.COM 
75*7836SJohn.Forte@Sun.COM static void
ncall_cfg_open(CFGLOCK lk)76*7836SJohn.Forte@Sun.COM ncall_cfg_open(CFGLOCK lk)
77*7836SJohn.Forte@Sun.COM {
78*7836SJohn.Forte@Sun.COM 	char hostid[32];
79*7836SJohn.Forte@Sun.COM 
80*7836SJohn.Forte@Sun.COM 	if (cfg != NULL) {
81*7836SJohn.Forte@Sun.COM 		return;
82*7836SJohn.Forte@Sun.COM 	}
83*7836SJohn.Forte@Sun.COM 
84*7836SJohn.Forte@Sun.COM 	if (snprintf(hostid, sizeof (hostid), "%lx", gethostid()) >=
85*7836SJohn.Forte@Sun.COM 	    sizeof (hostid)) {
86*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, gettext("%s: hostid %lx too large\n"),
87*7836SJohn.Forte@Sun.COM 		    progname, gethostid());
88*7836SJohn.Forte@Sun.COM 		exit(1);
89*7836SJohn.Forte@Sun.COM 	}
90*7836SJohn.Forte@Sun.COM 
91*7836SJohn.Forte@Sun.COM 	if ((cfg = cfg_open(NULL)) == NULL) {
92*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
93*7836SJohn.Forte@Sun.COM 		    gettext("%s: unable to access the configuration: %s\n"),
94*7836SJohn.Forte@Sun.COM 		    progname, cfg_error(NULL));
95*7836SJohn.Forte@Sun.COM 		exit(1);
96*7836SJohn.Forte@Sun.COM 	}
97*7836SJohn.Forte@Sun.COM 
98*7836SJohn.Forte@Sun.COM 	if (!cfg_lock(cfg, lk)) {
99*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
100*7836SJohn.Forte@Sun.COM 		    gettext("%s: unable to lock the configuration: %s\n"),
101*7836SJohn.Forte@Sun.COM 		    progname, cfg_error(NULL));
102*7836SJohn.Forte@Sun.COM 		exit(1);
103*7836SJohn.Forte@Sun.COM 	}
104*7836SJohn.Forte@Sun.COM 
105*7836SJohn.Forte@Sun.COM 	cfg_resource(cfg, hostid);
106*7836SJohn.Forte@Sun.COM }
107*7836SJohn.Forte@Sun.COM 
108*7836SJohn.Forte@Sun.COM 
109*7836SJohn.Forte@Sun.COM static void
ncall_cfg_close(void)110*7836SJohn.Forte@Sun.COM ncall_cfg_close(void)
111*7836SJohn.Forte@Sun.COM {
112*7836SJohn.Forte@Sun.COM 	if (cfg_changed && cfg_commit(cfg) < 0) {
113*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
114*7836SJohn.Forte@Sun.COM 		    gettext("%s: unable to update the configuration: %s\n"),
115*7836SJohn.Forte@Sun.COM 		    progname, cfg_error(NULL));
116*7836SJohn.Forte@Sun.COM 		exit(1);
117*7836SJohn.Forte@Sun.COM 	}
118*7836SJohn.Forte@Sun.COM 
119*7836SJohn.Forte@Sun.COM 	cfg_close(cfg);
120*7836SJohn.Forte@Sun.COM 	cfg = NULL;
121*7836SJohn.Forte@Sun.COM }
122*7836SJohn.Forte@Sun.COM 
123*7836SJohn.Forte@Sun.COM 
124*7836SJohn.Forte@Sun.COM /*
125*7836SJohn.Forte@Sun.COM  * Get config from dscfg.
126*7836SJohn.Forte@Sun.COM  */
127*7836SJohn.Forte@Sun.COM static int
get_nodeid_from_cfg(int * nodeid)128*7836SJohn.Forte@Sun.COM get_nodeid_from_cfg(int *nodeid)
129*7836SJohn.Forte@Sun.COM {
130*7836SJohn.Forte@Sun.COM 	char buf[CFG_MAX_BUF];
131*7836SJohn.Forte@Sun.COM 	int ret = -1;
132*7836SJohn.Forte@Sun.COM 	int rc;
133*7836SJohn.Forte@Sun.COM 
134*7836SJohn.Forte@Sun.COM 	ncall_cfg_open(CFG_RDLOCK);
135*7836SJohn.Forte@Sun.COM 
136*7836SJohn.Forte@Sun.COM 	if (cfg_get_cstring(cfg, "ncallcore.set1", buf, sizeof (buf)) >= 0) {
137*7836SJohn.Forte@Sun.COM 		rc = sscanf(buf, "%d", nodeid);
138*7836SJohn.Forte@Sun.COM 		if (rc == 1) {
139*7836SJohn.Forte@Sun.COM 			ret = 0;
140*7836SJohn.Forte@Sun.COM 		}
141*7836SJohn.Forte@Sun.COM 	}
142*7836SJohn.Forte@Sun.COM 
143*7836SJohn.Forte@Sun.COM 	ncall_cfg_close();
144*7836SJohn.Forte@Sun.COM 
145*7836SJohn.Forte@Sun.COM 	return (ret);
146*7836SJohn.Forte@Sun.COM }
147*7836SJohn.Forte@Sun.COM 
148*7836SJohn.Forte@Sun.COM 
149*7836SJohn.Forte@Sun.COM static void
ncall_print(void)150*7836SJohn.Forte@Sun.COM ncall_print(void)
151*7836SJohn.Forte@Sun.COM {
152*7836SJohn.Forte@Sun.COM 	int cfnodeid, clnodeid, rc;
153*7836SJohn.Forte@Sun.COM 
154*7836SJohn.Forte@Sun.COM 	clnodeid = cfg_issuncluster();
155*7836SJohn.Forte@Sun.COM 
156*7836SJohn.Forte@Sun.COM 	rc = get_nodeid_from_cfg(&cfnodeid);
157*7836SJohn.Forte@Sun.COM 
158*7836SJohn.Forte@Sun.COM 	if (rc < 0 && clnodeid > 0) {
159*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("%s: ncall is using the SunCluster "
160*7836SJohn.Forte@Sun.COM 		    "nodeid: %d\n"), progname, clnodeid);
161*7836SJohn.Forte@Sun.COM 	} else if (rc < 0) {
162*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("%s: ncall is using the default "
163*7836SJohn.Forte@Sun.COM 		    "nodeid: %d\n"), progname, 0);
164*7836SJohn.Forte@Sun.COM 	} else {
165*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("%s: current configuration:\n"),
166*7836SJohn.Forte@Sun.COM 		    progname);
167*7836SJohn.Forte@Sun.COM 		/* deliberately not i18n'd - "nodeid" is a keyword */
168*7836SJohn.Forte@Sun.COM 		(void) printf("nodeid %d\n", cfnodeid);
169*7836SJohn.Forte@Sun.COM 	}
170*7836SJohn.Forte@Sun.COM }
171*7836SJohn.Forte@Sun.COM 
172*7836SJohn.Forte@Sun.COM 
173*7836SJohn.Forte@Sun.COM static void
ncall_config(const int nodeid)174*7836SJohn.Forte@Sun.COM ncall_config(const int nodeid)
175*7836SJohn.Forte@Sun.COM {
176*7836SJohn.Forte@Sun.COM 	char buf[CFG_MAX_BUF];
177*7836SJohn.Forte@Sun.COM 
178*7836SJohn.Forte@Sun.COM 	ncall_cfg_open(CFG_WRLOCK);
179*7836SJohn.Forte@Sun.COM 
180*7836SJohn.Forte@Sun.COM 	if (cfg_get_cstring(cfg, "ncallcore.set1", buf, sizeof (buf)) >= 0) {
181*7836SJohn.Forte@Sun.COM 		/* remove old config */
182*7836SJohn.Forte@Sun.COM 		if (cfg_put_cstring(cfg, "ncallcore.set1", NULL, 0) < 0) {
183*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
184*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to update the configuration: "
185*7836SJohn.Forte@Sun.COM 			    "%s\n"), cfg_error(NULL));
186*7836SJohn.Forte@Sun.COM 			exit(1);
187*7836SJohn.Forte@Sun.COM 		}
188*7836SJohn.Forte@Sun.COM 	}
189*7836SJohn.Forte@Sun.COM 
190*7836SJohn.Forte@Sun.COM 	if (snprintf(buf, sizeof (buf), "%d", nodeid) >= sizeof (buf)) {
191*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
192*7836SJohn.Forte@Sun.COM 		    gettext("%s: unable to update configuration: "
193*7836SJohn.Forte@Sun.COM 		    "data too long\n"), progname);
194*7836SJohn.Forte@Sun.COM 		exit(1);
195*7836SJohn.Forte@Sun.COM 	}
196*7836SJohn.Forte@Sun.COM 
197*7836SJohn.Forte@Sun.COM 	if (cfg_put_cstring(cfg, "ncallcore", buf, sizeof (buf)) < 0) {
198*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
199*7836SJohn.Forte@Sun.COM 		    gettext("%s: unable to update the configuration: %s\n"),
200*7836SJohn.Forte@Sun.COM 		    cfg_error(NULL));
201*7836SJohn.Forte@Sun.COM 		exit(1);
202*7836SJohn.Forte@Sun.COM 	}
203*7836SJohn.Forte@Sun.COM 
204*7836SJohn.Forte@Sun.COM 	cfg_changed = 1;
205*7836SJohn.Forte@Sun.COM 	ncall_cfg_close();
206*7836SJohn.Forte@Sun.COM 
207*7836SJohn.Forte@Sun.COM 	(void) printf(gettext("%s: configuration set to:\n"), progname);
208*7836SJohn.Forte@Sun.COM 	/* deliberately not i18n'd - "nodeid" is a keyword */
209*7836SJohn.Forte@Sun.COM 	(void) printf("nodeid %d\n", nodeid);
210*7836SJohn.Forte@Sun.COM }
211*7836SJohn.Forte@Sun.COM 
212*7836SJohn.Forte@Sun.COM #ifdef lint
213*7836SJohn.Forte@Sun.COM int
ncalladm_lintmain(int argc,char * argv[])214*7836SJohn.Forte@Sun.COM ncalladm_lintmain(int argc, char *argv[])
215*7836SJohn.Forte@Sun.COM #else
216*7836SJohn.Forte@Sun.COM int
217*7836SJohn.Forte@Sun.COM main(int argc, char *argv[])
218*7836SJohn.Forte@Sun.COM #endif
219*7836SJohn.Forte@Sun.COM {
220*7836SJohn.Forte@Sun.COM 	const char *dev = "/dev/ncall";
221*7836SJohn.Forte@Sun.COM 	extern int optind, opterr;
222*7836SJohn.Forte@Sun.COM 	ncall_node_t nodeinfo, *nodes;
223*7836SJohn.Forte@Sun.COM 	int nsize;
224*7836SJohn.Forte@Sun.COM 	int i;
225*7836SJohn.Forte@Sun.COM 	int cflag, dflag, eflag, iflag, pflag;
226*7836SJohn.Forte@Sun.COM 	int rc, fd, opt;
227*7836SJohn.Forte@Sun.COM 	int clnodeid, cfnodeid;
228*7836SJohn.Forte@Sun.COM 	int up;
229*7836SJohn.Forte@Sun.COM 	char *cp, *ping;
230*7836SJohn.Forte@Sun.COM 	int mnode;	/* mirror nodeid */
231*7836SJohn.Forte@Sun.COM 
232*7836SJohn.Forte@Sun.COM 	(void) setlocale(LC_ALL, "");
233*7836SJohn.Forte@Sun.COM 	(void) textdomain("ncalladm");
234*7836SJohn.Forte@Sun.COM 
235*7836SJohn.Forte@Sun.COM 	opterr = 0;
236*7836SJohn.Forte@Sun.COM 	cflag = dflag = eflag = iflag = pflag = 0;
237*7836SJohn.Forte@Sun.COM 	ping = NULL;
238*7836SJohn.Forte@Sun.COM 
239*7836SJohn.Forte@Sun.COM 	progname = basename(argv[0]);
240*7836SJohn.Forte@Sun.COM 
241*7836SJohn.Forte@Sun.COM 	while ((opt = getopt(argc, argv,
242*7836SJohn.Forte@Sun.COM #ifdef DEBUG
243*7836SJohn.Forte@Sun.COM 	    "cip:"
244*7836SJohn.Forte@Sun.COM #endif
245*7836SJohn.Forte@Sun.COM 	    "deh")) != -1) {
246*7836SJohn.Forte@Sun.COM 		switch (opt) {
247*7836SJohn.Forte@Sun.COM 		case 'c':
248*7836SJohn.Forte@Sun.COM 			cflag = 1;
249*7836SJohn.Forte@Sun.COM 			break;
250*7836SJohn.Forte@Sun.COM 
251*7836SJohn.Forte@Sun.COM 		case 'd':
252*7836SJohn.Forte@Sun.COM 			dflag = 1;
253*7836SJohn.Forte@Sun.COM 			break;
254*7836SJohn.Forte@Sun.COM 
255*7836SJohn.Forte@Sun.COM 		case 'e':
256*7836SJohn.Forte@Sun.COM 			eflag = 1;
257*7836SJohn.Forte@Sun.COM 			break;
258*7836SJohn.Forte@Sun.COM 
259*7836SJohn.Forte@Sun.COM 		case 'h':
260*7836SJohn.Forte@Sun.COM 			usage(0);
261*7836SJohn.Forte@Sun.COM 			break;
262*7836SJohn.Forte@Sun.COM 
263*7836SJohn.Forte@Sun.COM 		case 'i':
264*7836SJohn.Forte@Sun.COM 			iflag = 1;
265*7836SJohn.Forte@Sun.COM 			break;
266*7836SJohn.Forte@Sun.COM 
267*7836SJohn.Forte@Sun.COM 		case 'p':
268*7836SJohn.Forte@Sun.COM 			ping = optarg;
269*7836SJohn.Forte@Sun.COM 			pflag = 1;
270*7836SJohn.Forte@Sun.COM 			break;
271*7836SJohn.Forte@Sun.COM 
272*7836SJohn.Forte@Sun.COM 		default:
273*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, gettext("%s: unknown option\n"),
274*7836SJohn.Forte@Sun.COM 			    progname);
275*7836SJohn.Forte@Sun.COM 			usage(1);
276*7836SJohn.Forte@Sun.COM 			break;
277*7836SJohn.Forte@Sun.COM 		}
278*7836SJohn.Forte@Sun.COM 	}
279*7836SJohn.Forte@Sun.COM 
280*7836SJohn.Forte@Sun.COM 	if (!(cflag || dflag || eflag || iflag || pflag)) {
281*7836SJohn.Forte@Sun.COM 		usage(1);
282*7836SJohn.Forte@Sun.COM 	}
283*7836SJohn.Forte@Sun.COM 
284*7836SJohn.Forte@Sun.COM 	if (argc != optind) {
285*7836SJohn.Forte@Sun.COM 		if (!cflag ||
286*7836SJohn.Forte@Sun.COM 		    (argc - optind) != 2 ||
287*7836SJohn.Forte@Sun.COM 		    strcmp(argv[optind], "nodeid") != 0) {
288*7836SJohn.Forte@Sun.COM 			usage(1);
289*7836SJohn.Forte@Sun.COM 		}
290*7836SJohn.Forte@Sun.COM 	}
291*7836SJohn.Forte@Sun.COM 
292*7836SJohn.Forte@Sun.COM 	if ((cflag + dflag + eflag + iflag + pflag) > 1) {
293*7836SJohn.Forte@Sun.COM 		(void) fprintf(stderr,
294*7836SJohn.Forte@Sun.COM 		    gettext("%s: multiple options are not supported\n"),
295*7836SJohn.Forte@Sun.COM 		    progname);
296*7836SJohn.Forte@Sun.COM 		usage(1);
297*7836SJohn.Forte@Sun.COM 	}
298*7836SJohn.Forte@Sun.COM 
299*7836SJohn.Forte@Sun.COM 	if (!cflag) {
300*7836SJohn.Forte@Sun.COM 		fd = open(dev, O_RDONLY);
301*7836SJohn.Forte@Sun.COM 		if (fd < 0) {
302*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
303*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to open %s: %s\n"),
304*7836SJohn.Forte@Sun.COM 			    progname, dev, strerror(errno));
305*7836SJohn.Forte@Sun.COM 			exit(1);
306*7836SJohn.Forte@Sun.COM 		}
307*7836SJohn.Forte@Sun.COM 	}
308*7836SJohn.Forte@Sun.COM 
309*7836SJohn.Forte@Sun.COM 	if (dflag) {
310*7836SJohn.Forte@Sun.COM 		/* ioctl stop into kernel */
311*7836SJohn.Forte@Sun.COM 		if (ioctl(fd, NC_IOC_STOP, 0) < 0) {
312*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
313*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to disable ncall: %s\n"),
314*7836SJohn.Forte@Sun.COM 			    progname, strerror(errno));
315*7836SJohn.Forte@Sun.COM 			exit(1);
316*7836SJohn.Forte@Sun.COM 		}
317*7836SJohn.Forte@Sun.COM 	} else if (eflag) {
318*7836SJohn.Forte@Sun.COM 		bzero(&nodeinfo, sizeof (nodeinfo));
319*7836SJohn.Forte@Sun.COM 
320*7836SJohn.Forte@Sun.COM 		clnodeid = cfg_issuncluster();
321*7836SJohn.Forte@Sun.COM 		cfnodeid = 0;
322*7836SJohn.Forte@Sun.COM 
323*7836SJohn.Forte@Sun.COM 		/* get node info */
324*7836SJohn.Forte@Sun.COM 		rc = gethostname(nodeinfo.nc_nodename,
325*7836SJohn.Forte@Sun.COM 		    sizeof (nodeinfo.nc_nodename));
326*7836SJohn.Forte@Sun.COM 		if (rc < 0) {
327*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
328*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to determine hostname: %s\n"),
329*7836SJohn.Forte@Sun.COM 			    progname, strerror(errno));
330*7836SJohn.Forte@Sun.COM 			exit(1);
331*7836SJohn.Forte@Sun.COM 		}
332*7836SJohn.Forte@Sun.COM 
333*7836SJohn.Forte@Sun.COM 		rc = get_nodeid_from_cfg(&cfnodeid);
334*7836SJohn.Forte@Sun.COM 
335*7836SJohn.Forte@Sun.COM 		if (clnodeid > 0 && rc == 0) {
336*7836SJohn.Forte@Sun.COM 			/*
337*7836SJohn.Forte@Sun.COM 			 * check that the nodeids from the cf file and
338*7836SJohn.Forte@Sun.COM 			 * cluster match.
339*7836SJohn.Forte@Sun.COM 			 */
340*7836SJohn.Forte@Sun.COM 			if (clnodeid != cfnodeid) {
341*7836SJohn.Forte@Sun.COM 				(void) fprintf(stderr,
342*7836SJohn.Forte@Sun.COM 				    gettext("%s: nodeid from configuration "
343*7836SJohn.Forte@Sun.COM 				    "(%d) != cluster nodeid (%d)\n"),
344*7836SJohn.Forte@Sun.COM 				    progname, cfnodeid, clnodeid);
345*7836SJohn.Forte@Sun.COM 				exit(1);
346*7836SJohn.Forte@Sun.COM 			}
347*7836SJohn.Forte@Sun.COM 		}
348*7836SJohn.Forte@Sun.COM 
349*7836SJohn.Forte@Sun.COM 		if (rc == 0) {
350*7836SJohn.Forte@Sun.COM 			nodeinfo.nc_nodeid = cfnodeid;
351*7836SJohn.Forte@Sun.COM 		} else if (clnodeid > 0) {
352*7836SJohn.Forte@Sun.COM 			nodeinfo.nc_nodeid = clnodeid;
353*7836SJohn.Forte@Sun.COM 		} else {
354*7836SJohn.Forte@Sun.COM 			nodeinfo.nc_nodeid = 0;
355*7836SJohn.Forte@Sun.COM 		}
356*7836SJohn.Forte@Sun.COM 
357*7836SJohn.Forte@Sun.COM 		/* ioctl node info into kernel and start ncall */
358*7836SJohn.Forte@Sun.COM 		rc = ioctl(fd, NC_IOC_START, &nodeinfo);
359*7836SJohn.Forte@Sun.COM 		if (rc < 0) {
360*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
361*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to enable ncall: %s\n"),
362*7836SJohn.Forte@Sun.COM 			    progname, strerror(errno));
363*7836SJohn.Forte@Sun.COM 			exit(1);
364*7836SJohn.Forte@Sun.COM 		}
365*7836SJohn.Forte@Sun.COM 	}
366*7836SJohn.Forte@Sun.COM 
367*7836SJohn.Forte@Sun.COM 	if (iflag || pflag) {
368*7836SJohn.Forte@Sun.COM 		nodes = getnodelist(fd, &nsize, &mnode);
369*7836SJohn.Forte@Sun.COM 
370*7836SJohn.Forte@Sun.COM 		if (nodes == NULL) {
371*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
372*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to get node info\n"),
373*7836SJohn.Forte@Sun.COM 			    progname);
374*7836SJohn.Forte@Sun.COM 			exit(1);
375*7836SJohn.Forte@Sun.COM 		}
376*7836SJohn.Forte@Sun.COM 	}
377*7836SJohn.Forte@Sun.COM 
378*7836SJohn.Forte@Sun.COM 	if (iflag) {
379*7836SJohn.Forte@Sun.COM 		char *mname;
380*7836SJohn.Forte@Sun.COM 		char *pnodestr;
381*7836SJohn.Forte@Sun.COM 
382*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("Self Node Name: %s\n"),
383*7836SJohn.Forte@Sun.COM 		    nodes[0].nc_nodename);
384*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("Self Node ID: %d\n"),
385*7836SJohn.Forte@Sun.COM 		    nodes[0].nc_nodeid);
386*7836SJohn.Forte@Sun.COM 		/*
387*7836SJohn.Forte@Sun.COM 		 * determine which slot is the mirror node.
388*7836SJohn.Forte@Sun.COM 		 */
389*7836SJohn.Forte@Sun.COM 		if (mnode != -1) {
390*7836SJohn.Forte@Sun.COM 			for (i = 1; i < nsize; i++) {
391*7836SJohn.Forte@Sun.COM 				if (nodes[i].nc_nodeid == mnode) {
392*7836SJohn.Forte@Sun.COM 					mname = nodes[i].nc_nodename;
393*7836SJohn.Forte@Sun.COM 					break;
394*7836SJohn.Forte@Sun.COM 				}
395*7836SJohn.Forte@Sun.COM 			}
396*7836SJohn.Forte@Sun.COM 		}
397*7836SJohn.Forte@Sun.COM 		if ((mnode == -1) || (i >= nsize)) {
398*7836SJohn.Forte@Sun.COM 			mname = gettext("unknown");
399*7836SJohn.Forte@Sun.COM 			mnode = -1;
400*7836SJohn.Forte@Sun.COM 		}
401*7836SJohn.Forte@Sun.COM 
402*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("Mirror Node Name: %s\n"), mname);
403*7836SJohn.Forte@Sun.COM 		(void) printf(gettext("Mirror Node ID: %d\n"), mnode);
404*7836SJohn.Forte@Sun.COM 		/*
405*7836SJohn.Forte@Sun.COM 		 * See if we need to translate the node strings.
406*7836SJohn.Forte@Sun.COM 		 */
407*7836SJohn.Forte@Sun.COM 		if (nsize > 1) {
408*7836SJohn.Forte@Sun.COM 			pnodestr = gettext("Node Name: %s\nNode ID: %d\n");
409*7836SJohn.Forte@Sun.COM 			for (i = 1; i < nsize; i++) {
410*7836SJohn.Forte@Sun.COM 				/*
411*7836SJohn.Forte@Sun.COM 				 * Don't print the mirror twice.
412*7836SJohn.Forte@Sun.COM 				 */
413*7836SJohn.Forte@Sun.COM 				if (nodes[i].nc_nodeid != mnode) {
414*7836SJohn.Forte@Sun.COM 					(void) printf(pnodestr,
415*7836SJohn.Forte@Sun.COM 					    nodes[i].nc_nodename,
416*7836SJohn.Forte@Sun.COM 					    nodes[i].nc_nodeid);
417*7836SJohn.Forte@Sun.COM 				}
418*7836SJohn.Forte@Sun.COM 			}
419*7836SJohn.Forte@Sun.COM 		}
420*7836SJohn.Forte@Sun.COM 	}
421*7836SJohn.Forte@Sun.COM 
422*7836SJohn.Forte@Sun.COM 	if (pflag) {
423*7836SJohn.Forte@Sun.COM 		if (strlen(ping) >= sizeof (nodeinfo.nc_nodename)) {
424*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
425*7836SJohn.Forte@Sun.COM 			    gettext("%s: hostname '%s' is too long\n"),
426*7836SJohn.Forte@Sun.COM 			    progname, ping);
427*7836SJohn.Forte@Sun.COM 			exit(1);
428*7836SJohn.Forte@Sun.COM 		}
429*7836SJohn.Forte@Sun.COM 		up = 0;
430*7836SJohn.Forte@Sun.COM 		if (strcmp(nodes[0].nc_nodename, ping) == 0) {
431*7836SJohn.Forte@Sun.COM 			up = 1;		/* self */
432*7836SJohn.Forte@Sun.COM 		} else {
433*7836SJohn.Forte@Sun.COM 			/* not self, so ask kernel */
434*7836SJohn.Forte@Sun.COM 			bzero(&nodeinfo, sizeof (nodeinfo));
435*7836SJohn.Forte@Sun.COM 			/* strlen(ping) checked above */
436*7836SJohn.Forte@Sun.COM 			(void) strcpy(nodeinfo.nc_nodename, ping);
437*7836SJohn.Forte@Sun.COM 			up = ioctl(fd, NC_IOC_PING, nodeinfo);
438*7836SJohn.Forte@Sun.COM 		}
439*7836SJohn.Forte@Sun.COM 
440*7836SJohn.Forte@Sun.COM 		/* model the ping messages on ping(1m) */
441*7836SJohn.Forte@Sun.COM 
442*7836SJohn.Forte@Sun.COM 		if (up < 0) {
443*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
444*7836SJohn.Forte@Sun.COM 			    gettext("%s: unable to ping host '%s': %s\n"),
445*7836SJohn.Forte@Sun.COM 			    progname, ping, strerror(errno));
446*7836SJohn.Forte@Sun.COM 			exit(1);
447*7836SJohn.Forte@Sun.COM 		} else if (up > 0) {
448*7836SJohn.Forte@Sun.COM 			(void) printf(gettext("%s is alive\n"), ping);
449*7836SJohn.Forte@Sun.COM 		} else {
450*7836SJohn.Forte@Sun.COM 			(void) printf(gettext("no answer from %s\n"), ping);
451*7836SJohn.Forte@Sun.COM 			exit(1);
452*7836SJohn.Forte@Sun.COM 		}
453*7836SJohn.Forte@Sun.COM 	}
454*7836SJohn.Forte@Sun.COM 
455*7836SJohn.Forte@Sun.COM 	if (iflag || pflag) {
456*7836SJohn.Forte@Sun.COM 		free(nodes);
457*7836SJohn.Forte@Sun.COM 	}
458*7836SJohn.Forte@Sun.COM 
459*7836SJohn.Forte@Sun.COM 	if (cflag) {
460*7836SJohn.Forte@Sun.COM 		if (argc == optind) {
461*7836SJohn.Forte@Sun.COM 			ncall_print();
462*7836SJohn.Forte@Sun.COM 			return (0);
463*7836SJohn.Forte@Sun.COM 		}
464*7836SJohn.Forte@Sun.COM 
465*7836SJohn.Forte@Sun.COM 		cp = NULL;
466*7836SJohn.Forte@Sun.COM 		cfnodeid = (int)strtol(argv[optind+1], &cp, 0);
467*7836SJohn.Forte@Sun.COM 		if (cp != NULL && *cp != '\0') {
468*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
469*7836SJohn.Forte@Sun.COM 			    gettext("%s: nodeid \"%s\" is not an "
470*7836SJohn.Forte@Sun.COM 			    "integer number\n"), progname, argv[optind+1]);
471*7836SJohn.Forte@Sun.COM 			exit(1);
472*7836SJohn.Forte@Sun.COM 		}
473*7836SJohn.Forte@Sun.COM 
474*7836SJohn.Forte@Sun.COM 		clnodeid = cfg_issuncluster();
475*7836SJohn.Forte@Sun.COM 		if (clnodeid > 0 && cfnodeid != clnodeid) {
476*7836SJohn.Forte@Sun.COM 			(void) fprintf(stderr,
477*7836SJohn.Forte@Sun.COM 			    gettext("%s: nodeid from command line "
478*7836SJohn.Forte@Sun.COM 			    "(%d) != cluster nodeid (%d)\n"),
479*7836SJohn.Forte@Sun.COM 			    progname, cfnodeid, clnodeid);
480*7836SJohn.Forte@Sun.COM 			exit(1);
481*7836SJohn.Forte@Sun.COM 		}
482*7836SJohn.Forte@Sun.COM 
483*7836SJohn.Forte@Sun.COM 		ncall_config(cfnodeid);
484*7836SJohn.Forte@Sun.COM 	}
485*7836SJohn.Forte@Sun.COM 
486*7836SJohn.Forte@Sun.COM 	if (!cflag) {
487*7836SJohn.Forte@Sun.COM 		(void) close(fd);
488*7836SJohn.Forte@Sun.COM 	}
489*7836SJohn.Forte@Sun.COM 
490*7836SJohn.Forte@Sun.COM 	return (0);
491*7836SJohn.Forte@Sun.COM }
492*7836SJohn.Forte@Sun.COM 
493*7836SJohn.Forte@Sun.COM 
494*7836SJohn.Forte@Sun.COM /*
495*7836SJohn.Forte@Sun.COM  * return a pointer to a list of currently configured
496*7836SJohn.Forte@Sun.COM  * nodes.
497*7836SJohn.Forte@Sun.COM  * Return the number of nodes via the nodesizep pointer.
498*7836SJohn.Forte@Sun.COM  * Return the mirror nodeid via the mirrorp pointer.
499*7836SJohn.Forte@Sun.COM  * Return NULL on errors.
500*7836SJohn.Forte@Sun.COM  */
501*7836SJohn.Forte@Sun.COM static ncall_node_t *
getnodelist(int ifd,int * nodesizep,int * mirrorp)502*7836SJohn.Forte@Sun.COM getnodelist(int ifd, int *nodesizep, int *mirrorp)
503*7836SJohn.Forte@Sun.COM {
504*7836SJohn.Forte@Sun.COM 	int maxsize;
505*7836SJohn.Forte@Sun.COM 	int cnt;
506*7836SJohn.Forte@Sun.COM 	ncall_node_t *noderet = NULL;
507*7836SJohn.Forte@Sun.COM 	ncall_node_t *nodelist;
508*7836SJohn.Forte@Sun.COM 	ncall_node_t thisnode;
509*7836SJohn.Forte@Sun.COM 	int mirror;
510*7836SJohn.Forte@Sun.COM 	int nonet;
511*7836SJohn.Forte@Sun.COM 
512*7836SJohn.Forte@Sun.COM 	/*
513*7836SJohn.Forte@Sun.COM 	 * Get this host info and mirror nodeid.
514*7836SJohn.Forte@Sun.COM 	 */
515*7836SJohn.Forte@Sun.COM 	mirror = ioctl(ifd, NC_IOC_GETNODE, &thisnode);
516*7836SJohn.Forte@Sun.COM 
517*7836SJohn.Forte@Sun.COM 	if (mirror < 0) {
518*7836SJohn.Forte@Sun.COM 		return (NULL);
519*7836SJohn.Forte@Sun.COM 	}
520*7836SJohn.Forte@Sun.COM 
521*7836SJohn.Forte@Sun.COM 	/*
522*7836SJohn.Forte@Sun.COM 	 * See if we need to allocate the buffer.
523*7836SJohn.Forte@Sun.COM 	 */
524*7836SJohn.Forte@Sun.COM 	nonet = 0;
525*7836SJohn.Forte@Sun.COM 	maxsize = ioctl(ifd, NC_IOC_GETNETNODES, 0);
526*7836SJohn.Forte@Sun.COM 	if (maxsize < 1) {
527*7836SJohn.Forte@Sun.COM 		maxsize = 1;
528*7836SJohn.Forte@Sun.COM 		nonet = 1;
529*7836SJohn.Forte@Sun.COM 	}
530*7836SJohn.Forte@Sun.COM 	nodelist = malloc(sizeof (*nodelist) * maxsize);
531*7836SJohn.Forte@Sun.COM 	if (nodelist) {
532*7836SJohn.Forte@Sun.COM 		if (nonet == 0) {
533*7836SJohn.Forte@Sun.COM 			/*
534*7836SJohn.Forte@Sun.COM 			 * fetch the node data.
535*7836SJohn.Forte@Sun.COM 			 */
536*7836SJohn.Forte@Sun.COM 			cnt = ioctl(ifd, NC_IOC_GETNETNODES, nodelist);
537*7836SJohn.Forte@Sun.COM 			if (cnt > 0) {
538*7836SJohn.Forte@Sun.COM 				*nodesizep = cnt;
539*7836SJohn.Forte@Sun.COM 				noderet = nodelist;
540*7836SJohn.Forte@Sun.COM 				*mirrorp = mirror;
541*7836SJohn.Forte@Sun.COM 			} else {
542*7836SJohn.Forte@Sun.COM 				*nodesizep = 0;
543*7836SJohn.Forte@Sun.COM 				free(nodelist);
544*7836SJohn.Forte@Sun.COM 			}
545*7836SJohn.Forte@Sun.COM 		} else {
546*7836SJohn.Forte@Sun.COM 			(void) memcpy(nodelist, &thisnode, sizeof (*nodelist));
547*7836SJohn.Forte@Sun.COM 			*nodesizep = 1;
548*7836SJohn.Forte@Sun.COM 			noderet = nodelist;
549*7836SJohn.Forte@Sun.COM 			/*
550*7836SJohn.Forte@Sun.COM 			 * Although we know the mirror nodeid, there
551*7836SJohn.Forte@Sun.COM 			 * is no point in returning it as we have
552*7836SJohn.Forte@Sun.COM 			 * no information about any other hosts.
553*7836SJohn.Forte@Sun.COM 			 */
554*7836SJohn.Forte@Sun.COM 			*mirrorp = -1;
555*7836SJohn.Forte@Sun.COM 		}
556*7836SJohn.Forte@Sun.COM 	}
557*7836SJohn.Forte@Sun.COM 	return (noderet);
558*7836SJohn.Forte@Sun.COM }
559