/* Gate Specific Code -- BEGIN */
/*
 * Copyright 1998-2003 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */
#pragma ident "@(#)xfs_probe.c 1.13 03/10/17 SMI"

/* Gate Specific Code -- END */
/* Sun Cluster Data Services Builder template version 1.0 */
/*
 * xfs_probe.c - Probe for XFS
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <rgm/libdsdev.h>
#include <sys/types.h>
#include "xfs.h"

/* GDS Specific Code -- BEGIN */
#include "gds_eventlog.h"
/* GDS Specific Code -- END */

/* User added code -- BEGIN vvvvvvvvvvvvvvv */
/* User added code -- END   ^^^^^^^^^^^^^^^ */

/* Network aware applications code -- BEGIN */
/*
 * Now probe all netaddresses we use (through svc_probe),
 * and record the result in the failure history of the
 * application resource (through scds_fm_action).
 */
void
probe_all_network_addresses(scds_handle_t scds_handle, int timeout,
    scds_netaddr_list_t *netaddr)
{
	char *hostname;
	int		port, ip, probe_result;
	hrtime_t	ht1, ht2;
	unsigned long	dt;

	for (ip = 0; ip < netaddr->num_netaddrs; ip++) {
		/*
		 * Grab the hostname and port on which the
		 * health has to be monitored.
		 */
		hostname = netaddr->netaddrs[ip].hostname;
		port = netaddr->netaddrs[ip].port_proto.port;
		ht1 = gethrtime(); /* Latch probe start time */

		/* User added code -- BEGIN vvvvvvvvvvvvvvv */
		/* User added code -- END   ^^^^^^^^^^^^^^^ */

		probe_result = svc_probe_network_aware(scds_handle,
		    hostname, port, timeout);

		ht2 = gethrtime();

		/* Convert to milliseconds */
		dt = (ht2 - ht1) / 1e6;

		/* User added code -- BEGIN vvvvvvvvvvvvvvv */
		/* User added code -- END   ^^^^^^^^^^^^^^^ */

		/*
		 * Compute failure history and take action if needed
		 */
		(void) scds_fm_action(scds_handle, probe_result, dt);
	}	/* Each netaddr */
}
/* Network aware applications code -- END */

int
main(int argc, char *argv[])
{
	scds_handle_t	scds_handle;
	scha_err_t 	rc;
	int		timeout, probe_result;
	/* GDS Specific Code -- BEGIN */
	boolean_t 	network_aware = B_TRUE;
	scha_extprop_value_t *network_aware_prop = NULL;
	/* GDS Specific Code -- END */
	/* Network aware applications code -- BEGIN */
	scds_netaddr_list_t *netaddr;
	/* Network aware applications code -- END */

	/* User added code -- BEGIN vvvvvvvvvvvvvvv */
	/* User added code -- END   ^^^^^^^^^^^^^^^ */

	if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
		return (1);

	/*
	 * Get the timeout from the extension props.
	 */
	timeout = scds_get_ext_probe_timeout(scds_handle);

	/* GDS Specific Code -- BEGIN */
	rc = scds_get_ext_property(scds_handle, "network_aware",
	    SCHA_PTYPE_BOOLEAN, &network_aware_prop);

	if (rc == SCHA_ERR_NOERR) {
		network_aware = network_aware_prop->val.val_boolean;
		scds_syslog(LOG_INFO,
		    "Extension property <network_aware> has a value "
		    "of <%d>", network_aware);
	} else {
		scds_syslog(LOG_INFO,
		    "Either extension property <network_aware> is not "
		    "defined, or an error occured while retrieving this "
		    "property; using the default value of TRUE.");
	}

	/*
	 * If the service is non-network aware, there is no need to retrieve
	 * the network addresses. Hence, jump straight to doing probing.
	 */
	if (!network_aware)
		goto do_probe;
	/* GDS Specific Code -- END */

	/* Network aware applications code -- BEGIN */
	/* Get the ip addresses available for this resource */
	if (scds_get_netaddr_list(scds_handle, &netaddr)) {
		scds_syslog(LOG_ERR,
		    "No network address resource in resource group.");
		scds_close(&scds_handle);
		return (1);
	}

	/* Return an error if there are no network resources */
	if (netaddr == NULL || netaddr->num_netaddrs == 0) {
		scds_syslog(LOG_ERR,
		    "No network address resource in resource group.");
		return (1);
	}
	/* Network aware applications code -- END */
	/* User added code -- BEGIN vvvvvvvvvvvvvvv */
	/* User added code -- END   ^^^^^^^^^^^^^^^ */

/* GDS Specific Code -- BEGIN */
do_probe:
	(int)gds_publish_eventlog(GDS_PROBE, GDS_LOG_INFO, scds_handle,
	    "The GDS monitor (gds_probe) has been started");
/* GDS Specific Code -- END */

	for (;;) {
		/*
		 * sleep for a duration of thorough_probe_interval between
		 * successive probes.
		 */
		scds_fm_sleep(scds_handle,
		    scds_get_rs_thorough_probe_interval(scds_handle));

		probe_result = 0;
		/* GDS Specific Code -- BEGIN */
		if (network_aware) {
		/* GDS Specific Code -- END */
			/* Network aware applications code -- BEGIN */
		probe_all_network_addresses(scds_handle, timeout, netaddr);
			/* Network aware applications code -- END */
		/* GDS Specific Code -- BEGIN */
		} else {
		/* GDS Specific Code -- END */
		/* Stand alone applications code -- BEGIN */
		probe_result = svc_probe_non_network_aware(scds_handle,
		    timeout);
		(void) scds_fm_action(scds_handle, probe_result, 0);
		/* Stand alone applications code -- END */
		/* GDS Specific Code -- BEGIN */
		}
		(int)gds_publish_eventlog(GDS_PROBE, GDS_LOG_INFO, scds_handle,
		    "The probe result is %d", probe_result);
/* GDS Specific Code -- END */

	} 	/* Keep probing forever */
}
