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