mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2026-02-01 16:27:26 +00:00
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:
parent
b0c735ee64
commit
e993689ac5
2
Doxyfile
2
Doxyfile
@ -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 =
|
||||
|
||||
@ -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
2453
exec/amf.c
File diff suppressed because it is too large
Load Diff
679
exec/amf.h
Normal file
679
exec/amf.h
Normal 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
113
exec/amfapp.c
Normal 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
123
exec/amfcluster.c
Normal 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
1521
exec/amfcomp.c
Normal file
File diff suppressed because it is too large
Load Diff
378
exec/amfconfig.h
378
exec/amfconfig.h
@ -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
107
exec/amfnode.c
Normal 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
422
exec/amfsg.c
Normal 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
132
exec/amfsi.c
Normal 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
456
exec/amfsu.c
Normal 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");
|
||||
}
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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++) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user