Go to main content

Developing Data Services

Exit Print View

Updated: August 2018

xfnts_start Method

The RGM runs the Start method on a cluster node when the resource group that contains the data service resource is brought online on that node or when the resource is enabled. In the ORCL.xfnts sample resource type, the xfnts_start method activates the xfs daemon on that node.

The xfnts_start method calls scds_pmf_start() to start the daemon under the PMF. The PMF provides automatic failure notification and restart features, as well as integration with the fault monitor.

Note - The first call in xfnts_start is to scds_initialize(), which performs some necessary housekeeping functions. scds_initialize Function and the scds_initialize(3HA) man page contain more information.

Validating the Service Before Starting the X Font Server

Before the xfnts_start method attempts to start the X Font Server, it calls svc_validate() to verify that a correct configuration is in place to support the xfs daemon.

rc = svc_validate(scds_handle);
if (rc != 0) {
"Failed to validate configuration.");
return (rc);

See xfnts_validate Method for details.

Starting the Service With svc_start()

The xfnts_start method calls the svc_start() method, which is defined in the xfnts.c file, to start the xfs daemon. This section describes svc_start().

The command to start the xfs daemon is as follows:

# xfs -config config-directory/fontserver.cfg -port port-number

The Confdir_list extension property identifies the config-directory while the Port_list system property identifies the port-number. The cluster administrator provides specific values for these properties when he or she configures the data service.

The xfnts_start method declares these properties as string arrays. The xfnts_start method obtains the values that the cluster administrator sets by using the scds_get_ext_confdir_list() and scds_get_port_list() functions. These functions are described in the scds_property_functions(3HA) man page.

scha_str_array_t *confdirs;
scds_port_list_t    *portlist;
scha_err_t   err;

/* get the configuration directory from the confdir_list property */
confdirs = scds_get_ext_confdir_list(scds_handle);

(void) sprintf(xfnts_conf, "%s/fontserver.cfg", confdirs->str_array[0]);

/* obtain the port to be used by XFS from the Port_list property */
err = scds_get_port_list(scds_handle, &portlist);
if (err != SCHA_ERR_NOERR) {
"Could not access property Port_list.");
return (1);

Note that the confdirs variable points to the first element (0) of the array.

The xfnts_start method uses sprintf() to form the command line for xfs.

/* Construct the command to start the xfs daemon. */
(void) sprintf(cmd,
"/usr/bin/xfs -config %s -port %d 2>/dev/null",
xfnts_conf, portlist->ports[0].port);

Note that the output is redirected to /dev/null to suppress messages that are generated by the daemon.

The xfnts_start method passes the xfs command line to scds_pmf_start() to start the data service under the control of the PMF.

scds_syslog(LOG_INFO, "Issuing a start request.");
err = scds_pmf_start(scds_handle, SCDS_PMF_TYPE_SVC,

if (err == SCHA_ERR_NOERR) {
"Start command completed successfully.");
} else {
"Failed to start HA-XFS ");

    Note the following points about the call to scds_pmf_start():

  • The SCDS_PMF_TYPE_SVC argument identifies the program to start as a data service application. This method can also start a fault monitor or some other type of application.

  • The SCDS_PMF_SINGLE_INSTANCE argument identifies this as a single-instance resource.

  • The cmd argument is the command line that was generated previously.

  • The final argument, -1, specifies the child monitoring level. The -1 value specifies that the PMF monitor all children as well as the original process.

Before returning, svc_pmf_start() frees the memory that is allocated for the portlist structure.

return (err);

Returning From svc_start()

Even when svc_start() returns successfully, the underlying application might have failed to start. Therefore, svc_start() must probe the application to verify that it is running before returning a success message. The probe must also take into account that the application might not be immediately available because it takes some time to start. The svc_start() method calls svc_wait(), which is defined in the xfnts.c file, to verify that the application is running.

/* Wait for the service to start up fully */
"Calling svc_wait to verify that service has started.");

rc = svc_wait(scds_handle);

"Returned from svc_wait");

if (rc == 0) {
scds_syslog(LOG_INFO, "Successfully started the service.");
} else {
scds_syslog(LOG_ERR, "Failed to start the service.");

The svc_wait() function calls scds_get_netaddr_list() to obtain the network address resources that are needed to probe the application.

/* obtain the network resource to use for probing */
if (scds_get_netaddr_list(scds_handle, &netaddr)) {
"No network address resources found in resource group.");
return (1);

/* Return an error if there are no network resources */
if (netaddr == NULL || netaddr->num_netaddrs == 0) {
"No network address resource in resource group.");
return (1);

The svc_wait() function obtains the Start_timeout and Stop_timeout values.

svc_start_timeout = scds_get_rs_start_timeout(scds_handle)
probe_timeout = scds_get_ext_probe_timeout(scds_handle)

To account for the time the server might take to start, svc_wait() calls scds_svc_wait() and passes a timeout value equivalent to three percent of the Start_timeout value. The svc_wait() function calls the svc_probe() function to verify that the application has started. The svc_probe() method makes a simple socket connection to the server on the specified port. If it fails to connect to the port, svc_probe() returns a value of 100, which indicates a total failure. If the connect goes through but the disconnect to the port fails, svc_probe() returns a value of 50.

On failure or partial failure of svc_probe(), svc_wait() calls scds_svc_wait() with a timeout value of 5. The scds_svc_wait() method limits the frequency of the probes to every five seconds. This method also counts the number of attempts to start the service. If the number of attempts exceeds the value of the Retry_count property of the resource within the period that is specified by the Retry_interval property of the resource, the scds_svc_wait() function returns failure. In this case, the svc_start() function also returns failure.

#define    SVC_CONNECT_TIMEOUT_PCT    95
#define    SVC_WAIT_PCT       3
if (scds_svc_wait(scds_handle, (svc_start_timeout * SVC_WAIT_PCT)/100)

scds_syslog(LOG_ERR, "Service failed to start.");
return (1);

do {
* probe the data service on the IP address of the
* network resource and the portname
rc = svc_probe(scds_handle,
netaddr->netaddrs[0].port_proto.port, probe_timeout);
if (rc == SCHA_ERR_NOERR) {
/* Success. Free up resources and return */
return (0);

/* Call scds_svc_wait() so that if service fails too
if (scds_svc_wait(scds_handle, SVC_WAIT_TIME)
scds_syslog(LOG_ERR, "Service failed to start.");
return (1);

/* Rely on RGM to timeout and terminate the program */
} while (1);

Note - Before it exits, the xfnts_start method calls scds_close() to reclaim resources that are allocated by scds_initialize(). scds_initialize Function and the scds_close(3HA) man page contain more information.