| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853 |
- /** @file amfsg.c
- *
- * Copyright (c) 2002-2006 MontaVista Software, Inc.
- * Author: Steven Dake (sdake@redhat.com)
- *
- * Copyright (c) 2006 Ericsson AB.
- * Author: Hans Feldt, Anders Eriksson, Lars Holm
- * - 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
- * - Component/SU restart, SU failover
- * - Constructors/destructors
- * - Serializers/deserializers
- *
- * 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 cluster 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 three states and one of them
- * is composite. Being a composite state means that it contains substates.
- * The states are:
- * - IDLE (non composite state)
- * - INSTANTIATING_SERVICE_UNITS
- * - 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_si (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)
- *
- * 1. SG Availability Control State Machine
- * ==========================================
- *
- * 1.1 State Transition Table
- *
- * State: Event: Action: New state:
- * ============================================================================
- * IDLE start A48,A28 INSTANTIATING_SUs
- * IDLE assign_si A48,A31 ASSIGNING_ON_REQ
- * IDLE failover_su A48,[C22]A10,A11 DEACTIVATING_DEP
- * IDLE failover_su A48,[!C22]A12 TERMINATING_SUSP
- * IDLE failover_node A48,[!C22]A12 TERMINATING_SUSP
- * IDLE failover_node A48,[C22]A10,A11 DEACTIVATING_DEP
- * IDLE failover_node A48,[C100]A34 IDLE
- * INSTANTIATING_SUs start A48,A28 INSTANTIATING_SUs
- * INSTANTIATING_SUs su_state_chg [C101]A26,A53 IDLE
- * INSTANTIATING_SUs su_state_chg [C102]A26,A53 IDLE
- * INSTANTIATING_SUs assign_si A31 ASSIGNING_ON_REQ
- * INSTANTIATING_SUs failover_su A52 INSTANTIATING_SUs
- * INSTANTIATING_SUs failover_node A52 INSTANTIATING_SUs
- * ASSIGNING_ON_REQ ha_state_assumed [C15]A54 IDLE
- * ASSIGNING_ON_REQ failover_su A52 ASSIGNING_ON_REQ
- * ASSIGNING_ON_REQ failover_node A52 ASSIGNING_ON_REQ
- * DEACTIVATING_DEP si_deactivated [C20] REMOVING_S-BY_ASS
- * DEACTIVATING_DEP si_deactivated [!C20]A12 TERMINATING_SUSP
- * TERMINATING_SUSP su_state_chg [C103]A24,A20 ASS_S-BY_TO_SPARE
- * TERMINATING_SUSP su_state_chg [C104]A24,A50 REMOVING_S-BY_ASS
- * TERMINATING_SUSP su_state_chg [C105]A16,A17 ACTIVATING_S-BY
- * TERMINATING_SUSP su_state_chg [C106]A20 ASS_S-BY_TO_SPARE
- * TERMINATING_SUSP su_state_chg [C108]A23 REPAIRING_SU
- * TERMINATING_SUSP su_state_chg [C109] IDLE
- * TERMINATING_SUSP failover_su A52 TERMINATING_SUSP
- * TERMINATING_SUSP failover_node A52 TERMINATING_SUSP
- * REMOVING_S-BY_ASS assignment_removed A51 REMOVING_S-BY_ASS
- * REMOVING_S-BY_ASS assignment_removed [C27]&[C24] ACTIVATING_S-BY
- * REMOVING_S-BY_ASS assignment_removed [C110]A20 ASS_S-BY_TO_SPARE
- * REMOVING_S-BY_ASS assignment_removed [C111]A23 REPAIRING_SU
- * REMOVING_S-BY_ASS assignment_removed [C112] IDLE
- * REMOVING_S-BY_ASS failover_su A52 REMOVING_S-BY_ASS
- * REMOVING_S-BY_ASS failover_node A52 REMOVING_S-BY_ASS
- * ACTIVATING_S-BY su_activated [C2]&[C11]A20 ASS_S-BY_TO_SPARE
- * ACTIVATING_S-BY su_activated [C113]A23 REPAIRING_SU
- * ACTIVATING_S-BY su_activated [C114] IDLE
- * ACTIVATING_S-BY failover_su A52 ACTIVATING_S-BY
- * ACTIVATING_S-BY failover_node A52 ACTIVATING_S-BY
- * ASS_S-BY_TO_SPARE ha_state_assumed [C115]A23 REPAIRING_SU
- * ASS_S-BY_TO_SPARE ha_state_assumed [C116] IDLE
- * ASS_S-BY_TO_SPARE failover_su A52 ASS_S-BY_TO_SPARE
- * ASS_S-BY_TO_SPARE failover_node A52 ASS_S-BY_TO_SPARE
- * REPAIRING_SU su_state_chg [C28]A36,A37,A31 ASSIGNING_WL
- * REPAIRING_SU su_state_chg [C28][C31] IDLE
- * REPAIRING_SU failover_su A52 REPAIRING_SU
- * REPAIRING_SU failover_node A52 REPAIRING_SU
- * ASSIGNING_WL ha_state_assumed [C15] IDLE
- * ASSIGNING_WL failover_su A52 ASSIGNING_WL
- * ASSIGNING_WL failover_node A52 ASSIGNING_WL
- *
- * 1.2 State Description
- * =====================
- * IDLE - SG is synchronized and idle. When IDLE state is set,
- * the oldest deferred event (if any) is recalled.
- * INSTANTIATING_SUs - INSTANTIATING_SERVICE_UNITS
- * SG has ordered all contained SUs to instantiate and
- * waits for the SUs to report a change of their
- * presence state. SG is also prepared to accept an
- * order to assign workload in this state.
- * ASSIGNING_ON_REQ - ASSIGNING_ON_REQUEST
- * SG has on request assigned workload to all service units
- * on the requested dependency level and waits for SIs to
- * indicate that the requested HA-state have been set to the
- * appropriate components.
- * TERMINATING_SUSP - TERMINATING_SUSPECTED
- * SG has cleaned up all components suspected to be
- * erroneous and waits for the concerned SUs to report a
- * change of their presence states.
- * REMOVING_S-BY_ASS - REMOVING_STANDBY_ASSIGNMENTS
- * This state is only applicable to the n-plus-m redundancy
- * model. In this state, SG has initiated the removal of
- * those assignments from standby SUs that do not match the
- * assignments of error suspected SUs. The reason for this
- * removal is a preparation for not violating the rule which
- * says an SU can not have both active and standby assign-
- * ments simultaneously in the n-plus-m redundancy model.
- * ACTIVATING_S-BY - ACTIVATING_STANDBY
- * SG has located all standby SI-assignments in the recovery
- * scope and ordered the corresponding SI to set the active
- * HA-state and waits for SI to indicate that the requested
- * HA-state has been set to the appropriate components.
- * ASS_S-BY_TO_SPARE - ASSIGNING_STANDBY_TO_SPARE
- * Current SG is configured with a spare SU. In this state,
- * SG has requested all SIs to assign the standby HA-state
- * to the spare SU and waits for the SIs to indicate that
- * the standby HA-state have been set.
- * REPAIRING_SU - REPAIRING_SU
- * In this state SG has initiated instantiation of all SUs
- * in current recovery scope until the configured preference
- * of number of instantiated SUs is fulfiled. SG then waits
- * for the concerned SUs to report a change of presence
- * state.
- * ASSIGNING_WL - ASSIGNING_WORKLOAD
- * In this state SG has initiated the assignment of workload
- * to all or a subset of its contained SUs and waits for the
- * concerned SIs to indicated that the requested HA-state
- * has been assumed.
- *
- * 1.3 Actions
- * ===========
- * A1 -
- * A2 -
- * A3 -
- * A4 -
- * A5 -
- * A6 -
- * A7 -
- * A8 -
- * A9 -
- * A10 - [foreach SI in the scope]&[foreach SI-assignment with
- * confirmed-HA-state == ACTIVE]/set requested-ha-state = QUIESCED
- * A11 - [foreach SI in the scope]/deactivate SI
- * A12 - [foreach suspected SU]/terminate all components
- * A13 -
- * A14 -
- * A15 -
- * A16 - [foreach SI in the scope]&[foreach SI-assignment with
- * confirmed-HA-state == STANDBY]/set requested-ha-state = ACTIVE
- * A17 - [foreach SI in the scope]/activate SI
- * A18 -
- * A19 -
- * A20 -
- * A21 -
- * A22 -
- * A23 -
- * A24 -
- * A25 -
- * A26 -
- * A27 -
- * A28 -
- * A29 -
- * A30 -
- * A31 -
- * A32 -
- * A33 -
- * A34 -
- * A35 -
- * A36 -
- * A37 -
- * A38 -
- * A39 -
- * A40 -
- * A41 -
- * A42 -
- * A43 -
- * A44 -
- * A45 -
- * A46 -
- * A47 -
- * A48 -
- * A49 -
- *
- * 1.4 Composite Guards
- * ====================
- * The meaning with these guards is just to save space in the state transition
- * table above.
- * C100 - [C7]&[!C22]&[C20]
- * C101 - [C12]&[C28]
- * C102 - [C13]&[C28]
- * C103 - [C6]&[C21]&[C11]
- * C104 - [C6]&[C25]&[C26]
- * C105 - [C6]&(!([C25]|[C26]))&[C24]
- * C106 - [C6]&(!([C25]|[C26]))&[!C24]&[C11]
- * C107 -
- * C108 - [C6]&(!([C25]|[C26]))&[!C24]&[!C11]&[C9]&[C10]&[!C30]
- * C109 - [C6]&(!([C25]|[C26]))&[!C24]&[!C11]&[C9]&[C10]&[C30]
- * C110 - [C27]&[!C24]&[C11]
- * C111 - [C27]&[!C24]&[!C11]&[C9]&[C10]&[!C30]
- * C112 - [C27]&[!C24]&[!C11]&[C9]&[C10]&[C30]
- * C113 - [C2]&[!C11]&[C9]&[C10]&[!C30]
- * C114 - [C2]&[!C11]&[C9]&[C10]&[C30]
- * C115 - [C9]&[C10]&[!C30]
- * C116 - [C9]&[C10]&[C30]
- *
- * 1.4 Guards
- * ==========
- * C1 -
- * C2 - all SI in the recovery scope
- * C3 -
- * C4 -
- * C5 -
- * C6 - all supected SUs or components have presence state == UNINSTANTIATED
- * or presence state == INSTANTIATION_FAILED
- * C7 - original event == failover node
- * C8 -
- * C9 - original event == failover su
- * C10 - SaAmfSGAutoRepair == true
- * C11 - spare SUs exist
- * C12 - original event == start(all SUs)
- * C13 - original event == start(node)
- * C14 -
- * C15 - all SI-assignments on current dependency-level have requested-ha-state
- == confirmed-ha-state or operation failed
- * C16 -
- * C17 -
- * C18 -
- * C19 -
- * C20 - all suspected SUs have presence state == UNINSTANTIATED or
- presence state == xx_FAILED
- * C21 - no SI in the scope has an SI-assignment with HA-state == STANDBY
- * C22 - the concerned entity has ACTIVE HA-state
- * C23 -
- * C24 - at least one SI-assignment related to an SI in the scope has HA-state
- == STANDBY
- * C25 - redundancy model == N plus M
- * C26 - at least one SU has STANDBY assignments for more SIs than those SIs
- that are within the recovery scope
- * C27 - no SI-assignment related to SI protected by current SG has requested
- HA-state == REMOVED
- * C28 - no SU has presence state == INSTANTIATING
- * C29 -
- * C30 - more SUs not needed or the node hosting the SU to repair is disabled.
- * C31 - no new additional assignments needed or possible
- */
- #include <stdlib.h>
- #include <errno.h>
- #include "amf.h"
- #include "logsys.h"
- #include "main.h"
- #include "util.h"
- LOGSYS_DECLARE_SUBSYS ("AMF", LOG_INFO);
- static int assign_si (struct amf_sg *sg, int dependency_level);
- static void acsm_enter_activating_standby (struct amf_sg *sg);
- static void delete_si_assignments_in_scope (struct amf_sg *sg);
- static void acsm_enter_repairing_su (struct amf_sg *sg);
- static void standby_su_activated_cbfn (
- struct amf_si_assignment *si_assignment, int result);
- static void dependent_si_deactivated_cbfn (
- struct amf_si_assignment *si_assignment, int result);
- static void dependent_si_deactivated_cbfn2 (struct amf_sg *sg);
- static void assign_si_assumed_cbfn (
- struct amf_si_assignment *si_assignment, int result);
- static void acsm_enter_removing_standby_assignments (amf_sg_t *sg);
- static void acsm_enter_assigning_standby_to_spare (amf_sg_t *sg);
- static const char *sg_event_type_text[] = {
- "Unknown",
- "Failover SU",
- "Failover node",
- "Failover comp",
- "Switchover node",
- "Start",
- "Autoadjust",
- "Assign SI"
- };
- typedef struct sg_event {
- amf_sg_event_type_t event_type;
- amf_sg_t *sg;
- amf_su_t *su;
- amf_comp_t *comp;
- amf_node_t *node;
- } sg_event_t;
- /******************************************************************************
- * Internal (static) utility functions
- *****************************************************************************/
- static int is_cluster_start(amf_node_t *node_to_start)
- {
- return node_to_start == NULL;
- }
- static void sg_set_event (amf_sg_event_type_t sg_event_type,
- amf_sg_t *sg, amf_su_t *su, amf_comp_t *comp, amf_node_t * node,
- sg_event_t *sg_event)
- {
- sg_event->event_type = sg_event_type;
- sg_event->node = node;
- sg_event->su = su;
- sg_event->comp = comp;
- sg_event->sg = sg;
- }
- static void sg_defer_event (amf_sg_event_type_t event_type,
- sg_event_t *sg_event)
- {
- ENTER("Defered event = %d", event_type);
- amf_fifo_put (event_type, &sg_event->sg->deferred_events,
- sizeof (sg_event_t),
- sg_event);
- }
- static void sg_recall_deferred_events (amf_sg_t *sg)
- {
- sg_event_t sg_event;
- ENTER ("%s", sg->name.value);
- if (amf_fifo_get (&sg->deferred_events, &sg_event)) {
- switch (sg_event.event_type) {
- case SG_FAILOVER_SU_EV:
- amf_sg_failover_su_req (sg_event.sg,
- sg_event.su, sg_event.node);
- break;
- case SG_FAILOVER_NODE_EV:
- amf_sg_failover_node_req (sg_event.sg,
- sg_event.node);
- break;
- case SG_FAILOVER_COMP_EV:
- case SG_SWITCH_OVER_NODE_EV:
- case SG_START_EV:
- case SG_AUTO_ADJUST_EV:
- default:
- dprintf("event_type = %d", sg_event.event_type);
- break;
- }
- }
- }
- static void timer_function_sg_recall_deferred_events (void *data)
- {
- amf_sg_t *sg = (amf_sg_t*)data;
- ENTER ("");
- sg_recall_deferred_events (sg);
- }
- static void acsm_enter_idle (amf_sg_t *sg)
- {
- SaNameT dn;
- ENTER ("sg: %s state: %d", sg->name.value, sg->avail_state);
- sg->avail_state = SG_AC_Idle;
- if (sg->recovery_scope.event_type != 0) {
- switch (sg->recovery_scope.event_type) {
- case SG_FAILOVER_SU_EV:
- assert (sg->recovery_scope.sus[0] != NULL);
- amf_su_dn_make (sg->recovery_scope.sus[0], &dn);
- log_printf (
- LOG_NOTICE,
- "'%s' %s recovery action finished",
- dn.value,
- sg_event_type_text[sg->recovery_scope.event_type]);
- break;
- case SG_FAILOVER_NODE_EV:
- amf_node_sg_failed_over (
- sg->recovery_scope.node, sg);
- log_printf (
- LOG_NOTICE,
- "'%s for %s' recovery action finished",
- sg_event_type_text[sg->recovery_scope.event_type],
- sg->name.value);
- break;
- case SG_START_EV:
- amf_application_sg_started (sg->application,
- sg, this_amf_node);
- break;
- case SG_ASSIGN_SI_EV:
- log_printf (LOG_NOTICE, "All SI assigned");
- break;
- default:
- log_printf (
- LOG_NOTICE,
- "'%s' recovery action finished",
- sg_event_type_text[sg->recovery_scope.event_type]);
- break;
- }
- }
- if (sg->recovery_scope.sus != NULL) {
- free ((void *)sg->recovery_scope.sus);
- }
- if (sg->recovery_scope.sis != NULL) {
- free ((void *)sg->recovery_scope.sis);
- }
- memset (&sg->recovery_scope, 0, sizeof (struct sg_recovery_scope));
- sg->node_to_start = NULL;
- amf_call_function_asynchronous (
- timer_function_sg_recall_deferred_events, sg);
- }
- static int su_instantiated_count (struct amf_sg *sg)
- {
- int cnt = 0;
- struct amf_su *su;
- for (su = sg->su_head; su != NULL; su = su->next) {
- if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED)
- cnt++;
- }
- return cnt;
- }
- static int has_any_su_in_scope_active_workload (struct amf_sg *sg)
- {
- struct amf_su **sus= sg->recovery_scope.sus;
- struct amf_si_assignment *si_assignment;
- while (*sus != NULL) {
- si_assignment = amf_su_get_next_si_assignment (*sus, NULL);
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState !=
- SA_AMF_HA_ACTIVE) {
- break;
- }
- si_assignment = amf_su_get_next_si_assignment (
- *sus, si_assignment);
- }
- if (si_assignment != NULL) {
- break;
- }
- sus++;
- }
- return(*sus == NULL);
- }
- static int is_any_si_in_scope_assigned_standby (struct amf_sg *sg)
- {
- struct amf_si **sis= sg->recovery_scope.sis;
- struct amf_si_assignment *si_assignment;
- /*
- * Check if there is any si in the scope which has no
- * active assignment and at least one standby assignment.
- */
- while (*sis != NULL) {
- si_assignment = (*sis)->assigned_sis;
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState ==
- SA_AMF_HA_ACTIVE) {
- break;
- }
- si_assignment = si_assignment->next;
- }
- if (si_assignment == NULL) {
- /* There is no ACTIVE assignment ..*/
- si_assignment = (*sis)->assigned_sis;
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState ==
- SA_AMF_HA_STANDBY) {
- break;
- }
- si_assignment = si_assignment->next;
- }
- if (si_assignment != NULL) {
- /* .. and one STANDBY assignment*/
- break;
- }
- }
- sis++;
- }
- return(*sis != NULL);
- }
- static void acsm_enter_terminating_suspected (struct amf_sg *sg)
- {
- struct amf_su **sus= sg->recovery_scope.sus;
- ENTER("%s",sg->name.value);
- sg->avail_state = SG_AC_TerminatingSuspected;
- /*
- * Terminate suspected SU(s)
- */
- while (*sus != 0) {
- amf_su_terminate (*sus);
- sus++;
- }
- }
- static inline int su_presense_state_is_ored (amf_su_t *su,
- SaAmfPresenceStateT state1,SaAmfPresenceStateT state2,
- SaAmfPresenceStateT state3)
- {
- return(su->saAmfSUPresenceState == state1 || su->saAmfSUPresenceState ==
- state2 || su->saAmfSUPresenceState == state3) ? 1 : 0;
- }
- static inline int su_presense_state_is_not (amf_su_t *su,
- SaAmfPresenceStateT state1,SaAmfPresenceStateT state2,
- SaAmfPresenceStateT state3)
- {
- return(su->saAmfSUPresenceState != state1 && su->saAmfSUPresenceState !=
- state2 && su->saAmfSUPresenceState != state3) ? 1 : 0;
- }
- static void timer_function_dependent_si_deactivated2 (void *data)
- {
- amf_sg_t *sg = (amf_sg_t *)data;
- ENTER ("");
- dependent_si_deactivated_cbfn2 (sg);
- }
- static struct amf_si *si_get_dependent (struct amf_si *si)
- {
- struct amf_si *tmp_si = NULL;
- if (si->depends_on != NULL) {
- SaNameT res_arr[2];
- int is_match;
- if (si->depends_on->name.length < SA_MAX_NAME_LENGTH) {
- si->depends_on->name.value[si->depends_on->name.length] = '\0';
- }
- is_match = sa_amf_grep ((char*)si->depends_on->name.value,
- "safDepend=.*,safSi=(.*),safApp=.*",
- 2, res_arr);
- if (is_match) {
- tmp_si = amf_si_find (si->application, (char*)res_arr[1].value);
- } else {
- log_printf (LOG_LEVEL_ERROR, "distinguished name for "
- "amf_si_depedency failed\n");
- openais_exit_error (AIS_DONE_FATAL_ERR);
- }
- }
- return tmp_si;
- }
- static struct amf_si *amf_dependent_get_next (struct amf_si *si,
- struct amf_si *si_iter)
- {
- struct amf_si *tmp_si;
- struct amf_application *application;
- if (si_iter == NULL) {
- assert(amf_cluster != NULL);
- application = amf_cluster->application_head;
- assert(application != NULL);
- tmp_si = application->si_head;
- } else {
- tmp_si = si_iter->next;
- if (tmp_si == NULL) {
- application = si->application->next;
- if (application == NULL) {
- goto out;
- }
- }
- }
- for (; tmp_si != NULL; tmp_si = tmp_si->next) {
- struct amf_si *depends_on_si = si_get_dependent (tmp_si);
- while (depends_on_si != NULL) {
- if (depends_on_si == si) {
- goto out;
- }
- depends_on_si = depends_on_si->next;
- }
- }
- out:
- return tmp_si;
- }
- static void acsm_enter_deactivating_dependent_workload (amf_sg_t *sg)
- {
- struct amf_si **sis= sg->recovery_scope.sis;
- struct amf_si_assignment *si_assignment;
- int callback_pending = 0;
- sg->avail_state = SG_AC_DeactivatingDependantWorkload;
- ENTER("'%s'",sg->name.value);
- /*
- * For each SI in the recovery scope, find all active
- * assignments and request them to be deactivated.
- */
- while (*sis != NULL) {
- struct amf_si *dependent_si;
- struct amf_si *si = *sis;
- si_assignment = si->assigned_sis;
- dependent_si = amf_dependent_get_next (si, NULL);
- while (dependent_si != NULL) {
- si_assignment = dependent_si->assigned_sis;
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState ==
- SA_AMF_HA_ACTIVE) {
- si_assignment->requested_ha_state =
- SA_AMF_HA_QUIESCED;
- callback_pending = 1;
- amf_si_ha_state_assume (
- si_assignment,
- dependent_si_deactivated_cbfn);
- }
- si_assignment = si_assignment->next;
- }
- dependent_si = amf_dependent_get_next (si, dependent_si);
- }
- sis++;
- }
- if (callback_pending == 0) {
- static poll_timer_handle dependent_si_deactivated_handle;
- ENTER("");
- poll_timer_add (aisexec_poll_handle, 0, sg,
- timer_function_dependent_si_deactivated2,
- &dependent_si_deactivated_handle);
- }
- }
- /**
- * Enter function for state SG_AC_ActivatingStandby. It activates
- * one STANDBY assignment for each SI in the recovery scope.
- * @param sg
- */
- static void acsm_enter_activating_standby (struct amf_sg *sg)
- {
- struct amf_si **sis= sg->recovery_scope.sis;
- struct amf_si_assignment *si_assignment;
- int is_no_standby_activated = 1;
- ENTER("'%s'",sg->name.value);
- sg->avail_state = SG_AC_ActivatingStandby;
- /*
- * For each SI in the recovery scope, find one standby
- * SI assignment and activate it.
- */
- while (*sis != NULL) {
- si_assignment = (*sis)->assigned_sis;
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState ==
- SA_AMF_HA_STANDBY) {
- si_assignment->requested_ha_state =
- SA_AMF_HA_ACTIVE;
- amf_si_ha_state_assume (
- si_assignment, standby_su_activated_cbfn);
- is_no_standby_activated = 0;
- break;
- }
- si_assignment = si_assignment->next;
- }
- sis++;
- }
- if (is_no_standby_activated) {
- acsm_enter_assigning_standby_to_spare (sg);
- }
- }
- static void acsm_enter_repairing_su (struct amf_sg *sg)
- {
- struct amf_su **sus= sg->recovery_scope.sus;
- int is_any_su_instantiated = 0;
- const int PERFORMS_INSTANTIATING = 1;
- ENTER("'%s'",sg->name.value);
- sg->avail_state = SG_AC_ReparingSu;
- /*
- * Instantiate SUs in current recovery scope until the configured
- * preference is fulfiled.
- */
- while (*sus != NULL) {
- if (su_instantiated_count ((*sus)->sg) <
- (*sus)->sg->saAmfSGNumPrefInserviceSUs) {
- struct amf_node *node =
- amf_node_find(&((*sus)->saAmfSUHostedByNode));
- if (node == NULL) {
- log_printf (LOG_LEVEL_ERROR,
- "Su to recover not hosted on any node\n");
- openais_exit_error (AIS_DONE_FATAL_ERR);
- }
- if (node->saAmfNodeOperState == SA_AMF_OPERATIONAL_ENABLED) {
- /* node is synchronized */
-
- if (amf_su_instantiate ((*sus)) == PERFORMS_INSTANTIATING) {
- is_any_su_instantiated = 1;
- }
- }
- }
- sus++;
- }
- if (is_any_su_instantiated == 0) {
- acsm_enter_idle (sg);
- }
- }
- static inline void remove_all_suspected_sus (amf_sg_t *sg)
- {
- amf_su_t *su;
- ENTER("");
- for (su = sg->su_head; su != NULL; su =su->next) {
- amf_comp_t *component;
- for (component = su->comp_head; component != NULL;
- component = component->next) {
- amf_comp_error_suspected_clear (component);
- }
- }
- }
- static int is_all_si_assigned (amf_sg_t *sg)
- {
- struct amf_si_assignment *si_assignment;
- int si_assignment_cnt = 0;
- int confirmed_assignments = 0;
- amf_si_t *si;
- for (si = sg->application->si_head; si != NULL; si = si->next) {
- if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
- for (si_assignment = si->assigned_sis;
- si_assignment != NULL;
- si_assignment = si_assignment->next) {
- si_assignment_cnt++;
- if (si_assignment->requested_ha_state ==
- si_assignment->saAmfSISUHAState) {
- confirmed_assignments++;
- }
- }
- }
- }
- return (confirmed_assignments == si_assignment_cnt);
- }
- /**
- * Inquire if SI is assigned to SU
- * @param si
- * @param su
- *
- * @return int
- */
- static int is_si_assigned_to_su (amf_si_t *si, amf_su_t *su)
- {
- amf_si_assignment_t *si_assignment = 0;
- int si_assignment_assigned_to_su = 0;
- for (si_assignment = si->assigned_sis; si_assignment != NULL;
- si_assignment = si_assignment->next) {
- if (si_assignment->su == su) {
- si_assignment_assigned_to_su = 1;
- break;
- }
- }
- return si_assignment_assigned_to_su;
- }
- /**
- * Inquire if SU is a spare.
- * @param sg
- * @param su
- *
- * @return int
- */
- static int is_spare_su (amf_sg_t *sg, amf_su_t *su)
- {
- amf_si_t *si;
- int spare_su = 1;
- for (si = sg->application->si_head; si != NULL; si = si->next) {
- if(name_match(&sg->name, &si->saAmfSIProtectedbySG)) {
- if (is_si_assigned_to_su (si, su)) {
- spare_su = 0;
- break;
- }
- }
- }
- return (spare_su && su->saAmfSUPresenceState ==
- SA_AMF_PRESENCE_INSTANTIATED);
- }
- /**
- * Inqure if it is any spare SUs covered by SG
- * @param sg
- *
- * @return int
- */
- static int is_spare_sus (amf_sg_t *sg)
- {
- amf_su_t *su = NULL;
- int spare_sus = 0;
- for (su = sg->su_head; su != NULL; su = su->next) {
- if (is_spare_su(sg, su)) {
- spare_sus = 1;
- break;
- }
- }
- return spare_sus;
- }
- /**
- * Provide standby assignments for the spare SUs in SG
- * @param sg
- */
- static void assume_standby_si_assignment_for_spare_sus (amf_sg_t *sg)
- {
- ENTER("");
- assign_si (sg, 0);
- }
- /**
- * Enter the AssigningStandbyToSpare state.
- * @param sg
- */
- static void acsm_enter_assigning_standby_to_spare (amf_sg_t *sg)
- {
- ENTER("%s", sg->name.value);
- sg->avail_state = SG_AC_AssigningStandbyToSpare;
- if (is_spare_sus (sg)) {
- assume_standby_si_assignment_for_spare_sus (sg);
- } else {
- switch (sg->recovery_scope.event_type) {
- case SG_FAILOVER_NODE_EV:
- acsm_enter_idle (sg);
- break;
- case SG_FAILOVER_SU_EV:
- acsm_enter_repairing_su (sg);
- break;
- default:
- dprintf("event_type %d",sg->recovery_scope.event_type);
- assert (0);
- break;
- }
- }
- }
- /**
- * Checks if the si pointed out is already in the scope.
- * @param sg
- * @param si
- */
- static int is_si_in_scope(struct amf_sg *sg, struct amf_si *si)
- {
- struct amf_si **tmp_sis= sg->recovery_scope.sis;
- while (*tmp_sis != NULL) {
- if (*tmp_sis == si) {
- break;
- }
- tmp_sis++;
- }
- return(*tmp_sis == si);
- }
- /**
- * Adds the si pointed out to the scope.
- * @param sg
- * @param si
- */
- static void add_si_to_scope ( struct amf_sg *sg, struct amf_si *si)
- {
- int number_of_si = 2; /* It shall be at least two */
- struct amf_si **tmp_sis= sg->recovery_scope.sis;
- ENTER ("'%s'", si->name.value);
- while (*tmp_sis != NULL) {
- number_of_si++;
- tmp_sis++;
- }
- sg->recovery_scope.sis = (struct amf_si **)
- realloc((void *)sg->recovery_scope.sis,
- sizeof (struct amf_si *)*number_of_si);
- assert (sg->recovery_scope.sis != NULL);
- tmp_sis= sg->recovery_scope.sis;
- while (*tmp_sis != NULL) {
- tmp_sis++;
- }
- *tmp_sis = si;
- *(++tmp_sis) = NULL;
- }
- /**
- * Adds the ssu pointed out to the scope.
- * @param sg
- * @param su
- */
- static void add_su_to_scope (struct amf_sg *sg, struct amf_su *su)
- {
- int number_of_su = 2; /* It shall be at least two */
- struct amf_su **tmp_sus= sg->recovery_scope.sus;
- ENTER ("'%s'", su->name.value);
- while (*tmp_sus != NULL) {
- number_of_su++;
- tmp_sus++;
- }
- sg->recovery_scope.sus = (struct amf_su **)
- realloc((void *)sg->recovery_scope.sus,
- sizeof (struct amf_su *)*number_of_su);
- assert (sg->recovery_scope.sus != NULL);
- tmp_sus= sg->recovery_scope.sus;
- while (*tmp_sus != NULL) {
- tmp_sus++;
- }
- *tmp_sus = su;
- *(++tmp_sus) = NULL;
- }
- /**
- * Set recovery scope for failover SU.
- * @param sg
- * @param su
- */
- static void set_scope_for_failover_su (struct amf_sg *sg, struct amf_su *su)
- {
- struct amf_si_assignment *si_assignment;
- struct amf_si **sis;
- struct amf_su **sus;
- SaNameT dn;
- sg->recovery_scope.event_type = SG_FAILOVER_SU_EV;
- sg->recovery_scope.node = NULL;
- sg->recovery_scope.comp = NULL;
- sg->recovery_scope.sus = (struct amf_su **)
- calloc (2, sizeof (struct amf_su *));
- sg->recovery_scope.sis = (struct amf_si **)
- calloc (1, sizeof (struct amf_si *));
- assert ((sg->recovery_scope.sus != NULL) &&
- (sg->recovery_scope.sis != NULL));
- sg->recovery_scope.sus[0] = su;
- amf_su_dn_make (sg->recovery_scope.sus[0], &dn);
- log_printf (
- LOG_NOTICE, "'%s' for %s recovery action started",
- sg_event_type_text[sg->recovery_scope.event_type],
- dn.value);
- si_assignment = amf_su_get_next_si_assignment (su, NULL);
- while (si_assignment != NULL) {
- if (is_si_in_scope(sg, si_assignment->si) == 0) {
- add_si_to_scope(sg,si_assignment->si );
- }
- si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
- }
- sus = sg->recovery_scope.sus;
- dprintf("The following sus are within the scope:\n");
- while (*sus != NULL) {
- dprintf("%s\n", (*sus)->name.value);
- sus++;
- }
- sis= sg->recovery_scope.sis;
- dprintf("The following sis are within the scope:\n");
- while (*sis != NULL) {
- dprintf("%s\n", (*sis)->name.value);
- sis++;
- }
- }
- static void set_scope_for_failover_node (struct amf_sg *sg, struct amf_node *node)
- {
- struct amf_si_assignment *si_assignment;
- struct amf_si **sis;
- struct amf_su **sus;
- struct amf_su *su;
- ENTER ("'%s'", node->name.value);
- sg->recovery_scope.event_type = SG_FAILOVER_NODE_EV;
- sg->recovery_scope.node = node;
- sg->recovery_scope.comp = NULL;
- sg->recovery_scope.sus = (struct amf_su **)
- calloc (1, sizeof (struct amf_su *));
- sg->recovery_scope.sis = (struct amf_si **)
- calloc (1, sizeof (struct amf_si *));
- log_printf (
- LOG_NOTICE, "'%s' for node %s recovery action started",
- sg_event_type_text[sg->recovery_scope.event_type],
- node->name.value);
- assert ((sg->recovery_scope.sus != NULL) &&
- (sg->recovery_scope.sis != NULL));
- for (su = sg->su_head; su != NULL; su = su->next) {
- if (name_match (&node->name, &su->saAmfSUHostedByNode)) {
- add_su_to_scope (sg, su);
- }
- }
- sus = sg->recovery_scope.sus;
- while (*sus != 0) {
- su = *sus;
- si_assignment = amf_su_get_next_si_assignment (su, NULL);
- while (si_assignment != NULL) {
- if (is_si_in_scope(sg, si_assignment->si) == 0) {
- add_si_to_scope(sg, si_assignment->si );
- }
- si_assignment = amf_su_get_next_si_assignment (
- su, si_assignment);
- }
- sus++;
- }
- sus = sg->recovery_scope.sus;
- dprintf("The following sus are within the scope:\n");
- while (*sus != NULL) {
- dprintf("%s\n", (*sus)->name.value);
- sus++;
- }
- sis = sg->recovery_scope.sis;
- dprintf("The following sis are within the scope:\n");
- while (*sis != NULL) {
- dprintf("%s\n", (*sis)->name.value);
- sis++;
- }
- }
- static void delete_si_assignment (amf_si_assignment_t *si_assignment)
- {
- amf_csi_t *csi;
- amf_si_assignment_t *si_assignment_tmp;
- amf_si_assignment_t **prev = &si_assignment->si->assigned_sis;
- for (csi = si_assignment->si->csi_head; csi != NULL; csi = csi->next) {
- amf_csi_delete_assignments (csi, si_assignment->su);
- }
- for (si_assignment_tmp = si_assignment->si->assigned_sis;
- si_assignment_tmp != NULL;
- si_assignment_tmp = si_assignment_tmp->next) {
- if (si_assignment_tmp == si_assignment) {
- amf_si_assignment_t *to_be_removed = si_assignment_tmp;
- *prev = si_assignment_tmp->next;
- dprintf ("SI assignment %s unlinked",
- to_be_removed->name.value);
- free (to_be_removed);
- } else {
- prev = &si_assignment_tmp->next;
- }
- }
- }
- /**
- * Delete all SI assignments and all CSI assignments
- * by requesting all contained components.
- * @param su
- */
- static void delete_si_assignments (struct amf_su *su)
- {
- struct amf_csi *csi;
- struct amf_si *si;
- struct amf_si_assignment *si_assignment;
- struct amf_si_assignment **prev;
- ENTER ("'%s'", su->name.value);
- for (si = su->sg->application->si_head; si != NULL; si = si->next) {
- prev = &si->assigned_sis;
- if (!name_match (&si->saAmfSIProtectedbySG, &su->sg->name)) {
- continue;
- }
- for (csi = si->csi_head; csi != NULL; csi = csi->next) {
- amf_csi_delete_assignments (csi, su);
- }
- for (si_assignment = si->assigned_sis; si_assignment != NULL;
- si_assignment = si_assignment->next) {
- if (si_assignment->su == su) {
- struct amf_si_assignment *tmp = si_assignment;
- *prev = si_assignment->next;
- dprintf ("SI assignment %s unlinked", tmp->name.value);
- free (tmp);
- } else {
- prev = &si_assignment->next;
- }
- }
- }
- }
- /**
- * Delete all SI assignments and all CSI assignments in current
- * recovery scope.
- * @param sg
- */
- static void delete_si_assignments_in_scope (struct amf_sg *sg)
- {
- struct amf_su **sus= sg->recovery_scope.sus;
- while (*sus != NULL) {
- delete_si_assignments (*sus);
- sus++;
- }
- }
- /**
- * Given an SI, find and return the SU assigned as standby
- * @param si
- *
- * @return amf_su_t*
- */
- static amf_su_t *find_standby_su (amf_si_t *si)
- {
- amf_si_assignment_t *si_assignment;
- amf_su_t *standby_su = NULL;
- si_assignment = si->assigned_sis;
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
- standby_su = si_assignment->su;
- break;
- }
- si_assignment = si_assignment->next;
- }
- return standby_su;
- }
- static int no_si_assignment_is_requested_to_be_removed (amf_sg_t *sg)
- {
- amf_si_t *si;
- int no_to_be_removed = 1;
- for (si = sg->application->si_head; si != NULL; si = si->next) {
- if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
- amf_si_assignment_t *si_assignment = 0;
- for (si_assignment = si->assigned_sis; si_assignment != NULL;
- si_assignment = si_assignment->next) {
- if (si_assignment->requested_ha_state ==
- USR_AMF_HA_STATE_REMOVED) {
- no_to_be_removed = 0;
- goto out;
- }
- }
- }
- }
- out:
- return no_to_be_removed;
- }
- static void removed_si_assignment_callback_fn (void *si_assignment_in)
- {
- amf_si_assignment_t *si_assignment = si_assignment_in;
- ENTER("");
- delete_si_assignment (si_assignment);
- /*
- * if all si assignments are remove then change state
- */
- if (no_si_assignment_is_requested_to_be_removed (si_assignment->su->sg)) {
- acsm_enter_activating_standby (si_assignment->su->sg);
- }
- }
- /**
- *
- * @param sg
- *
- * @return int, number of removed SI assignments
- */
- static int remove_standby_si_assignments (amf_sg_t *sg)
- {
- struct amf_si **sis = sg->recovery_scope.sis;
- struct amf_si_assignment *si_assignment;
- amf_su_t *standby_su;
- int removed = 0;
- ENTER("'%s'", sg->name.value);
- /*
- * For each SI in the recovery scope, find a standby
- * SU, then remove all 'standby SI assignment' not in
- * the recovery scope.
- */
- while (*sis != NULL) {
- standby_su = find_standby_su (*sis);
- if (standby_su != NULL) {
- si_assignment = amf_su_get_next_si_assignment (standby_su, NULL);
- while (si_assignment != NULL) {
- amf_si_t **sia;
- int in_recovery_scope;
- for (sia = sg->recovery_scope.sis, in_recovery_scope = 0;
- *sia != NULL; sia++) {
- if (name_match (&si_assignment->si->name, &(*sia)->name)) {
- in_recovery_scope = 1;
- }
- }
- /*
- * The si_assignment found with standby hastate is not in the
- * recovery scope. The found si_assignment will then be
- * requested to be removed once.
- */
- if (!in_recovery_scope &&
- si_assignment->requested_ha_state !=
- USR_AMF_HA_STATE_REMOVED) {
- amf_si_assignment_remove (si_assignment,
- removed_si_assignment_callback_fn);
- removed++;
- }
- si_assignment = amf_su_get_next_si_assignment (standby_su,
- si_assignment);
- }
- }
- sis++;
- }
- return removed;
- }
- /**
- * Entry function for state 'removing standby assignments'
- * @param sg
- */
- static void acsm_enter_removing_standby_assignments (amf_sg_t *sg)
- {
- ENTER("SG: %s", sg->name.value);
- sg->avail_state = SG_AC_RemovingStandbyAssignments;
- if (sg->saAmfSGRedundancyModel == SA_AMF_NPM_REDUNDANCY_MODEL) {
- if (!remove_standby_si_assignments (sg)) {
- acsm_enter_activating_standby (sg);
- }
- }
- }
- static inline int div_round (int a, int b)
- {
- int res;
- assert (b != 0);
- res = a / b;
- if ((a % b) != 0)
- res++;
- return res;
- }
- static int no_su_has_presence_state (
- struct amf_sg *sg, struct amf_node *node_to_start,
- SaAmfPresenceStateT state)
- {
- struct amf_su *su;
- int no_su_has_presence_state = 1;
- for (su = sg->su_head; su != NULL; su = su->next) {
- if (su->saAmfSUPresenceState == state) {
- if (node_to_start == NULL) {
- no_su_has_presence_state = 0;
- break;
- } else {
- if (name_match(&node_to_start->name,
- &su->saAmfSUHostedByNode)) {
- no_su_has_presence_state = 0;
- break;
- }
- }
- }
- }
- return no_su_has_presence_state;
- }
- #if COMPILE_OUT
- static int all_su_in_scope_has_presence_state (
- struct amf_sg *sg, SaAmfPresenceStateT state)
- {
- struct amf_su **sus= sg->recovery_scope.sus;
- while (*sus != NULL) {
- if ((*sus)->saAmfSUPresenceState != state) {
- break;
- }
- sus++;
- }
- return(*sus == NULL);
- }
- #endif
- static int all_su_in_scope_has_either_two_presence_state (
- amf_sg_t *sg,
- SaAmfPresenceStateT state1,
- SaAmfPresenceStateT state2)
- {
- struct amf_su **sus = sg->recovery_scope.sus;
- while (*sus != NULL) {
- if (!((*sus)->saAmfSUPresenceState == state1 ||
- (*sus)->saAmfSUPresenceState == state2)) {
- break;
- }
- sus++;
- }
- return (*sus == NULL);
- }
- static int all_su_in_scope_has_either_of_three_presence_state (amf_sg_t *sg,
- SaAmfPresenceStateT state1, SaAmfPresenceStateT state2,
- SaAmfPresenceStateT state3)
- {
- struct amf_su **sus = sg->recovery_scope.sus;
- while (*sus != NULL) {
- if (!((*sus)->saAmfSUPresenceState == state1 ||
- (*sus)->saAmfSUPresenceState == state2 ||
- (*sus)->saAmfSUPresenceState == state3)) {
- break;
- }
- sus++;
- }
- return (*sus == NULL);
- }
- /**
- * Get number of SIs protected by the specified SG.
- * @param sg
- *
- * @return int
- */
- static int sg_si_count_get (struct amf_sg *sg)
- {
- struct amf_si *si;
- int cnt = 0;
- for (si = sg->application->si_head; si != NULL; si = si->next) {
- if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
- cnt += 1;
- }
- }
- return(cnt);
- }
- static int amf_si_get_saAmfSINumReqActiveAssignments(struct amf_si *si)
- {
- struct amf_si_assignment *si_assignment = si->assigned_sis;
- int number_of_req_active_assignments = 0;
- for (; si_assignment != NULL; si_assignment = si_assignment->next) {
- if (si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
- number_of_req_active_assignments++;
- }
- }
- return number_of_req_active_assignments;
- }
- static int amf_si_get_saAmfSINumReqStandbyAssignments(struct amf_si *si)
- {
- struct amf_si_assignment *si_assignment = si->assigned_sis;
- int number_of_req_active_assignments = 0;
- for (; si_assignment != NULL; si_assignment = si_assignment->next) {
- if (si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
- number_of_req_active_assignments++;
- }
- }
- return number_of_req_active_assignments;
- }
- static int sg_assign_active_nplusm (struct amf_sg *sg, int su_active_assign)
- {
- struct amf_su *su;
- struct amf_si *si;
- int assigned = 0;
- int assign_to_su = 0;
- int total_assigned = 0;
- int si_left;
- int si_total;
- int su_left_to_assign = su_active_assign;
- ENTER("SG: %s", sg->name.value);
- si_total = sg_si_count_get (sg);
- si_left = si_total;
- assign_to_su = div_round (si_left, su_active_assign);
- if (assign_to_su > sg->saAmfSGMaxActiveSIsperSUs) {
- assign_to_su = sg->saAmfSGMaxActiveSIsperSUs;
- }
- su = sg->su_head;
- while (su != NULL && su_left_to_assign > 0) {
- if (amf_su_get_saAmfSUReadinessState (su) !=
- SA_AMF_READINESS_IN_SERVICE ||
- amf_su_get_saAmfSUNumCurrActiveSIs (su) == assign_to_su ||
- amf_su_get_saAmfSUNumCurrStandbySIs (su) > 0) {
- su = su->next;
- continue; /* Not in service */
- }
- si = sg->application->si_head;
- assigned = 0;
- assign_to_su = div_round (si_left, su_left_to_assign);
- if (assign_to_su > sg->saAmfSGMaxActiveSIsperSUs) {
- assign_to_su = sg->saAmfSGMaxActiveSIsperSUs;
- }
- while (si != NULL) {
- if (name_match (&si->saAmfSIProtectedbySG, &sg->name) &&
- assigned < assign_to_su &&
- amf_si_get_saAmfSINumReqActiveAssignments(si) == 0) {
- assigned += 1;
- total_assigned += 1;
- amf_su_assign_si (su, si, SA_AMF_HA_ACTIVE);
- }
- si = si->next;
- }
- su = su->next;
- su_left_to_assign -= 1;
- si_left -= assigned;
- dprintf (" su_left_to_assign =%d, si_left=%d\n",
- su_left_to_assign, si_left);
- }
- assert (total_assigned <= si_total);
- if (total_assigned == 0) {
- dprintf ("Info: No SIs assigned");
- }
- return total_assigned;
- }
- static int sg_assign_standby_nplusm (struct amf_sg *sg, int su_standby_assign)
- {
- struct amf_su *su;
- struct amf_si *si;
- int assigned = 0;
- int assign_to_su = 0;
- int total_assigned = 0;
- int si_left;
- int si_total;
- int su_left_to_assign = su_standby_assign;
- ENTER ("'%s'", sg->name.value);
- if (su_standby_assign == 0) {
- return 0;
- }
- si_total = sg_si_count_get (sg);
- si_left = si_total;
- assign_to_su = div_round (si_left, su_standby_assign);
- if (assign_to_su > sg->saAmfSGMaxStandbySIsperSUs) {
- assign_to_su = sg->saAmfSGMaxStandbySIsperSUs;
- }
- su = sg->su_head;
- while (su != NULL && su_left_to_assign > 0) {
- if (amf_su_get_saAmfSUReadinessState (su) !=
- SA_AMF_READINESS_IN_SERVICE ||
- amf_su_get_saAmfSUNumCurrActiveSIs (su) > 0 ||
- amf_su_get_saAmfSUNumCurrStandbySIs (su) ==
- assign_to_su) {
- su = su->next;
- continue; /* Not available for assignment */
- }
- si = sg->application->si_head;
- assigned = 0;
- assign_to_su = div_round (si_left, su_left_to_assign);
- if (assign_to_su > sg->saAmfSGMaxStandbySIsperSUs) {
- assign_to_su = sg->saAmfSGMaxStandbySIsperSUs;
- }
- while (si != NULL) {
- if (name_match (&si->saAmfSIProtectedbySG, &sg->name) &&
- assigned < assign_to_su &&
- amf_si_get_saAmfSINumReqStandbyAssignments (si) == 0) {
- assigned += 1;
- total_assigned += 1;
- amf_su_assign_si (su, si, SA_AMF_HA_STANDBY);
- }
- si = si->next;
- }
- su_left_to_assign -= 1;
- si_left -= assigned;
- dprintf (" su_left_to_assign =%d, si_left=%d\n",
- su_left_to_assign, si_left);
- su = su->next;
- }
- assert (total_assigned <= si_total);
- if (total_assigned == 0) {
- dprintf ("Info: No SIs assigned!");
- }
- return total_assigned;
- }
- static int su_inservice_count_get (struct amf_sg *sg)
- {
- struct amf_su *su;
- int answer = 0;
- for (su = sg->su_head; su != NULL; su = su->next) {
- if (amf_su_get_saAmfSUReadinessState (su) ==
- SA_AMF_READINESS_IN_SERVICE) {
- answer += 1;
- }
- }
- return(answer);
- }
- static int su_active_out_of_service_count_get (amf_sg_t *sg)
- {
- int active_out_of_service_count = 0;
- amf_su_t *su;
- for (su = sg->su_head; su != NULL; su = su->next) {
- amf_si_assignment_t *si_assignment;
- si_assignment = amf_su_get_next_si_assignment (su, NULL);
- while (si_assignment != NULL) {
- if ((si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) &&
- (amf_su_get_saAmfSUReadinessState (su) ==
- SA_AMF_READINESS_OUT_OF_SERVICE)) {
- active_out_of_service_count += 1;
- }
- si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
- }
- }
- return active_out_of_service_count;
- }
- static int su_standby_out_of_service_count_get (amf_sg_t *sg)
- {
- int active_out_of_service_count = 0;
- amf_su_t *su;
- for (su = sg->su_head; su != NULL; su = su->next) {
- amf_si_assignment_t *si_assignment;
- si_assignment = amf_su_get_next_si_assignment (su, NULL);
- while (si_assignment != NULL) {
- if ((si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) &&
- (amf_su_get_saAmfSUReadinessState (su) ==
- SA_AMF_READINESS_OUT_OF_SERVICE)) {
- active_out_of_service_count += 1;
- }
- si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
- }
- }
- return active_out_of_service_count;
- }
- /**
- * This function calculates the number of active and standby assignments that
- * shall be done according to what is configured and the number of in-service
- * SUs available. This function leaves possible existing assignments as they are
- * but possibly adds new assignments. This function also initiates the transfer
- * of the calculated assignments to the SUs that shall execute them.
- *
- * TODO: dependency_level not used, hard coded
- * @param sg
- * @param dependency_level
- * @return - the sum of assignments initiated
- */
- static int assign_si (struct amf_sg *sg, int dependency_level)
- {
- int active_sus_needed = 0;
- int standby_sus_needed = 0;
- int inservice_count;
- int su_active_assign;
- int su_standby_assign;
- int su_spare_assign;
- int assigned = 0;
- int active_out_of_service = 0;
- int standby_out_of_service = 0;
- ENTER ("'%s'", sg->name.value);
- /**
- * Phase 1: Calculate assignments and create all runtime objects in
- * information model. Do not do the actual assignment, done in
- * phase 2.
- */
- /**
- * Calculate number of SUs to assign to active or standby state
- */
- inservice_count = su_inservice_count_get (sg);
- active_out_of_service = su_active_out_of_service_count_get(sg);
- standby_out_of_service = su_standby_out_of_service_count_get(sg);
- if (sg->saAmfSGNumPrefActiveSUs > 0) {
- active_sus_needed = div_round (
- sg_si_count_get (sg),
- sg->saAmfSGMaxActiveSIsperSUs);
- } else {
- log_printf (LOG_LEVEL_ERROR, "ERROR: saAmfSGNumPrefActiveSUs == 0 !!");
- openais_exit_error (AIS_DONE_FATAL_ERR);
- }
- if (sg->saAmfSGNumPrefStandbySUs > 0) {
- standby_sus_needed = div_round (
- sg_si_count_get (sg),
- sg->saAmfSGMaxStandbySIsperSUs);
- } else {
- log_printf (LOG_LEVEL_ERROR, "ERROR: saAmfSGNumPrefStandbySUs == 0 !!");
- openais_exit_error (AIS_DONE_FATAL_ERR);
- }
- dprintf ("(inservice=%d) (active_sus_needed=%d) (standby_sus_needed=%d)"
- "\n",
- inservice_count, active_sus_needed, standby_sus_needed);
- /* Determine number of active and standby service units
- * to assign based upon reduction procedure
- */
- if ((inservice_count < active_sus_needed - active_out_of_service)) {
- dprintf ("assignment VI - partial assignment with SIs drop outs\n");
- su_active_assign = inservice_count;
- su_standby_assign = 0;
- su_spare_assign = 0;
- } else
- if ((inservice_count < active_sus_needed - active_out_of_service +
- standby_sus_needed)) {
- dprintf ("assignment V - partial assignment with reduction of"
- " standby units\n");
- su_active_assign = active_sus_needed;
- su_standby_assign = inservice_count - active_sus_needed - active_out_of_service;
- su_spare_assign = 0;
- } else
- if ((inservice_count < sg->saAmfSGNumPrefActiveSUs + standby_sus_needed)) {
- 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 ((inservice_count <
- sg->saAmfSGNumPrefActiveSUs + sg->saAmfSGNumPrefStandbySUs)) {
- dprintf ("III: full assignment with reduction of standby service"
- " units\n");
- su_active_assign = sg->saAmfSGNumPrefActiveSUs;
- su_standby_assign = inservice_count - sg->saAmfSGNumPrefActiveSUs;
- su_spare_assign = 0;
- } else
- if ((inservice_count ==
- sg->saAmfSGNumPrefActiveSUs + sg->saAmfSGNumPrefStandbySUs)) {
- if (sg->saAmfSGNumPrefInserviceSUs > inservice_count) {
- dprintf ("II: full assignment with spare reduction\n");
- } else {
- dprintf ("II: full assignment without spares\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 = inservice_count -
- sg->saAmfSGNumPrefActiveSUs - sg->saAmfSGNumPrefStandbySUs;
- }
- dprintf ("(inservice=%d) (assigning active=%d) (assigning standby=%d)"
- " (assigning spares=%d)\n",
- inservice_count, su_active_assign, su_standby_assign, su_spare_assign);
- if (inservice_count > 0) {
- assigned = sg_assign_active_nplusm (sg, su_active_assign);
- assigned += sg_assign_standby_nplusm (sg, su_standby_assign);
- sg->saAmfSGNumCurrAssignedSUs = inservice_count;
- /**
- * Phase 2: do the actual assignment to the component
- * TODO: first do active, then standby
- */
- {
- struct amf_si *si;
- struct amf_si_assignment *si_assignment;
- for (si = sg->application->si_head; si != NULL; si = si->next) {
- if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
- for (si_assignment = si->assigned_sis;
- si_assignment != NULL;
- si_assignment = si_assignment->next) {
- if (si_assignment->requested_ha_state !=
- si_assignment->saAmfSISUHAState) {
- amf_si_ha_state_assume (
- si_assignment, assign_si_assumed_cbfn);
- }
- }
- }
- }
- }
- }
- LEAVE ("'%s'", sg->name.value);
- return assigned;
- }
- #ifdef COMPILE_OUT
- static void remove_si_in_scope (amf_sg_t *sg, amf_si_t *si)
- {
- int i;
- int j;
- amf_si_t **sis = sg->recovery_scope.sis;
- amf_si_t **new_sis = amf_calloc (1, sizeof (amf_si_t*));
- for (i = 0,j = 0; sis[i] != NULL; i++) {
- if (sis[i] == si) {
- continue;
- }
- new_sis[j] = sis[i];
- new_sis = amf_realloc (new_sis, j + sizeof (amf_si_t *));
- j++;
- }
- sg->recovery_scope.sis = new_sis;
- }
- #endif
- #ifdef COMPILE_OUT
- static void remove_sis_for_term_failed_su_from_scope (amf_sg_t *sg,
- amf_su_t *su)
- {
- amf_comp_t *component;
- /*
- * foreach component with presense state termiantion failed in su
- */
-
- for (component = su->comp_head; component != NULL;
- component = component->next) {
- amf_csi_assignment_t *csi_assignment;
- if (component->saAmfCompPresenceState !=
- SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
- continue;
- }
- csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
- while (csi_assignment != NULL) {
- remove_si_in_scope (sg, csi_assignment->csi->si);
- csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
- }
- }
- }
- #endif
- /**
- * This function returns 1 if the redundancy model is N plus M and at least one
- * component of the specified SU has an active HA-state, else the function
- * returns 0.
- * @param sg
- * @param su
- * @return int
- */
- static int is_comp_in_active_ha_state_nplusm (
- amf_sg_t *sg, amf_su_t *su)
- {
- amf_comp_t *component;
- amf_csi_assignment_t *csi_assignment;
- int comp_is_in_active_ha_state = 0;
- if(sg->saAmfSGRedundancyModel == SA_AMF_NPM_REDUNDANCY_MODEL) {
- for (component = su->comp_head; component != NULL;
- component = component->next) {
- csi_assignment = amf_comp_get_next_csi_assignment(component, NULL);
- while (csi_assignment != NULL) {
- if (csi_assignment->saAmfCSICompHAState == SA_AMF_HA_ACTIVE) {
- comp_is_in_active_ha_state = 1;
- goto out;
- }
- csi_assignment = amf_comp_get_next_csi_assignment(component,
- csi_assignment);
- }
- }
- }
- out:
- return comp_is_in_active_ha_state;
- }
- /**
- * This function handles a change of presence state reported by an SU contained
- * in specified SG. The new presence state is INSTANTIATED.
- * @param sg
- * @param su
- */
- static void sg_su_state_changed_to_instantiated (struct amf_sg *sg, struct amf_su *su)
- {
- ENTER("%s %s",sg->name.value, su->name.value);
- switch (sg->avail_state) {
- case SG_AC_InstantiatingServiceUnits:
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_INSTANTIATING)) {
- acsm_enter_idle (sg);
- }
- break;
- case SG_AC_ReparingSu:
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_INSTANTIATING)) {
- if (all_su_in_scope_has_either_of_three_presence_state(
- su->sg,
- SA_AMF_PRESENCE_INSTANTIATED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED,
- SA_AMF_PRESENCE_UNINSTANTIATED)) {
- su->sg->avail_state = SG_AC_AssigningWorkload;
- if (assign_si (sg, 0) == 0) {
- acsm_enter_idle (sg);
- }
- } else {
- dprintf ("avail-state: %u", sg->avail_state);
- assert (0);
- }
- }
- break;
- default:
- dprintf ("avail-state: %u", sg->avail_state);
- assert (0);
- break;
- }
- }
- /**
- * This function handles a change of presence state reported by an SU contained
- * in specified SG. The new presence state is UNINSTANTIATED.
- * @param sg
- * @param su
- */
- static void amf_sg_su_state_changed_to_uninstantiated (amf_sg_t *sg,
- amf_su_t *su)
- {
- ENTER("%s %s",sg->name.value, su->name.value);
- switch (sg->avail_state) {
- case SG_AC_TerminatingSuspected:
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_TERMINATING)) {
- if (all_su_in_scope_has_either_two_presence_state (sg,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED)) {
-
- delete_si_assignments_in_scope (sg);
-
- if (is_any_si_in_scope_assigned_standby (sg)) {
- remove_all_suspected_sus (sg);
- acsm_enter_removing_standby_assignments (sg);
- } else { /*is_no_si_in_scope_assigned_standby*/
- remove_all_suspected_sus (sg);
- acsm_enter_assigning_standby_to_spare (sg);
- }
- }
- }
- break;
- case SG_AC_ReparingSu:
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_TERMINATING)) {
- if (all_su_in_scope_has_either_of_three_presence_state(
- su->sg,
- SA_AMF_PRESENCE_INSTANTIATED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED,
- SA_AMF_PRESENCE_UNINSTANTIATED)) {
- su->sg->avail_state = SG_AC_AssigningWorkload;
- if (assign_si (sg, 0) == 0) {
- acsm_enter_idle (sg);
- }
- }
- }
- break;
- default:
- log_printf (LOG_ERR, "sg avail_state = %d", sg->avail_state);
- assert (0);
- break;
- }
- }
- /**
- * This function handles a change of presence state reported by an SU contained
- * in specified SG. The new presence state is TERMINATION_FAILED.
- * @param sg
- * @param su
- */
- static void amf_sg_su_state_changed_to_termination_failed (amf_sg_t *sg,
- amf_su_t *su)
- {
- ENTER("%s %s",sg->name.value, su->name.value);
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_TERMINATING)) {
- if (is_comp_in_active_ha_state_nplusm (sg, su)) {
- acsm_enter_idle (sg);
- goto out;
- }
- if (all_su_in_scope_has_either_two_presence_state (sg,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED)) {
-
- delete_si_assignments_in_scope (sg);
-
- if (is_any_si_in_scope_assigned_standby (sg)) {
- remove_all_suspected_sus (sg);
- acsm_enter_removing_standby_assignments (sg);
- } else { /*is_no_si_in_scope_assigned_standby*/
- remove_all_suspected_sus (sg);
- acsm_enter_assigning_standby_to_spare (sg);
- }
- }
- }
- out:
- return;
- }
- /**
- * This function handles a change of presence state reported by an SU contained
- * in specified SG. The new presence state is INSTANTIATION_FAILED.
- * @param sg
- * @param su
- */
- static void amf_sg_su_state_changed_to_instantiation_failed (amf_sg_t *sg,
- amf_su_t *su)
- {
- ENTER("%s %s",sg->name.value, su->name.value);
- switch (sg->avail_state) {
- case SG_AC_InstantiatingServiceUnits:
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_INSTANTIATING)) {
- acsm_enter_idle (sg);
- }
- break;
- case SG_AC_ReparingSu:
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_INSTANTIATING)) {
- if (all_su_in_scope_has_either_of_three_presence_state(
- su->sg,
- SA_AMF_PRESENCE_INSTANTIATED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED,
- SA_AMF_PRESENCE_UNINSTANTIATED)) {
- su->sg->avail_state = SG_AC_AssigningWorkload;
- if (assign_si (sg, 0) == 0) {
- acsm_enter_idle (sg);
- }
- }
- }
- break;
- default:
- /* TODO: Insert the assert (0) until solving defers in SU */
- dprintf("sg->avail_state = %d", sg->avail_state);
- break;
- }
- }
- /******************************************************************************
- * Event methods
- *****************************************************************************/
- /**
- * This function starts all SUs in the SG or all SUs on a specified node.
- * @param sg
- * @param node - Node on which all SUs shall be started or
- * NULL indicating that all SUs on all nodes shall be started.
- * @return - No of SUs that has been attempted to start
- */
- int amf_sg_start (struct amf_sg *sg, struct amf_node *node)
- {
- sg->recovery_scope.event_type = SG_START_EV;
- ENTER ("'%s'", sg->name.value);
- int instantiated_sus = 0;
- switch (sg->avail_state) {
- case SG_AC_InstantiatingServiceUnits:
- case SG_AC_Idle: {
- amf_su_t *su;
- sg_avail_control_state_t old_avail_state = sg->avail_state;
- ENTER ("'%s'", sg->name.value);
- sg->node_to_start = node;
- sg->avail_state = SG_AC_InstantiatingServiceUnits;
- for (su = sg->su_head;
- (su != NULL) &&
- (instantiated_sus < sg->saAmfSGNumPrefInserviceSUs);
- su = su->next) {
- if (is_cluster_start (node)) {
- amf_su_instantiate (su);
- instantiated_sus++;
- } else { /*is_not_cluster_start*/
- /*
- * Node start, match if SU is hosted on the
- * specified node
- */
- if (name_match (&node->name,
- &su->saAmfSUHostedByNode)) {
- amf_su_instantiate (su);
- instantiated_sus++;
- }
- }
- }
- if (instantiated_sus == 0) {
- sg->avail_state = old_avail_state;
- }
- break;
- }
- case SG_AC_DeactivatingDependantWorkload:
- case SG_AC_TerminatingSuspected:
- case SG_AC_ActivatingStandby:
- case SG_AC_AssigningStandbyToSpare:
- case SG_AC_ReparingComponent:
- case SG_AC_ReparingSu:
- case SG_AC_AssigningOnRequest:
- case SG_AC_RemovingAssignment:
- case SG_AC_AssigningActiveworkload:
- case SG_AC_AssigningAutoAdjust:
- case SG_AC_AssigningWorkload:
- case SG_AC_WaitingAfterOperationFailed:
- case SG_AC_RemovingStandbyAssignments:
- default:
- assert (0);
- break;
- }
- return instantiated_sus;
- }
- /**
- * This function initiates assignment of the subset of the workload which
- * matches the specified workload dependency level, to all SUs contained in the
- * SG according to the requirements specified in the configuration.
- * @param sg -
- * @param dependency_level - Dependency level to assign
- * @return - No of SUs that has been attempted to start
- */
- int amf_sg_assign_si_req (struct amf_sg *sg, int dependency_level)
- {
- /* TODO: Introduce state control in this function
- */
- int posible_to_assign_si;
- sg->recovery_scope.event_type = SG_ASSIGN_SI_EV;
- sg->avail_state = SG_AC_AssigningOnRequest;
- if ((posible_to_assign_si = assign_si (sg, dependency_level)) == 0) {
- acsm_enter_idle (sg);
- }
- return posible_to_assign_si;
- }
- /**
- * This function is called because an error has been detected and the analysis
- * (done elsewhere) indicated that this error shall be recovered by a Node
- * failover. This function initiates the recovery action 'Node failover'.
- * @param sg
- * @param su - SU to failover
- * @param node -
- */
- void amf_sg_failover_node_req (struct amf_sg *sg, struct amf_node *node)
- {
- ENTER("'%s, %s'",node->name.value, sg->name.value);
- sg_event_t sg_event;
- switch (sg->avail_state) {
- case SG_AC_Idle:
- set_scope_for_failover_node(sg, node);
- if (has_any_su_in_scope_active_workload (sg)) {
- acsm_enter_deactivating_dependent_workload (sg);
- } else {
- amf_su_t **sus = sg->recovery_scope.sus;
- /*
- * Select next state depending on if some
- * SU in the scope needs to be terminated.
- */
- while (*sus != NULL) {
- amf_su_t *su = *sus;
- ENTER("SU %s pr_state='%d'",su->name.value,
- su->saAmfSUPresenceState);
- if (su_presense_state_is_ored (su,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
- sus++;
- continue;
- }
- break;
- }
- if (*sus != NULL) {
- acsm_enter_terminating_suspected (sg);
- } else {
- delete_si_assignments_in_scope (sg);
- acsm_enter_idle (sg);
- }
- }
- break;
- case SG_AC_DeactivatingDependantWorkload:
- case SG_AC_TerminatingSuspected:
- case SG_AC_ActivatingStandby:
- case SG_AC_AssigningStandbyToSpare:
- case SG_AC_ReparingComponent:
- case SG_AC_ReparingSu:
- case SG_AC_AssigningOnRequest:
- case SG_AC_InstantiatingServiceUnits:
- case SG_AC_RemovingAssignment:
- case SG_AC_AssigningActiveworkload:
- case SG_AC_AssigningAutoAdjust:
- case SG_AC_AssigningWorkload:
- case SG_AC_WaitingAfterOperationFailed:
- case SG_AC_RemovingStandbyAssignments:
- sg_set_event (SG_FAILOVER_NODE_EV, sg, 0, 0, node, &sg_event);
- sg_defer_event (SG_FAILOVER_NODE_EV, &sg_event);
- break;
- default:
- assert (0);
- break;
- }
- }
- /**
- * This function is called because an error has been detected and the analysis
- * (done elsewhere) indicated that this error shall be recovered by an SU
- * failover. This function initiates the recovery action 'SU failover'.
- * @param sg
- * @param su - SU to failover
- * @param node -
- */
- void amf_sg_failover_su_req (struct amf_sg *sg, struct amf_su *su,
- struct amf_node *node)
- {
- ENTER ("%s", su->name.value);
- sg_event_t sg_event;
- switch (sg->avail_state) {
- case SG_AC_Idle:
- su->su_failover_cnt += 1;
- set_scope_for_failover_su (sg, su);
- if (has_any_su_in_scope_active_workload (sg)) {
- acsm_enter_deactivating_dependent_workload (sg);
- } else {
- acsm_enter_terminating_suspected (sg);
- }
- break;
- case SG_AC_DeactivatingDependantWorkload:
- case SG_AC_TerminatingSuspected:
- case SG_AC_ActivatingStandby:
- case SG_AC_AssigningStandbyToSpare:
- case SG_AC_ReparingComponent:
- case SG_AC_ReparingSu:
- case SG_AC_AssigningOnRequest:
- case SG_AC_InstantiatingServiceUnits:
- case SG_AC_RemovingAssignment:
- case SG_AC_AssigningActiveworkload:
- case SG_AC_AssigningAutoAdjust:
- case SG_AC_AssigningWorkload:
- case SG_AC_WaitingAfterOperationFailed:
- case SG_AC_RemovingStandbyAssignments:
- sg_set_event (SG_FAILOVER_SU_EV, sg, su, 0, 0, &sg_event);
- sg_defer_event (SG_FAILOVER_SU_EV, &sg_event);
- break;
- default:
- assert (0);
- break;
- }
- }
- /******************************************************************************
- * Event response methods
- *****************************************************************************/
- #ifdef COMPILE_OUT
- void amf_sg_su_state_changed_2 (struct amf_sg *sg,
- struct amf_su *su, SaAmfStateT type, int state)
- {
- ENTER ("'%s' SU '%s' state %s",
- sg->name.value, su->name.value, amf_presence_state(state));
- if (type == SA_AMF_PRESENCE_STATE) {
- if (state == SA_AMF_PRESENCE_INSTANTIATED) {
- if (sg->avail_state == SG_AC_InstantiatingServiceUnits) {
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_INSTANTIATING)) {
- acsm_enter_idle (sg);
- }
- } else if (sg->avail_state == SG_AC_ReparingSu) {
- if (all_su_in_scope_has_either_of_three_presence_state(
- su->sg,
- SA_AMF_PRESENCE_INSTANTIATED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED,
- SA_AMF_PRESENCE_UNINSTANTIATED)) {
- su->sg->avail_state = SG_AC_AssigningWorkload;
- if (assign_si (sg, 0) == 0) {
- acsm_enter_idle (sg);
- }
- } else {
- dprintf ("avail-state: %u", sg->avail_state);
- assert (0);
- }
- } else {
- dprintf ("avail-state: %u", sg->avail_state);
- assert (0);
- }
- } else if (state == SA_AMF_PRESENCE_UNINSTANTIATED) {
- if (sg->avail_state == SG_AC_TerminatingSuspected) {
- if (all_su_in_scope_has_either_two_presence_state (sg,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED)) {
- delete_si_assignments_in_scope (sg);
- if (is_any_si_in_scope_assigned_standby (sg)) {
- remove_all_suspected_sus (sg);
- acsm_enter_removing_standby_assignments (sg);
- } else { /*is_no_si_in_scope_assigned_standby*/
- remove_all_suspected_sus (sg);
- acsm_enter_assigning_standby_to_spare (sg);
- }
- }
- } else if (sg->avail_state == SG_AC_ReparingSu) {
- if (all_su_in_scope_has_either_of_three_presence_state(
- su->sg,
- SA_AMF_PRESENCE_INSTANTIATED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED,
- SA_AMF_PRESENCE_UNINSTANTIATED)) {
- su->sg->avail_state = SG_AC_AssigningWorkload;
- if (assign_si (sg, 0) == 0) {
- acsm_enter_idle (sg);
- }
- } else {
- dprintf("%d",sg->avail_state);
- assert (0);
- }
- }
- } else if (state == SA_AMF_PRESENCE_TERMINATION_FAILED) {
- if (all_su_in_scope_has_either_two_presence_state (sg,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED) &&
- is_any_si_in_scope_assigned_standby (sg)) {
- remove_all_suspected_sus (sg);
- acsm_enter_removing_standby_assignments (sg);
- } else if (all_su_in_scope_has_either_two_presence_state (sg,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED) &&
- !is_any_si_in_scope_assigned_standby (sg)) {
- remove_all_suspected_sus (sg);
- acsm_enter_assigning_standby_to_spare (sg);
- } else {
- remove_sis_for_term_failed_su_from_scope (sg, su);
- }
- } else if (state == SA_AMF_PRESENCE_INSTANTIATING) {
- ; /* nop */
- } else if (state == SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
- if (sg->avail_state == SG_AC_InstantiatingServiceUnits) {
- if (no_su_has_presence_state(sg, sg->node_to_start,
- SA_AMF_PRESENCE_INSTANTIATING)) {
- acsm_enter_idle (sg);
- }
- } else if (sg->avail_state == SG_AC_ReparingSu) {
- if (all_su_in_scope_has_either_of_three_presence_state(
- su->sg,
- SA_AMF_PRESENCE_INSTANTIATED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED,
- SA_AMF_PRESENCE_UNINSTANTIATED)) {
- su->sg->avail_state = SG_AC_AssigningWorkload;
- if (assign_si (sg, 0) == 0) {
- acsm_enter_idle (sg);
- }
- }
- } else {
- /* TODO: Insert the assert (0) until solving defers in SU */
- dprintf("sg->avail_state = %d, su instantiation state = %d",
- sg->avail_state, state);
- }
- } else {
- dprintf("sg->avail_state = %d, su instantiation state = %d",
- sg->avail_state, state);
- assert (0);
- }
- }
- }
- #endif
- /**
- * SU indicates to SG that one of its state machines has changed state.
- * @param sg - SG which contains the SU that has changed state
- * @param su - SU which has changed state
- * @param type - Indicates which state machine that has changed state
- * @param state - The new state that has been assumed.
- *
- */
- void amf_sg_su_state_changed (struct amf_sg *sg, struct amf_su *su,
- SaAmfStateT type, int state)
- {
- ENTER ("'%s' SU '%s' state %s",
- sg->name.value, su->name.value, amf_presence_state(state));
- if (sg->avail_state != SG_AC_Idle) {
- if (type == SA_AMF_PRESENCE_STATE) {
- switch (state) {
- case SA_AMF_PRESENCE_INSTANTIATED:
- sg_su_state_changed_to_instantiated(sg, su);
- break;
- case SA_AMF_PRESENCE_UNINSTANTIATED:
- amf_sg_su_state_changed_to_uninstantiated(sg, su);
- break;
- case SA_AMF_PRESENCE_TERMINATION_FAILED:
- amf_sg_su_state_changed_to_termination_failed(sg, su);
- break;
- case SA_AMF_PRESENCE_INSTANTIATING:
- ; /* nop */
- break;
- case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
- amf_sg_su_state_changed_to_instantiation_failed(sg, su);
- break;
- case SA_AMF_PRESENCE_TERMINATING:
- ; /* nop */
- break;
- default :
- dprintf("sg->avail_state = %d, su instantiation state = %d",
- sg->avail_state, state);
- assert (0);
- break;
- }
- }
- }
- }
- /**
- * Callback function used by SI when there is no dependent SI to
- * deactivate.
- * @param sg
- */
- static void dependent_si_deactivated_cbfn2 (struct amf_sg *sg)
- {
- struct amf_su **sus = sg->recovery_scope.sus;
- ENTER("'%s'", sg->name.value);
- /*
- * Select next state depending on if some
- * SU in the scope needs to be terminated.
- */
- while (*sus != NULL) {
- amf_su_t *su = *sus;
- ENTER("SU %s pr_state='%d'",su->name.value,
- su->saAmfSUPresenceState);
- if (su_presense_state_is_ored (su,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
- sus++;
- continue;
- }
- break;
- }
- if (*sus != NULL) {
- acsm_enter_terminating_suspected (sg);
- } else {
- delete_si_assignments_in_scope(sg);
- acsm_enter_removing_standby_assignments (sg);
- }
- }
- /**
- * Callback function used by SI when an SI has been deactivated, i.e.
- * transitioned from active HA-state to any other state.
- * @param si_assignment
- * @param result - Indicates the result of the operation.
- */
- static void dependent_si_deactivated_cbfn (
- struct amf_si_assignment *si_assignment, int result)
- {
- struct amf_sg *sg = si_assignment->su->sg;
- struct amf_su **sus = sg->recovery_scope.sus;
- struct amf_su *su;
- ENTER ("'%s', %d", si_assignment->si->name.value, result);
- /*
- * If all SI assignments for all SUs in the SG are not pending,
- * goto next state (TerminatingSuspected).
- */
- for (su = sg->su_head ; su != NULL; su = su->next) {
- struct amf_si_assignment *si_assignment;
- si_assignment = amf_su_get_next_si_assignment(su, NULL);
- while (si_assignment != NULL) {
- if (si_assignment->saAmfSISUHAState !=
- si_assignment->requested_ha_state) {
- goto still_wating;
- }
- si_assignment = amf_su_get_next_si_assignment(su,
- si_assignment);
- }
- }
- still_wating:
- if (su == NULL) {
- sus = si_assignment->su->sg->recovery_scope.sus;
- /*
- * Select next state depending on if some
- * SU in the scope is needs to be terminated.
- */
- while (*sus != NULL) {
- if (su_presense_state_is_not (*sus,
- SA_AMF_PRESENCE_UNINSTANTIATED,
- SA_AMF_PRESENCE_TERMINATION_FAILED,
- SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
- break;
- }
- sus++;
- }
- if (*sus != NULL) {
- acsm_enter_terminating_suspected (sg);
- } else {
- acsm_enter_removing_standby_assignments (sg);
- }
- }
- LEAVE("");
- }
- /**
- * Callback function used by SI to indicate an SI has assumed a new HA-state or
- * that the attempt to do so failed.
- * @param si_assignment
- * @param result - Indicates the result of the operation.
- */
- static void assign_si_assumed_cbfn (
- struct amf_si_assignment *si_assignment, int result)
- {
- struct amf_sg *sg = si_assignment->su->sg;
- int si_assignment_cnt = 0;
- int confirmed_assignments = 0;
- ENTER ("'%s', %d", si_assignment->si->name.value, result);
- switch (sg->avail_state) {
- case SG_AC_AssigningOnRequest:
- if (is_all_si_assigned (sg)) {
- acsm_enter_idle (sg);
- amf_application_sg_assigned (sg->application, sg);
- } else {
- dprintf ("%d, %d", si_assignment_cnt, confirmed_assignments);
- }
- break;
- case SG_AC_AssigningWorkload:
- {
- if (is_all_si_assigned(sg)) {
- acsm_enter_idle (sg);
- }
- break;
- }
- case SG_AC_AssigningStandbyToSpare:
- {
- if(is_all_si_assigned (sg)) {
- /*
- * All si_assignments has asumed
- * Prescense state SA_AMF_HA_STANDBY
- */
- switch (sg->recovery_scope.event_type) {
- case SG_FAILOVER_NODE_EV:
- acsm_enter_idle (sg);
- break;
- case SG_FAILOVER_SU_EV:
- if (sg->saAmfSGAutoRepair == SA_TRUE) {
- acsm_enter_repairing_su (sg);
- }
- break;
- default:
- assert (0);
- break;
- }
- } else {
- si_assignment->saAmfSISUHAState = SA_AMF_HA_STANDBY;
- }
- }
- break;
- default:
- dprintf ("%d, %d, %d", sg->avail_state, si_assignment_cnt,
- confirmed_assignments);
- amf_runtime_attributes_print (amf_cluster);
- assert (0);
- break;
- }
- }
- /**
- * Callback function used by SI when an SI has been activated, i.e. transitioned
- * from any HA-state to an active HA-state.
- * @param si_assignment
- * @param result - Indicates the result of the operation.
- */
- static void standby_su_activated_cbfn (
- struct amf_si_assignment *si_assignment, int result)
- {
- struct amf_su **sus = si_assignment->su->sg->recovery_scope.sus;
- struct amf_si **sis = si_assignment->su->sg->recovery_scope.sis;
- ENTER ("'%s', %d", si_assignment->si->name.value, result);
- /*
- * If all SI assignments for all SIs in the scope are activated, goto next
- * state.
- */
- while (*sis != NULL) {
- if ((*sis)->assigned_sis != NULL &&
- (*sis)->assigned_sis->saAmfSISUHAState != SA_AMF_HA_ACTIVE) {
- break;
- }
- sis++;
- }
- if (*sis == NULL) {
- acsm_enter_assigning_standby_to_spare ((*sus)->sg);
- }
- }
- /******************************************************************************
- * General methods
- *****************************************************************************/
- /**
- * Constructor for SG objects. Adds SG to the list owned by
- * the specified application. Always returns a valid SG
- * object, out-of-memory problems are handled here. Default
- * values are initialized.
- * @param sg
- * @param name
- *
- * @return struct amf_sg*
- */
- struct amf_sg *amf_sg_new (struct amf_application *app, char *name)
- {
- struct amf_sg *sg = amf_calloc (1, sizeof (struct amf_sg));
- setSaNameT (&sg->name, name);
- sg->saAmfSGAdminState = SA_AMF_ADMIN_UNLOCKED;
- sg->saAmfSGNumPrefActiveSUs = 1;
- sg->saAmfSGNumPrefStandbySUs = 1;
- sg->saAmfSGNumPrefInserviceSUs = ~0;
- sg->saAmfSGNumPrefAssignedSUs = ~0;
- sg->saAmfSGCompRestartProb = -1;
- sg->saAmfSGCompRestartMax = ~0;
- sg->saAmfSGSuRestartProb = -1;
- sg->saAmfSGSuRestartMax = ~0;
- sg->saAmfSGAutoAdjustProb = -1;
- sg->saAmfSGAutoRepair = SA_TRUE;
- sg->application = app;
- sg->next = app->sg_head;
- app->sg_head = sg;
- sg->deferred_events = NULL;
- return sg;
- }
- void amf_sg_delete (struct amf_sg *sg)
- {
- struct amf_su *su;
- for (su = sg->su_head; su != NULL;) {
- struct amf_su *tmp = su;
- su = su->next;
- amf_su_delete (tmp);
- }
- free (sg);
- }
- void *amf_sg_serialize (struct amf_sg *sg, int *len)
- {
- char *buf = NULL;
- int offset = 0, size = 0;
- TRACE8 ("%s", sg->name.value);
- buf = amf_serialize_SaNameT (buf, &size, &offset, &sg->name);
- buf = amf_serialize_SaUint32T (buf, &size, &offset, sg->saAmfSGRedundancyModel);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGAutoAdjust);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumPrefActiveSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumPrefStandbySUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumPrefInserviceSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumPrefAssignedSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGMaxActiveSIsperSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGMaxStandbySIsperSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGCompRestartProb);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGCompRestartMax);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGSuRestartProb);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGSuRestartMax);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGAutoAdjustProb);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGAutoRepair);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGAdminState);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumCurrAssignedSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->saAmfSGNumCurrInstantiatedSpareSUs);
- buf = amf_serialize_SaStringT (
- buf, &size, &offset, sg->clccli_path);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->avail_state);
- buf = amf_serialize_SaUint32T (
- buf, &size, &offset, sg->recovery_scope.event_type);
- *len = offset;
- return buf;
- }
- struct amf_sg *amf_sg_deserialize (struct amf_application *app, char *buf)
- {
- char *tmp = buf;
- struct amf_sg *sg = amf_sg_new (app, "");
- tmp = amf_deserialize_SaNameT (tmp, &sg->name);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGRedundancyModel);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoAdjust);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefActiveSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefStandbySUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefInserviceSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefAssignedSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGMaxActiveSIsperSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGMaxStandbySIsperSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGCompRestartProb);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGCompRestartMax);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGSuRestartProb);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGSuRestartMax);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoAdjustProb);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoRepair);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAdminState);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrAssignedSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrInstantiatedSpareSUs);
- tmp = amf_deserialize_SaStringT (tmp, &sg->clccli_path);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->avail_state);
- tmp = amf_deserialize_SaUint32T (tmp, &sg->recovery_scope.event_type);
- return sg;
- }
- struct amf_sg *amf_sg_find (struct amf_application *app, char *name)
- {
- struct amf_sg *sg;
- for (sg = app->sg_head; sg != NULL; sg = sg->next) {
- if (sg->name.length == strlen(name) &&
- strncmp (name, (char*)sg->name.value, sg->name.length) == 0) {
- break;
- }
- }
- return sg;
- }
|