xref: /titanic_51/usr/src/cmd/cmd-inet/usr.sbin/ilbadm/ilbadm_hc.c (revision dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9)
1*dbed73cbSSangeeta Misra /*
2*dbed73cbSSangeeta Misra  * CDDL HEADER START
3*dbed73cbSSangeeta Misra  *
4*dbed73cbSSangeeta Misra  * The contents of this file are subject to the terms of the
5*dbed73cbSSangeeta Misra  * Common Development and Distribution License (the "License").
6*dbed73cbSSangeeta Misra  * You may not use this file except in compliance with the License.
7*dbed73cbSSangeeta Misra  *
8*dbed73cbSSangeeta Misra  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*dbed73cbSSangeeta Misra  * or http://www.opensolaris.org/os/licensing.
10*dbed73cbSSangeeta Misra  * See the License for the specific language governing permissions
11*dbed73cbSSangeeta Misra  * and limitations under the License.
12*dbed73cbSSangeeta Misra  *
13*dbed73cbSSangeeta Misra  * When distributing Covered Code, include this CDDL HEADER in each
14*dbed73cbSSangeeta Misra  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*dbed73cbSSangeeta Misra  * If applicable, add the following below this CDDL HEADER, with the
16*dbed73cbSSangeeta Misra  * fields enclosed by brackets "[]" replaced with your own identifying
17*dbed73cbSSangeeta Misra  * information: Portions Copyright [yyyy] [name of copyright owner]
18*dbed73cbSSangeeta Misra  *
19*dbed73cbSSangeeta Misra  * CDDL HEADER END
20*dbed73cbSSangeeta Misra  */
21*dbed73cbSSangeeta Misra 
22*dbed73cbSSangeeta Misra /*
23*dbed73cbSSangeeta Misra  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*dbed73cbSSangeeta Misra  * Use is subject to license terms.
25*dbed73cbSSangeeta Misra  */
26*dbed73cbSSangeeta Misra 
27*dbed73cbSSangeeta Misra #include <sys/types.h>
28*dbed73cbSSangeeta Misra #include <sys/socket.h>
29*dbed73cbSSangeeta Misra #include <sys/list.h>
30*dbed73cbSSangeeta Misra #include <netinet/in.h>
31*dbed73cbSSangeeta Misra #include <stdio.h>
32*dbed73cbSSangeeta Misra #include <unistd.h>
33*dbed73cbSSangeeta Misra #include <stdlib.h>
34*dbed73cbSSangeeta Misra #include <strings.h>
35*dbed73cbSSangeeta Misra #include <errno.h>
36*dbed73cbSSangeeta Misra #include <ofmt.h>
37*dbed73cbSSangeeta Misra #include <libilb.h>
38*dbed73cbSSangeeta Misra #include "ilbadm.h"
39*dbed73cbSSangeeta Misra 
40*dbed73cbSSangeeta Misra extern int	optind, optopt, opterr;
41*dbed73cbSSangeeta Misra extern char	*optarg;
42*dbed73cbSSangeeta Misra 
43*dbed73cbSSangeeta Misra typedef struct hc_export_arg {
44*dbed73cbSSangeeta Misra 	FILE	*fp;
45*dbed73cbSSangeeta Misra } hc_export_arg_t;
46*dbed73cbSSangeeta Misra 
47*dbed73cbSSangeeta Misra /* Maximum columns for printing hc output. */
48*dbed73cbSSangeeta Misra #define	SHOW_HC_COLS	80
49*dbed73cbSSangeeta Misra 
50*dbed73cbSSangeeta Misra /* OFMT call back to print out a hc server result field. */
51*dbed73cbSSangeeta Misra static boolean_t print_hc_result(ofmt_arg_t *, char *, uint_t);
52*dbed73cbSSangeeta Misra 
53*dbed73cbSSangeeta Misra /* ID to indicate which field to be printed. */
54*dbed73cbSSangeeta Misra enum hc_print_id {
55*dbed73cbSSangeeta Misra 	hc_of_rname, hc_of_hname, hc_of_sname, hc_of_status, hc_of_fail_cnt,
56*dbed73cbSSangeeta Misra 	hc_of_lasttime, hc_of_nexttime, hc_of_rtt,
57*dbed73cbSSangeeta Misra 	hc_of_name, hc_of_timeout, hc_of_count, hc_of_interval, hc_of_def_ping,
58*dbed73cbSSangeeta Misra 	hc_of_test
59*dbed73cbSSangeeta Misra };
60*dbed73cbSSangeeta Misra 
61*dbed73cbSSangeeta Misra /*
62*dbed73cbSSangeeta Misra  * Fields of a hc server result.  The sum of all fields' width is SHOW_HC_COLS.
63*dbed73cbSSangeeta Misra  */
64*dbed73cbSSangeeta Misra static ofmt_field_t hc_results[] = {
65*dbed73cbSSangeeta Misra 	{"RULENAME",	14,	hc_of_rname,	print_hc_result},
66*dbed73cbSSangeeta Misra 	{"HCNAME",	14,	hc_of_hname,	print_hc_result},
67*dbed73cbSSangeeta Misra 	{"SERVERID",	14,	hc_of_sname,	print_hc_result},
68*dbed73cbSSangeeta Misra 	{"STATUS",	9,	hc_of_status,	print_hc_result},
69*dbed73cbSSangeeta Misra 	{"FAIL",	5,	hc_of_fail_cnt,	print_hc_result},
70*dbed73cbSSangeeta Misra 	{"LAST",	9,	hc_of_lasttime,	print_hc_result},
71*dbed73cbSSangeeta Misra 	{"NEXT",	9,	hc_of_nexttime,	print_hc_result},
72*dbed73cbSSangeeta Misra 	{"RTT",		6,	hc_of_rtt,	print_hc_result},
73*dbed73cbSSangeeta Misra 	{NULL,		0,	0,		NULL}
74*dbed73cbSSangeeta Misra };
75*dbed73cbSSangeeta Misra 
76*dbed73cbSSangeeta Misra /* OFMT call back to print out a hc info field. */
77*dbed73cbSSangeeta Misra static boolean_t print_hc(ofmt_arg_t *, char *, uint_t);
78*dbed73cbSSangeeta Misra 
79*dbed73cbSSangeeta Misra /*
80*dbed73cbSSangeeta Misra  * Fields of a hc info.  The sume of all fields' width is SHOW_HC_COLS.
81*dbed73cbSSangeeta Misra  */
82*dbed73cbSSangeeta Misra static ofmt_field_t hc_fields[] = {
83*dbed73cbSSangeeta Misra 	{"HCNAME",	14,	hc_of_name,	print_hc},
84*dbed73cbSSangeeta Misra 	{"TIMEOUT",	8,	hc_of_timeout,	print_hc},
85*dbed73cbSSangeeta Misra 	{"COUNT",	8,	hc_of_count,	print_hc},
86*dbed73cbSSangeeta Misra 	{"INTERVAL",	9,	hc_of_interval,	print_hc},
87*dbed73cbSSangeeta Misra 	{"DEF_PING",	9,	hc_of_def_ping,	print_hc},
88*dbed73cbSSangeeta Misra 	{"TEST",	32,	hc_of_test,	print_hc},
89*dbed73cbSSangeeta Misra 	{NULL,		0,	0,		NULL}
90*dbed73cbSSangeeta Misra };
91*dbed73cbSSangeeta Misra 
92*dbed73cbSSangeeta Misra static boolean_t
93*dbed73cbSSangeeta Misra print_hc(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
94*dbed73cbSSangeeta Misra {
95*dbed73cbSSangeeta Misra 	enum hc_print_id id = of_arg->ofmt_id;
96*dbed73cbSSangeeta Misra 	ilb_hc_info_t *info = (ilb_hc_info_t *)of_arg->ofmt_cbarg;
97*dbed73cbSSangeeta Misra 
98*dbed73cbSSangeeta Misra 	switch (id) {
99*dbed73cbSSangeeta Misra 	case hc_of_name:
100*dbed73cbSSangeeta Misra 		(void) strlcpy(buf, info->hci_name, bufsize);
101*dbed73cbSSangeeta Misra 		break;
102*dbed73cbSSangeeta Misra 	case hc_of_timeout:
103*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%d", info->hci_timeout);
104*dbed73cbSSangeeta Misra 		break;
105*dbed73cbSSangeeta Misra 	case hc_of_count:
106*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%d", info->hci_count);
107*dbed73cbSSangeeta Misra 		break;
108*dbed73cbSSangeeta Misra 	case hc_of_interval:
109*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%d", info->hci_interval);
110*dbed73cbSSangeeta Misra 		break;
111*dbed73cbSSangeeta Misra 	case hc_of_def_ping:
112*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%c",
113*dbed73cbSSangeeta Misra 		    info->hci_def_ping ? 'Y' : 'N');
114*dbed73cbSSangeeta Misra 		break;
115*dbed73cbSSangeeta Misra 	case hc_of_test:
116*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%s", info->hci_test);
117*dbed73cbSSangeeta Misra 		break;
118*dbed73cbSSangeeta Misra 	}
119*dbed73cbSSangeeta Misra 	return (B_TRUE);
120*dbed73cbSSangeeta Misra }
121*dbed73cbSSangeeta Misra 
122*dbed73cbSSangeeta Misra /* Call back to ilb_walk_hc(). */
123*dbed73cbSSangeeta Misra /* ARGSUSED */
124*dbed73cbSSangeeta Misra static ilb_status_t
125*dbed73cbSSangeeta Misra ilbadm_print_hc(ilb_handle_t h, ilb_hc_info_t *hc_info, void *arg)
126*dbed73cbSSangeeta Misra {
127*dbed73cbSSangeeta Misra 	ofmt_handle_t	ofmt_h = arg;
128*dbed73cbSSangeeta Misra 
129*dbed73cbSSangeeta Misra 	ofmt_print(ofmt_h, hc_info);
130*dbed73cbSSangeeta Misra 	return (ILB_STATUS_OK);
131*dbed73cbSSangeeta Misra }
132*dbed73cbSSangeeta Misra 
133*dbed73cbSSangeeta Misra /*
134*dbed73cbSSangeeta Misra  * Print out health check objects given their name.
135*dbed73cbSSangeeta Misra  * Or print out all health check objects if no name given.
136*dbed73cbSSangeeta Misra  */
137*dbed73cbSSangeeta Misra /* ARGSUSED */
138*dbed73cbSSangeeta Misra ilbadm_status_t
139*dbed73cbSSangeeta Misra ilbadm_show_hc(int argc, char *argv[])
140*dbed73cbSSangeeta Misra {
141*dbed73cbSSangeeta Misra 	ilb_handle_t	h = ILB_INVALID_HANDLE;
142*dbed73cbSSangeeta Misra 	ilb_status_t	rclib;
143*dbed73cbSSangeeta Misra 	ofmt_handle_t	ofmt_h;
144*dbed73cbSSangeeta Misra 	ofmt_status_t	ofmt_ret;
145*dbed73cbSSangeeta Misra 
146*dbed73cbSSangeeta Misra 	if ((ofmt_ret = ofmt_open("all", hc_fields, 0, SHOW_HC_COLS,
147*dbed73cbSSangeeta Misra 	    &ofmt_h)) != OFMT_SUCCESS) {
148*dbed73cbSSangeeta Misra 		char err_buf[SHOW_HC_COLS];
149*dbed73cbSSangeeta Misra 
150*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("ofmt_open failed: %s"),
151*dbed73cbSSangeeta Misra 		    ofmt_strerror(ofmt_h, ofmt_ret, err_buf, SHOW_HC_COLS));
152*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
153*dbed73cbSSangeeta Misra 	}
154*dbed73cbSSangeeta Misra 	rclib = ilb_open(&h);
155*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK)
156*dbed73cbSSangeeta Misra 		goto out;
157*dbed73cbSSangeeta Misra 
158*dbed73cbSSangeeta Misra 	if (argc == 1) {
159*dbed73cbSSangeeta Misra 		rclib = ilb_walk_hc(h, ilbadm_print_hc, ofmt_h);
160*dbed73cbSSangeeta Misra 	} else {
161*dbed73cbSSangeeta Misra 		ilb_hc_info_t hc_info;
162*dbed73cbSSangeeta Misra 		int i;
163*dbed73cbSSangeeta Misra 
164*dbed73cbSSangeeta Misra 		for (i = 1; i < argc; i++) {
165*dbed73cbSSangeeta Misra 			rclib = ilb_get_hc_info(h, argv[i], &hc_info);
166*dbed73cbSSangeeta Misra 			if (rclib == ILB_STATUS_OK)
167*dbed73cbSSangeeta Misra 				ofmt_print(ofmt_h, &hc_info);
168*dbed73cbSSangeeta Misra 			else
169*dbed73cbSSangeeta Misra 				break;
170*dbed73cbSSangeeta Misra 		}
171*dbed73cbSSangeeta Misra 	}
172*dbed73cbSSangeeta Misra out:
173*dbed73cbSSangeeta Misra 	ofmt_close(ofmt_h);
174*dbed73cbSSangeeta Misra 
175*dbed73cbSSangeeta Misra 	if (h != ILB_INVALID_HANDLE)
176*dbed73cbSSangeeta Misra 		(void) ilb_close(h);
177*dbed73cbSSangeeta Misra 
178*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK) {
179*dbed73cbSSangeeta Misra 		ilbadm_err(ilb_errstr(rclib));
180*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
181*dbed73cbSSangeeta Misra 	}
182*dbed73cbSSangeeta Misra 
183*dbed73cbSSangeeta Misra 	return (ILBADM_OK);
184*dbed73cbSSangeeta Misra }
185*dbed73cbSSangeeta Misra 
186*dbed73cbSSangeeta Misra static boolean_t
187*dbed73cbSSangeeta Misra print_hc_result(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
188*dbed73cbSSangeeta Misra {
189*dbed73cbSSangeeta Misra 	enum hc_print_id id = of_arg->ofmt_id;
190*dbed73cbSSangeeta Misra 	ilb_hc_srv_t *srv = (ilb_hc_srv_t *)of_arg->ofmt_cbarg;
191*dbed73cbSSangeeta Misra 	struct tm tv;
192*dbed73cbSSangeeta Misra 
193*dbed73cbSSangeeta Misra 	switch (id) {
194*dbed73cbSSangeeta Misra 	case hc_of_rname:
195*dbed73cbSSangeeta Misra 		(void) strlcpy(buf, srv->hcs_rule_name, bufsize);
196*dbed73cbSSangeeta Misra 		break;
197*dbed73cbSSangeeta Misra 	case hc_of_hname:
198*dbed73cbSSangeeta Misra 		(void) strlcpy(buf, srv->hcs_hc_name, bufsize);
199*dbed73cbSSangeeta Misra 		break;
200*dbed73cbSSangeeta Misra 	case hc_of_sname:
201*dbed73cbSSangeeta Misra 		(void) strlcpy(buf, srv->hcs_ID, bufsize);
202*dbed73cbSSangeeta Misra 		break;
203*dbed73cbSSangeeta Misra 	case hc_of_status:
204*dbed73cbSSangeeta Misra 		switch (srv->hcs_status) {
205*dbed73cbSSangeeta Misra 		case ILB_HCS_UNINIT:
206*dbed73cbSSangeeta Misra 			(void) strlcpy(buf, "un-init", bufsize);
207*dbed73cbSSangeeta Misra 			break;
208*dbed73cbSSangeeta Misra 		case ILB_HCS_UNREACH:
209*dbed73cbSSangeeta Misra 			(void) strlcpy(buf, "unreach", bufsize);
210*dbed73cbSSangeeta Misra 			break;
211*dbed73cbSSangeeta Misra 		case ILB_HCS_ALIVE:
212*dbed73cbSSangeeta Misra 			(void) strlcpy(buf, "alive", bufsize);
213*dbed73cbSSangeeta Misra 			break;
214*dbed73cbSSangeeta Misra 		case ILB_HCS_DEAD:
215*dbed73cbSSangeeta Misra 			(void) strlcpy(buf, "dead", bufsize);
216*dbed73cbSSangeeta Misra 			break;
217*dbed73cbSSangeeta Misra 		case ILB_HCS_DISABLED:
218*dbed73cbSSangeeta Misra 			(void) strlcpy(buf, "disabled", bufsize);
219*dbed73cbSSangeeta Misra 			break;
220*dbed73cbSSangeeta Misra 		}
221*dbed73cbSSangeeta Misra 		break;
222*dbed73cbSSangeeta Misra 	case hc_of_fail_cnt:
223*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%u", srv->hcs_fail_cnt);
224*dbed73cbSSangeeta Misra 		break;
225*dbed73cbSSangeeta Misra 	case hc_of_lasttime:
226*dbed73cbSSangeeta Misra 		if (localtime_r(&srv->hcs_lasttime, &tv) == NULL)
227*dbed73cbSSangeeta Misra 			return (B_FALSE);
228*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%02d:%02d:%02d", tv.tm_hour,
229*dbed73cbSSangeeta Misra 		    tv.tm_min, tv.tm_sec);
230*dbed73cbSSangeeta Misra 		break;
231*dbed73cbSSangeeta Misra 	case hc_of_nexttime:
232*dbed73cbSSangeeta Misra 		if (srv->hcs_status == ILB_HCS_DISABLED)
233*dbed73cbSSangeeta Misra 			break;
234*dbed73cbSSangeeta Misra 		if (localtime_r(&srv->hcs_nexttime, &tv) == NULL)
235*dbed73cbSSangeeta Misra 			return (B_FALSE);
236*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%02d:%02d:%02d", tv.tm_hour,
237*dbed73cbSSangeeta Misra 		    tv.tm_min, tv.tm_sec);
238*dbed73cbSSangeeta Misra 		break;
239*dbed73cbSSangeeta Misra 	case hc_of_rtt:
240*dbed73cbSSangeeta Misra 		(void) snprintf(buf, bufsize, "%u", srv->hcs_rtt);
241*dbed73cbSSangeeta Misra 		break;
242*dbed73cbSSangeeta Misra 	}
243*dbed73cbSSangeeta Misra 	return (B_TRUE);
244*dbed73cbSSangeeta Misra }
245*dbed73cbSSangeeta Misra 
246*dbed73cbSSangeeta Misra /* Call back to ilbd_walk_hc_srvs(). */
247*dbed73cbSSangeeta Misra /* ARGSUSED */
248*dbed73cbSSangeeta Misra static ilb_status_t
249*dbed73cbSSangeeta Misra ilbadm_print_hc_result(ilb_handle_t h, ilb_hc_srv_t *srv, void *arg)
250*dbed73cbSSangeeta Misra {
251*dbed73cbSSangeeta Misra 	ofmt_handle_t	ofmt_h = arg;
252*dbed73cbSSangeeta Misra 
253*dbed73cbSSangeeta Misra 	ofmt_print(ofmt_h, srv);
254*dbed73cbSSangeeta Misra 	return (ILB_STATUS_OK);
255*dbed73cbSSangeeta Misra }
256*dbed73cbSSangeeta Misra 
257*dbed73cbSSangeeta Misra /*
258*dbed73cbSSangeeta Misra  * Output hc result of a specified rule or all rules.
259*dbed73cbSSangeeta Misra  */
260*dbed73cbSSangeeta Misra ilbadm_status_t
261*dbed73cbSSangeeta Misra ilbadm_show_hc_result(int argc, char *argv[])
262*dbed73cbSSangeeta Misra {
263*dbed73cbSSangeeta Misra 	ilb_handle_t	h = ILB_INVALID_HANDLE;
264*dbed73cbSSangeeta Misra 	ilb_status_t 	rclib = ILB_STATUS_OK;
265*dbed73cbSSangeeta Misra 	int		i;
266*dbed73cbSSangeeta Misra 	ofmt_handle_t	ofmt_h;
267*dbed73cbSSangeeta Misra 	ofmt_status_t	ofmt_ret;
268*dbed73cbSSangeeta Misra 
269*dbed73cbSSangeeta Misra 	/* ilbadm show-hc-result [rule-name] */
270*dbed73cbSSangeeta Misra 	if (argc < 1) {
271*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("usage: ilbadm show-hc-result"
272*dbed73cbSSangeeta Misra 		    " [rule-name]"));
273*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
274*dbed73cbSSangeeta Misra 	}
275*dbed73cbSSangeeta Misra 
276*dbed73cbSSangeeta Misra 	if ((ofmt_ret = ofmt_open("all", hc_results, 0, SHOW_HC_COLS,
277*dbed73cbSSangeeta Misra 	    &ofmt_h)) != OFMT_SUCCESS) {
278*dbed73cbSSangeeta Misra 		char err_buf[SHOW_HC_COLS];
279*dbed73cbSSangeeta Misra 
280*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("ofmt_open failed: %s"),
281*dbed73cbSSangeeta Misra 		    ofmt_strerror(ofmt_h, ofmt_ret, err_buf, SHOW_HC_COLS));
282*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
283*dbed73cbSSangeeta Misra 	}
284*dbed73cbSSangeeta Misra 
285*dbed73cbSSangeeta Misra 	rclib = ilb_open(&h);
286*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK)
287*dbed73cbSSangeeta Misra 		goto out;
288*dbed73cbSSangeeta Misra 
289*dbed73cbSSangeeta Misra 	/* If no rule name is given, show results for all rules. */
290*dbed73cbSSangeeta Misra 	if (argc == 1) {
291*dbed73cbSSangeeta Misra 		rclib = ilb_walk_hc_srvs(h, ilbadm_print_hc_result, NULL,
292*dbed73cbSSangeeta Misra 		    ofmt_h);
293*dbed73cbSSangeeta Misra 	} else {
294*dbed73cbSSangeeta Misra 		for (i = 1; i < argc; i++) {
295*dbed73cbSSangeeta Misra 			rclib = ilb_walk_hc_srvs(h, ilbadm_print_hc_result,
296*dbed73cbSSangeeta Misra 			    argv[i], ofmt_h);
297*dbed73cbSSangeeta Misra 			if (rclib != ILB_STATUS_OK)
298*dbed73cbSSangeeta Misra 				break;
299*dbed73cbSSangeeta Misra 		}
300*dbed73cbSSangeeta Misra 	}
301*dbed73cbSSangeeta Misra out:
302*dbed73cbSSangeeta Misra 	ofmt_close(ofmt_h);
303*dbed73cbSSangeeta Misra 
304*dbed73cbSSangeeta Misra 	if (h != ILB_INVALID_HANDLE)
305*dbed73cbSSangeeta Misra 		(void) ilb_close(h);
306*dbed73cbSSangeeta Misra 
307*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK) {
308*dbed73cbSSangeeta Misra 		ilbadm_err(ilb_errstr(rclib));
309*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
310*dbed73cbSSangeeta Misra 	}
311*dbed73cbSSangeeta Misra 	return (ILBADM_OK);
312*dbed73cbSSangeeta Misra }
313*dbed73cbSSangeeta Misra 
314*dbed73cbSSangeeta Misra #define	ILBADM_DEF_HC_COUNT	3
315*dbed73cbSSangeeta Misra #define	ILBADM_DEF_HC_INTERVAL	30	/* in sec */
316*dbed73cbSSangeeta Misra #define	ILBADM_DEF_HC_TIMEOUT	5	/* in sec */
317*dbed73cbSSangeeta Misra 
318*dbed73cbSSangeeta Misra static ilbadm_key_name_t hc_parse_keys[] = {
319*dbed73cbSSangeeta Misra 	{ILB_KEY_HC_TEST, "hc-test", "hc-test"},
320*dbed73cbSSangeeta Misra 	{ILB_KEY_HC_COUNT, "hc-count", "hc-count"},
321*dbed73cbSSangeeta Misra 	{ILB_KEY_HC_TIMEOUT, "hc-timeout", "hc-tout"},
322*dbed73cbSSangeeta Misra 	{ILB_KEY_HC_INTERVAL, "hc-interval", "hc-intl"},
323*dbed73cbSSangeeta Misra 	{ILB_KEY_BAD, "", ""}
324*dbed73cbSSangeeta Misra };
325*dbed73cbSSangeeta Misra 
326*dbed73cbSSangeeta Misra static ilbadm_status_t
327*dbed73cbSSangeeta Misra ilbadm_hc_parse_arg(char *arg, ilb_hc_info_t *hc)
328*dbed73cbSSangeeta Misra {
329*dbed73cbSSangeeta Misra 	ilbadm_status_t ret;
330*dbed73cbSSangeeta Misra 
331*dbed73cbSSangeeta Misra 	/* set default value for count, interval, timeout */
332*dbed73cbSSangeeta Misra 	hc->hci_count = ILBADM_DEF_HC_COUNT;
333*dbed73cbSSangeeta Misra 	hc->hci_interval = ILBADM_DEF_HC_INTERVAL;
334*dbed73cbSSangeeta Misra 	hc->hci_timeout = ILBADM_DEF_HC_TIMEOUT;
335*dbed73cbSSangeeta Misra 	hc->hci_test[0] = '\0';
336*dbed73cbSSangeeta Misra 
337*dbed73cbSSangeeta Misra 	ret = i_parse_optstring(arg, hc, hc_parse_keys, 0, NULL);
338*dbed73cbSSangeeta Misra 	if (ret != ILBADM_OK && ret != ILBADM_LIBERR) {
339*dbed73cbSSangeeta Misra 		ilbadm_err(ilbadm_errstr(ret));
340*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
341*dbed73cbSSangeeta Misra 	}
342*dbed73cbSSangeeta Misra 	if (hc->hci_test[0] == '\0' && ret != ILBADM_LIBERR) {
343*dbed73cbSSangeeta Misra 		ilbadm_err("hc-test: missing");
344*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
345*dbed73cbSSangeeta Misra 	}
346*dbed73cbSSangeeta Misra 	return (ret);
347*dbed73cbSSangeeta Misra }
348*dbed73cbSSangeeta Misra 
349*dbed73cbSSangeeta Misra /* ARGSUSED */
350*dbed73cbSSangeeta Misra ilbadm_status_t
351*dbed73cbSSangeeta Misra ilbadm_create_hc(int argc, char *argv[])
352*dbed73cbSSangeeta Misra {
353*dbed73cbSSangeeta Misra 	ilb_handle_t	h = ILB_INVALID_HANDLE;
354*dbed73cbSSangeeta Misra 	ilb_hc_info_t	hc_info;
355*dbed73cbSSangeeta Misra 	ilbadm_status_t	ret = ILBADM_OK;
356*dbed73cbSSangeeta Misra 	ilb_status_t	rclib;
357*dbed73cbSSangeeta Misra 	char		c;
358*dbed73cbSSangeeta Misra 
359*dbed73cbSSangeeta Misra 
360*dbed73cbSSangeeta Misra 	hc_info.hci_def_ping = B_TRUE;
361*dbed73cbSSangeeta Misra 	while ((c = getopt(argc, argv, ":h:n")) != -1) {
362*dbed73cbSSangeeta Misra 		if (c == 'h') {
363*dbed73cbSSangeeta Misra 			ret = ilbadm_hc_parse_arg(optarg, &hc_info);
364*dbed73cbSSangeeta Misra 			if (ret != ILBADM_OK)
365*dbed73cbSSangeeta Misra 				return (ret);
366*dbed73cbSSangeeta Misra 		} else if (c == 'n') {
367*dbed73cbSSangeeta Misra 			hc_info.hci_def_ping = B_FALSE;
368*dbed73cbSSangeeta Misra 		} else {
369*dbed73cbSSangeeta Misra 			ilbadm_err(gettext("bad argument %c"), c);
370*dbed73cbSSangeeta Misra 			return (ILBADM_LIBERR);
371*dbed73cbSSangeeta Misra 		}
372*dbed73cbSSangeeta Misra 	}
373*dbed73cbSSangeeta Misra 
374*dbed73cbSSangeeta Misra 	if (optind >= argc) {
375*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("usage: ilbadm"
376*dbed73cbSSangeeta Misra 		    " create-healthcheck [-n] -h"
377*dbed73cbSSangeeta Misra 		    " hc-test=val[,hc-timeout=val][,hc-count=va]"
378*dbed73cbSSangeeta Misra 		    "[,hc-interval=val]  hc-name"));
379*dbed73cbSSangeeta Misra 		return (ILBADM_FAIL);
380*dbed73cbSSangeeta Misra 	}
381*dbed73cbSSangeeta Misra 
382*dbed73cbSSangeeta Misra 	if (strlen(argv[optind]) > ILBD_NAMESZ - 1) {
383*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("health check object name %s is too long - "
384*dbed73cbSSangeeta Misra 		    "must not exceed %d chars"), argv[optind],
385*dbed73cbSSangeeta Misra 		    ILBD_NAMESZ - 1);
386*dbed73cbSSangeeta Misra 		return (ILBADM_FAIL);
387*dbed73cbSSangeeta Misra 	}
388*dbed73cbSSangeeta Misra 
389*dbed73cbSSangeeta Misra 	if (((strcasecmp(hc_info.hci_test, ILB_HC_STR_UDP) == 0) ||
390*dbed73cbSSangeeta Misra 	    (strcasecmp(hc_info.hci_test, ILB_HC_STR_PING) == 0)) &&
391*dbed73cbSSangeeta Misra 	    !(hc_info.hci_def_ping)) {
392*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("cannot disable default PING"
393*dbed73cbSSangeeta Misra 		    " for this test"));
394*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
395*dbed73cbSSangeeta Misra 	}
396*dbed73cbSSangeeta Misra 
397*dbed73cbSSangeeta Misra 	rclib = ilb_open(&h);
398*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK)
399*dbed73cbSSangeeta Misra 		goto out;
400*dbed73cbSSangeeta Misra 
401*dbed73cbSSangeeta Misra 	(void) strlcpy(hc_info.hci_name, argv[optind],
402*dbed73cbSSangeeta Misra 	    sizeof (hc_info.hci_name));
403*dbed73cbSSangeeta Misra 	rclib = ilb_create_hc(h, &hc_info);
404*dbed73cbSSangeeta Misra out:
405*dbed73cbSSangeeta Misra 	if (h != ILB_INVALID_HANDLE)
406*dbed73cbSSangeeta Misra 		(void) ilb_close(h);
407*dbed73cbSSangeeta Misra 
408*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK) {
409*dbed73cbSSangeeta Misra 		ilbadm_err(ilb_errstr(rclib));
410*dbed73cbSSangeeta Misra 		ret = ILBADM_LIBERR;
411*dbed73cbSSangeeta Misra 	}
412*dbed73cbSSangeeta Misra 	return (ret);
413*dbed73cbSSangeeta Misra }
414*dbed73cbSSangeeta Misra 
415*dbed73cbSSangeeta Misra ilbadm_status_t
416*dbed73cbSSangeeta Misra ilbadm_destroy_hc(int argc, char *argv[])
417*dbed73cbSSangeeta Misra {
418*dbed73cbSSangeeta Misra 	ilb_handle_t	h = ILB_INVALID_HANDLE;
419*dbed73cbSSangeeta Misra 	ilb_status_t	rclib;
420*dbed73cbSSangeeta Misra 	ilbadm_status_t ret = ILBADM_OK;
421*dbed73cbSSangeeta Misra 	int		i;
422*dbed73cbSSangeeta Misra 
423*dbed73cbSSangeeta Misra 	if (argc < 2) {
424*dbed73cbSSangeeta Misra 		ilbadm_err(gettext("usage: ilbadm"
425*dbed73cbSSangeeta Misra 		    " delete-healthcheck hc-name ..."));
426*dbed73cbSSangeeta Misra 		return (ILBADM_LIBERR);
427*dbed73cbSSangeeta Misra 	}
428*dbed73cbSSangeeta Misra 
429*dbed73cbSSangeeta Misra 	rclib = ilb_open(&h);
430*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK)
431*dbed73cbSSangeeta Misra 		goto out;
432*dbed73cbSSangeeta Misra 
433*dbed73cbSSangeeta Misra 	for (i = 1; i < argc; i++) {
434*dbed73cbSSangeeta Misra 		rclib = ilb_destroy_hc(h, argv[i]);
435*dbed73cbSSangeeta Misra 		if (rclib != ILB_STATUS_OK)
436*dbed73cbSSangeeta Misra 			break;
437*dbed73cbSSangeeta Misra 	}
438*dbed73cbSSangeeta Misra out:
439*dbed73cbSSangeeta Misra 	if (h != ILB_INVALID_HANDLE)
440*dbed73cbSSangeeta Misra 		(void) ilb_close(h);
441*dbed73cbSSangeeta Misra 
442*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK) {
443*dbed73cbSSangeeta Misra 		ilbadm_err(ilb_errstr(rclib));
444*dbed73cbSSangeeta Misra 		ret = ILBADM_LIBERR;
445*dbed73cbSSangeeta Misra 	}
446*dbed73cbSSangeeta Misra 	return (ret);
447*dbed73cbSSangeeta Misra }
448*dbed73cbSSangeeta Misra 
449*dbed73cbSSangeeta Misra /*
450*dbed73cbSSangeeta Misra  * Since this function is used by libilb function, it
451*dbed73cbSSangeeta Misra  * must return libilb errors
452*dbed73cbSSangeeta Misra  */
453*dbed73cbSSangeeta Misra /* ARGSUSED */
454*dbed73cbSSangeeta Misra ilb_status_t
455*dbed73cbSSangeeta Misra ilbadm_export_hcinfo(ilb_handle_t h, ilb_hc_info_t *hc_info, void *arg)
456*dbed73cbSSangeeta Misra {
457*dbed73cbSSangeeta Misra 	FILE 		*fp = ((hc_export_arg_t *)arg)->fp;
458*dbed73cbSSangeeta Misra 	int		count = 0;
459*dbed73cbSSangeeta Misra 	int		ret;
460*dbed73cbSSangeeta Misra 
461*dbed73cbSSangeeta Misra 	/*
462*dbed73cbSSangeeta Misra 	 * a test name "PING" implies "no default ping", so we only
463*dbed73cbSSangeeta Misra 	 * print -n if the test is NOT "PING"
464*dbed73cbSSangeeta Misra 	 */
465*dbed73cbSSangeeta Misra 	if (hc_info->hci_def_ping == B_FALSE &&
466*dbed73cbSSangeeta Misra 	    strncasecmp(hc_info->hci_test, "PING", 5) != 0)
467*dbed73cbSSangeeta Misra 		(void) fprintf(fp, "create-healthcheck -n -h ");
468*dbed73cbSSangeeta Misra 	else
469*dbed73cbSSangeeta Misra 		(void) fprintf(fp, "create-healthcheck -h ");
470*dbed73cbSSangeeta Misra 
471*dbed73cbSSangeeta Misra 	if (*hc_info->hci_test != '\0') {
472*dbed73cbSSangeeta Misra 		(void) fprintf(fp, "hc-test=%s", hc_info->hci_test);
473*dbed73cbSSangeeta Misra 		count++;
474*dbed73cbSSangeeta Misra 	}
475*dbed73cbSSangeeta Misra 	if (hc_info->hci_timeout != 0) {
476*dbed73cbSSangeeta Misra 		if (count++ > 0)
477*dbed73cbSSangeeta Misra 			(void) fprintf(fp, ",");
478*dbed73cbSSangeeta Misra 		(void) fprintf(fp, "hc-timeout=%d", hc_info->hci_timeout);
479*dbed73cbSSangeeta Misra 	}
480*dbed73cbSSangeeta Misra 	if (hc_info->hci_count != 0) {
481*dbed73cbSSangeeta Misra 		if (count++ > 0)
482*dbed73cbSSangeeta Misra 			(void) fprintf(fp, ",");
483*dbed73cbSSangeeta Misra 		(void) fprintf(fp, "hc-count=%d", hc_info->hci_count);
484*dbed73cbSSangeeta Misra 	}
485*dbed73cbSSangeeta Misra 	if (hc_info->hci_interval != 0) {
486*dbed73cbSSangeeta Misra 		if (count > 0)
487*dbed73cbSSangeeta Misra 			(void) fprintf(fp, ",");
488*dbed73cbSSangeeta Misra 		(void) fprintf(fp, "hc-interval=%d", hc_info->hci_interval);
489*dbed73cbSSangeeta Misra 	}
490*dbed73cbSSangeeta Misra 
491*dbed73cbSSangeeta Misra 	/*
492*dbed73cbSSangeeta Misra 	 * if any of the above writes fails, then, we assume, so will
493*dbed73cbSSangeeta Misra 	 * this one; so it's sufficient to test once
494*dbed73cbSSangeeta Misra 	 */
495*dbed73cbSSangeeta Misra 	ret = fprintf(fp, " %s\n", hc_info->hci_name);
496*dbed73cbSSangeeta Misra 	if (ret < 0)
497*dbed73cbSSangeeta Misra 		goto out_fail;
498*dbed73cbSSangeeta Misra 	ret = fflush(fp);
499*dbed73cbSSangeeta Misra 
500*dbed73cbSSangeeta Misra out_fail:
501*dbed73cbSSangeeta Misra 	if (ret < 0)
502*dbed73cbSSangeeta Misra 		return (ILB_STATUS_WRITE);
503*dbed73cbSSangeeta Misra 	return (ILB_STATUS_OK);
504*dbed73cbSSangeeta Misra }
505*dbed73cbSSangeeta Misra 
506*dbed73cbSSangeeta Misra ilbadm_status_t
507*dbed73cbSSangeeta Misra ilbadm_export_hc(ilb_handle_t h, FILE *fp)
508*dbed73cbSSangeeta Misra {
509*dbed73cbSSangeeta Misra 	ilb_status_t	rclib;
510*dbed73cbSSangeeta Misra 	ilbadm_status_t	ret = ILBADM_OK;
511*dbed73cbSSangeeta Misra 	hc_export_arg_t	arg;
512*dbed73cbSSangeeta Misra 
513*dbed73cbSSangeeta Misra 	arg.fp = fp;
514*dbed73cbSSangeeta Misra 	rclib = ilb_walk_hc(h, ilbadm_export_hcinfo, (void *)&arg);
515*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK) {
516*dbed73cbSSangeeta Misra 		ilbadm_err(ilb_errstr(rclib));
517*dbed73cbSSangeeta Misra 		ret = ILBADM_LIBERR;
518*dbed73cbSSangeeta Misra 	}
519*dbed73cbSSangeeta Misra 	return (ret);
520*dbed73cbSSangeeta Misra }
521