Refactoring of AMF into several files (based on classed in inf.

model). A central header file (amf.h) keeps all the definitions and
prototypes needed.

New things apart from that:
- some doxygen html generated from AMF e.g. each file has a description
- saAmfHAStateGet() now works
- component invoked healthchecks implemented (but not tested)



git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1071 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
Hans Feldt 2006-06-20 06:45:16 +00:00
parent b0c735ee64
commit e993689ac5
15 changed files with 4034 additions and 2752 deletions

View File

@ -49,7 +49,7 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = lib include
INPUT = lib include exec
FILE_PATTERNS = *.c *.h
RECURSIVE = YES
EXAMPLE_PATH =

View File

@ -48,9 +48,13 @@ TOTEM_SRC = aispoll.c totemip.c totemnet.c totemrrp.c totemsrp.c totemmrp.c tote
TOTEM_OBJS = aispoll.o totemip.o totemnet.o totemrrp.o totemsrp.o totemmrp.o totempg.o crypto.o wthread.o
EXEC_LIBS = libtotem_pg.a
# AMF objects
AMF_SRC = amf.c amfutil.c amfnode.c amfcluster.c amfapp.c amfsg.c amfsu.c amfcomp.c amfsi.c
AMF_OBJS = amf.o amfutil.o amfnode.o amfcluster.o amfapp.o amfsg.o amfsu.o amfcomp.o amfsi.o
# LCR objects
LCR_SRC = evs.c clm.c amf.c ckpt.c evt.c lck.c msg.c cfg.c cpg.c amfconfig.c aisparser.c vsf_ykd.c
LCR_OBJS = evs.o clm.o amf.o ckpt.o evt.o lck.o msg.o cfg.o cpg.o amfconfig.o aisparser.o vsf_ykd.o
LCR_SRC = evs.c clm.c ckpt.c evt.c lck.c msg.c cfg.c cpg.c aisparser.c vsf_ykd.c $(AMF_SRC)
LCR_OBJS = evs.o clm.o ckpt.o evt.o lck.o msg.o cfg.o cpg.o aisparser.o vsf_ykd.o $(AMF_OBJS)
# main executive objects
MAIN_SRC = main.c print.c mempool.c util.c sync.c service.c ipc.c timer.c \
@ -83,8 +87,8 @@ service_evs.lcrso: evs.o
service_clm.lcrso: clm.o
$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load clm.o -o $@
service_amf.lcrso: amf.o amfconfig.o
$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load amf.o amfconfig.o -o $@
service_amf.lcrso: $(AMF_OBJS)
$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load $(AMF_OBJS) -o $@
service_ckpt.lcrso: ckpt.o
$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load ckpt.o -o $@
@ -122,8 +126,8 @@ service_evs.lcrso: evs.o
service_clm.lcrso: clm.o
$(CC) -shared -Wl,-soname,service_clm.lcrso clm.o -o $@
service_amf.lcrso: amf.o amfconfig.o
$(CC) -shared -Wl,-soname,service_amf.lcrso amf.o amfconfig.o -o $@
service_amf.lcrso: $(AMF_OBJS)
$(CC) -shared -Wl,-soname,service_amf.lcrso $(AMF_OBJS) -o $@
service_ckpt.lcrso: ckpt.o
$(CC) -shared -Wl,-soname,service_ckpt.lcrso ckpt.o -o $@
@ -274,24 +278,19 @@ totempg.o: totemmrp.h swab.h
tlist.o: ../include/list.h tlist.h
crypto.o: crypto.h
wthread.o: wthread.h ../include/queue.h
evs.o: ../include/saAis.h ../include/ipc_gen.h ../exec/totemip.h
evs.o: ../include/ipc_evs.h ../include/saAis.h ../include/evs.h
evs.o: ../include/ipc_gen.h ../include/list.h ../include/queue.h
evs.o: ../lcr/lcr_comp.h aispoll.h totempg.h totemsrp.h totem.h totemip.h
evs.o: totem.h totemip.h ../include/saAis.h ../include/ipc_gen.h
evs.o: ../exec/totemip.h ../include/ipc_evs.h ../include/saAis.h
evs.o: ../include/evs.h ../include/ipc_gen.h ../include/list.h
evs.o: ../include/queue.h ../lcr/lcr_comp.h aispoll.h totempg.h totemsrp.h
evs.o: main.h ../include/saClm.h mainconfig.h objdb.h mempool.h service.h
evs.o: print.h
clm.o: ../include/saAis.h ../include/saClm.h ../include/saAis.h
clm.o: ../include/ipc_gen.h ../exec/totemip.h ../include/ipc_clm.h
clm.o: ../include/saClm.h ../include/ipc_gen.h ../include/list.h
clm.o: ../include/queue.h ../lcr/lcr_comp.h aispoll.h totempg.h totemsrp.h
clm.o: totem.h totemip.h main.h mainconfig.h objdb.h mempool.h service.h
clm.o: print.h
amf.o: ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amf.o: ../include/ipc_gen.h ../exec/totemip.h ../include/ipc_amf.h
amf.o: ../include/ipc_gen.h ../include/ais_amf.h ../include/list.h
amf.o: ../include/queue.h ../lcr/lcr_comp.h totempg.h aispoll.h totemsrp.h
amf.o: totem.h totemip.h mempool.h util.h amfconfig.h main.h
amf.o: ../include/saClm.h mainconfig.h objdb.h service.h print.h
clm.o: totem.h totemip.h ../include/saAis.h ../include/saClm.h
clm.o: ../include/saAis.h ../include/ipc_gen.h ../exec/totemip.h
clm.o: ../include/ipc_clm.h ../include/saClm.h ../include/ipc_gen.h
clm.o: ../include/mar_clm.h ../include/mar_gen.h ../include/mar_gen.h
clm.o: ../include/mar_clm.h ../include/list.h ../include/queue.h
clm.o: ../lcr/lcr_comp.h aispoll.h totempg.h totemsrp.h main.h mainconfig.h
clm.o: objdb.h mempool.h service.h swab.h print.h
ckpt.o: ../include/saAis.h ../include/saCkpt.h ../include/ipc_ckpt.h
ckpt.o: ../include/saAis.h ../include/saCkpt.h ../include/ipc_gen.h
ckpt.o: ../include/list.h ../include/queue.h ../include/hdb.h
@ -327,12 +326,46 @@ cpg.o: ../include/ipc_gen.h ../exec/totemip.h ../include/ipc_cpg.h
cpg.o: ../include/ipc_gen.h ../include/list.h ../include/queue.h
cpg.o: ../lcr/lcr_comp.h aispoll.h totempg.h totemsrp.h totem.h totemip.h
cpg.o: main.h mainconfig.h objdb.h mempool.h service.h jhash.h swab.h print.h
amfconfig.o: ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amfconfig.o: ../include/ipc_amf.h ../include/ipc_gen.h ../include/ais_amf.h
amfconfig.o: ../include/list.h util.h amfconfig.h aispoll.h mempool.h totem.h
amfconfig.o: totemip.h
aisparser.o: ../lcr/lcr_comp.h objdb.h config.h mempool.h ../include/list.h
aisparser.o: util.h ../include/saAis.h
vsf_ykd.o: main.h ../include/saAis.h ../include/saClm.h ../include/saAis.h
vsf_ykd.o: ../include/queue.h ../include/ipc_gen.h ../exec/totemip.h
vsf_ykd.o: mainconfig.h ../include/list.h aispoll.h totemsrp.h totem.h
vsf_ykd.o: totemip.h totempg.h objdb.h print.h swab.h vsf.h ../lcr/lcr_comp.h
amf.o: ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amf.o: ../include/ipc_gen.h ../exec/totemip.h ../include/ipc_amf.h
amf.o: ../include/ipc_gen.h ../include/ais_amf.h ../include/list.h
amf.o: ../lcr/lcr_comp.h totempg.h aispoll.h totemsrp.h totem.h totemip.h
amf.o: mempool.h util.h amf.h objdb.h main.h ../include/saClm.h
amf.o: ../include/queue.h mainconfig.h service.h print.h
amfutil.o: ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amfutil.o: ../include/ipc_amf.h ../include/ipc_gen.h ../include/ais_amf.h
amfutil.o: ../include/list.h util.h amf.h ../include/ipc_gen.h
amfutil.o: ../exec/totemip.h aispoll.h objdb.h totem.h totemip.h print.h
amfutil.o: mainconfig.h totemsrp.h totempg.h
amfcluster.o: print.h mainconfig.h ../include/saAis.h ../include/list.h
amfcluster.o: aispoll.h totemsrp.h totem.h totemip.h totempg.h objdb.h amf.h
amfcluster.o: ../include/saAmf.h ../include/saAis.h ../include/ipc_gen.h
amfcluster.o: ../exec/totemip.h util.h main.h ../include/saClm.h
amfcluster.o: ../include/queue.h
amfapp.o: amf.h ../include/saAis.h ../include/saAmf.h
amfapp.o: ../include/saAis.h ../include/list.h ../include/ipc_gen.h
amfapp.o: ../exec/totemip.h aispoll.h objdb.h print.h mainconfig.h
amfapp.o: totemsrp.h totem.h totemip.h totempg.h
amfsg.o: amf.h ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amfsg.o: ../include/list.h ../include/ipc_gen.h ../exec/totemip.h aispoll.h
amfsg.o: objdb.h print.h mainconfig.h totemsrp.h totem.h totemip.h totempg.h
amfsg.o: main.h ../include/saClm.h ../include/queue.h
amfsu.o: amf.h ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amfsu.o: ../include/list.h ../include/ipc_gen.h ../exec/totemip.h aispoll.h
amfsu.o: objdb.h util.h print.h mainconfig.h totemsrp.h totem.h totemip.h
amfsu.o: totempg.h main.h ../include/saClm.h ../include/queue.h
amfcomp.o: ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amfcomp.o: ../include/ipc_gen.h ../exec/totemip.h ../include/ipc_amf.h
amfcomp.o: ../include/ipc_gen.h ../include/ais_amf.h totempg.h aispoll.h
amfcomp.o: totemsrp.h totem.h totemip.h main.h ../include/saClm.h
amfcomp.o: ../include/queue.h mainconfig.h ../include/list.h objdb.h
amfcomp.o: service.h util.h amf.h print.h
amfsi.o: amf.h ../include/saAis.h ../include/saAmf.h ../include/saAis.h
amfsi.o: ../include/list.h ../include/ipc_gen.h ../exec/totemip.h aispoll.h
amfsi.o: objdb.h print.h mainconfig.h totemsrp.h totem.h totemip.h totempg.h

2453
exec/amf.c

File diff suppressed because it is too large Load Diff

679
exec/amf.h Normal file
View File

@ -0,0 +1,679 @@
/*
* Copyright (c) 2002-2005 MontaVista Software, Inc.
* Author: Steven Dake (sdake@mvista.com)
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* Description: - Reworked to match AMF B.02 information model
* - New state machine design
*
* All rights reserved.
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AMF_H_DEFINED
#define AMF_H_DEFINED
#include <limits.h>
#include "../include/saAis.h"
#include "../include/saAmf.h"
#include "../include/list.h"
#include "../include/ipc_gen.h"
#include "aispoll.h"
#include "objdb.h"
enum escalation_levels {
ESCALATION_LEVEL_NO_ESCALATION = 1, /* execute component restart */
ESCALATION_LEVEL_ONE = 2, /* escalate to service unit restart */
ESCALATION_LEVEL_TWO = 3, /* escalate to service unit failover */
ESCALATION_LEVEL_THREE = 4 /* escalate to node failover */
};
enum clc_component_types {
clc_component_sa_aware = 0, /* sa aware */
clc_component_proxied_pre = 1, /* proxied, pre-instantiable */
clc_component_proxied_non_pre = 2, /* proxied, non pre-instantiable */
clc_component_non_proxied_non_sa_aware = 3 /* non-proxied, non sa aware */
};
struct amf_si_assignment;
struct amf_csi_assignment;
struct amf_healthcheck;
struct amf_cluster {
/* Configuration Attributes */
SaNameT name;
int saAmfClusterStartupTimeout;
SaNameT saAmfClusterClmCluster;
/* Runtime Attributes */
SaAmfAdminStateT saAmfClusterAdminState;
/* Relations */
struct amf_node *node_head;
struct amf_application *application_head;
/* Implementation */
poll_timer_handle timeout_handle;
};
struct amf_node {
/* Configuration Attributes */
SaNameT name;
SaNameT saAmfNodeClmNode;
int saAmfNodeSuFailOverProb;
SaUint32T saAmfNodeSuFailoverMax;
SaBoolT saAmfNodeAutoRepair;
SaBoolT saAmfNodeRebootOnInstantiationFailure;
SaBoolT saAmfNodeRebootOnTerminationFailure;
/* Runtime Attributes */
SaAmfAdminStateT saAmfNodeAdminState;
SaAmfOperationalStateT saAmfNodeOperState;
/* Relations */
struct amf_cluster *cluster;
/* Implementation */
struct amf_node *next;
};
struct amf_application {
/* Configuration Attributes */
SaNameT name;
/* Runtime Attributes */
SaAmfAdminStateT saAmfApplicationAdminState;
SaUint32T saAmfApplicationCurrNumSG;
/* Relations */
struct amf_cluster *cluster;
struct amf_sg *sg_head;
struct amf_si *si_head;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
struct amf_application *next;
};
struct amf_sg {
/* Configuration Attributes */
SaNameT name;
saAmfRedundancyModelT saAmfSGRedundancyModel;
SaBoolT saAmfSGAutoAdjust;
SaUint32T saAmfSGNumPrefActiveSUs;
SaUint32T saAmfSGNumPrefStandbySUs;
SaUint32T saAmfSGNumPrefInserviceSUs;
SaUint32T saAmfSGNumPrefAssignedSUs;
SaUint32T saAmfSGMaxActiveSIsperSUs;
SaUint32T saAmfSGMaxStandbySIsperSUs;
SaTimeT saAmfSGCompRestartProb;
SaUint32T saAmfSGCompRestartMax;
SaTimeT saAmfSGSuRestartProb;
SaUint32T saAmfSGSuRestartMax;
SaTimeT saAmfSGAutoAdjustProb;
SaBoolT saAmfSGAutoRepair;
/* Runtime Attributes */
SaAmfAdminStateT saAmfSGAdminState;
SaUint32T saAmfSGNumCurrAssignedSUs;
SaUint32T saAmfSGNumCurrNonInstantiatedSpareSUs;
SaUint32T saAmfSGNumCurrInstantiatedSpareSUs;
/* Relations */
struct amf_application *application;
struct amf_su *su_head;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
struct amf_sg *next;
};
struct amf_su {
/* Configuration Attributes */
SaNameT name;
SaUint32T saAmfSURank;
SaUint32T saAmfSUNumComponents;
SaBoolT saAmfSUIsExternal;
SaBoolT saAmfSUFailover;
/* Runtime Attributes */
SaBoolT saAmfSUPreInstantiable;
SaAmfOperationalStateT saAmfSUOperState;
SaAmfAdminStateT saAmfSUAdminState;
SaAmfReadinessStateT saAmfSUReadinessState;
SaAmfPresenceStateT saAmfSUPresenceState;
SaNameT saAmfSUAssignedSIs;
SaNameT saAmfSUHostedByNode;
SaUint32T saAmfSUNumCurrActiveSIs;
SaUint32T saAmfSUNumCurrStandbySIs;
SaUint32T saAmfSURestartCount;
/* Relations */
struct amf_sg *sg;
struct amf_comp *comp_head;
struct amf_si_assignment *assigned_sis;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
SaUint32T su_failover_cnt; /* missing in SAF specs? */
enum escalation_levels escalation_level;
struct amf_su *next;
};
struct amf_comp {
/* Configuration Attributes */
SaNameT name;
SaNameT **saAmfCompCsTypes;
saAmfCompCategoryT saAmfCompCategory;
saAmfCompCapabilityModelT saAmfCompCapability;
SaUint32T saAmfCompNumMaxActiveCsi;
SaUint32T saAmfCompNumMaxStandbyCsi;
SaStringT *saAmfCompCmdEnv;
int saAmfCompDefaultClcCliTimeout;
int saAmfCompDefaultCallbackTimeOut;
SaStringT saAmfCompInstantiateCmd;
SaStringT saAmfCompInstantiateCmdArgv;
int saAmfCompInstantiateTimeout;
SaUint32T saAmfCompInstantiationLevel;
SaUint32T saAmfCompNumMaxInstantiateWithoutDelay;
SaUint32T saAmfCompNumMaxInstantiateWithDelay;
int saAmfCompDelayBetweenInstantiateAttempts;
SaStringT saAmfCompTerminateCmd;
int saAmfCompTerminateTimeout;
SaStringT saAmfCompTerminateCmdArgv;
SaStringT saAmfCompCleanupCmd;
int saAmfCompCleanupTimeout;
SaStringT saAmfCompCleanupCmdArgv;
SaStringT saAmfCompAmStartCmd;
int saAmfCompAmStartTimeout;
SaStringT saAmfCompAmStartCmdArgv;
SaUint32T saAmfCompNumMaxAmStartAttempt;
SaStringT saAmfCompAmStopCmd;
int saAmfCompAmStopTimeout;
SaStringT saAmfCompAmStopCmdArgv;
SaUint32T saAmfCompNumMaxAmStopAttempt;
int saAmfCompTerminateCallbackTimeout;
int saAmfCompCSISetCallbackTimeout;
int saAmfCompQuiescingCompleteTimeout;
int saAmfCompCSIRmvCallbackTimeout;
SaAmfRecommendedRecoveryT saAmfCompRecoveryOnError;
SaBoolT saAmfCompDisableRestart;
SaNameT saAmfCompProxyCsi;
/* Runtime Attributes */
SaAmfOperationalStateT saAmfCompOperState;
SaAmfReadinessStateT saAmfCompReadinessState;
SaAmfPresenceStateT saAmfCompPresenceState;
SaUint32T saAmfCompRestartCount;
SaUint32T saAmfCompNumCurrActiveCsi;
SaUint32T saAmfCompNumCurrStandbyCsi;
SaNameT saAmfCompAssignedCsi;
SaNameT saAmfCompCurrProxyName;
SaNameT saAmfCompCurrProxiedNames;
/* Relations */
struct amf_comp *proxy_comp;
struct amf_su *su;
struct amf_csi_assignment *assigned_csis;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
struct amf_comp *next;
void *conn;
enum clc_component_types comptype;
struct amf_healthcheck *healthcheck_head;
};
struct amf_healthcheck {
/* Configuration Attributes */
SaAmfHealthcheckKeyT safHealthcheckKey;
int saAmfHealthcheckMaxDuration;
int saAmfHealthcheckPeriod;
/* Relations */
struct amf_comp *comp;
/* Implementation */
struct amf_healthcheck *next;
int active;
SaAmfHealthcheckInvocationT invocationType;
SaAmfRecommendedRecoveryT recommendedRecovery;
poll_timer_handle timer_handle_duration;
poll_timer_handle timer_handle_period;
};
struct amf_si {
/* Configuration Attributes */
SaNameT name;
SaNameT saAmfSIProtectedbySG;
SaUint32T saAmfSIRank;
SaUint32T saAmfSINumCSIs;
SaUint32T saAmfSIPrefActiveAssignments;
SaUint32T saAmfSIPrefStandbyAssignments;
/* Runtime Attributes */
SaAmfAdminStateT saAmfSIAdminState;
SaAmfAssignmentStateT saAmfSIAssignmentState;
SaUint32T saAmfSINumCurrActiveAssignments;
SaUint32T saAmfSINumCurrStandbyAssignments;
/* Relations */
struct amf_application *application;
struct amf_csi *csi_head;
struct amf_si_assignment *si_assignments;
struct amf_si_dependency *depends_on;
struct amf_si_ranked_su *ranked_sus;
/* Implementation */
struct amf_si *next;
};
struct amf_si_ranked_su {
/* Configuration Attributes */
SaNameT name;
SaUint32T saAmfRank;
/* Relations */
struct amf_si *si;
struct amf_su *su;
/* Implementation */
struct amf_si_ranked_su *su_next;
struct amf_si_ranked_su *si_next;
};
struct amf_si_dependency {
/* Configuration Attributes */
SaNameT name;
int saAmfToleranceTime;
/* Relations */
/* Implementation */
struct amf_si_dependency *next;
};
struct amf_si_assignment {
/* Runtime Attributes */
SaNameT name;
SaAmfHAStateT saAmfSISUHAState;
/* Relations */
struct amf_si *si;
/* Implementation */
struct amf_si_assignment *next;
};
struct amf_csi {
/* Configuration Attributes */
SaNameT name;
SaNameT saAmfCSTypeName;
SaNameT **saAmfCSIDependencies;
/* Relations */
struct amf_si *si;
struct amf_csi_assignment *csi_assignments;
struct amf_csi_attribute *attributes_head;
/* Implementation */
struct amf_csi *next;
int pg_set;
};
struct amf_csi_attribute {
/* Configuration Attributes */
SaStringT name;
SaStringT *value;
/* Implementation */
struct amf_csi_attribute *next;
};
struct amf_csi_assignment {
/* Runtime Attributes */
SaNameT name;
SaAmfHAStateT saAmfCSICompHAState; /* confirmed HA state */
/* Relations */
struct amf_csi *csi;
struct amf_comp *comp;
/* Implementation */
SaAmfHAStateT requested_ha_state;
struct amf_csi_assignment *comp_next;
struct amf_csi_assignment *csi_next;
};
enum amf_response_interfaces {
AMF_RESPONSE_HEALTHCHECKCALLBACK = 1,
AMF_RESPONSE_CSISETCALLBACK = 2,
AMF_RESPONSE_CSIREMOVECALLBACK = 3,
AMF_RESPONSE_COMPONENTTERMINATECALLBACK = 4
};
enum amf_message_req_types {
MESSAGE_REQ_EXEC_AMF_COMPONENT_REGISTER = 0,
MESSAGE_REQ_EXEC_AMF_COMPONENT_ERROR_REPORT = 1,
MESSAGE_REQ_EXEC_AMF_CLC_CLEANUP_COMPLETED = 2,
MESSAGE_REQ_EXEC_AMF_HEALTHCHECK_TMO = 3,
MESSAGE_REQ_EXEC_AMF_RESPONSE = 4
};
struct req_exec_amf_clc_cleanup_completed {
struct req_header header;
SaNameT compName;
};
struct req_exec_amf_healthcheck_tmo {
struct req_header header;
SaNameT compName;
SaAmfHealthcheckKeyT safHealthcheckKey;
};
/*===========================================================================*/
/* amfutil.c */
extern int amf_config_read (struct amf_cluster *cluster, char **error_string);
extern char *amf_serialize (struct amf_cluster *cluster);
extern int amf_deserialize (char *buf, struct amf_cluster *cluster);
extern void amf_state_print (struct amf_cluster *cluster);
extern void amf_runtime_attributes_print (struct amf_cluster *cluster);
extern int amf_enabled (struct objdb_iface_ver0 *objdb);
extern int amf_invocation_create (int interface, void *data);
extern int amf_invocation_get_and_destroy (
int invocation, int *interface, void **data);
extern void amf_invocation_destroy_by_data (void *data);
extern const char *amf_admin_state (int state);
extern const char *amf_op_state (int state);
extern const char *amf_presence_state (int state);
extern const char *amf_ha_state (int state);
extern const char *amf_readiness_state (int state);
/*===========================================================================*/
/* amfnode.c */
/* General methods */
extern struct amf_node *amf_node_create (void);
extern int amf_node_serialize (
struct amf_node *node, char **buf, int *offset);
extern struct amf_node *amf_node_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
/* Event methods */
extern void amf_node_sync_ready (struct amf_node *node);
extern void amf_node_leave (struct amf_node *node);
extern void amf_node_failover (struct amf_node *node);
extern void amf_node_switchover (struct amf_node *node);
extern void amf_node_failfast (struct amf_node *node);
extern void amf_node_comp_restart_req (
struct amf_node *node, struct amf_comp *comp);
extern void amf_node_comp_failover_req (
struct amf_node *node, struct amf_comp *comp);
enum amf_reboot_reason {
TERMINATION_FAILED = 1,
INSTANTIATION_FAILED = 2
};
extern int amf_node_reboot (
struct amf_node *node, enum amf_reboot_reason reason);
/* Response event methods */
extern void amf_node_application_started (
struct amf_node *node, struct amf_application *app);
extern void amf_node_application_workload_assigned (
struct amf_node *node, struct amf_application *app);
/* Timer event methods */
extern void timer_function_node_probation_period_expired (void *node);
/*===========================================================================*/
/* amfcluster.c */
/* General methods */
extern void amf_cluster_init (void);
extern int amf_cluster_serialize (
struct amf_cluster *cluster, char **buf, int *offset);
extern struct amf_cluster *amf_cluster_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
/* Event methods */
extern void amf_cluster_start (struct amf_cluster *cluster);
/* Response event methods */
extern void amf_cluster_application_started (
struct amf_cluster *cluster, struct amf_application *app);
extern void amf_cluster_application_workload_assigned (
struct amf_cluster *cluster, struct amf_application *app);
/*===========================================================================*/
/* amfapp.c */
/* General methods */
extern void amf_application_init (void);
extern struct amf_application *amf_application_create (void);
extern int amf_application_calc_and_set_si_dependency_level (
struct amf_application *app);
extern int amf_application_serialize (
struct amf_application *application, char **buf, int *offset);
extern struct amf_application *amf_application_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
extern int amf_application_si_count_get (struct amf_application *app);
/* Event methods */
extern void amf_application_start (
struct amf_application *app, struct amf_node *node);
extern void amf_application_assign_workload (
struct amf_application *app, struct amf_node *node);
/* Response event methods */
extern void amf_application_sg_started (
struct amf_application *app, struct amf_sg *sg, struct amf_node *node);
extern void amf_application_sg_assigned (
struct amf_application *app, struct amf_sg *sg);
/*===========================================================================*/
/* amfsg.c */
/* General methods */
extern void amf_sg_init (void);
extern struct amf_sg *amf_sg_create (void);
extern int amf_sg_serialize (
struct amf_sg *sg, char **buf, int *offset);
extern struct amf_sg *amf_sg_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
/* Event methods */
extern void amf_sg_start (struct amf_sg *sg, struct amf_node *node);
extern void amf_sg_assign_si (struct amf_sg *sg, int dependency_level);
extern void amf_sg_failover_node_req (
struct amf_sg *sg, struct amf_node *node);
extern void amf_sg_failover_su_req (
struct amf_sg *sg, struct amf_node *node);
extern void amf_sg_failover_comp_req (
struct amf_sg *sg, struct amf_node *node);
extern void amf_sg_switchover_node_req (
struct amf_sg *sg, struct amf_node *node);
/* Response event methods */
extern void amf_sg_su_state_changed (
struct amf_sg *sg, struct amf_su *su, SaAmfStateT type, int state);
extern void amf_sg_si_ha_state_changed (
struct amf_sg *sg, struct amf_si *si, int state);
extern void amf_sg_su_assignment_removed (
struct amf_sg *sg, struct amf_su *su);
/* Timer event methods */
//static void timer_function_auto_adjust_tmo (void *sg);
/*===========================================================================*/
/* amfsu.c */
/* General methods */
extern void amf_su_init (void);
extern struct amf_su *amf_su_create (void);
extern int amf_su_serialize (
struct amf_su *su, char **buf, int *offset);
extern struct amf_su *amf_su_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
extern int amf_su_is_local (struct amf_su *su);
/* Event methods */
extern void amf_su_instantiate (struct amf_su *su);
extern void amf_su_assign_si (
struct amf_su *su, struct amf_si *si, SaAmfHAStateT ha_state);
extern void amf_su_restart_req (struct amf_su *su);
extern void amf_su_terminate (struct amf_su *su);
extern struct amf_node *amf_su_get_node (struct amf_su *su);
extern void amf_su_escalation_level_reset (struct amf_su *su);
extern void amf_su_remove_assignment (struct amf_su *su);
/* Response event methods */
extern void amf_su_comp_state_changed (
struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state);
extern void amf_su_comp_hastate_changed (
struct amf_su *su, struct amf_comp *comp,
struct amf_csi_assignment *csi_assignment);
extern void amf_su_comp_error_suspected (
struct amf_su *su,
struct amf_comp *comp,
SaAmfRecommendedRecoveryT recommended_recovery);
/* Timer event methods */
//static void timer_function_su_probation_period_expired(void *data);
/*===========================================================================*/
/* amfcomp.c */
/* General methods */
extern void amf_comp_init (void);
extern struct amf_comp *amf_comp_create (struct amf_su *su);
extern char *amf_comp_dn_make (struct amf_comp *comp, SaNameT *name);
extern struct amf_comp *amf_comp_find (
struct amf_cluster *cluster, SaNameT *name);
extern int amf_comp_serialize (
struct amf_comp *comp, char **buf, int *offset);
extern struct amf_comp *amf_comp_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
/* Event methods */
extern void amf_comp_instantiate (struct amf_comp *comp);
extern void amf_comp_terminate (struct amf_comp *comp);
extern void amf_comp_hastate_set (
struct amf_comp *comp,
struct amf_csi_assignment *csi_assignment,
SaAmfHAStateT requested_ha_state);
extern void amf_comp_restart (struct amf_comp *comp);
extern void amf_comp_operational_state_set (
struct amf_comp *comp, SaAmfOperationalStateT opstate);
extern void amf_comp_readiness_state_set (
struct amf_comp *comp, SaAmfReadinessStateT state);
extern struct amf_healthcheck *amf_comp_find_healthcheck (
struct amf_comp *comp, SaAmfHealthcheckKeyT *key);
extern void amf_comp_healthcheck_tmo (
struct amf_comp *comp, struct amf_healthcheck *healthcheck);
extern void amf_comp_cleanup_completed (struct amf_comp *comp);
/*
* Originates from library
*/
extern SaAisErrorT amf_comp_healthcheck_start (
struct amf_comp *comp,
SaAmfHealthcheckKeyT *healthcheckKey,
SaAmfHealthcheckInvocationT invocationType,
SaAmfRecommendedRecoveryT recommendedRecovery);
extern SaAisErrorT amf_comp_healthcheck_stop (
struct amf_comp *comp,
SaAmfHealthcheckKeyT *healthcheckKey);
extern SaAisErrorT amf_comp_register (struct amf_comp *comp);
extern void amf_comp_unregister (struct amf_comp *comp);
extern void amf_comp_error_report (
struct amf_comp *comp, SaAmfRecommendedRecoveryT recommendedRecovery);
extern int amf_comp_response_1 (
SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval);
extern struct amf_comp *amf_comp_response_2 (
SaInvocationT invocation, SaAisErrorT error, SaAisErrorT *retval);
extern SaAisErrorT amf_comp_hastate_get (
struct amf_comp *comp, SaNameT *csi_name, SaAmfHAStateT *ha_state);
extern SaAisErrorT amf_comp_healthcheck_confirm (
struct amf_comp *comp,
SaAmfHealthcheckKeyT *healthcheckKey,
SaAisErrorT healthcheckResult);
/*===========================================================================*/
/* amfsi.c */
/* General methods */
extern void amf_si_init (void);
extern struct amf_si *amf_si_create (void);
extern int amf_si_calc_and_set_csi_dependency_level (struct amf_si *si);
extern int amf_si_serialize (
struct amf_si *si, char **buf, int *offset);
extern struct amf_si *amf_si_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
/* Event methods */
extern void amf_si_activate (
struct amf_si *si,
void (*activated_callback_fn)(struct amf_si *si, int result));
extern void amf_si_deactivate (
struct amf_si *si,
struct amf_csi *csi,
void (*deactivated_callback_fn)(struct amf_si *si, int result));
extern void amf_si_set_ha_state (
struct amf_si *si,
SaAmfHAStateT ha_state,
void (*set_ha_state_callback_fn)(struct amf_si *si, int result));
/* Response event methods */
extern void amf_si_comp_set_ha_state_done (
struct amf_si *si, struct amf_csi_assignment *csi_assignment);
extern void amf_si_comp_set_ha_state_failed (
struct amf_si *si, struct amf_csi_assignment *csi_assignment);
/* General methods */
extern struct amf_csi *amf_csi_create (void);
extern int amf_csi_serialize (
struct amf_csi *csi, char **buf, int *offset);
extern struct amf_csi *amf_csi_deserialize (
char **buf, int *size, struct amf_cluster *cluster);
extern char *amf_csi_dn_make (struct amf_csi *csi, SaNameT *name);
/*===========================================================================*/
extern struct amf_node *this_amf_node;
extern struct amf_cluster amf_cluster;
#endif /* AMF_H_DEFINED */

113
exec/amfapp.c Normal file
View File

@ -0,0 +1,113 @@
/** @file amfapp.c
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* - Refactoring of code into several AMF files
* Author: Anders Eriksson
*
* All rights reserved.
*
*
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF Application Class implementation
*
* This file contains functions for handling the AMF applications. It can
* be viewed as the implementation of the AMF Application class
* as described in SAI-Overview-B.02.01. The SA Forum specification
* SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
* and is referred to as 'the spec' below.
*
* The functions in this file are responsible for:
* - on request start the service groups it contains
* - on request order the service groups to assign workload to all
* service units contained in the service group, level by level
* - to handle administrative operation support for the application (FUTURE)
*
* The cluster class contains the following state machines:
* - administrative state machine (ADSM)
* - availability control state machine (ACSM)
*
* The administrative state machine will be implemented in the future.
*
* ACSM handles initial start of an application. In the future it will also
* handle administrative commands on the application as described in paragraph
* 7.4 of the spec. ACSM includes two stable states (UNINSTANTIATED and
* STARTED) and a number of states to control the transition between the
* stable states.
*
* The application is in state UNINSTANTIATED when the application starts.
* (In the future this state will also be assumed after the LOCK_INSTANTIATION
* administrative command.)
*
* State STARTED is assumed when the application has been initially started and
* will in the future be re-assumed after the administrative command RESTART
* have been executed.
*
*/
#include "amf.h"
#include "print.h"
int amf_application_si_count_get (struct amf_application *app)
{
struct amf_si *si;
int answer = 0;
for (si = app->si_head; si != NULL; si = si->next) {
answer += 1;
}
return (answer);
}
void amf_application_start (
struct amf_application *app, struct amf_node *node)
{
struct amf_sg *sg;
ENTER ("'%s'", app->name.value);
for (sg = app->sg_head; sg != NULL; sg = sg->next) {
amf_sg_start (sg, node);
}
}
void amf_application_assign_workload (
struct amf_application *app, struct amf_node *node)
{
struct amf_sg *sg;
for (sg = app->sg_head; sg != NULL; sg = sg->next) {
amf_sg_assign_si (sg, 0);
}
}
void amf_application_init (void)
{
log_init ("AMF");
}

123
exec/amfcluster.c Normal file
View File

@ -0,0 +1,123 @@
/** @file amfcluster.c
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* - Refactoring of code into several AMF files
* Author: Anders Eriksson
*
* All rights reserved.
*
*
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF Cluster Class Implementation
*
* This file contains functions for handling the AMF cluster. It can be
* viewed as the implementation of the AMF Cluster class
* as described in SAI-Overview-B.02.01. The SA Forum specification
* SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
* and is referred to as 'the spec' below.
*
* The functions in this file are responsible for:
* - to start the cluster initially
* - to handle the administrative operation support for the cluster (FUTURE)
*
* The cluster class contains the following state machines:
* - administrative state machine (ADSM)
* - availability control state machine (ACSM)
*
* The administrative state machine will be implemented in the future.
*
* ACSM handles initial start of the cluster. In the future it will also handle
* administrative commands on the cluster as described in paragraph 7.4 of the
* spec. ACSM includes two stable states (UNINSTANTIATED and STARTED) and a
* number of states to control the transition between the stable states.
*
* The cluster is in state UNINSTANTIATED when the cluster starts. (In the
* future this state will also be assumed after the LOCK_INSTANTIATION
* administrative command.)
*
* State STARTED is assumed when the cluster has been initially started and
* will in the future be re-assumed after the administrative command RESTART
* have been executed.
*/
#include <stdlib.h>
#include <errno.h>
#include "print.h"
#include "amf.h"
#include "aispoll.h"
#include "util.h"
#include "main.h"
static void timer_function_cluster_assign_workload_tmo (void *_cluster)
{
struct amf_application *app;
struct amf_cluster *cluster = _cluster;
dprintf("2nd Cluster start timer expired, assigning workload to application\n");
for (app = cluster->application_head; app != NULL; app = app->next) {
amf_application_assign_workload (app, this_amf_node);
}
}
static void timer_function_cluster_startup_tmo (void *_cluster)
{
struct amf_cluster *cluster = _cluster;
struct amf_application *app;
dprintf("1st Cluster start timer expired, starting applications");
for (app = cluster->application_head; app != NULL; app = app->next) {
amf_application_start (app, this_amf_node);
}
/* wait a while before assigning workload */
poll_timer_add (aisexec_poll_handle,
cluster->saAmfClusterStartupTimeout,
cluster,
timer_function_cluster_assign_workload_tmo,
&cluster->timeout_handle);
}
void amf_cluster_start (struct amf_cluster *cluster)
{
/* wait a while before starting applications */
poll_timer_add (aisexec_poll_handle,
cluster->saAmfClusterStartupTimeout,
cluster,
timer_function_cluster_startup_tmo,
&cluster->timeout_handle);
}
void amf_cluster_init (void)
{
log_init ("AMF");
}

1521
exec/amfcomp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,378 +0,0 @@
/*
* Copyright (c) 2002-2005 MontaVista Software, Inc.
* Author: Steven Dake (sdake@mvista.com)
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* Description: Reworked to match AMF B.02 information model
*
* All rights reserved.
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <limits.h>
#include "../include/saAis.h"
#include "../include/saAmf.h"
#include "../include/list.h"
#include "aispoll.h"
#ifndef AMFCONFIG_H_DEFINED
#define AMFCONFIG_H_DEFINED
enum escalation_levels {
ESCALATION_LEVEL_NO_ESCALATION = 1, /* execute component restart */
ESCALATION_LEVEL_ONE = 2, /* escalate to service unit restart */
ESCALATION_LEVEL_TWO = 3, /* escalate to service unit failover */
ESCALATION_LEVEL_THREE = 4 /* escalate to node failover */
};
enum clc_component_types {
clc_component_sa_aware = 0, /* sa aware */
clc_component_proxied_pre = 1, /* proxied, pre-instantiable */
clc_component_proxied_non_pre = 2, /* proxied, non pre-instantiable */
clc_component_non_proxied_non_sa_aware = 3 /* non-proxied, non sa aware */
};
struct amf_si_assignment;
struct amf_csi_assignment;
struct amf_healthcheck;
struct amf_cluster {
/* Configuration Attributes */
SaNameT name;
int saAmfClusterStartupTimeout;
SaNameT saAmfClusterClmCluster;
/* Runtime Attributes */
SaAmfAdminStateT saAmfClusterAdminState;
/* Relations */
struct amf_node *node_head;
struct amf_application *application_head;
/* Implementation */
poll_timer_handle timeout_handle;
};
struct amf_node {
/* Configuration Attributes */
SaNameT name;
SaNameT saAmfNodeClmNode;
int saAmfNodeSuFailOverProb;
SaUint32T saAmfNodeSuFailoverMax;
SaBoolT saAmfNodeAutoRepair;
SaBoolT saAmfNodeRebootOnInstantiationFailure;
SaBoolT saAmfNodeRebootOnTerminationFailure;
/* Runtime Attributes */
SaAmfAdminStateT saAmfNodeAdminState;
SaAmfOperationalStateT saAmfNodeOperState;
/* Relations */
struct amf_cluster *cluster;
/* Implementation */
struct amf_node *next;
};
struct amf_application {
/* Configuration Attributes */
SaNameT name;
/* Runtime Attributes */
SaAmfAdminStateT saAmfApplicationAdminState;
SaUint32T saAmfApplicationCurrNumSG;
/* Relations */
struct amf_cluster *cluster;
struct amf_sg *sg_head;
struct amf_si *si_head;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
struct amf_application *next;
};
struct amf_sg {
/* Configuration Attributes */
SaNameT name;
saAmfRedundancyModelT saAmfSGRedundancyModel;
SaBoolT saAmfSGAutoAdjust;
SaUint32T saAmfSGNumPrefActiveSUs;
SaUint32T saAmfSGNumPrefStandbySUs;
SaUint32T saAmfSGNumPrefInserviceSUs;
SaUint32T saAmfSGNumPrefAssignedSUs;
SaUint32T saAmfSGMaxActiveSIsperSUs;
SaUint32T saAmfSGMaxStandbySIsperSUs;
SaTimeT saAmfSGCompRestartProb;
SaUint32T saAmfSGCompRestartMax;
SaTimeT saAmfSGSuRestartProb;
SaUint32T saAmfSGSuRestartMax;
SaTimeT saAmfSGAutoAdjustProb;
SaBoolT saAmfSGAutoRepair;
/* Runtime Attributes */
SaAmfAdminStateT saAmfSGAdminState;
SaUint32T saAmfSGNumCurrAssignedSUs;
SaUint32T saAmfSGNumCurrNonInstantiatedSpareSUs;
SaUint32T saAmfSGNumCurrInstantiatedSpareSUs;
/* Relations */
struct amf_application *application;
struct amf_su *su_head;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
struct amf_sg *next;
};
struct amf_su {
/* Configuration Attributes */
SaNameT name;
SaUint32T saAmfSURank;
SaUint32T saAmfSUNumComponents;
SaBoolT saAmfSUIsExternal;
SaBoolT saAmfSUFailover;
/* Runtime Attributes */
SaBoolT saAmfSUPreInstantiable;
SaAmfOperationalStateT saAmfSUOperState;
SaAmfAdminStateT saAmfSUAdminState;
SaAmfReadinessStateT saAmfSUReadinessState;
SaAmfPresenceStateT saAmfSUPresenceState;
SaNameT saAmfSUAssignedSIs;
SaNameT saAmfSUHostedByNode;
SaUint32T saAmfSUNumCurrActiveSIs;
SaUint32T saAmfSUNumCurrStandbySIs;
SaUint32T saAmfSURestartCount;
/* Relations */
struct amf_sg *sg;
struct amf_comp *comp_head;
struct amf_si_assignment *assigned_sis;
/* Implementation */
int is_local;
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
SaUint32T su_failover_cnt; /* missing in SAF specs? */
enum escalation_levels escalation_level;
struct amf_su *next;
};
struct amf_comp {
/* Configuration Attributes */
SaNameT name;
SaNameT **saAmfCompCsTypes;
saAmfCompCategoryT saAmfCompCategory;
saAmfCompCapabilityModelT saAmfCompCapability;
SaUint32T saAmfCompNumMaxActiveCsi;
SaUint32T saAmfCompNumMaxStandbyCsi;
SaStringT *saAmfCompCmdEnv;
int saAmfCompDefaultClcCliTimeout;
int saAmfCompDefaultCallbackTimeOut;
SaStringT saAmfCompInstantiateCmd;
SaStringT saAmfCompInstantiateCmdArgv;
int saAmfCompInstantiateTimeout;
SaUint32T saAmfCompInstantiationLevel;
SaUint32T saAmfCompNumMaxInstantiateWithoutDelay;
SaUint32T saAmfCompNumMaxInstantiateWithDelay;
int saAmfCompDelayBetweenInstantiateAttempts;
SaStringT saAmfCompTerminateCmd;
int saAmfCompTerminateTimeout;
SaStringT saAmfCompTerminateCmdArgv;
SaStringT saAmfCompCleanupCmd;
int saAmfCompCleanupTimeout;
SaStringT saAmfCompCleanupCmdArgv;
SaStringT saAmfCompAmStartCmd;
int saAmfCompAmStartTimeout;
SaStringT saAmfCompAmStartCmdArgv;
SaUint32T saAmfCompNumMaxAmStartAttempt;
SaStringT saAmfCompAmStopCmd;
int saAmfCompAmStopTimeout;
SaStringT saAmfCompAmStopCmdArgv;
SaUint32T saAmfCompNumMaxAmStopAttempt;
int saAmfCompTerminateCallbackTimeout;
int saAmfCompCSISetCallbackTimeout;
int saAmfCompQuiescingCompleteTimeout;
int saAmfCompCSIRmvCallbackTimeout;
SaAmfRecommendedRecoveryT saAmfCompRecoveryOnError;
SaBoolT saAmfCompDisableRestart;
SaNameT saAmfCompProxyCsi;
/* Runtime Attributes */
SaAmfOperationalStateT saAmfCompOperState;
SaAmfReadinessStateT saAmfCompReadinessState;
SaAmfPresenceStateT saAmfCompPresenceState;
SaUint32T saAmfCompRestartCount;
SaUint32T saAmfCompNumCurrActiveCsi;
SaUint32T saAmfCompNumCurrStandbyCsi;
SaNameT saAmfCompAssignedCsi;
SaNameT saAmfCompCurrProxyName;
SaNameT saAmfCompCurrProxiedNames;
/* Relations */
struct amf_comp *proxy_comp;
struct amf_su *su;
struct amf_csi_assignment *assigned_csis;
/* Implementation */
char clccli_path[PATH_MAX];
char binary_path[PATH_MAX];
struct amf_comp *next;
void *conn;
enum clc_component_types comptype;
struct amf_healthcheck *healthcheck_head;
};
struct amf_healthcheck {
/* Configuration Attributes */
SaAmfHealthcheckKeyT safHealthcheckKey;
int saAmfHealthcheckMaxDuration;
int saAmfHealthcheckPeriod;
/* Relations */
struct amf_comp *comp;
/* Implementation */
struct amf_healthcheck *next;
SaAmfHealthcheckInvocationT invocationType;
poll_timer_handle timer_handle_duration;
poll_timer_handle timer_handle_period;
int active;
};
struct amf_si {
/* Configuration Attributes */
SaNameT name;
SaNameT saAmfSIProtectedbySG;
SaUint32T saAmfSIRank;
SaUint32T saAmfSINumCSIs;
SaUint32T saAmfSIPrefActiveAssignments;
SaUint32T saAmfSIPrefStandbyAssignments;
/* Runtime Attributes */
SaAmfAdminStateT saAmfSIAdminState;
SaAmfAssignmentStateT saAmfSIAssignmentState;
SaUint32T saAmfSINumCurrActiveAssignments;
SaUint32T saAmfSINumCurrStandbyAssignments;
/* Relations */
struct amf_application *application;
struct amf_csi *csi_head;
struct amf_si_assignment *si_assignments;
struct amf_si_dependency *depends_on;
struct amf_si_ranked_su *ranked_sus;
/* Implementation */
struct amf_si *next;
};
struct amf_si_ranked_su {
/* Configuration Attributes */
SaNameT name;
SaUint32T saAmfRank;
/* Relations */
struct amf_si *si;
struct amf_su *su;
/* Implementation */
struct amf_si_ranked_su *su_next;
struct amf_si_ranked_su *si_next;
};
struct amf_si_dependency {
/* Configuration Attributes */
SaNameT name;
int saAmfToleranceTime;
/* Relations */
/* Implementation */
struct amf_si_dependency *next;
};
struct amf_si_assignment {
/* Runtime Attributes */
SaNameT name;
SaAmfHAStateT saAmfSISUHAState;
/* Relations */
struct amf_si *si;
/* Implementation */
struct amf_si_assignment *next;
};
struct amf_csi {
/* Configuration Attributes */
SaNameT name;
SaNameT saAmfCSTypeName;
SaNameT **saAmfCSIDependencies;
/* Relations */
struct amf_si *si;
struct amf_csi_assignment *csi_assignments;
struct amf_csi_attribute *attributes_head;
/* Implementation */
struct amf_csi *next;
int pg_set;
};
struct amf_csi_attribute {
/* Configuration Attributes */
SaStringT name;
SaStringT *value;
/* Implementation */
struct amf_csi_attribute *next;
};
struct amf_csi_assignment {
/* Runtime Attributes */
SaNameT name;
SaAmfHAStateT saAmfCSICompHASate;
/* Relations */
struct amf_csi *csi;
struct amf_comp *comp;
/* Implementation */
struct amf_csi_assignment *comp_next;
struct amf_csi_assignment *csi_next;
};
extern struct amf_comp *amf_find_comp (struct amf_cluster *cluster, SaNameT *name);
extern struct amf_healthcheck *amf_find_healthcheck (struct amf_comp *comp, SaAmfHealthcheckKeyT *key);
extern int amf_config_read (struct amf_cluster *cluster, char **error_string);
#endif /* AMFCONFIG_H_DEFINED */

107
exec/amfnode.c Normal file
View File

@ -0,0 +1,107 @@
/** @file amfnode.c
*
* Copyright (c) 2006 Ericsson AB.
* Author: Anders Eriksson
*
* All rights reserved.
*
*
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF Node Class Implementation
*
* This file contains functions for handling AMF nodes. It can be
* viewed as the implementation of the AMF Node class (called NODE)
* as described in SAI-Overview-B.02.01. The SA Forum specification
* SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
* and is referred to as 'the spec' below.
*
* The functions in this file are responsible for:
* - controlling the instantiation of the SUs hosted on current node and
* controlling the assigning of workload to them when a node joins the
* cluster (cluster start is controlled by the Cluster Class)
* - controlling node level recovery and repair functions
* - implementing error escallation level 2 and 3 (paragraph 3.12.2.2 and
* 3.12.2.3 in the spec)
* - handling run time attributes of the AMF NODE; cached
* attributes are stored as variables and sent to the IMM service (future)
* upon the changes described in the specification
*
* The node class contains the following state machines:
* - administrative state machine (ADSM)
* - operational state machine (OPSM)
* - availability control state machine (ACSM)
*
* The administrative state machine will be implemented in the future.
*
* The operational state machine is primarily used to report status of the
* node.
*
* The availability control state machine is used for control purposes.
* ACSM contains three states of which two are composite.
* Being a composite state means that the state contains substates.
* ACSM states are:
* - REPAIR_NEEDED
* - ESCALLATION_LEVEL (LEVEL_0, LEVEL_2 and LEVEL_3)
* - MANAGING_HOSTED_SERVICE_UNITS (
* . FAILING_FAST (REBOOTING_NODE and ACTIVATING_STANDBY_NODE)
* . FAILING_GRACEFULLY (SWITCHING_OVER, FAILING_OVER and REBOOTING_NODE)
* . LEAVING_SPONTANEOUSLY (DEACTIVATE_DEPENDENT and
* WAITING_FOR_NODE_TO_JOIN)
* . JOINING (STARTING_SERVICE_UNITS, ASSIGNING_ACTIVE_WORKLOAD and
* ASSIGNING_STANDBY_WORKLOAD)
*
* REPAIR_NEEDED indicates the node needs a manual repair and this state will
* maintained until the administrative command REPAIRED is entered
* (implemented in the future)
*
* ESCALLATION_LEVEL is a kind of idle state where no actions are performed
* and used only to remember the escallation level. Substate LEVEL_0 indicates
* no escallation. LEVEL_2 indicates that so many component restarts have been
* executed recently that a new component restart request will escalate
* to service unit restart action. Node will request a service unit restart
* from SU.
* LEVEL_3 will be entered if either there are too many service unit restarts
* been made or a component failover recovery action is requested. On level 3
* the recovery action performed is service unit failover (paragraph 3.12.1.3).
*
* FAILING_FAST state executes a node re-boot and waits for the node to join
* the cluster again.
*
* FAILING_GRACEFULLY state requests all SGs which have SUs hosted on current
* node to switch or failover according to the procedures described in
* paragraphs 3.12.1.3 before re-boot is executed. Then the confirmation is
* awaited from all concerned SGs and finally a node re-boot is executed as
* the repair action (see paragraph 2.12.1.4).
*
* LEAVING_SPONTANEOUSLY state handles the spontaneous leave of a node.
*
* JOINING state handles the start of a node in all cases except cluster start,
* which is handled by the CLUSTER class.
*
*/

422
exec/amfsg.c Normal file
View File

@ -0,0 +1,422 @@
/** @file amfsg.c
*
* Copyright (c) 2002-2006 MontaVista Software, Inc.
* Author: Steven Dake (sdake@mvista.com)
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* - Introduced AMF B.02 information model
* - Use DN in API and multicast messages
* - (Re-)Introduction of event based multicast messages
* - Refactoring of code into several AMF files
* Author: Anders Eriksson
*
* All rights reserved.
*
*
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF Service Group Class Implementation
*
* This file contains functions for handling AMF-service groups(SGs). It can be
* viewed as the implementation of the AMF Service Group class (called SG)
* as described in SAI-Overview-B.02.01. The SA Forum specification
* SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
* and is referred to as 'the spec' below.
*
* The functions in this file are responsible for:
* -on request start the service group by instantiating the contained SUs
* -on request assign the service instances it protects to the in-service
* service units it contains respecting as many as possible of the configured
* requirements for the group
* -create and delete an SI-assignment object for each relation between
* an SI and an SU
* -order each contained SU to create and delete CSI-assignments
* -request the Service Instance class (SI) to execute the transfer of the
* HA-state set/remove requests to each component involved
* -fully control the execution of component failover and SU failover
* -on request control the execution of the initial steps of node switchover
* and node failover
* -fully handle the auto adjust procedure
*
* Currently only the 'n+m' redundancy model is implemented. It is the
* ambition to identify n+m specific variables and functions and add the suffix
* '_nplusm' to them so that they can be easily recognized.
*
* When SG is requested to assign workload to all SUs or all SUs hosted on
* a specific node, a procedure containing several steps is executed:
* <1> An algorithm is executed which assigns SIs to SUs respecting the rules
* that has been configured for SG. The algorithm also has to consider
* if assignments between som SIs and SUs already exist. The scope of this
* algorithm is to create SI-assignments and set up requested HA-state for
* each assignment but not to transfer those HA-states to the components.
* <2> All SI-assignments with a requested HA state == ACTIVE are transferred
* to the components concerned before any STANDBY assignments are
* transferred. All components have to acknowledge the setting of the
* ACTIVE HA state before the transfer of any STANDBY assignment is
* initiated.
* <3> All active assignments can not be transferred at the same time to the
* different components because the rules for dependencies between SI and
* SI application wide and CSI and CSI within one SI, has to be respected.
*
* SG is fully responsible for step <1> but not fully responsible for handling
* step <2> and <3>. However, SG uses an attribute called 'dependency level'
* when requsted to assign workload. This parameter refers to an integer that
* has been calculated initially for each SI. The 'dependency level' indicates
* to which extent an SI depends on other SIs such that an SI that depends on
* no other SI is on dependecy_level == 1, an SI that depends only on an SI on
* dependency_level == 1 is on dependency-level == 2.
* An SI that depends on several SIs gets a
* dependency_level that is one unit higher than the SI with the highest
* dependency_level it depends on. When SG is requested to assign the workload
* on a certain dependency level, it requests all SI objects on that level to
* activate (all) SI-assignments that during step <1> has been requested to
* assume the active HA state.
*
* SG contains the following state machines:
* - administrative state machine (ADSM) (NOT IN THIS RELEASE)
* - availability control state machine (ACSM)
*
* The availability control state machine contains two states and one of them
* is composite. Being a composite state means that it contains substates.
* The states are:
* - IDLE (non composite state)
* - MANAGING_SG (composite state)
* MANAGING_SG is entered at several different events which has in common
* the need to set up or change the assignment of SIs to SUs. Only one such
* event can be handled at the time. If new events occur while one event is
* being handled then the new event is saved and will be handled after the
* handling of the first event is ready (return to IDLE state has been done).
* MANAGING_SG handles the following events:
* - start (requests SG to order SU to instantiate all SUs in SG and waits
* for SU to indicate presence state change reports from the SUs and
* finally responds 'started' to the requester)
* - assign (requests SG to assign SIs to SUs according to pre-configured
* rules (if not already done) and transfer the HA state of
* the SIs on the requested SI dependency level. Then SG waits for
* confirmation that the HA state has been succesfully set and
* finally responds 'assigned' to the reqeuster)
* - auto_adjust (this event indicates that the auto-adjust probation timer has
* expired and that SG should evaluate current assignments of
* SIs to SUs and if needed remove current assignments and
* create new according to what is specified in paragraph
* 3.7.1.2)
* - failover_comp (requests SG to failover a specific component according to
* the procedure described in paragraph 3.12.1.3)
* - failover_su (requests SG to failover a specific SU according to the
* procedure described in paragraph 3.12.1.3 and 3.12.1.4)
* - switchover_node (requests SG to execute the recovery actions described
* in 3.12.1.3 and respond to the requester when recovery
* is completed)
* - failover_node (requests SG to execute the recovery actions described
* in 3.12.1.3 and respond to the requester when recovery is
* completed)
*
*/
#include <stdlib.h>
#include <errno.h>
#include "amf.h"
#include "print.h"
#include "main.h"
static inline int div_round (int a, int b)
{
int res;
res = a / b;
if ((a % b) != 0)
res++;
return res;
}
static int sg_all_su_in_service(struct amf_sg *sg)
{
struct amf_su *su;
struct amf_comp *comp;
int ready = 1;
for (su = sg->su_head; su != NULL; su = su->next) {
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
if (su->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE) {
ready = 0;
}
}
}
return ready;
}
static int application_si_count_get (struct amf_application *app)
{
struct amf_si *si;
int answer = 0;
for (si = app->si_head; si != NULL; si = si->next) {
answer += 1;
}
return (answer);
}
static void sg_assign_nm_active (struct amf_sg *sg, int su_units_assign)
{
struct amf_su *unit;
struct amf_si *si;
int assigned = 0;
int assign_per_su = 0;
int total_assigned = 0;
assign_per_su = application_si_count_get (sg->application);
assign_per_su = div_round (assign_per_su, su_units_assign);
if (assign_per_su > sg->saAmfSGMaxActiveSIsperSUs) {
assign_per_su = sg->saAmfSGMaxActiveSIsperSUs;
}
si = sg->application->si_head;
unit = sg->su_head;
while (unit != NULL) {
if (unit->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE ||
unit->saAmfSUNumCurrActiveSIs == sg->saAmfSGMaxActiveSIsperSUs ||
unit->saAmfSUNumCurrStandbySIs > 0) {
unit = unit->next;
continue; /* Not in service */
}
assigned = 0;
while (si != NULL &&
assigned < assign_per_su &&
total_assigned < application_si_count_get (sg->application)) {
assigned += 1;
total_assigned += 1;
amf_su_assign_si (unit, si, SA_AMF_HA_ACTIVE);
si = si->next;
}
unit = unit->next;
}
if (total_assigned == 0) {
dprintf ("Error: No SIs assigned!");
}
}
static void sg_assign_nm_standby (struct amf_sg *sg, int units_assign_standby)
{
struct amf_su *unit;
struct amf_si *si;
int assigned = 0;
int assign_per_su = 0;
int total_assigned = 0;
if (units_assign_standby == 0) {
return;
}
assign_per_su = application_si_count_get (sg->application);
assign_per_su = div_round (assign_per_su, units_assign_standby);
if (assign_per_su > sg->saAmfSGMaxStandbySIsperSUs) {
assign_per_su = sg->saAmfSGMaxStandbySIsperSUs;
}
si = sg->application->si_head;
unit = sg->su_head;
while (unit != NULL) {
if (unit->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE ||
unit->saAmfSUNumCurrActiveSIs > 0 ||
unit->saAmfSUNumCurrStandbySIs == sg->saAmfSGMaxStandbySIsperSUs) {
unit = unit->next;
continue; /* Not available for assignment */
}
assigned = 0;
while (si != NULL && assigned < assign_per_su) {
assigned += 1;
total_assigned += 1;
amf_su_assign_si (unit, si, SA_AMF_HA_STANDBY);
si = si->next;
}
unit = unit->next;
}
if (total_assigned == 0) {
dprintf ("Error: No SIs assigned!");
}
}
#if 0
static void assign_nm_spare (struct amf_sg *sg)
{
struct amf_su *unit;
for (unit = sg->su_head; unit != NULL; unit = unit->next) {
if (unit->saAmfSUReadinessState == SA_AMF_READINESS_IN_SERVICE &&
(unit->requested_ha_state != SA_AMF_HA_ACTIVE &&
unit->requested_ha_state != SA_AMF_HA_STANDBY)) {
dprintf ("Assigning to SU %s with SPARE\n",
getSaNameT (&unit->name));
}
}
}
#endif
static int su_inservice_count_get (struct amf_sg *sg)
{
struct amf_su *unit;
int answer = 0;
for (unit = sg->su_head; unit != NULL; unit = unit->next) {
if (unit->saAmfSUReadinessState == SA_AMF_READINESS_IN_SERVICE) {
answer += 1;
}
}
return (answer);
}
void amf_sg_assign_si (struct amf_sg *sg, int dependency_level)
{
int active_sus_needed;
int standby_sus_needed;
int inservice_count;
int units_for_standby;
int units_for_active;
int ii_spare;
int su_active_assign;
int su_standby_assign;
int su_spare_assign;
ENTER ("'%s'", sg->name.value);
/*
* Number of SUs to assign to active or standby state
*/
inservice_count = (float)su_inservice_count_get (sg);
active_sus_needed = div_round (application_si_count_get (sg->application),
sg->saAmfSGMaxActiveSIsperSUs);
standby_sus_needed = div_round (application_si_count_get (sg->application),
sg->saAmfSGMaxStandbySIsperSUs);
units_for_active = inservice_count - sg->saAmfSGNumPrefStandbySUs;
if (units_for_active < 0) {
units_for_active = 0;
}
units_for_standby = inservice_count - sg->saAmfSGNumPrefActiveSUs;
if (units_for_standby < 0) {
units_for_standby = 0;
}
ii_spare = inservice_count - sg->saAmfSGNumPrefActiveSUs - sg->saAmfSGNumPrefStandbySUs;
if (ii_spare < 0) {
ii_spare = 0;
}
/*
* Determine number of active and standby service units
* to assign based upon reduction procedure
*/
if ((inservice_count - active_sus_needed) < 0) {
dprintf ("assignment VI - partial assignment with SIs drop outs\n");
su_active_assign = active_sus_needed;
su_standby_assign = 0;
su_spare_assign = 0;
} else
if ((inservice_count - active_sus_needed - standby_sus_needed) < 0) {
dprintf ("assignment V - partial assignment with reduction of standby units\n");
su_active_assign = active_sus_needed;
if (standby_sus_needed > units_for_standby) {
su_standby_assign = units_for_standby;
} else {
su_standby_assign = standby_sus_needed;
}
su_spare_assign = 0;
} else
if ((sg->saAmfSGMaxStandbySIsperSUs * units_for_standby) <= application_si_count_get (sg->application)) {
dprintf ("IV: full assignment with reduction of active service units\n");
su_active_assign = inservice_count - standby_sus_needed;
su_standby_assign = standby_sus_needed;
su_spare_assign = 0;
} else
if ((sg->saAmfSGMaxActiveSIsperSUs * units_for_active) <= application_si_count_get (sg->application)) {
dprintf ("III: full assignment with reduction of standby service units\n");
su_active_assign = sg->saAmfSGNumPrefActiveSUs;
su_standby_assign = units_for_standby;
su_spare_assign = 0;
} else
if (ii_spare == 0) {
dprintf ("II: full assignment with spare reduction\n");
su_active_assign = sg->saAmfSGNumPrefActiveSUs;
su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
su_spare_assign = 0;
} else {
dprintf ("I: full assignment with spares\n");
su_active_assign = sg->saAmfSGNumPrefActiveSUs;
su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
su_spare_assign = ii_spare;
}
dprintf ("(inservice=%d) (assigning active=%d) (assigning standby=%d) (assigning spares=%d)\n",
inservice_count, su_active_assign, su_standby_assign, su_spare_assign);
sg_assign_nm_active (sg, su_active_assign);
sg_assign_nm_standby (sg, su_standby_assign);
LEAVE ("'%s'", sg->name.value);
}
void amf_sg_start (struct amf_sg *sg, struct amf_node *node)
{
struct amf_su *su;
ENTER ("'%s'", sg->name.value);
for (su = sg->su_head; su != NULL; su = su->next) {
amf_su_instantiate (su);
}
}
extern void amf_sg_su_state_changed (
struct amf_sg *sg, struct amf_su *su, SaAmfStateT type, int state)
{
if (sg_all_su_in_service(su->sg)) {
TRACE1 ("All SUs in SG '%s' in service, assigning SIs\n", su->sg->name.value);
amf_sg_assign_si (su->sg, 0);
if (amf_cluster.timeout_handle) {
poll_timer_delete (aisexec_poll_handle, amf_cluster.timeout_handle);
}
}
}
void amf_sg_init (void)
{
log_init ("AMF");
}

132
exec/amfsi.c Normal file
View File

@ -0,0 +1,132 @@
/** @file amfsi.c
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* - Refactoring of code into several AMF files
* Author: Anders Eriksson
*
* All rights reserved.
*
*
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF Workload related classes Implementation
*
* This file contains functions for handling :
* - AMF service instances(SI)
* - AMF SI Dependency
* - AMF SI Ranked SU
* - AMF SI Assignment
* - AMF component service instances (CSI)
* - AMF CSI Assignment
* - AMF CSI Type
* - AMF CSI Attribute
* The file can be viewed as the implementation of the classes listed above
* as described in SAI-Overview-B.02.01. The SA Forum specification
* SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
* and is referred to as 'the spec' below.
*
* The functions in this file are responsible for:
* - calculating and storing an SI_dependency_level integer per SI
* - calculating and storing a csi_dependency_level integer per CSI
* - on request change HA state of an SI or CSI in such a way that the
* requirements regarding SI -> SI dependencies (paragraphs 3.9.1.1 and
* 3.9.1.2) and CSI -> CSI dependencies (paragraph 3.9.1.3) are fully
* respected
*
* The si_dependency_level is an attribute calculated at init (in the future
* also at reconfiguration) which indicates dependencies between SIs as
* an integer. The si_dependency level indicates to which extent an SI depends
* on other SIs such that an SI that depends on no other SI is on
* si_dependecy_level == 1, an SI that depends only on an SI on
* si_dependency_level == 1 is on si_dependency-level == 2.
* An SI that depends on several SIs gets a si_dependency_level that is one
* unit higher than the SI with the highest si_dependency_level it depends on.
*
* The csi_dependency_level attribute works the same way.
*
* According to paragraph 3.9.1 of the spec, a change to or from the ACTIVE
* HA state is not always allowed without first deactivate dependent SI and CSI
* assignments. Dependencies between CSIs are absolute while an SI that depends
* on another SI may tolerate that the SI on which it depends is inactive for a
* configurable time (the tolerance time). The consequence of this is that a
* request to change the SI state may require a sequence of requests to
* components to assume a new HA state for a CSI-assignment and to guarantee
* the dependency rules, the active response from the component has to be
* awaited before next HA state can be set.
*
* This file implements an SI state machine that fully implements these rules.
* This state machine is called SI Dependency Control State Machine (dcsm)
* and has the following states:
* - DEACTIVATED (there is no SI-assignment with active HA state)
* - ACTIVATING (a request to set the ACTIVE HA state has been received and
* setting ACTIVE HA states to the appropriate components are
* in progress)
* - ACTIVATED (there is at least one SI-assignment with the ACTIVE HA-state)
* - DEACTIVATING (a request to de-activate an SI or only a specific CSI
* within an SI has been received and setting the QUISCED
* HA states to the appropriate components are in progress)
* - DEPENDENCY_DEACTIVATING (the SI-SI dependency tolerance timer has expired
* and setting the QUISCED HA states to the
* appropriate components are in progress)
* - DEPENDENCY_DEACTIVATED (as state DEACTIVATED but will automatically
* transition to state ACTIVATING when the
* dependency problem is solved, i.e. the SI on
* which it depends has re-assumed the ACTIVE HA
* state)
* - SETTING (a request to change the HA state when neither the existing
* nor the requested state is ACTIVE)
*
* This file also implements:
* - SI: Assignment state (for report purposes)
* - SI Assignment: HA state
* - CSI Assignment: HA state
*
*/
#include <assert.h>
#include <stdio.h>
#include "amf.h"
#include "print.h"
char *amf_csi_dn_make (struct amf_csi *csi, SaNameT *name)
{
int i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
"safCsi=%s,safSi=%s,safApp=%s",
csi->name.value, csi->si->name.value,
csi->si->application->name.value);
assert (i <= SA_MAX_NAME_LENGTH);
name->length = i;
return (char *)name->value;
}
void amf_si_init (void)
{
log_init ("AMF");
}

456
exec/amfsu.c Normal file
View File

@ -0,0 +1,456 @@
/** @file exec/amfsu.c
*
* Copyright (c) 2002-2006 MontaVista Software, Inc.
* Author: Steven Dake (sdake@mvista.com)
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* - Introduced AMF B.02 information model
* - Use DN in API and multicast messages
* - (Re-)Introduction of event based multicast messages
* - Refactoring of code into several AMF files
* Author: Anders Eriksson
*
* All rights reserved.
*
*
* This software licensed under BSD license, the text of which follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the MontaVista Software, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF Service Unit Class Implementation
*
* This file contains functions for handling AMF-service units(SUs). It can be
* viewed as the implementation of the AMF Service Unit class (called SU)
* as described in SAI-Overview-B.02.01. The SA Forum specification
* SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
* and is referred to as 'the spec' below.
*
* The functions in this file are responsible for:
* - instantiating and terminating service units on request
* (considering the dependencies between components described in paragraph
* 3.9.2)
* - creating and deleting CSI-assignment objects between its components and
* CSI-objects upon request
* - receiving error reports from its components and forwarding them to
* appropriate handler (SU or SG or node or cluster)
* - implementing restart of itself and its components (paragraph 3.12.1.2)
* - implementing error escallation level 1 (paragraph 3.12.2.2 in the spec)
* - handling all run time attributes of the AMF SU; all cached
* attributes are stored as variables and sent to the IMM service
* upon the changes described in the specification.
*
* SU contains the following state machines:
* - presence state machine (PRSM)
* - administrative state machine (ADSM) (NOT IN THIS RELEASE)
* - operational state machine (OPSM)
* - readiness state machine (RESM)
* - ha state per service instance (SI)
* - restart control state machine (RCSM)
*
* The presence state machine orders intantiation of its components on request.
* It fully respects the dependency rules between components at instantiation
* such that it orders instantiation simultaneously only of components on the
* same instantiation level. The presence state machine is implemented with
* the states described in the spec and the state transitions are trigged by
* reported state transitions from its contained components according to
* paragraph 3.3.1.1.
*
* The operational state machine is not responsible for any control function.
* It assumes the DISABLED state if an incoming operational state change report
* from a component indicates the component has assumed the DISABLED state.
* Operational state changes are reported to IMM.
*
* The readiness state machine is not used for any control but is updated and
* reported to IMM when it is changed.
*
* The restart control state machine (RCSM) is used to implement level 1 of
* the error escallation polycy described in chapter 3.12.2 of the spec. It
* also implements component restart and service unit restart as described in
* paragraph 3.12.1.2 and 3.12.1.3.
* RCSM contains three composite states.
* Being a composite state means that the state contains substates.
* RCSM composite states are:
* - ESCALLATION_LEVEL (LEVEL_0, LEVEL_1 and LEVEL_2)
* - RESTARTING_COMPONENT (DEACTIVATING, RESTARTING, SETTING and ACTIVATING)
* - RESTARTING_SERVICE_UNIT (DEACTIVATING, TERMINATING, INSTANTIATING,
* and ACTIVATING)
*
* ESCALLATION_LEVEL is a kind of idle state where no actions are performed
* and used only to remember the escallation level. Substate LEVEL_0 indicates
* no escallation. LEVEL_1 indicates that a component restart has been
* executed recently and the escallation timer is still running. At this level
* component restart requests will transition to RESTARTING_COMPONENT but
* if there are too many restart requests before the probation timer expires
* then a transition will be made to LEVEL_2 and the restart request will
* be forwarded to the node instance hosting this component.
* State RESTARTING_SERVICE_UNIT will only be assumed if the node explicitly
* requests the SU to execute a restart of itself (after having evaluated its
* part of the error escallation policy).
*
*/
/*
*
*/
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include "amf.h"
#include "util.h"
#include "print.h"
#include "main.h"
static int presence_state_all_comps_in_su_are_set (struct amf_su *su,
SaAmfPresenceStateT state)
{
int all_set = 1;
struct amf_comp *comp;
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
if (comp->saAmfCompPresenceState != state) {
all_set = 0;
}
}
return all_set;
}
static void su_readiness_state_set (struct amf_su *su,
SaAmfReadinessStateT readiness_state)
{
su->saAmfSUReadinessState = readiness_state;
TRACE1 ("Setting SU '%s' readiness state: %s\n",
&su->name.value, amf_readiness_state(readiness_state));
}
static void su_presence_state_set (struct amf_su *su,
SaAmfPresenceStateT presence_state)
{
su->saAmfSUPresenceState = presence_state;
TRACE1 ("Setting SU '%s' presence state: %s\n",
su->name.value, amf_presence_state (presence_state));
}
static void su_operational_state_set (struct amf_su *su,
SaAmfOperationalStateT oper_state)
{
struct amf_comp* comp;
if (oper_state == su->saAmfSUOperState) {
log_printf (LOG_INFO,
"Not assigning service unit new operational state - same state\n");
return;
}
su->saAmfSUOperState = oper_state;
TRACE1 ("Setting SU '%s' operational state: %s\n",
su->name.value, amf_op_state (oper_state));
if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
su_readiness_state_set (su, SA_AMF_READINESS_IN_SERVICE);
for (comp = su->comp_head; comp; comp = comp->next) {
amf_comp_readiness_state_set (comp, SA_AMF_READINESS_IN_SERVICE);
}
amf_sg_su_state_changed (su->sg, su, SA_AMF_OP_STATE, SA_AMF_OPERATIONAL_ENABLED);
} else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
su_readiness_state_set (su, SA_AMF_READINESS_OUT_OF_SERVICE);
}
}
static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
SaAmfHAStateT ha_state)
{
struct amf_csi_assignment *csi_assignment;
dprintf (" Assigning CSI '%s' to comp '%s' with hastate %s\n",
getSaNameT (&csi->name), getSaNameT (&comp->name),
amf_ha_state (ha_state));
csi_assignment = malloc (sizeof (struct amf_csi_assignment));
if (csi_assignment == NULL) {
openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
}
csi_assignment->comp_next = comp->assigned_csis;
comp->assigned_csis = csi_assignment;
setSaNameT (&csi_assignment->name, (char*)comp->name.value);
csi_assignment->saAmfCSICompHAState = ha_state;
csi_assignment->csi = csi;
csi_assignment->comp = comp;
csi_assignment->saAmfCSICompHAState = ha_state;
if (ha_state == SA_AMF_HA_ACTIVE)
comp->saAmfCompNumCurrActiveCsi++;
else if (ha_state == SA_AMF_HA_STANDBY)
comp->saAmfCompNumCurrStandbyCsi++;
else
assert (0);
amf_comp_hastate_set (comp, csi_assignment, ha_state);
}
static void su_cleanup (struct amf_su *su)
{
struct amf_comp *comp;
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
amf_comp_restart (comp);
}
}
static void escalation_policy_cleanup (struct amf_comp *comp)
{
// escalation_timer_start (comp);
switch (comp->su->escalation_level) {
case ESCALATION_LEVEL_NO_ESCALATION:
comp->saAmfCompRestartCount += 1;
if (comp->saAmfCompRestartCount >= comp->su->sg->saAmfSGCompRestartMax) {
comp->su->escalation_level = ESCALATION_LEVEL_ONE;
escalation_policy_cleanup (comp);
comp->saAmfCompRestartCount = 0;
return;
}
dprintf ("Escalation level 0 - restart component\n");
dprintf ("Cleaning up and restarting component.\n");
amf_comp_restart (comp);
break;
case ESCALATION_LEVEL_ONE:
comp->su->saAmfSURestartCount += 1;
if (comp->su->saAmfSURestartCount >= comp->su->sg->saAmfSGSuRestartMax) {
comp->su->escalation_level = ESCALATION_LEVEL_TWO;
escalation_policy_cleanup (comp);
comp->saAmfCompRestartCount = 0;
comp->su->saAmfSURestartCount = 0;
return;
}
dprintf ("Escalation level 1 - restart unit\n");
dprintf ("Cleaning up and restarting unit.\n");
su_cleanup (comp->su);
break;
case ESCALATION_LEVEL_TWO:
dprintf ("Escalation level TWO\n");
su_cleanup (comp->su);
// unit_terminate_failover (comp);
break;
case ESCALATION_LEVEL_THREE:
//TODO
break;
}
}
void amf_su_instantiate (struct amf_su *su)
{
struct amf_comp *comp;
ENTER ("'%s'", su->name.value);
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
amf_comp_instantiate (comp);
}
}
void amf_su_assign_si (struct amf_su *su, struct amf_si *si,
SaAmfHAStateT ha_state)
{
struct amf_si_assignment *si_assignment;
dprintf ("Assigning SI '%s' to SU '%s' with hastate %s\n",
getSaNameT (&si->name), getSaNameT (&su->name),
amf_ha_state (ha_state));
si_assignment = malloc (sizeof (struct amf_si_assignment));
if (si_assignment == NULL) {
openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
}
setSaNameT (&si_assignment->name, (char*)su->name.value);
si_assignment->saAmfSISUHAState = ha_state;
si_assignment->next = su->assigned_sis;
su->assigned_sis = si_assignment;
si_assignment->si = si;
if (ha_state == SA_AMF_HA_ACTIVE) {
si->saAmfSINumCurrActiveAssignments++;
su->saAmfSUNumCurrActiveSIs++;
} else if (ha_state == SA_AMF_HA_STANDBY) {
su->saAmfSUNumCurrStandbySIs++;
si->saAmfSINumCurrStandbyAssignments++;
} else
assert(0);
if ((si->saAmfSINumCurrActiveAssignments == si->saAmfSIPrefActiveAssignments) &&
(si->saAmfSINumCurrStandbyAssignments == si->saAmfSIPrefStandbyAssignments)) {
si->saAmfSIAssignmentState = SA_AMF_ASSIGNMENT_FULLY_ASSIGNED;
} else if ((si->saAmfSINumCurrActiveAssignments < si->saAmfSIPrefActiveAssignments) ||
(si->saAmfSINumCurrStandbyAssignments < si->saAmfSIPrefStandbyAssignments)) {
si->saAmfSIAssignmentState = SA_AMF_ASSIGNMENT_PARTIALLY_ASSIGNED;
}
{
struct amf_csi *csi;
struct amf_comp *comp;
SaNameT *cs_type;
int i;
/*
** for each component in SU, find a CSI in the SI with the same type
*/
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
int no_of_cs_types = 0;
for (i = 0; comp->saAmfCompCsTypes[i]; i++) {
cs_type = comp->saAmfCompCsTypes[i];
no_of_cs_types++;
int no_of_assignments = 0;
for (csi = si->csi_head; csi != NULL; csi = csi->next) {
if (!memcmp(csi->saAmfCSTypeName.value, cs_type->value, cs_type->length)) {
comp_assign_csi (comp, csi, ha_state);
no_of_assignments++;
}
}
if (no_of_assignments == 0) {
log_printf (LOG_WARNING, "\t No CSIs of type %s configured?!!\n",
getSaNameT (cs_type));
}
}
if (no_of_cs_types == 0) {
log_printf (LOG_LEVEL_ERROR, "\t No CS types configured for comp %s ?!!\n",
getSaNameT (&comp->name));
}
}
}
}
/**
* Used by a component to report a state change event
* @param su
* @param comp
* @param type type of state
* @param state new state
*/
void amf_su_comp_state_changed (
struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state)
{
if (type == SA_AMF_PRESENCE_STATE) {
/*
* If all comp presence states are INSTANTIATED, then SU should
* be instantated.
*/
if (state == SA_AMF_PRESENCE_INSTANTIATED) {
if (presence_state_all_comps_in_su_are_set (
comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
su_presence_state_set (comp->su, SA_AMF_PRESENCE_INSTANTIATED);
} else {
assert (0);
}
} else if (state == SA_AMF_PRESENCE_INSTANTIATING) {
} else if (state == SA_AMF_PRESENCE_RESTARTING) {
} else {
assert (0);
}
} else if (type == SA_AMF_OP_STATE) {
/*
* If all component op states are ENABLED, then SU op
* state should be ENABLED.
*/
if (state == SA_AMF_OPERATIONAL_ENABLED) {
struct amf_comp *comp_compare;
int all_set = 1;
for (comp_compare = comp->su->comp_head; comp_compare != NULL; comp_compare = comp->next) {
if (comp_compare->saAmfCompOperState != SA_AMF_OPERATIONAL_ENABLED) {
all_set = 0;
break;
}
}
if (all_set) {
su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_ENABLED);
} else {
su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_DISABLED);
}
} else {
assert (0);
}
} else {
assert (0);
}
}
/**
* Used by a component to report a change in HA state
* @param su
* @param comp
* @param csi_assignment
*/
void amf_su_comp_hastate_changed (
struct amf_su *su, struct amf_comp *comp,
struct amf_csi_assignment *csi_assignment)
{
ENTER("'%s' '%s'", comp->name.value, csi_assignment->csi->name.value);
}
/**
* Determine if the SU is hosted on the local node.
* @param su
*
* @return int
*/
int amf_su_is_local (struct amf_su *su)
{
if (name_match (&this_amf_node->name, &su->saAmfSUHostedByNode)) {
return 1;
} else {
return 0;
}
}
/**
* Called by a component to report a suspected error on a component
* @param su
* @param comp
* @param recommended_recovery
*/
void amf_su_comp_error_suspected (
struct amf_su *su,
struct amf_comp *comp,
SaAmfRecommendedRecoveryT recommended_recovery)
{
escalation_policy_cleanup (comp);
}
void amf_su_init (void)
{
log_init ("AMF");
}

View File

@ -1,10 +1,13 @@
/*
/** @file exec/amfutil.c
*
* Copyright (c) 2002-2005 MontaVista Software, Inc.
* Author: Steven Dake (sdake@mvista.com)
*
* Copyright (c) 2006 Ericsson AB.
* Author: Hans Feldt
* Description: Reworked to match AMF B.02 information model
* Description:
* - Reworked to match AMF B.02 information model Description:
* - Refactoring of code into several AMF files
*
* All rights reserved.
*
@ -33,7 +36,14 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* AMF utility functions
*
* This file contains functions that provide different services used by other
* AMF files. For example parsing the configuration file, printing state etc.
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -44,7 +54,7 @@
#include "../include/ipc_amf.h"
#include "../include/list.h"
#include "util.h"
#include "amfconfig.h"
#include "amf.h"
#include "totem.h"
#include "print.h"
@ -68,90 +78,55 @@ typedef enum {
AMF_CS_TYPE,
} amf_parse_t;
typedef enum {
MAIN_HEAD,
MAIN_NETWORK,
MAIN_LOGGING,
MAIN_KEY,
MAIN_TIMEOUT,
MAIN_EVENT
} main_parse_t;
#ifndef OPENAIS_CLUSTER_STARTUP_TIMEOUT
#define OPENAIS_CLUSTER_STARTUP_TIMEOUT 5000
#endif
struct amf_healthcheck *amf_find_healthcheck (struct amf_comp *comp, SaAmfHealthcheckKeyT *key)
{
struct amf_healthcheck *healthcheck;
struct amf_healthcheck *ret_healthcheck = 0;
static const char *presence_state_text[] = {
"UNKNOWN",
"UNINSTANTIATED",
"INSTANTIATING",
"INSTANTIATED",
"TERMINATING",
"RESTARTING",
"INSTANTION_FAILED",
"TERMINIATION-FAILED"
};
for (healthcheck = comp->healthcheck_head;
healthcheck != NULL;
healthcheck = healthcheck->next) {
static const char *oper_state_text[] = {
"UNKNOWN",
"ENABLED",
"DISABLED"
};
if (memcmp (key, &healthcheck->safHealthcheckKey, sizeof (SaAmfHealthcheckKeyT)) == 0) {
ret_healthcheck = healthcheck;
break;
}
}
static const char *admin_state_text[] = {
"UNKNOWN",
"UNLOCKED",
"LOCKED",
"LOCKED-INSTANTIATION",
"SHUTTING-DOWN"
};
return (ret_healthcheck);
}
static const char *readiness_state_text[] = {
"UNKNOWN",
"OUT-OF-SERVICE",
"IN-SERVICE",
};
struct amf_comp *amf_find_comp (struct amf_cluster *cluster, SaNameT *name)
{
struct amf_application *app;
struct amf_sg *sg;
struct amf_su *su;
struct amf_comp *comp = NULL;
char *app_name;
char *sg_name;
char *su_name;
char *comp_name;
char *ptrptr;
char *buf;
static const char *ha_state_text[] = {
"UNKNOWN",
"ACTIVE",
"STANDBY",
"QUIESCED",
"QUIESCING",
};
/* malloc new buffer since strtok_r writes to its first argument */
buf = malloc (name->length);
memcpy (buf, name->value,name ->length);
comp_name = strtok_r(buf, ",", &ptrptr);
su_name = strtok_r(NULL, ",", &ptrptr);
sg_name = strtok_r(NULL, ",", &ptrptr);
app_name = strtok_r(NULL, ",", &ptrptr);
if (comp_name == NULL || su_name == NULL || sg_name == NULL || app_name == NULL) {
goto end;
}
comp_name += 8;
su_name += 6;
sg_name += 6;
app_name += 7;
for (app = cluster->application_head; app != NULL; app = app->next) {
if (strncmp (app_name, (char*)app->name.value, app->name.length) == 0) {
for (sg = app->sg_head; sg != NULL; sg = sg->next) {
if (strncmp (sg_name, (char*)sg->name.value, sg->name.length) == 0) {
for (su = sg->su_head; su != NULL; su = su->next) {
if (strncmp (su_name, (char*)su->name.value, su->name.length) == 0) {
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
if (strncmp (comp_name, (char*)comp->name.value, comp->name.length) == 0) {
goto end;
}
}
}
}
}
}
}
}
end:
free (buf);
return comp;
}
static const char *assignment_state_text[] = {
"UNKNOWN",
"UNASSIGNED",
"FULLY-ASSIGNED",
"PARTIALLY-ASSIGNED"
};
static int init_category (struct amf_comp *comp, char *loc)
{
@ -216,25 +191,6 @@ static int init_recovery_on_error (struct amf_comp *comp, char *loc)
return 0;
}
static struct amf_comp *new_comp(struct amf_su *su)
{
struct amf_comp *comp = calloc (1, sizeof (struct amf_comp));
if (comp == NULL) {
openais_exit_error(AIS_DONE_OUT_OF_MEMORY);
}
comp->next = su->comp_head;
su->comp_head = comp;
comp->su = su;
comp->saAmfCompOperState = SA_AMF_OPERATIONAL_DISABLED;
comp->saAmfCompPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
comp->saAmfCompNumMaxInstantiateWithoutDelay = 2;
comp->saAmfCompNumMaxAmStartAttempt = 2;
comp->saAmfCompNumMaxAmStopAttempt = 2;
return comp;
}
static void post_init_comp(struct amf_comp *comp)
{
if (comp->saAmfCompInstantiateTimeout == 0) {
@ -589,7 +545,7 @@ int amf_config_read (struct amf_cluster *cluster, char **error_string)
} else if ((loc = strstr_rs (line, "saAmfSUHostedByNode=")) != 0) {
setSaNameT (&su->saAmfSUHostedByNode, loc);
} else if ((loc = strstr_rs (line, "safComp=")) != 0) {
comp = new_comp (su);
comp = amf_comp_create (su);
comp_env_var_cnt = 0;
comp_cs_type_cnt = 0;
setSaNameT (&comp->name, trim_str (loc));
@ -775,7 +731,7 @@ int amf_config_read (struct amf_cluster *cluster, char **error_string)
comp->saAmfCompCmdEnv = realloc (comp->saAmfCompCmdEnv,
(comp_env_var_cnt + 1) * sizeof(SaStringT));
comp->saAmfCompCmdEnv[comp_env_var_cnt] = NULL;
env_var = comp->saAmfCompCmdEnv[comp_env_var_cnt - 1] = malloc (strlen (line + 1));
env_var = comp->saAmfCompCmdEnv[comp_env_var_cnt - 1] = malloc (strlen (line) + 1);
strcpy (env_var, line);
} else {
goto parse_error;
@ -933,3 +889,149 @@ parse_error:
fclose (fp);
return (-1);
}
void amf_runtime_attributes_print (struct amf_cluster *cluster)
{
struct amf_node *node;
struct amf_application *app;
struct amf_sg *sg;
struct amf_su *su;
struct amf_comp *comp;
struct amf_si *si;
struct amf_csi *csi;
struct amf_si_assignment *si_assignment;
struct amf_csi_assignment *csi_assignment;
dprintf("AMF runtime attributes:");
dprintf("===================================================");
dprintf("safCluster=%s", getSaNameT(&cluster->name));
dprintf(" admin state: %s\n", admin_state_text[cluster->saAmfClusterAdminState]);
for (node = cluster->node_head; node != NULL; node = node->next) {
dprintf(" safNode=%s\n", getSaNameT (&node->name));
dprintf(" admin state: %s\n", admin_state_text[node->saAmfNodeAdminState]);
dprintf(" oper state: %s\n", oper_state_text[node->saAmfNodeOperState]);
}
for (app = cluster->application_head; app != NULL; app = app->next) {
dprintf(" safApp=%s\n", getSaNameT(&app->name));
dprintf(" admin state: %s\n", admin_state_text[app->saAmfApplicationAdminState]);
dprintf(" num_sg: %d\n", app->saAmfApplicationCurrNumSG);
for (sg = app->sg_head; sg != NULL; sg = sg->next) {
dprintf(" safSG=%s\n", getSaNameT(&sg->name));
dprintf(" admin state: %s\n", admin_state_text[sg->saAmfSGAdminState]);
dprintf(" assigned SUs %d\n", sg->saAmfSGNumCurrAssignedSUs);
dprintf(" non inst. spare SUs %d\n", sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
dprintf(" inst. spare SUs %d\n", sg->saAmfSGNumCurrInstantiatedSpareSUs);
for (su = sg->su_head; su != NULL; su = su->next) {
dprintf(" safSU=%s\n", getSaNameT(&su->name));
dprintf(" oper state: %s\n", oper_state_text[su->saAmfSUOperState]);
dprintf(" admin state: %s\n", admin_state_text[su->saAmfSUAdminState]);
dprintf(" readiness state: %s\n", readiness_state_text[su->saAmfSUReadinessState]);
dprintf(" presence state: %s\n", presence_state_text[su->saAmfSUPresenceState]);
dprintf(" hosted by node %s\n", su->saAmfSUHostedByNode.value);
dprintf(" num active SIs %d\n", su->saAmfSUNumCurrActiveSIs);
dprintf(" num standby SIs %d\n", su->saAmfSUNumCurrStandbySIs);
dprintf(" restart count %d\n", su->saAmfSURestartCount);
dprintf(" escalation level %d\n", su->escalation_level);
dprintf(" SU failover cnt %d\n", su->su_failover_cnt);
dprintf(" assigned SIs:");
for (si_assignment = su->assigned_sis; si_assignment != NULL;
si_assignment = si_assignment->next) {
dprintf(" safSi=%s\n", si_assignment->si->name.value);
dprintf(" HA state: %s\n",
ha_state_text[si_assignment->saAmfSISUHAState]);
}
for (comp = su->comp_head; comp != NULL; comp = comp->next) {
dprintf(" safComp=%s\n", getSaNameT(&comp->name));
dprintf(" oper state: %s\n",
oper_state_text[comp->saAmfCompOperState]);
dprintf(" readiness state: %s\n",
readiness_state_text[comp->saAmfCompReadinessState]);
dprintf(" presence state: %s\n",
presence_state_text[comp->saAmfCompPresenceState]);
dprintf(" num active CSIs %d\n",
comp->saAmfCompNumCurrActiveCsi);
dprintf(" num standby CSIs %d\n",
comp->saAmfCompNumCurrStandbyCsi);
dprintf(" restart count %d\n", comp->saAmfCompRestartCount);
dprintf(" assigned CSIs:");
for (csi_assignment = comp->assigned_csis; csi_assignment != NULL;
csi_assignment = csi_assignment->comp_next) {
dprintf(" safCSI=%s\n", csi_assignment->csi->name.value);
dprintf(" HA state: %s\n",
ha_state_text[csi_assignment->saAmfCSICompHAState]);
}
}
}
}
for (si = app->si_head; si != NULL; si = si->next) {
dprintf(" safSi=%s\n", getSaNameT(&si->name));
dprintf(" admin state: %s\n", admin_state_text[si->saAmfSIAdminState]);
dprintf(" assignm. state: %s\n", assignment_state_text[si->saAmfSIAssignmentState]);
dprintf(" active assignments: %d\n", si->saAmfSINumCurrActiveAssignments);
dprintf(" standby assignments: %d\n", si->saAmfSINumCurrStandbyAssignments);
for (csi = si->csi_head; csi != NULL; csi = csi->next) {
dprintf(" safCsi=%s\n", getSaNameT(&csi->name));
}
}
}
dprintf("===================================================");
}
/* to be removed... */
int amf_enabled (struct objdb_iface_ver0 *objdb)
{
unsigned int object_service_handle;
char *value;
int enabled = 0;
objdb->object_find_reset (OBJECT_PARENT_HANDLE);
if (objdb->object_find (
OBJECT_PARENT_HANDLE,
"amf",
strlen ("amf"),
&object_service_handle) == 0) {
value = NULL;
if ( !objdb->object_key_get (object_service_handle,
"mode",
strlen ("mode"),
(void *)&value,
NULL) && value) {
if (strcmp (value, "enabled") == 0) {
enabled = 1;
} else
if (strcmp (value, "disabled") == 0) {
enabled = 0;
}
}
}
return enabled;
}
const char *amf_admin_state (int state)
{
return admin_state_text[state];
}
const char *amf_op_state (int state)
{
return oper_state_text[state];
}
const char *amf_presence_state (int state)
{
return presence_state_text[state];
}
const char *amf_ha_state (int state)
{
return ha_state_text[state];
}
const char *amf_readiness_state (int state)
{
return readiness_state_text[state];
}

View File

@ -53,7 +53,7 @@ typedef enum {
typedef enum {
SA_AMF_HEALTHCHECK_AMF_INVOKED = 1,
SA_AMF_HELATHCHECK_COMPONENT_INVOKED =2
SA_AMF_HEALTHCHECK_COMPONENT_INVOKED =2
} SaAmfHealthcheckInvocationT;
#define SA_AMF_HEALTHCHECK_KEY_MAX 32

View File

@ -131,13 +131,24 @@ void CSISetCallback (
SaAmfHAStateT haState,
SaAmfCSIDescriptorT *csiDescriptor)
{
SaAmfHAStateT state;
int res;
switch (haState) {
case SA_AMF_HA_ACTIVE:
printf ("Component '%s' requested to enter hastate SA_AMF_ACTIVE for \n\tCSI '%s'\n",
compName->value, csiDescriptor->csiName.value);
res = saAmfResponse (handle, invocation, SA_AIS_OK);
if (res != SA_AIS_OK) {
fprintf (stderr, "saAmfResponse failed: %d\n", res);
exit (-1);
}
res = saAmfHAStateGet (handle, compName, &csiDescriptor->csiName, &state);
if (res != SA_AIS_OK || haState != state) {
fprintf (stderr, "saAmfHAStateGet failed: %d\n", res);
exit (-1);
}
int i;
TR(TRU, csiDescriptor->csiAttr.number);
for(i=0; i<csiDescriptor->csiAttr.number; i++) {