ha/service-mgmt/sm/src/sm_api.c

772 lines
26 KiB
C

//
// Copyright (c) 2014-2023 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include "sm_api.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <glib.h>
#include "sm_types.h"
#include "sm_debug.h"
#include "sm_list.h"
#include "sm_timer.h"
#include "sm_selobj.h"
#define SM_API_MSG_SERVER_ADDRESS "/tmp/.sm_server_api"
#define SM_API_MSG_CLIENT_ADDRESS "/tmp/.sm_client_api"
#define SM_API_MSG_VERSION "1"
#define SM_API_MSG_REVISION "1"
#define SM_API_MSG_TYPE_SET_NODE "SET_NODE"
#define SM_API_MSG_TYPE_SET_NODE_ACK "SET_NODE_ACK"
#define SM_API_MSG_TYPE_RESTART_SERVICE "RESTART_SERVICE"
#define SM_API_MSG_SKIP_DEP_CHECK "skip-dep"
#define SM_API_MSG_TYPE_PROVISION_SERVICE "PROVISION_SERVICE"
#define SM_API_MSG_TYPE_DEPROVISION_SERVICE "DEPROVISION_SERVICE"
#define SM_API_MSG_TYPE_PROVISION_SERVICE_DOMAIN_INTERFACE "PROVISION_SERVICE_DOMAIN_INTERFACE"
#define SM_API_MSG_TYPE_DEPROVISION_SERVICE_DOMAIN_INTERFACE "DEPROVISION_SERVICE_DOMAIN_INTERFACE"
#define SM_API_MSG_NODE_ACTION_UNKNOWN "unknown"
#define SM_API_MSG_NODE_ACTION_LOCK "lock"
#define SM_API_MSG_NODE_ACTION_UNLOCK "unlock"
#define SM_API_MSG_NODE_ACTION_SWACT "swact"
#define SM_API_MSG_NODE_ACTION_SWACT_FORCE "swact-force"
#define SM_API_MSG_NODE_ACTION_EVENT "event"
#define SM_API_MSG_NODE_ADMIN_STATE_UNKNOWN "unknown"
#define SM_API_MSG_NODE_ADMIN_STATE_LOCKED "locked"
#define SM_API_MSG_NODE_ADMIN_STATE_UNLOCKED "unlocked"
#define SM_API_MSG_NODE_OPER_STATE_UNKNOWN "unknown"
#define SM_API_MSG_NODE_OPER_STATE_ENABLED "enabled"
#define SM_API_MSG_NODE_OPER_STATE_DISABLED "disabled"
#define SM_API_MSG_NODE_AVAIL_STATUS_UNKNOWN "unknown"
#define SM_API_MSG_NODE_AVAIL_STATUS_NONE "none"
#define SM_API_MSG_NODE_AVAIL_STATUS_AVAILABLE "available"
#define SM_API_MSG_NODE_AVAIL_STATUS_DEGRADED "degraded"
#define SM_API_MSG_NODE_AVAIL_STATUS_FAILED "failed"
#define SM_API_MSG_VERSION_FIELD 0
#define SM_API_MSG_REVISION_FIELD 1
#define SM_API_MSG_SEQNO_FIELD 2
#define SM_API_MSG_TYPE_FIELD 3
#define SM_API_MSG_ORIGIN_FIELD 4
#define SM_API_MSG_NODE_NAME_FIELD 5
#define SM_API_MSG_NODE_ACTION_FIELD 6
#define SM_API_MSG_NODE_ADMIN_FIELD 7
#define SM_API_MSG_NODE_OPER_FIELD 8
#define SM_API_MSG_NODE_AVAIL_FIELD 9
#define SM_API_MSG_SERVICE_NAME_FIELD 5
// The service domain interface provision / deprovision msg is at the same
// message offset as the service name field.
#define SM_API_MSG_SERVICE_DOMAIN_NAME_FIELD 5
#define SM_API_MSG_PARAM 6
#define SM_API_MAX_MSG_SIZE 2048
static int _sm_api_socket = -1;
static struct sockaddr_un _sm_api_client_address = {0};
static socklen_t _sm_api_client_address_len = 0;
static char _tx_buffer[SM_API_MAX_MSG_SIZE] __attribute__((aligned));
static char _rx_buffer[SM_API_MAX_MSG_SIZE] __attribute__((aligned));
static SmApiCallbacksT _callbacks = {0};
// ****************************************************************************
// API - Register Callbacks
// ========================
SmErrorT sm_api_register_callbacks( SmApiCallbacksT* callbacks )
{
memcpy( &_callbacks, callbacks, sizeof(SmApiCallbacksT) );
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// API - Deregister Callbacks
// ==========================
SmErrorT sm_api_deregister_callbacks( SmApiCallbacksT* callbacks )
{
memset( &_callbacks, 0, sizeof(SmApiCallbacksT) );
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// API - Node Set Action String
// ============================
static const char* sm_api_node_action_string( SmNodeSetActionT action )
{
switch( action )
{
case SM_NODE_SET_ACTION_LOCK:
return( SM_API_MSG_NODE_ACTION_LOCK );
break;
case SM_NODE_SET_ACTION_UNLOCK:
return( SM_API_MSG_NODE_ACTION_UNLOCK );
break;
case SM_NODE_SET_ACTION_SWACT:
return( SM_API_MSG_NODE_ACTION_SWACT );
break;
case SM_NODE_SET_ACTION_SWACT_FORCE:
return( SM_API_MSG_NODE_ACTION_SWACT_FORCE );
break;
case SM_NODE_SET_ACTION_EVENT:
return( SM_API_MSG_NODE_ACTION_EVENT );
break;
default:
return( SM_API_MSG_NODE_ACTION_UNKNOWN );
break;
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Set Action Value
// ===========================
static SmNodeSetActionT sm_api_node_action_value( const char* action_str )
{
if( 0 == strcmp( SM_API_MSG_NODE_ACTION_LOCK, action_str ) )
{
return( SM_NODE_SET_ACTION_LOCK );
} else if( 0 == strcmp( SM_API_MSG_NODE_ACTION_UNLOCK, action_str ) ) {
return( SM_NODE_SET_ACTION_UNLOCK );
} else if( 0 == strcmp( SM_API_MSG_NODE_ACTION_SWACT, action_str ) ) {
return( SM_NODE_SET_ACTION_SWACT );
} else if( 0 == strcmp( SM_API_MSG_NODE_ACTION_SWACT_FORCE, action_str ) ) {
return( SM_NODE_SET_ACTION_SWACT_FORCE );
} else if( 0 == strcmp( SM_API_MSG_NODE_ACTION_EVENT, action_str ) ) {
return( SM_NODE_SET_ACTION_EVENT );
} else {
return( SM_NODE_SET_ACTION_UNKNOWN );
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Administrative State String
// ======================================
static const char* sm_api_node_admin_state_string(
SmNodeAdminStateT admin_state )
{
switch( admin_state )
{
case SM_NODE_ADMIN_STATE_LOCKED:
return( SM_API_MSG_NODE_ADMIN_STATE_LOCKED );
break;
case SM_NODE_ADMIN_STATE_UNLOCKED:
return( SM_API_MSG_NODE_ADMIN_STATE_UNLOCKED );
break;
default:
return( SM_API_MSG_NODE_ADMIN_STATE_UNKNOWN );
break;
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Administrative State Value
// =====================================
static SmNodeAdminStateT sm_api_node_admin_state_value(
const char* state_str )
{
if( 0 == strcmp( SM_API_MSG_NODE_ADMIN_STATE_LOCKED, state_str ) )
{
return( SM_NODE_ADMIN_STATE_LOCKED );
} else if( 0 == strcmp( SM_API_MSG_NODE_ADMIN_STATE_UNLOCKED,
state_str ) )
{
return( SM_NODE_ADMIN_STATE_UNLOCKED );
} else {
return( SM_NODE_ADMIN_STATE_UNKNOWN );
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Operational State String
// ===================================
static const char* sm_api_node_oper_state_string(
SmNodeOperationalStateT oper_state )
{
switch( oper_state )
{
case SM_NODE_OPERATIONAL_STATE_ENABLED:
return( SM_API_MSG_NODE_OPER_STATE_ENABLED );
break;
case SM_NODE_OPERATIONAL_STATE_DISABLED:
return( SM_API_MSG_NODE_OPER_STATE_DISABLED );
break;
default:
return( SM_API_MSG_NODE_OPER_STATE_UNKNOWN );
break;
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Operational State Value
// ==================================
static SmNodeOperationalStateT sm_api_node_oper_state_value(
const char* state_str )
{
if( 0 == strcmp( SM_API_MSG_NODE_OPER_STATE_ENABLED, state_str ) )
{
return( SM_NODE_OPERATIONAL_STATE_ENABLED );
} else if( 0 == strcmp( SM_API_MSG_NODE_OPER_STATE_DISABLED,
state_str ) )
{
return( SM_NODE_OPERATIONAL_STATE_DISABLED );
} else {
return( SM_NODE_OPERATIONAL_STATE_UNKNOWN );
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Availability Status String
// =====================================
static const char* sm_api_node_avail_status_string(
SmNodeAvailStatusT avail_status )
{
switch( avail_status )
{
case SM_NODE_AVAIL_STATUS_NONE:
return( SM_API_MSG_NODE_AVAIL_STATUS_NONE );
break;
case SM_NODE_AVAIL_STATUS_AVAILABLE:
return( SM_API_MSG_NODE_AVAIL_STATUS_AVAILABLE );
break;
case SM_NODE_AVAIL_STATUS_DEGRADED:
return( SM_API_MSG_NODE_AVAIL_STATUS_DEGRADED );
break;
case SM_NODE_AVAIL_STATUS_FAILED:
return( SM_API_MSG_NODE_AVAIL_STATUS_FAILED );
break;
default:
return( SM_API_MSG_NODE_AVAIL_STATUS_UNKNOWN );
break;
}
}
// ****************************************************************************
// ****************************************************************************
// API - Node Availability Status Value
// ====================================
static SmNodeAvailStatusT sm_api_node_avail_status_value(
const char* state_str )
{
if( 0 == strcmp( SM_API_MSG_NODE_AVAIL_STATUS_NONE, state_str ) )
{
return( SM_NODE_AVAIL_STATUS_NONE );
} else if( 0 == strcmp( SM_API_MSG_NODE_AVAIL_STATUS_AVAILABLE,
state_str ) )
{
return( SM_NODE_AVAIL_STATUS_AVAILABLE );
} else if( 0 == strcmp( SM_API_MSG_NODE_AVAIL_STATUS_DEGRADED,
state_str ) )
{
return( SM_NODE_AVAIL_STATUS_DEGRADED );
} else if( 0 == strcmp( SM_API_MSG_NODE_AVAIL_STATUS_FAILED,
state_str ) )
{
return( SM_NODE_AVAIL_STATUS_FAILED );
} else {
return( SM_NODE_AVAIL_STATUS_UNKNOWN );
}
}
// ****************************************************************************
// ****************************************************************************
// API - Send Node Set
// ===================
SmErrorT sm_api_send_node_set( char node_name[], SmNodeSetActionT action,
SmNodeAdminStateT admin_state, SmNodeOperationalStateT oper_state,
SmNodeAvailStatusT avail_status, int seqno )
{
const char* action_str = sm_api_node_action_string(action);
const char* admin_state_str = sm_api_node_admin_state_string(admin_state);
const char* oper_state_str = sm_api_node_oper_state_string(oper_state);
const char* avail_status_str = sm_api_node_avail_status_string(avail_status);
int bytes_written;
memset( _tx_buffer, 0, sizeof(_tx_buffer) );
bytes_written = snprintf( _tx_buffer, sizeof(_tx_buffer),
"%s,%s,%i,%s,%s,%s,%s,%s,%s,%s",
SM_API_MSG_VERSION, SM_API_MSG_REVISION,
seqno, SM_API_MSG_TYPE_SET_NODE, "sm",
node_name, action_str, admin_state_str,
oper_state_str, avail_status_str );
if( 0 < bytes_written )
{
if( 0 > sendto( _sm_api_socket, &_tx_buffer, bytes_written, 0,
(struct sockaddr*) &_sm_api_client_address,
_sm_api_client_address_len ) )
{
DPRINTFE( "Failed to send node (%s) set, error=%s",
node_name, strerror( errno ) );
return( SM_FAILED );
}
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// API - Send Node Set Ack
// =======================
SmErrorT sm_api_send_node_set_ack( char node_name[], SmNodeSetActionT action,
SmNodeAdminStateT admin_state, SmNodeOperationalStateT oper_state,
SmNodeAvailStatusT avail_status, int seqno )
{
const char* action_str = sm_api_node_action_string(action);
const char* admin_state_str = sm_api_node_admin_state_string(admin_state);
const char* oper_state_str = sm_api_node_oper_state_string(oper_state);
const char* avail_status_str = sm_api_node_avail_status_string(avail_status);
int bytes_written;
memset( _tx_buffer, 0, sizeof(_tx_buffer) );
bytes_written = snprintf( _tx_buffer, sizeof(_tx_buffer),
"%s,%s,%i,%s,%s,%s,%s,%s,%s,%s",
SM_API_MSG_VERSION, SM_API_MSG_REVISION,
seqno, SM_API_MSG_TYPE_SET_NODE_ACK, "sm",
node_name, action_str, admin_state_str,
oper_state_str, avail_status_str );
if( 0 < bytes_written )
{
if( 0 > sendto( _sm_api_socket, &_tx_buffer, bytes_written, 0,
(struct sockaddr*) &_sm_api_client_address,
_sm_api_client_address_len ) )
{
DPRINTFE( "Failed to send node (%s) set ack, error=%s",
node_name, strerror( errno ) );
return( SM_FAILED );
}
}
return( SM_OKAY );
}
// ****************************************************************************
// ****************************************************************************
// API - Dispatch
// ==============
static void sm_api_dispatch( int selobj, int64_t user_data )
{
int seqno;
char* node_name;
char* service_name;
char* service_group_name;
char* service_domain;
char* service_domain_interface;
gchar** params;
int bytes_read;
SmNodeSetActionT action;
SmNodeAdminStateT admin_state;
SmNodeOperationalStateT oper_state;
SmNodeAvailStatusT avail_status;
int action_flag = 0;
int retry_count;
for( retry_count = 5; retry_count != 0; --retry_count )
{
memset( _rx_buffer, 0, sizeof(_rx_buffer) );
bytes_read = recv( selobj, &_rx_buffer, sizeof(_rx_buffer), 0 );
if( 0 < bytes_read )
{
break;
} else if( 0 == bytes_read ) {
// For connection oriented sockets, this indicates that the peer
// has performed an orderly shutdown.
return;
} else if(( 0 > bytes_read )&&( EINTR != errno )) {
DPRINTFE( "Failed to receive message, errno=%s.",
strerror( errno ) );
return;
}
DPRINTFD( "Interrupted while receiving message, retry=%d, errno=%s.",
retry_count, strerror( errno ) );
}
params = g_strsplit( _rx_buffer, ",", -1 );
if( params[SM_API_MSG_VERSION_FIELD] == NULL )
{
DPRINTFE( "Missing version field in received message." );
goto ERROR;
}
if( 0 != strcmp( SM_API_MSG_VERSION, params[SM_API_MSG_VERSION_FIELD] ) )
{
DPRINTFE( "Unsupported version (%s) received, expected=%s.",
params[SM_API_MSG_VERSION_FIELD], SM_API_MSG_VERSION );
goto ERROR;
}
if( params[SM_API_MSG_REVISION_FIELD] == NULL )
{
DPRINTFE( "Missing revision field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_SEQNO_FIELD] == NULL )
{
DPRINTFE( "Missing seqno field in received message." );
goto ERROR;
}
seqno = atoi( params[SM_API_MSG_SEQNO_FIELD] );
if( params[SM_API_MSG_TYPE_FIELD] == NULL )
{
DPRINTFE( "Missing message-type field in received message." );
goto ERROR;
}
if( 0 == strcmp( SM_API_MSG_TYPE_SET_NODE, params[SM_API_MSG_TYPE_FIELD] ) )
{
if( params[SM_API_MSG_ORIGIN_FIELD] == NULL )
{
DPRINTFE( "Missing origin field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_NODE_NAME_FIELD] == NULL )
{
DPRINTFE( "Missing node-name field in received message." );
goto ERROR;
}
node_name = (char*) params[SM_API_MSG_NODE_NAME_FIELD];
if( params[SM_API_MSG_NODE_ACTION_FIELD] == NULL )
{
DPRINTFE( "Missing node-action field in received message." );
goto ERROR;
}
action = sm_api_node_action_value(
(char*) params[SM_API_MSG_NODE_ACTION_FIELD]);
if( params[SM_API_MSG_NODE_ADMIN_FIELD] == NULL )
{
DPRINTFE( "Missing node-admin-state field in received message." );
goto ERROR;
}
admin_state = sm_api_node_admin_state_value(
(char*) params[SM_API_MSG_NODE_ADMIN_FIELD]);
if( params[SM_API_MSG_NODE_OPER_FIELD] == NULL )
{
DPRINTFE( "Missing node-oper-state field in received message." );
goto ERROR;
}
oper_state = sm_api_node_oper_state_value(
(char*) params[SM_API_MSG_NODE_OPER_FIELD]);
if( params[SM_API_MSG_NODE_AVAIL_FIELD] == NULL )
{
DPRINTFE( "Missing node-avail-status field in received message." );
goto ERROR;
}
avail_status = sm_api_node_avail_status_value(
(char*) params[SM_API_MSG_NODE_AVAIL_FIELD]);
if( NULL != _callbacks.node_set )
{
_callbacks.node_set( node_name, action, admin_state, oper_state,
avail_status, seqno );
}
}
else if( 0 == strcmp( SM_API_MSG_TYPE_RESTART_SERVICE,
params[SM_API_MSG_TYPE_FIELD] ) )
{
if( params[SM_API_MSG_ORIGIN_FIELD] == NULL )
{
DPRINTFE( "Missing origin field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_SERVICE_NAME_FIELD] == NULL )
{
DPRINTFE( "Missing service-name field in received message." );
goto ERROR;
}
service_name = (char*) params[SM_API_MSG_SERVICE_NAME_FIELD];
if ( params[SM_API_MSG_PARAM] != NULL &&
0 == strcmp( SM_API_MSG_SKIP_DEP_CHECK, params[SM_API_MSG_PARAM]) )
{
DPRINTFI( "Confirm restart-safe request is received." );
action_flag = SM_SVC_RESTART_NO_DEP;
}else
{
action_flag = 0;
}
if( NULL != _callbacks.service_restart )
{
_callbacks.service_restart( service_name, seqno, action_flag);
}
}
else if( 0 == strcmp( SM_API_MSG_TYPE_PROVISION_SERVICE,
params[SM_API_MSG_TYPE_FIELD] ) )
{
if( params[SM_API_MSG_ORIGIN_FIELD] == NULL )
{
DPRINTFE( "Missing origin field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_SERVICE_NAME_FIELD] == NULL )
{
DPRINTFE( "Missing service-name field in received message." );
goto ERROR;
}
service_name = (char*) params[SM_API_MSG_SERVICE_NAME_FIELD];
service_group_name = (char*) params[SM_API_MSG_PARAM];
if ( NULL == service_group_name )
{
DPRINTFE( "Missing service group name parameter." );
goto ERROR;
}else
{
DPRINTFI("Provision service %s:%s", service_group_name, service_name);
}
if( NULL != _callbacks.provision_service )
{
_callbacks.provision_service( service_group_name, service_name, seqno);
}
}
else if( 0 == strcmp( SM_API_MSG_TYPE_DEPROVISION_SERVICE,
params[SM_API_MSG_TYPE_FIELD] ) )
{
if( params[SM_API_MSG_ORIGIN_FIELD] == NULL )
{
DPRINTFE( "Missing origin field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_SERVICE_NAME_FIELD] == NULL )
{
DPRINTFE( "Missing service-name field in received message." );
goto ERROR;
}
service_name = (char*) params[SM_API_MSG_SERVICE_NAME_FIELD];
service_group_name = (char*) params[SM_API_MSG_PARAM];
if ( NULL == service_group_name )
{
DPRINTFE( "Missing service group name parameter." );
goto ERROR;
}else
{
DPRINTFI("Deprovision service %s:%s", service_group_name, service_name);
}
if( NULL != _callbacks.deprovision_service )
{
_callbacks.deprovision_service( service_group_name, service_name, seqno);
}
}
else if( 0 == strcmp( SM_API_MSG_TYPE_PROVISION_SERVICE_DOMAIN_INTERFACE,
params[SM_API_MSG_TYPE_FIELD] ) )
{
if( params[SM_API_MSG_ORIGIN_FIELD] == NULL )
{
DPRINTFE( "Missing origin field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_SERVICE_DOMAIN_NAME_FIELD] == NULL )
{
DPRINTFE( "Missing service-domain field in received message." );
goto ERROR;
}
service_domain = (char*) params[SM_API_MSG_SERVICE_DOMAIN_NAME_FIELD];
service_domain_interface = (char*) params[SM_API_MSG_PARAM];
if ( NULL == service_domain_interface )
{
DPRINTFE( "Missing service domain interface parameter." );
goto ERROR;
}
else
{
DPRINTFI( "Provision service domain interface %s:%s",
service_domain, service_domain_interface);
}
if( NULL != _callbacks.provision_service_domain_interface )
{
_callbacks.provision_service_domain_interface( service_domain, service_domain_interface, seqno);
}
}
else if( 0 == strcmp( SM_API_MSG_TYPE_DEPROVISION_SERVICE_DOMAIN_INTERFACE,
params[SM_API_MSG_TYPE_FIELD] ) )
{
if( params[SM_API_MSG_ORIGIN_FIELD] == NULL )
{
DPRINTFE( "Missing origin field in received message." );
goto ERROR;
}
if( params[SM_API_MSG_SERVICE_DOMAIN_NAME_FIELD] == NULL )
{
DPRINTFE( "Missing service-domain field in received message." );
goto ERROR;
}
service_domain = (char*) params[SM_API_MSG_SERVICE_DOMAIN_NAME_FIELD];
service_domain_interface = (char*) params[SM_API_MSG_PARAM];
if ( NULL == service_domain_interface )
{
DPRINTFE( "Missing service domain interface parameter." );
goto ERROR;
}
else
{
DPRINTFI( "Deprovision service domain interface %s:%s",
service_domain, service_domain_interface);
}
if( NULL != _callbacks.deprovision_service_domain_interface )
{
_callbacks.deprovision_service_domain_interface( service_domain, service_domain_interface, seqno);
}
} else {
DPRINTFE( "Unknown/unsupported message-type (%s) received.",
params[SM_API_MSG_TYPE_FIELD] );
goto ERROR;
}
g_strfreev( params );
return;
ERROR:
g_strfreev( params );
return;
}
// ***************************************************************************
// ***************************************************************************
// API - Initialize
// ================
SmErrorT sm_api_initialize( void )
{
int sock;
socklen_t len;
struct sockaddr_un src_addr;
struct sockaddr_un client_addr;
int result;
SmErrorT error;
memset( &src_addr, 0, sizeof(src_addr) );
src_addr.sun_family = AF_UNIX;
snprintf( src_addr.sun_path, sizeof(src_addr.sun_path),
SM_API_MSG_SERVER_ADDRESS );
sock = socket( AF_LOCAL, SOCK_DGRAM, 0 );
if( 0 > sock )
{
DPRINTFE( "Failed to create socket for sm-api, error=%s.",
strerror( errno ) );
return( SM_FAILED );
}
unlink( src_addr.sun_path );
len = strlen(src_addr.sun_path) + sizeof(src_addr.sun_family);
result = bind( sock, (struct sockaddr *) &src_addr, len );
if( 0 > result )
{
DPRINTFE( "Failed to bind address (%s) to socket for sm-api, "
"error=%s.", src_addr.sun_path, strerror( errno ) );
close( sock );
return( SM_FAILED );
}
memset( &client_addr, 0, sizeof(client_addr) );
client_addr.sun_family = AF_UNIX;
snprintf( client_addr.sun_path, sizeof(client_addr.sun_path),
SM_API_MSG_CLIENT_ADDRESS );
len = strlen(client_addr.sun_path) + sizeof(client_addr.sun_family);
_sm_api_socket = sock;
_sm_api_client_address = client_addr;
_sm_api_client_address_len = len;
error = sm_selobj_register( _sm_api_socket, sm_api_dispatch, 0 );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to register selection object, error=%s.",
sm_error_str( error ) );
return( error );
}
return( SM_OKAY );
}
// ***************************************************************************
// ***************************************************************************
// API - Finalize
// ==============
SmErrorT sm_api_finalize( void )
{
SmErrorT error;
memset( &_callbacks, 0, sizeof(_callbacks) );
if( -1 < _sm_api_socket )
{
error = sm_selobj_deregister( _sm_api_socket );
if( SM_OKAY != error )
{
DPRINTFE( "Failed to deregister selection object, error=%s.",
sm_error_str( error ) );
}
}
return( SM_OKAY );
}
// ***************************************************************************