xref: /illumos-gate/usr/src/lib/libilb/common/ilb_hc.c (revision dbed73cb)
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 <stdlib.h>
28*dbed73cbSSangeeta Misra #include <strings.h>
29*dbed73cbSSangeeta Misra #include <sys/types.h>
30*dbed73cbSSangeeta Misra #include <sys/socket.h>
31*dbed73cbSSangeeta Misra #include <netinet/in.h>
32*dbed73cbSSangeeta Misra #include <stddef.h>
33*dbed73cbSSangeeta Misra #include <libilb_impl.h>
34*dbed73cbSSangeeta Misra #include <libilb.h>
35*dbed73cbSSangeeta Misra 
36*dbed73cbSSangeeta Misra /*
37*dbed73cbSSangeeta Misra  * Create a health check, returning a health check handle upon success.
38*dbed73cbSSangeeta Misra  * Health check created will be recorded in persistent datastore.
39*dbed73cbSSangeeta Misra  */
40*dbed73cbSSangeeta Misra ilb_status_t
ilb_create_hc(ilb_handle_t h,const ilb_hc_info_t * hc)41*dbed73cbSSangeeta Misra ilb_create_hc(ilb_handle_t h, const ilb_hc_info_t *hc)
42*dbed73cbSSangeeta Misra {
43*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
44*dbed73cbSSangeeta Misra 	ilb_comm_t	*ic;
45*dbed73cbSSangeeta Misra 	size_t		ic_sz;
46*dbed73cbSSangeeta Misra 
47*dbed73cbSSangeeta Misra 	if (h == ILB_INVALID_HANDLE || hc == NULL || *hc->hci_name == '\0' ||
48*dbed73cbSSangeeta Misra 	    hc->hci_timeout < 0 || hc->hci_count < 0 ||
49*dbed73cbSSangeeta Misra 	    hc->hci_interval <= hc->hci_timeout * hc->hci_count)
50*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
51*dbed73cbSSangeeta Misra 
52*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(ILBD_CREATE_HC, &ic_sz)) == NULL)
53*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
54*dbed73cbSSangeeta Misra 
55*dbed73cbSSangeeta Misra 	(void) memcpy(&ic->ic_data, hc, sizeof (ilb_hc_info_t));
56*dbed73cbSSangeeta Misra 
57*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
58*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
59*dbed73cbSSangeeta Misra 		goto out;
60*dbed73cbSSangeeta Misra 
61*dbed73cbSSangeeta Misra 	if (ic->ic_cmd != ILBD_CMD_OK)
62*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&ic->ic_data;
63*dbed73cbSSangeeta Misra 
64*dbed73cbSSangeeta Misra out:
65*dbed73cbSSangeeta Misra 	free(ic);
66*dbed73cbSSangeeta Misra 	return (rc);
67*dbed73cbSSangeeta Misra }
68*dbed73cbSSangeeta Misra 
69*dbed73cbSSangeeta Misra /*
70*dbed73cbSSangeeta Misra  * Given a health check handle, destroy the corresponding health check.
71*dbed73cbSSangeeta Misra  * Persistent datastore will be updated as well.
72*dbed73cbSSangeeta Misra  */
73*dbed73cbSSangeeta Misra ilb_status_t
ilb_destroy_hc(ilb_handle_t h,const char * hcname)74*dbed73cbSSangeeta Misra ilb_destroy_hc(ilb_handle_t h, const char *hcname)
75*dbed73cbSSangeeta Misra {
76*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
77*dbed73cbSSangeeta Misra 	ilb_comm_t	*ic;
78*dbed73cbSSangeeta Misra 	size_t		ic_sz;
79*dbed73cbSSangeeta Misra 
80*dbed73cbSSangeeta Misra 	if (h == ILB_INVALID_HANDLE || hcname == NULL || *hcname == '\0')
81*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
82*dbed73cbSSangeeta Misra 
83*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(ILBD_DESTROY_HC, &ic_sz)) == NULL)
84*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
85*dbed73cbSSangeeta Misra 
86*dbed73cbSSangeeta Misra 	(void) strlcpy((char *)&ic->ic_data, hcname, sizeof (ilbd_name_t));
87*dbed73cbSSangeeta Misra 
88*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, ic, &ic_sz);
89*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
90*dbed73cbSSangeeta Misra 		goto out;
91*dbed73cbSSangeeta Misra 
92*dbed73cbSSangeeta Misra 	if (ic->ic_cmd != ILBD_CMD_OK)
93*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&ic->ic_data;
94*dbed73cbSSangeeta Misra 
95*dbed73cbSSangeeta Misra out:
96*dbed73cbSSangeeta Misra 	free(ic);
97*dbed73cbSSangeeta Misra 	return (rc);
98*dbed73cbSSangeeta Misra }
99*dbed73cbSSangeeta Misra 
100*dbed73cbSSangeeta Misra /*
101*dbed73cbSSangeeta Misra  * Given a health check name, get hc info associated with this handle
102*dbed73cbSSangeeta Misra  */
103*dbed73cbSSangeeta Misra ilb_status_t
ilb_get_hc_info(ilb_handle_t h,const char * name,ilb_hc_info_t * hcp)104*dbed73cbSSangeeta Misra ilb_get_hc_info(ilb_handle_t h, const char *name, ilb_hc_info_t *hcp)
105*dbed73cbSSangeeta Misra {
106*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
107*dbed73cbSSangeeta Misra 	ilb_comm_t	*ic, *rbuf;
108*dbed73cbSSangeeta Misra 	size_t		ic_sz, rbufsz;
109*dbed73cbSSangeeta Misra 
110*dbed73cbSSangeeta Misra 	if (h == ILB_INVALID_HANDLE || name == NULL || hcp == NULL)
111*dbed73cbSSangeeta Misra 		return (ILB_STATUS_EINVAL);
112*dbed73cbSSangeeta Misra 
113*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(ILBD_GET_HC_INFO, &ic_sz)) == NULL)
114*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
115*dbed73cbSSangeeta Misra 	rbufsz = sizeof (ilb_comm_t) + sizeof (ilb_hc_info_t);
116*dbed73cbSSangeeta Misra 	if ((rbuf = malloc(rbufsz)) == NULL) {
117*dbed73cbSSangeeta Misra 		free(ic);
118*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
119*dbed73cbSSangeeta Misra 	}
120*dbed73cbSSangeeta Misra 
121*dbed73cbSSangeeta Misra 	(void) strlcpy((char *)&ic->ic_data, name, sizeof (ilbd_name_t));
122*dbed73cbSSangeeta Misra 
123*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, rbuf, &rbufsz);
124*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
125*dbed73cbSSangeeta Misra 		goto out;
126*dbed73cbSSangeeta Misra 
127*dbed73cbSSangeeta Misra 	if (rbuf->ic_cmd != ILBD_CMD_OK) {
128*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&rbuf->ic_data;
129*dbed73cbSSangeeta Misra 		goto out;
130*dbed73cbSSangeeta Misra 	}
131*dbed73cbSSangeeta Misra 	(void) memcpy(hcp, &rbuf->ic_data, sizeof (*hcp));
132*dbed73cbSSangeeta Misra 
133*dbed73cbSSangeeta Misra out:
134*dbed73cbSSangeeta Misra 	free(ic);
135*dbed73cbSSangeeta Misra 	free(rbuf);
136*dbed73cbSSangeeta Misra 	return (rc);
137*dbed73cbSSangeeta Misra }
138*dbed73cbSSangeeta Misra 
139*dbed73cbSSangeeta Misra /*
140*dbed73cbSSangeeta Misra  * Walk through all health checks, will need if we implement list-hc
141*dbed73cbSSangeeta Misra  */
142*dbed73cbSSangeeta Misra ilb_status_t
ilb_walk_hc(ilb_handle_t h,hc_walkerfunc_t func,void * arg)143*dbed73cbSSangeeta Misra ilb_walk_hc(ilb_handle_t h, hc_walkerfunc_t func, void *arg)
144*dbed73cbSSangeeta Misra {
145*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
146*dbed73cbSSangeeta Misra 	ilb_hc_info_t	hc_info;
147*dbed73cbSSangeeta Misra 	ilbd_namelist_t	*hc_names;
148*dbed73cbSSangeeta Misra 	ilb_comm_t	ic, *rbuf;
149*dbed73cbSSangeeta Misra 	size_t		rbufsz;
150*dbed73cbSSangeeta Misra 	int		i;
151*dbed73cbSSangeeta Misra 
152*dbed73cbSSangeeta Misra 	rbufsz = ILBD_MSG_SIZE;
153*dbed73cbSSangeeta Misra 	if ((rbuf = malloc(rbufsz)) == NULL)
154*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
155*dbed73cbSSangeeta Misra 	ic.ic_cmd = ILBD_RETRIEVE_HC_NAMES;
156*dbed73cbSSangeeta Misra 
157*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, &ic, sizeof (ic), rbuf, &rbufsz);
158*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
159*dbed73cbSSangeeta Misra 		goto out;
160*dbed73cbSSangeeta Misra 	if (rbuf->ic_cmd != ILBD_CMD_OK) {
161*dbed73cbSSangeeta Misra 		rc = *(ilb_status_t *)&rbuf->ic_data;
162*dbed73cbSSangeeta Misra 		goto out;
163*dbed73cbSSangeeta Misra 	}
164*dbed73cbSSangeeta Misra 
165*dbed73cbSSangeeta Misra 	hc_names = (ilbd_namelist_t *)&rbuf->ic_data;
166*dbed73cbSSangeeta Misra 	for (i = 0; i < hc_names->ilbl_count; i++) {
167*dbed73cbSSangeeta Misra 		rc = ilb_get_hc_info(h, hc_names->ilbl_name[i], &hc_info);
168*dbed73cbSSangeeta Misra 		/*
169*dbed73cbSSangeeta Misra 		 * Since getting the list of hc names and getting the info
170*dbed73cbSSangeeta Misra 		 * of each of them are not atomic, some hc objects may have
171*dbed73cbSSangeeta Misra 		 * been deleted.  If this is the case, just skip them.
172*dbed73cbSSangeeta Misra 		 */
173*dbed73cbSSangeeta Misra 		if (rc == ILB_STATUS_ENOENT) {
174*dbed73cbSSangeeta Misra 			rc = ILB_STATUS_OK;
175*dbed73cbSSangeeta Misra 			continue;
176*dbed73cbSSangeeta Misra 		} else if (rc != ILB_STATUS_OK) {
177*dbed73cbSSangeeta Misra 			break;
178*dbed73cbSSangeeta Misra 		}
179*dbed73cbSSangeeta Misra 		rc = func(h, &hc_info, arg);
180*dbed73cbSSangeeta Misra 	}
181*dbed73cbSSangeeta Misra 
182*dbed73cbSSangeeta Misra out:
183*dbed73cbSSangeeta Misra 	free(rbuf);
184*dbed73cbSSangeeta Misra 	return (rc);
185*dbed73cbSSangeeta Misra }
186*dbed73cbSSangeeta Misra 
187*dbed73cbSSangeeta Misra static ilb_status_t
ilb_get_hc_srvs(ilb_handle_t h,const char * rulename,ilb_comm_t ** rbuf,size_t * rbufsz)188*dbed73cbSSangeeta Misra ilb_get_hc_srvs(ilb_handle_t h, const char *rulename, ilb_comm_t **rbuf,
189*dbed73cbSSangeeta Misra     size_t *rbufsz)
190*dbed73cbSSangeeta Misra {
191*dbed73cbSSangeeta Misra 	ilb_status_t	rc;
192*dbed73cbSSangeeta Misra 	ilb_comm_t	*ic, *tmp_rbuf;
193*dbed73cbSSangeeta Misra 	size_t		ic_sz;
194*dbed73cbSSangeeta Misra 
195*dbed73cbSSangeeta Misra 	if ((ic = i_ilb_alloc_req(ILBD_GET_HC_SRVS, &ic_sz)) == NULL)
196*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
197*dbed73cbSSangeeta Misra 	*rbufsz = ILBD_MSG_SIZE;
198*dbed73cbSSangeeta Misra 	if ((tmp_rbuf = malloc(*rbufsz)) == NULL) {
199*dbed73cbSSangeeta Misra 		free(ic);
200*dbed73cbSSangeeta Misra 		return (ILB_STATUS_ENOMEM);
201*dbed73cbSSangeeta Misra 	}
202*dbed73cbSSangeeta Misra 
203*dbed73cbSSangeeta Misra 	(void) strlcpy((char *)&ic->ic_data, rulename,
204*dbed73cbSSangeeta Misra 	    sizeof (ilbd_name_t));
205*dbed73cbSSangeeta Misra 
206*dbed73cbSSangeeta Misra 	rc = i_ilb_do_comm(h, ic, ic_sz, tmp_rbuf, rbufsz);
207*dbed73cbSSangeeta Misra 	if (rc != ILB_STATUS_OK)
208*dbed73cbSSangeeta Misra 		goto out;
209*dbed73cbSSangeeta Misra 
210*dbed73cbSSangeeta Misra 	if (tmp_rbuf->ic_cmd == ILBD_CMD_OK) {
211*dbed73cbSSangeeta Misra 		*rbuf = tmp_rbuf;
212*dbed73cbSSangeeta Misra 		return (rc);
213*dbed73cbSSangeeta Misra 	}
214*dbed73cbSSangeeta Misra 	rc = *(ilb_status_t *)&tmp_rbuf->ic_data;
215*dbed73cbSSangeeta Misra out:
216*dbed73cbSSangeeta Misra 	free(ic);
217*dbed73cbSSangeeta Misra 	free(tmp_rbuf);
218*dbed73cbSSangeeta Misra 	*rbuf = NULL;
219*dbed73cbSSangeeta Misra 	return (rc);
220*dbed73cbSSangeeta Misra }
221*dbed73cbSSangeeta Misra 
222*dbed73cbSSangeeta Misra ilb_status_t
ilb_walk_hc_srvs(ilb_handle_t h,hc_srvwalkerfunc_t fn,const char * rulename,void * arg)223*dbed73cbSSangeeta Misra ilb_walk_hc_srvs(ilb_handle_t h, hc_srvwalkerfunc_t fn, const char *rulename,
224*dbed73cbSSangeeta Misra     void *arg)
225*dbed73cbSSangeeta Misra {
226*dbed73cbSSangeeta Misra 	ilb_status_t		rc;
227*dbed73cbSSangeeta Misra 	ilb_hc_rule_srv_t	*srvs;
228*dbed73cbSSangeeta Misra 	int			i, j;
229*dbed73cbSSangeeta Misra 	ilb_comm_t		*rbuf;
230*dbed73cbSSangeeta Misra 	size_t			rbufsz;
231*dbed73cbSSangeeta Misra 
232*dbed73cbSSangeeta Misra 	if (rulename != NULL) {
233*dbed73cbSSangeeta Misra 		rc = ilb_get_hc_srvs(h, rulename, &rbuf, &rbufsz);
234*dbed73cbSSangeeta Misra 		if (rc != ILB_STATUS_OK)
235*dbed73cbSSangeeta Misra 			return (rc);
236*dbed73cbSSangeeta Misra 		srvs = (ilb_hc_rule_srv_t *)&rbuf->ic_data;
237*dbed73cbSSangeeta Misra 		for (i = 0; i < srvs->rs_num_srvs; i++) {
238*dbed73cbSSangeeta Misra 			rc = fn(h, &srvs->rs_srvs[i], arg);
239*dbed73cbSSangeeta Misra 			if (rc != ILB_STATUS_OK)
240*dbed73cbSSangeeta Misra 				break;
241*dbed73cbSSangeeta Misra 		}
242*dbed73cbSSangeeta Misra 		free(rbuf);
243*dbed73cbSSangeeta Misra 	} else {
244*dbed73cbSSangeeta Misra 		ilbd_namelist_t *names;
245*dbed73cbSSangeeta Misra 		ilb_comm_t	*srv_rbuf;
246*dbed73cbSSangeeta Misra 		size_t		srv_rbufsz;
247*dbed73cbSSangeeta Misra 
248*dbed73cbSSangeeta Misra 		rc = i_ilb_retrieve_rule_names(h, &rbuf, &rbufsz);
249*dbed73cbSSangeeta Misra 		if (rc != ILB_STATUS_OK)
250*dbed73cbSSangeeta Misra 			return (rc);
251*dbed73cbSSangeeta Misra 		names = (ilbd_namelist_t *)&rbuf->ic_data;
252*dbed73cbSSangeeta Misra 
253*dbed73cbSSangeeta Misra 		for (i = 0; i < names->ilbl_count; i++) {
254*dbed73cbSSangeeta Misra 			rc = ilb_get_hc_srvs(h, names->ilbl_name[i],
255*dbed73cbSSangeeta Misra 			    &srv_rbuf, &srv_rbufsz);
256*dbed73cbSSangeeta Misra 
257*dbed73cbSSangeeta Misra 			/* Not all rules have HC, so reset the error to OK. */
258*dbed73cbSSangeeta Misra 			if (rc == ILB_STATUS_RULE_NO_HC) {
259*dbed73cbSSangeeta Misra 				rc = ILB_STATUS_OK;
260*dbed73cbSSangeeta Misra 				continue;
261*dbed73cbSSangeeta Misra 			} else if (rc != ILB_STATUS_OK) {
262*dbed73cbSSangeeta Misra 				break;
263*dbed73cbSSangeeta Misra 			}
264*dbed73cbSSangeeta Misra 
265*dbed73cbSSangeeta Misra 			srvs = (ilb_hc_rule_srv_t *)&srv_rbuf->ic_data;
266*dbed73cbSSangeeta Misra 			for (j = 0; j < srvs->rs_num_srvs; j++) {
267*dbed73cbSSangeeta Misra 				rc = fn(h, &srvs->rs_srvs[j], arg);
268*dbed73cbSSangeeta Misra 				if (rc != ILB_STATUS_OK)
269*dbed73cbSSangeeta Misra 					break;
270*dbed73cbSSangeeta Misra 			}
271*dbed73cbSSangeeta Misra 			free(srv_rbuf);
272*dbed73cbSSangeeta Misra 		}
273*dbed73cbSSangeeta Misra 		free(rbuf);
274*dbed73cbSSangeeta Misra 	}
275*dbed73cbSSangeeta Misra 	return (rc);
276*dbed73cbSSangeeta Misra }
277