4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
37 #include <sys/nsctl/cfg.h>
38 #include <sys/ncall/ncall.h>
41 static int cfg_changed
;
42 static char *progname
;
43 static ncall_node_t
*getnodelist(int, int *, int *);
49 (void) fprintf(stderr
, gettext("usage:\n"));
50 (void) fprintf(stderr
, gettext(" %s -d\n"), progname
);
51 (void) fprintf(stderr
, gettext(" %s -e\n"), progname
);
52 (void) fprintf(stderr
, gettext(" %s -h\n"), progname
);
54 (void) fprintf(stderr
, gettext(" %s -c [nodeid <nodeid>]\n"),
56 (void) fprintf(stderr
, gettext(" %s -i\n"), progname
);
57 (void) fprintf(stderr
, gettext(" %s -p <host>\n"), progname
);
60 (void) fprintf(stderr
, gettext("where:\n"));
61 (void) fprintf(stderr
, gettext(" -d disable ncall\n"));
62 (void) fprintf(stderr
, gettext(" -e enable ncall core\n"));
63 (void) fprintf(stderr
, gettext(" -h this help message\n"));
65 (void) fprintf(stderr
,
66 gettext(" -c set or print ncall configuration\n"));
67 (void) fprintf(stderr
, gettext(" -i ncall information\n"));
68 (void) fprintf(stderr
, gettext(" -p ncall ping <host>\n"));
76 ncall_cfg_open(CFGLOCK lk
)
84 if (snprintf(hostid
, sizeof (hostid
), "%lx", gethostid()) >=
86 (void) fprintf(stderr
, gettext("%s: hostid %lx too large\n"),
87 progname
, gethostid());
91 if ((cfg
= cfg_open(NULL
)) == NULL
) {
92 (void) fprintf(stderr
,
93 gettext("%s: unable to access the configuration: %s\n"),
94 progname
, cfg_error(NULL
));
98 if (!cfg_lock(cfg
, lk
)) {
99 (void) fprintf(stderr
,
100 gettext("%s: unable to lock the configuration: %s\n"),
101 progname
, cfg_error(NULL
));
105 cfg_resource(cfg
, hostid
);
110 ncall_cfg_close(void)
112 if (cfg_changed
&& cfg_commit(cfg
) < 0) {
113 (void) fprintf(stderr
,
114 gettext("%s: unable to update the configuration: %s\n"),
115 progname
, cfg_error(NULL
));
125 * Get config from dscfg.
128 get_nodeid_from_cfg(int *nodeid
)
130 char buf
[CFG_MAX_BUF
];
134 ncall_cfg_open(CFG_RDLOCK
);
136 if (cfg_get_cstring(cfg
, "ncallcore.set1", buf
, sizeof (buf
)) >= 0) {
137 rc
= sscanf(buf
, "%d", nodeid
);
152 int cfnodeid
, clnodeid
, rc
;
154 clnodeid
= cfg_issuncluster();
156 rc
= get_nodeid_from_cfg(&cfnodeid
);
158 if (rc
< 0 && clnodeid
> 0) {
159 (void) printf(gettext("%s: ncall is using the SunCluster "
160 "nodeid: %d\n"), progname
, clnodeid
);
162 (void) printf(gettext("%s: ncall is using the default "
163 "nodeid: %d\n"), progname
, 0);
165 (void) printf(gettext("%s: current configuration:\n"),
167 /* deliberately not i18n'd - "nodeid" is a keyword */
168 (void) printf("nodeid %d\n", cfnodeid
);
174 ncall_config(const int nodeid
)
176 char buf
[CFG_MAX_BUF
];
178 ncall_cfg_open(CFG_WRLOCK
);
180 if (cfg_get_cstring(cfg
, "ncallcore.set1", buf
, sizeof (buf
)) >= 0) {
181 /* remove old config */
182 if (cfg_put_cstring(cfg
, "ncallcore.set1", NULL
, 0) < 0) {
183 (void) fprintf(stderr
,
184 gettext("%s: unable to update the configuration: "
185 "%s\n"), cfg_error(NULL
));
190 if (snprintf(buf
, sizeof (buf
), "%d", nodeid
) >= sizeof (buf
)) {
191 (void) fprintf(stderr
,
192 gettext("%s: unable to update configuration: "
193 "data too long\n"), progname
);
197 if (cfg_put_cstring(cfg
, "ncallcore", buf
, sizeof (buf
)) < 0) {
198 (void) fprintf(stderr
,
199 gettext("%s: unable to update the configuration: %s\n"),
207 (void) printf(gettext("%s: configuration set to:\n"), progname
);
208 /* deliberately not i18n'd - "nodeid" is a keyword */
209 (void) printf("nodeid %d\n", nodeid
);
214 ncalladm_lintmain(int argc
, char *argv
[])
217 main(int argc
, char *argv
[])
220 const char *dev
= "/dev/ncall";
221 extern int optind
, opterr
;
222 ncall_node_t nodeinfo
, *nodes
;
225 int cflag
, dflag
, eflag
, iflag
, pflag
;
227 int clnodeid
, cfnodeid
;
230 int mnode
; /* mirror nodeid */
232 (void) setlocale(LC_ALL
, "");
233 (void) textdomain("ncalladm");
236 cflag
= dflag
= eflag
= iflag
= pflag
= 0;
239 progname
= basename(argv
[0]);
241 while ((opt
= getopt(argc
, argv
,
273 (void) fprintf(stderr
, gettext("%s: unknown option\n"),
280 if (!(cflag
|| dflag
|| eflag
|| iflag
|| pflag
)) {
284 if (argc
!= optind
) {
286 (argc
- optind
) != 2 ||
287 strcmp(argv
[optind
], "nodeid") != 0) {
292 if ((cflag
+ dflag
+ eflag
+ iflag
+ pflag
) > 1) {
293 (void) fprintf(stderr
,
294 gettext("%s: multiple options are not supported\n"),
300 fd
= open(dev
, O_RDONLY
);
302 (void) fprintf(stderr
,
303 gettext("%s: unable to open %s: %s\n"),
304 progname
, dev
, strerror(errno
));
310 /* ioctl stop into kernel */
311 if (ioctl(fd
, NC_IOC_STOP
, 0) < 0) {
312 (void) fprintf(stderr
,
313 gettext("%s: unable to disable ncall: %s\n"),
314 progname
, strerror(errno
));
318 bzero(&nodeinfo
, sizeof (nodeinfo
));
320 clnodeid
= cfg_issuncluster();
324 rc
= gethostname(nodeinfo
.nc_nodename
,
325 sizeof (nodeinfo
.nc_nodename
));
327 (void) fprintf(stderr
,
328 gettext("%s: unable to determine hostname: %s\n"),
329 progname
, strerror(errno
));
333 rc
= get_nodeid_from_cfg(&cfnodeid
);
335 if (clnodeid
> 0 && rc
== 0) {
337 * check that the nodeids from the cf file and
340 if (clnodeid
!= cfnodeid
) {
341 (void) fprintf(stderr
,
342 gettext("%s: nodeid from configuration "
343 "(%d) != cluster nodeid (%d)\n"),
344 progname
, cfnodeid
, clnodeid
);
350 nodeinfo
.nc_nodeid
= cfnodeid
;
351 } else if (clnodeid
> 0) {
352 nodeinfo
.nc_nodeid
= clnodeid
;
354 nodeinfo
.nc_nodeid
= 0;
357 /* ioctl node info into kernel and start ncall */
358 rc
= ioctl(fd
, NC_IOC_START
, &nodeinfo
);
360 (void) fprintf(stderr
,
361 gettext("%s: unable to enable ncall: %s\n"),
362 progname
, strerror(errno
));
367 if (iflag
|| pflag
) {
368 nodes
= getnodelist(fd
, &nsize
, &mnode
);
371 (void) fprintf(stderr
,
372 gettext("%s: unable to get node info\n"),
382 (void) printf(gettext("Self Node Name: %s\n"),
383 nodes
[0].nc_nodename
);
384 (void) printf(gettext("Self Node ID: %d\n"),
387 * determine which slot is the mirror node.
390 for (i
= 1; i
< nsize
; i
++) {
391 if (nodes
[i
].nc_nodeid
== mnode
) {
392 mname
= nodes
[i
].nc_nodename
;
397 if ((mnode
== -1) || (i
>= nsize
)) {
398 mname
= gettext("unknown");
402 (void) printf(gettext("Mirror Node Name: %s\n"), mname
);
403 (void) printf(gettext("Mirror Node ID: %d\n"), mnode
);
405 * See if we need to translate the node strings.
408 pnodestr
= gettext("Node Name: %s\nNode ID: %d\n");
409 for (i
= 1; i
< nsize
; i
++) {
411 * Don't print the mirror twice.
413 if (nodes
[i
].nc_nodeid
!= mnode
) {
414 (void) printf(pnodestr
,
415 nodes
[i
].nc_nodename
,
423 if (strlen(ping
) >= sizeof (nodeinfo
.nc_nodename
)) {
424 (void) fprintf(stderr
,
425 gettext("%s: hostname '%s' is too long\n"),
430 if (strcmp(nodes
[0].nc_nodename
, ping
) == 0) {
433 /* not self, so ask kernel */
434 bzero(&nodeinfo
, sizeof (nodeinfo
));
435 /* strlen(ping) checked above */
436 (void) strcpy(nodeinfo
.nc_nodename
, ping
);
437 up
= ioctl(fd
, NC_IOC_PING
, nodeinfo
);
440 /* model the ping messages on ping(1m) */
443 (void) fprintf(stderr
,
444 gettext("%s: unable to ping host '%s': %s\n"),
445 progname
, ping
, strerror(errno
));
448 (void) printf(gettext("%s is alive\n"), ping
);
450 (void) printf(gettext("no answer from %s\n"), ping
);
455 if (iflag
|| pflag
) {
460 if (argc
== optind
) {
466 cfnodeid
= (int)strtol(argv
[optind
+1], &cp
, 0);
467 if (cp
!= NULL
&& *cp
!= '\0') {
468 (void) fprintf(stderr
,
469 gettext("%s: nodeid \"%s\" is not an "
470 "integer number\n"), progname
, argv
[optind
+1]);
474 clnodeid
= cfg_issuncluster();
475 if (clnodeid
> 0 && cfnodeid
!= clnodeid
) {
476 (void) fprintf(stderr
,
477 gettext("%s: nodeid from command line "
478 "(%d) != cluster nodeid (%d)\n"),
479 progname
, cfnodeid
, clnodeid
);
483 ncall_config(cfnodeid
);
495 * return a pointer to a list of currently configured
497 * Return the number of nodes via the nodesizep pointer.
498 * Return the mirror nodeid via the mirrorp pointer.
499 * Return NULL on errors.
501 static ncall_node_t
*
502 getnodelist(int ifd
, int *nodesizep
, int *mirrorp
)
506 ncall_node_t
*noderet
= NULL
;
507 ncall_node_t
*nodelist
;
508 ncall_node_t thisnode
;
513 * Get this host info and mirror nodeid.
515 mirror
= ioctl(ifd
, NC_IOC_GETNODE
, &thisnode
);
522 * See if we need to allocate the buffer.
525 maxsize
= ioctl(ifd
, NC_IOC_GETNETNODES
, 0);
530 nodelist
= malloc(sizeof (*nodelist
) * maxsize
);
534 * fetch the node data.
536 cnt
= ioctl(ifd
, NC_IOC_GETNETNODES
, nodelist
);
546 (void) memcpy(nodelist
, &thisnode
, sizeof (*nodelist
));
550 * Although we know the mirror nodeid, there
551 * is no point in returning it as we have
552 * no information about any other hosts.