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