Handling provision/deprovision request

Handle provision/deprovision request
To provision a service
1. load service and service group member records
2. reload service dependency table
3. schedule new provisioned service to proper state

To deprovision a service
1. deregister all monitor timers
2. remove the service and service group member records
3. reload service dependency table
4. deregister service process monitor

Story: 2005486
Task: 30621

Depends-on: https://review.opendev.org/#/c/653749/
Depends-on: https://review.opendev.org/#/c/653783/

Change-Id: Ib6a49da31e2e50e8e1175e39c34d04d333616f9d
Signed-off-by: Bin Qian <bin.qian@windriver.com>
This commit is contained in:
Bin Qian 2019-04-25 14:53:50 -04:00
parent 64bb6f60cf
commit 7d35e10e2c
6 changed files with 315 additions and 3 deletions

View File

@ -117,6 +117,7 @@ SRCS+=sm_service_domain_interface_not_in_use_state.c
SRCS+=sm_configuration_table.c
SRCS+=sm_failover_utils.c
SRCS+=sm_cluster_hbs_info_msg.cpp
SRCS+=sm_configure.cpp
OBJS= $(SRCS:.c=.o)
CCFLAGS= -g -O2 -Wall -Werror -Wformat -std=c++11

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
// Copyright (c) 2014-2019 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
@ -30,6 +30,9 @@
#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_NODE_ACTION_UNKNOWN "unknown"
#define SM_API_MSG_NODE_ACTION_LOCK "lock"
@ -375,6 +378,7 @@ static void sm_api_dispatch( int selobj, int64_t user_data )
int seqno;
char* node_name;
char* service_name;
char* service_group_name;
gchar** params;
int bytes_read;
SmNodeSetActionT action;
@ -530,6 +534,70 @@ static void sm_api_dispatch( int selobj, int64_t user_data )
{
_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 {
DPRINTFE( "Unknown/unsupported message-type (%s) received.",
params[SM_API_MSG_TYPE_FIELD] );

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
// Copyright (c) 2014-2019 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
@ -31,10 +31,18 @@ typedef void (*SmApiNodeSetCallbackT) ( char node_name[],
typedef void (*SmApiServiceRestartCallbackT) ( char service_name[],
int seqno, int flag );
typedef void (*SmApiProvisionServiceCallbackT) (char service_group_name[],
char service_name[], int seqno);
typedef void (*SmApiDeprovisionServiceCallbackT) (char service_group_name[],
char service_name[], int seqno);
typedef struct
{
SmApiNodeSetCallbackT node_set;
SmApiServiceRestartCallbackT service_restart;
SmApiProvisionServiceCallbackT provision_service;
SmApiDeprovisionServiceCallbackT deprovision_service;
} SmApiCallbacksT;
// ****************************************************************************

View File

@ -0,0 +1,186 @@
//
// Copyright (c) 2019 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include "sm_configure.h"
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "sm_types.h"
#include "sm_debug.h"
#include "sm_node_api.h"
#include "sm_service_group_member_table.h"
#include "sm_service_table.h"
#include "sm_service_dependency_table.h"
#include "sm_service_api.h"
#include "sm_service_domain_assignment_table.h"
#include "sm_timer.h"
#include "sm_service_fsm.h"
// The behavior of a service is configured in multiple (>1) service groups has
// not been defined (no use case identified). Currently all services are
// configured in one service group per domain. Therefore if a service group member
// shall always be in the same provisioned state as the corresponding service.
// TODO: to remove the provisioned column in services table
// services table should refer to (join) service_group_members table for provisioned status
// ****************************************************************************
// sm configure: provision service
// ================================
extern SmErrorT sm_provision_service( char service_group_name[], char service_name[] )
{
SmErrorT error;
SmServiceDomainAssignmentT* sdm;
char hostname[SM_NODE_NAME_MAX_CHAR];
char domain[] = "controller";
DPRINTFI("Start provisioning %s:%s...", service_group_name, service_name);
error = sm_node_api_get_hostname( hostname );
if(SM_OKAY != error)
{
DPRINTFE("Failed to get hostname");
return error;
}
sdm = sm_service_domain_assignment_table_read(domain, hostname, service_group_name);
if(NULL == sdm)
{
DPRINTFE("Failed to get service domain assignment controller:%s@%s", service_group_name, hostname);
return SM_NOT_FOUND;
}
error = sm_service_group_member_provision(service_group_name, service_name);
if(SM_OKAY != error)
{
DPRINTFE("Failed to provision service group member %s:%s", service_group_name, service_name);
return error;
}
error = sm_service_provision(service_name);
if(SM_OKAY != error)
{
DPRINTFE("Failed to provision service %s", service_name);
return error;
}
error = sm_service_dependency_table_load();
if(SM_OKAY != error)
{
DPRINTFE("Failed to reload service dependency");
return error;
}
switch(sdm->desired_state)
{
case SM_SERVICE_GROUP_STATE_ACTIVE:
error = sm_service_api_go_active(service_name);
break;
case SM_SERVICE_GROUP_STATE_STANDBY:
error = sm_service_api_go_standby(service_name);
break;
case SM_SERVICE_GROUP_STATE_DISABLED:
error = sm_service_api_disable(service_name);
break;
default:
error = SM_FAILED;
DPRINTFE("Unexpected service domain assignment desired state %s",
sm_service_group_state_str(sdm->desired_state));
}
if(SM_OKAY != error)
{
DPRINTFE("Failed to set service state");
return error;
}
error = sm_service_api_audit(service_name);
if(SM_OKAY != error)
{
DPRINTFE("Failed to audit service %s. Error %s", service_name, sm_error_str(error));
return error;
}
DPRINTFI("%s:%s is provisioned successfully", service_group_name, service_name);
return SM_OKAY;
}
// ****************************************************************************
void static stop_all_service_timers(SmServiceT& service)
{
SmTimerIdT* timers[] = {
&service.fail_countdown_timer_id,
&service.audit_timer_id,
&service.action_timer_id,
&service.action_state_timer_id,
&service.pid_file_audit_timer_id
};
SmTimerIdT* timer;
for(unsigned int i = 0; i < sizeof(timers) / sizeof(SmTimerIdT*); i++)
{
timer = timers[i];
if( SM_TIMER_ID_INVALID != *timer )
{
sm_timer_deregister(*timer);
*timer = SM_TIMER_ID_INVALID;
}
}
}
// ****************************************************************************
// sm configure: deprovision service
// ===============================
SmErrorT sm_deprovision_service( char service_group_name[], char service_name[] )
{
SmErrorT error;
DPRINTFI("Start deprovisioning %s:%s ...", service_group_name, service_name);
SmServiceT* service = sm_service_table_read(service_name);
if(NULL == service)
{
DPRINTFI("Service %s not found, already deprovisioned?", service_name);
return SM_OKAY;
}
stop_all_service_timers(*service);
error = sm_service_deprovision(service_name);
if(SM_OKAY != error)
{
DPRINTFE("Failed to deprovision service %s", service_name);
return error;
}
error = sm_service_group_member_deprovision(service_group_name, service_name);
if(SM_OKAY != error)
{
DPRINTFE("Failed to deprovision service group member %s:%s", service_group_name, service_name);
return error;
}
error = sm_service_dependency_table_load();
if(SM_OKAY != error)
{
DPRINTFE("Failed to reload service dependency");
return error;
}
error = sm_service_fsm_process_failure_deregister(service);
if(SM_OKAY != error)
{
// By not able to deregister the process monitor routine, there will be an error log
// nothing will go wrong. So log and continue as success
DPRINTFE("Failed to deregister process failure monitor for service %s", service_name);
}
DPRINTFI("%s:%s is deprovisioned successfully", service_group_name, service_name);
return SM_OKAY;
}
// ****************************************************************************

View File

@ -0,0 +1,32 @@
//
// Copyright (c) 2019 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef __SM_CONFIGURE_H__
#define __SM_CONFIGURE_H__
#include "sm_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// ****************************************************************************
// system config: provision service
// ================================
extern SmErrorT sm_provision_service( char service_group_name[], char service_name[] );
// ****************************************************************************
// ****************************************************************************
// system config: deprovision service
// ===============================
extern SmErrorT sm_deprovision_service( char service_group_name[], char service_name[] );
// ****************************************************************************
#ifdef __cplusplus
}
#endif
#endif // __SM_CONFIGURE_H__

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
// Copyright (c) 2014-2019 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
@ -27,6 +27,7 @@
#include "sm_failover.h"
#include "sm_node_swact_monitor.h"
#include "sm_failover_fsm.h"
#include "sm_configure.h"
#define SM_NODE_AUDIT_TIMER_IN_MS 1000
#define SM_INTERFACE_AUDIT_TIMER_IN_MS 1000
@ -240,6 +241,18 @@ static void sm_main_event_handler_api_service_restart_callback(
}
// ****************************************************************************
static void sm_main_event_handler_api_provision_service_callback(
char service_group_name[], char service_name[], int seqno )
{
sm_provision_service(service_group_name, service_name);
}
static void sm_main_event_handler_api_deprovision_service_callback(
char service_group_name[], char service_name[], int seqno )
{
sm_deprovision_service(service_group_name, service_name);
}
// ****************************************************************************
// Main Event Handler - Notify API Service Event Callback
// ======================================================
@ -374,6 +387,10 @@ SmErrorT sm_main_event_handler_initialize( void )
= sm_main_event_handler_api_node_set_callback;
_api_callbacks.service_restart
= sm_main_event_handler_api_service_restart_callback;
_api_callbacks.provision_service
= sm_main_event_handler_api_provision_service_callback;
_api_callbacks.deprovision_service
= sm_main_event_handler_api_deprovision_service_callback;
error = sm_api_register_callbacks( &_api_callbacks );
if( SM_OKAY != error )