amfsu.c 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805
  1. /** @file exec/amfsu.c
  2. *
  3. * Copyright (c) 2002-2006 MontaVista Software, Inc.
  4. * Author: Steven Dake (sdake@mvista.com)
  5. *
  6. * Copyright (c) 2006 Ericsson AB.
  7. * Author: Hans Feldt, Anders Eriksson, Lars Holm
  8. * - Introduced AMF B.02 information model
  9. * - Use DN in API and multicast messages
  10. * - (Re-)Introduction of event based multicast messages
  11. * - Refactoring of code into several AMF files
  12. * - Component/SU restart, SU failover
  13. * - Constructors/destructors
  14. * - Serializers/deserializers
  15. *
  16. * All rights reserved.
  17. *
  18. *
  19. * This software licensed under BSD license, the text of which follows:
  20. *
  21. * Redistribution and use in source and binary forms, with or without
  22. * modification, are permitted provided that the following conditions are met:
  23. *
  24. * - Redistributions of source code must retain the above copyright notice,
  25. * this list of conditions and the following disclaimer.
  26. * - Redistributions in binary form must reproduce the above copyright notice,
  27. * this list of conditions and the following disclaimer in the documentation
  28. * and/or other materials provided with the distribution.
  29. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  30. * contributors may be used to endorse or promote products derived from this
  31. * software without specific prior written permission.
  32. *
  33. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  34. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  36. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  37. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  38. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  39. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  40. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  41. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  42. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  43. * THE POSSIBILITY OF SUCH DAMAGE.
  44. *
  45. * AMF Service Unit Class Implementation
  46. *
  47. * This file contains functions for handling AMF-service units(SUs). It can be
  48. * viewed as the implementation of the AMF Service Unit class (called SU)
  49. * as described in SAI-Overview-B.02.01. The SA Forum specification
  50. * SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
  51. * and is referred to as 'the spec' below.
  52. *
  53. * The functions in this file are responsible for:
  54. * - instantiating and terminating service units on request
  55. * (considering the dependencies between components described in paragraph
  56. * 3.9.2)
  57. * - creating and deleting CSI-assignment objects between its components and
  58. * CSI-objects upon request
  59. * - receiving error reports from its components and forwarding them to
  60. * appropriate handler (SU or SG or node or cluster)
  61. * - implementing restart of itself and its components (paragraph 3.12.1.2)
  62. * - implementing error escallation level 1 (paragraph 3.12.2.2 in the spec)
  63. * - handling all run time attributes of the AMF SU; all cached
  64. * attributes are stored as variables and sent to the IMM service
  65. * upon the changes described in the specification.
  66. *
  67. * SU contains the following state machines:
  68. * - presence state machine (PRSM)
  69. * - administrative state machine (ADSM) (NOT IN THIS RELEASE)
  70. * - operational state machine (OPSM)
  71. * - readiness state machine (RESM)
  72. * - ha state per service instance (SI)
  73. * - restart control state machine (RCSM)
  74. *
  75. * The presence state machine orders intantiation of its components on request.
  76. * It fully respects the dependency rules between components at instantiation
  77. * such that it orders instantiation simultaneously only of components on the
  78. * same instantiation level. The presence state machine is implemented with
  79. * the states described in the spec and the state transitions are trigged by
  80. * reported state transitions from its contained components according to
  81. * paragraph 3.3.1.1.
  82. *
  83. * The operational state machine is not responsible for any control function.
  84. * It assumes the DISABLED state if an incoming operational state change report
  85. * from a component indicates the component has assumed the DISABLED state.
  86. * Operational state changes are reported to IMM.
  87. *
  88. * The readiness state machine is not used for any control but is updated and
  89. * reported to IMM when it is changed.
  90. *
  91. * The restart control state machine (RCSM) is used to implement level 1 of
  92. * the error escallation policy described in chapter 3.12.2 of the spec. It also
  93. * implements component restart and service unit restart as described in
  94. * paragraph 3.12.1.2 and 3.12.1.3.
  95. * RCSM contains three composite states.
  96. * Being a composite state means that the state contains substates.
  97. * RCSM composite states are:
  98. * - IDLE (LEVEL_0, LEVEL_1 and LEVEL_2)
  99. * - RESTARTING_COMPONENT (DEACTIVATING, RESTARTING, SETTING and ACTIVATING)
  100. * - RESTARTING_SERVICE_UNIT (DEACTIVATING, TERMINATING, INSTANTIATING,
  101. * and ACTIVATING)
  102. *
  103. * IDLE is a kind of state where no actions are performed and used only to
  104. * remember the escallation level. Substate LEVEL_0 indicates no escallation.
  105. * LEVEL_1 indicates that a component restart has been executed recently and the
  106. * escallation timer is still running. At this level component restart requests
  107. * will transition to RESTARTING_COMPONENT but if there are too many restart
  108. * requests before the probation timer expires then a transition will be made to
  109. * LEVEL_2 and the restart request will be forwarded to the node instance
  110. * hosting this component. State RESTARTING_SERVICE_UNIT will only be assumed if
  111. * the node explicitly requests the SU to execute a restart of itself (after
  112. * having evaluated its part of the error escallation policy).
  113. *
  114. * 1. Service Unit Restart Control State Machine
  115. * ============================================
  116. *
  117. * 1.1 State Transition Table
  118. * ===========================
  119. *
  120. * State: Event: Action: New state:
  121. * ===========================================================================
  122. * IDLE_ESCALATION_x comp_restart A9 RS_COMP_RESTARTING
  123. * IDLE_ESCALATION_x su_restart A20 RS_SU_TERMINATING
  124. * IDLE_ESCALATION_0 error_suspected A1,A3 IDLE_ESCALATION_1
  125. * IDLE_ESCALATION_1 error_suspected [!C3] A1,A3 IDLE_ESCALATION_1
  126. * IDLE_ESCALATION_1 error_suspected [C3] A2,A5 IDLE_ESCALATION_2
  127. * IDLE_ESCALATION_2 error_suspected A2 IDLE_ESCALATION_2
  128. * RS_COMP_RESTARTING comp_instantiated A11 RS_COMP_SETTING
  129. * RS_COMP_RESTARTING comp_inst_failed A14,A15 RS_COMP_T-ING_2
  130. * RS_COMP_RESTARTING comp_term_failed A19 IDLE_ESCALATION_x
  131. * RS_COMP_RESTARTING error_suspected A18 RS_COMP_RESTARTING
  132. * RS_COMP_T-ING_2 comp_uninst..ed [C8] A16,A15 RS_COMP_T-ING_2
  133. * RS_COMP_T-ING_2 comp_uninst..ed [C100] IDLE_ESCALATION_x
  134. * RS_COMP_T-ING_2 comp_uninst..ed [C101] A25 IDLE_ESCALATION_x
  135. * RS_COMP_T-ING_2 comp_uninst..ed [C102] A26 IDLE_ESCALATION_x
  136. * RS_COMP_T-ING_2 comp_term_failed [C100] RS_COMP_T-ING_2
  137. * RS_COMP_T-ING_2 error_suspected A18 RS_COMP_T-ING_2
  138. * RS_COMP_SETTING ha_state_assumed [C7] A19 IDLE_ESCALATION_x
  139. * RS_COMP_SETTING error_suspected A18 RS_COMP_SETTING
  140. * RS_SU_TERMINATING comp_uninst..ed [C8] A16,A15 RS_SU_TERMINATING
  141. * RS_SU_TERMINATING comp_uninst..ed [C103] A17,A23 RS_SU_INSTANTIATING
  142. * RS_SU_TERMINATING comp_uninst..ed [C104] A19 IDLE_ESCALATION_x
  143. * RS_SU_TERMINATING comp_term_failed [C104]A19 IDLE_ESCALATION_X
  144. * RS_SU_TERMINATING error_suspected A18 RS_SU_TERMINATING
  145. * RS_SU_INSTANTIATING comp_instantiated [C14]A21,A22 RS_SU_INSTANTIATING
  146. * RS_SU_INSTANTIATING comp_instantiated [C105]A15 RS_SU_T-ING_2
  147. * RS_SU_INSTANTIATING comp_instantiated [C106]A11 RS_SU_SETTING
  148. * RS_SU_INSTANTIATING comp_inst_failed [C105]A15 RS_SU_T-ING_2
  149. * RS_SU_INSTANTIATING error_suspected A18 RS_SU_INSTANTIATING
  150. * RS_SU_T-ING_2 comp_uninst..ed [C8] A16,A15 RS_SU_T-ING_2
  151. * RS_SU_T-ING_2 comp_uninst..ed [C100] IDLE_ESCALATION_x
  152. * RS_SU_T-ING_2 comp_uninst..ed [C101] A25 IDLE_ESCALATION_x
  153. * RS_SU_T-ING_2 comp_uninst..ed [C102] A26 IDLE_ESCALATION_x
  154. * RS_SU_T-ING_2 comp_term_failed [C100] RS_SU_T-ING_2
  155. * RS_SU_T-ING_2 error_suspected A18 RS_SU_T-ING_2
  156. * RS_SU_SETTING ha_state_assumed [C10] A19 IDLE_ESCALATION_X
  157. * RS_SU_SETTING error_suspected A18 RS_SU_SETTING
  158. *
  159. * 1.2 State Description
  160. * =====================
  161. * IDLE_ESCALATION_x - This is just an abbreviated notation for
  162. * IDLE_ESCALATION_0, IDLE_ESCALATION_1 or IDLE_ESCALATION_2
  163. * When leaving any of the idle states, a history state
  164. * is used to save the (exact) state value. When returning
  165. * to idle, the value of the history state is used to set
  166. * the correct idle state.
  167. *
  168. * IDLE_ESCALATION_0 - SU_RC_IDLE_ESCALATION_LEVEL_0
  169. * Service unit is idle and the restart probation timer is
  170. * off.
  171. *
  172. * IDLE_ESCALATION_1 - SU_RC_IDLE_ESCALATION_LEVEL_1
  173. * Service unit is idle and the restart probation timer is
  174. * on. This indicates there has recently been an error
  175. * detected on at least one of its components which has been
  176. * recovered by a component restart but we are still in the
  177. * probation period which follows every restart.
  178. *
  179. * IDLE_ESCALATION_2 - SU_RC_IDLE_ESCALATION_LEVEL_2
  180. * Service unit is idle and handling on potential new error
  181. * indications on any of its components has been delegated
  182. * to the node object where the service unit is hosted.
  183. *
  184. * RS_COMP_DEACTIVATING - SU_RC_RESTART_COMP_DEACTIVATING
  185. * Service unit is busy handling restart of one of its
  186. * components. In this sub-state, the service unit is
  187. * waiting for acknowledgements that all components which
  188. * had csi-assignments that were dependent of csi-
  189. * assignments associated to the restarting component
  190. * have been de-activated. This is a neccesary step to
  191. * take before the component to restart is terminated,
  192. * to avoid that the csi or si dependency rules are
  193. * violated.
  194. *
  195. * RS_COMP_RESTARTING - SU_RC_RESTART_COMP_RESTARTING
  196. * Service unit is busy handling restart of one of its
  197. * components. In this sub-state, the service unit has
  198. * ordered one of its components to restart and waits for
  199. * the component to indicate that the restart is done.
  200. *
  201. * RS_COMP_T-ING_2 - SU_RC_RESTART_COMP_TERMINATING_AFTER_INST_FAILED
  202. * Service unit is busy handling restart of one of its
  203. * components. In this sub-state, the restart of the component
  204. * has failed and the rest of the components in the service
  205. * unit has to be terminated.
  206. *
  207. * RS_COMP_SETTING - SU_RC_RESTART_COMP_SETTING
  208. * Service unit is busy handling restart of one of its
  209. * components. In this sub-state, the service unit has ordered
  210. * the component that just have been restarted to re-assume
  211. * the HA-states it had before, provided none of the states
  212. * were ACTIVE. It waits for an acknowledgement that the
  213. * setting of the HA-states are done.
  214. *
  215. * RS_COMP_ACTIVATING - SU_RC_RESTART_COMP_ACTIVATING
  216. * Service unit is busy handling restart of one of its
  217. * components. In this sub-state, the service unit has
  218. * ordered the component that just have been restarted to
  219. * re-assume the active HA-states it had before and also
  220. * to activate the csi-assignments that possibly were
  221. * de-activated because of this restart. The service unit
  222. * waits in this state for an acknowledgement of the
  223. * activation.
  224. *
  225. * RS_SU_DEACTIVATING - SU_RC_RESTART_SU_DEACTIVATING
  226. * Service unit is busy handling restart of all of its
  227. * components. In this sub-state, the service unit is
  228. * waiting for acknowledgements that all components which
  229. * had csi-assignments that were dependent of si-
  230. * assignments associated to this service unit
  231. * have been de-activated. This is a neccesary step to
  232. * take before all components of the service unit are
  233. * terminated, to avoid that the csi or si dependency rules
  234. * are violated.
  235. *
  236. * RS_SU_TERMINATING - SU_RC_RESTART_SU_TERMINATING
  237. * Service unit is busy handling restart of all of its
  238. * components. In this sub-state, the service unit has
  239. * ordered all its components to terminate and is waiting
  240. * for an acknowledgement that all components are done with
  241. * the termination.
  242. *
  243. * RS_SU_INSTANTIATING - SU_RC_RESTART_SU_INSTANTIATING
  244. * Service unit is busy handling restart of all of its
  245. * components. In this sub-state, the service unit has
  246. * ordered all components to instantiate and is waiting
  247. * for an acknowledgement that all components are done with
  248. * the instantiation.
  249. *
  250. * RS_SU_T-ING_2 - SU_RC_RESTART_SU_TERMINATING_AFTER_INST_FAILED
  251. * Service unit is busy handling restart of all of its
  252. * components. In this sub-state, the instantiation at least
  253. * one component has failed and the rest of the components in
  254. * the service unit has to be terminated.
  255. *
  256. * RS_SU_SETTING - SU_RC_RESTART_SU_SETTING
  257. * Service unit is busy handling restart of all of its
  258. * components. In this sub-state, the service unit has ordered
  259. * all components that just have been restarted to re-assume
  260. * the HA-states they had before, provided none of the states
  261. * were ACTIVE. The service unit waits for an acknowledgement
  262. * that the setting of the HA-states are done.
  263. *
  264. * RS_SU_ACTIVATING - SU_RC_RESTART_SU_ACTIVATING
  265. * Service unit is busy handling restart of all of its
  266. * components. In this sub-state, the service unit has
  267. * ordered all components that just have been restarted to
  268. * re-assume the active HA-states they had before and also
  269. * to activate the csi-assignments that possibly were
  270. * de-activated because of this restart. The service unit
  271. * waits in this state for an acknowledgement of the
  272. * activation.
  273. *
  274. * 1.3 Actions
  275. * ===========
  276. * A1 - generate event comp_restart
  277. * A2 - forward component restart request to the node which hosts current su
  278. * A3 - start probation timer (SaAmfSGCompRestartProb)
  279. * A4 - [foreach component in su]/ cnt += SaAmfSGCompRestartCount
  280. * A5 - stop probation timer
  281. * A6 - restart ??
  282. * A7 - set restarting_comp = component
  283. * A8 - [foreach csi-assignment assigned to component] SI deactivate csi
  284. * A9 - order component to restart
  285. * A10 - set restarting_comp == ALL
  286. * A11 - initiate setting of the same HA-state as was set before the restart
  287. * A12 - SI activate
  288. * A13 - [foreach si-assignment assigned to su] SI deactivate
  289. * A14 - set current instantiation level = highest level
  290. * A15 - [foreach component on current instantiation level]/terminate component
  291. * A16 - current instantiation level is decremented
  292. * A17 - request the presence state state machine to instantiate the su
  293. * A18 - defer the event
  294. * A19 - recall deferred event
  295. * A20 - restart all components contained in current su
  296. * A21 - current instantiation level is incremented
  297. * A22 - [foreach component on current instantiation level]/instantiate
  298. * component
  299. * A23 - set current instantiation level = lowest level
  300. * A24 - order SG to do component failover
  301. * A25 - order Node to do node failover
  302. * A26 - order SG to do SU failover
  303. *
  304. * 1.4 Guards
  305. * ==========
  306. * C1 - disableRestart == False
  307. * C2 - the component has been restarted less than SaAmfSGCompRestartMax times
  308. * C3 - the component has been restarted SaAmfSGCompRestartMax number of times
  309. * C4 - all si-assignments have confirmed-ha-state == QUIESCED or the
  310. * operation failed flag set.
  311. * C5 - for each si-assignment related to the restarting component where
  312. * requested-ha-state != confirmed-ha-state and requested-ha-state !=
  313. * ACTIVE
  314. * C6 - - for each si-assignment related to the restarting component where
  315. * requested-ha-state != confirmed-ha-state and requested-ha-state ==
  316. * ACTIVE
  317. * C7 - all si-assignments related to the restarting component have
  318. * requested-ha-state == confirmed-ha-state or has the operation failed
  319. * flag set
  320. * C8 - all components on current instantiation level == UNINSTANTIATED
  321. * C9 - current instantiation level < lowest instantiation level
  322. * C10 - all si-assignments related to current service unit have
  323. * requested-ha-state == confirmed-ha-state or the operation failed
  324. * flag set.
  325. * C11 - for each si-assignment related to current su where
  326. * requested-ha-state != confirmed-ha-state and requested-ha-state ==
  327. * ACTIVE
  328. * C12 - for each si-assignment related to current su where
  329. * requested-ha-state != confirmed-ha-state and requested-ha-state ==
  330. * STANDBY
  331. * C13 - at least one component has presence state == TERMINATION_FAILED
  332. * C14 - all components on current instantiation level == INSTANTIATED,
  333. * INSTANTIATION_FAILED or INSTANTIATION_FAILED_REBOOT_NODE
  334. * C15 - current instantiation level is highest
  335. * C16 - all components has presence state == INSTANTIATED
  336. * C17 - at least one component has presence state == INSTANTIATION_FAILED and
  337. * it is not allowed to reboot the node because of this problem
  338. * C18 - at least one component has presence state == INSTANTIATION_FAILED and
  339. * it is allowed to reboot the node to recover from this problem
  340. * C19 - all components in the SU permit restart
  341. *
  342. * 1.4.2 Composed Guards
  343. * =====================
  344. *
  345. * C100 - C9 & C13
  346. * C101 - C9 & C18
  347. * C102 - C9 & C17
  348. * C103 - C8 & C9 & !C13
  349. * C104 - C8 & C9 & C13
  350. * C105 - C14 & (C17 | C18)
  351. * C106 - C14 & C15 & C16
  352. *
  353. * 1.5 Events
  354. * ==========
  355. *
  356. * E1 - component restart request
  357. * E2 - restart
  358. * E3 - probation timer expired
  359. * E4 - escalation reverted
  360. * E5 - operation failed
  361. * E6 - deactivated
  362. * E7 - comp_state(prsm, INSTANTIATED)
  363. * E8 - comp_state(prsm, INSTANTIATION_FAILED)
  364. * E9 - comp_state(prsm, TERMINATION_FAILED)
  365. * E10 - si_state(ha-state)
  366. * E11 - activated
  367. * E12 - comp_state(prsm, UNINSTANTIATED)
  368. * E13 -
  369. * E14 -
  370. *
  371. */
  372. #include <stdio.h>
  373. #include <stdlib.h>
  374. #include <assert.h>
  375. #include <string.h>
  376. #include <errno.h>
  377. #include "amf.h"
  378. #include "util.h"
  379. #include "print.h"
  380. #include "main.h"
  381. static int terminate_all_components_in_level (struct amf_su *su,
  382. SaUint32T current_instantiation_level);
  383. static int are_all_comps_in_level_uninst_or_term_failed (struct amf_su *su);
  384. static int are_all_comps_in_level_instantiated (struct amf_su *su);
  385. static int instantiate_all_components_in_level (struct amf_su *su,
  386. SaUint32T current_instantiation_level);
  387. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su);
  388. static void si_ha_state_assumed_cbfn (
  389. struct amf_si_assignment *si_assignment, int result);
  390. static int is_any_component_instantiating (amf_su_t *su);
  391. typedef struct su_event {
  392. amf_su_event_type_t event_type;
  393. amf_su_t *su;
  394. amf_comp_t *comp;
  395. SaAmfRecommendedRecoveryT recommended_recovery;
  396. } su_event_t;
  397. /******************************************************************************
  398. * Internal (static) utility functions
  399. *****************************************************************************/
  400. static void su_event_set(struct amf_su *su, struct amf_comp *comp,
  401. SaAmfRecommendedRecoveryT recommended_recovery,
  402. su_event_t *su_event, amf_su_event_type_t event_type)
  403. {
  404. su_event->event_type = event_type;
  405. su_event->comp = comp;
  406. su_event->su = su;
  407. su_event->recommended_recovery = recommended_recovery;
  408. }
  409. static void su_defer_event (amf_su_t *su, amf_comp_t *comp,
  410. SaAmfRecommendedRecoveryT recommended_recovery,
  411. amf_su_event_type_t su_event_type)
  412. {
  413. su_event_t event;
  414. su_event_set(su, comp, recommended_recovery,&event, su_event_type);
  415. ENTER("event_type = %d", event.event_type);
  416. amf_fifo_put (event.event_type, &event.su->deferred_events,
  417. sizeof (su_event_t), &event);
  418. }
  419. static void su_recall_deferred_events (amf_su_t *su)
  420. {
  421. su_event_t su_event;
  422. ENTER ("%s", su->name.value);
  423. if (amf_fifo_get (&su->deferred_events, &su_event)) {
  424. switch (su_event.event_type) {
  425. case SU_COMP_ERROR_SUSPECTED_EV:
  426. amf_su_comp_error_suspected (su_event.su,su_event.comp,
  427. su_event.recommended_recovery);
  428. break;
  429. default:
  430. dprintf("event_type = %d", su_event.event_type);
  431. break;
  432. }
  433. }
  434. }
  435. static int has_component_restarted_max_times (amf_comp_t *comp, amf_su_t *su)
  436. {
  437. return comp->saAmfCompRestartCount >= su->sg->saAmfSGCompRestartMax;
  438. }
  439. #ifdef COMPILE_OUT
  440. static int has_su_restarted_max_times (amf_su_t *su)
  441. {
  442. return su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax;
  443. }
  444. #endif
  445. /**
  446. * This function only logs since the readiness state is runtime
  447. * calculated.
  448. * @param su
  449. * @param amf_readiness_state
  450. */
  451. static void su_readiness_state_set (struct amf_su *su,
  452. SaAmfReadinessStateT readiness_state)
  453. {
  454. log_printf (LOG_NOTICE, "Setting SU '%s' readiness state: %s\n",
  455. su->name.value, amf_readiness_state (readiness_state));
  456. }
  457. static void clear_ha_state (
  458. struct amf_su *su, struct amf_si_assignment *si_assignment)
  459. {
  460. ENTER ("");
  461. si_assignment->saAmfSISUHAState = 0;
  462. }
  463. /**
  464. * This function sets presence state to the specified value. It also has the
  465. * following intentional side effects:
  466. * - sets HA-state to unknown when presence state is set to UNINSTANTIATED
  467. * - reports the change of presence state to the sg in which su is contained
  468. * when the new state is 'stable'
  469. * @param su
  470. * @param presence_state - new value of presence state
  471. */
  472. static void su_presence_state_set (struct amf_su *su,
  473. SaAmfPresenceStateT presence_state)
  474. {
  475. /*
  476. * Set all SI's confirmed HA state to unknown if uninstantiated
  477. */
  478. if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) {
  479. amf_su_foreach_si_assignment (su, clear_ha_state);
  480. }
  481. su->saAmfSUPresenceState = presence_state;
  482. log_printf (LOG_NOTICE, "Setting SU '%s' presence state: %s\n",
  483. su->name.value, amf_presence_state (presence_state));
  484. if (su->restart_control_state != SU_RC_RESTART_SU_SETTING &&
  485. su->restart_control_state != SU_RC_RESTART_COMP_RESTARTING) {
  486. amf_sg_su_state_changed (su->sg, su, SA_AMF_PRESENCE_STATE,
  487. presence_state);
  488. }
  489. }
  490. static void enter_idle (struct amf_su *su)
  491. {
  492. su->restart_control_state = su->escalation_level_history_state;
  493. }
  494. static void enter_idle_with_recall (struct amf_su *su)
  495. {
  496. su->restart_control_state = su->escalation_level_history_state;
  497. su_recall_deferred_events (su);
  498. }
  499. /**
  500. * This function sets operational state to the specified value. It also has the
  501. * following side effects:
  502. * - sets the readiness state for su
  503. * - sets the readiness state for all components contained in the su
  504. * @param su
  505. * @param oper_state - new value of operational state
  506. */
  507. void amf_su_operational_state_set (struct amf_su *su,
  508. SaAmfOperationalStateT oper_state)
  509. {
  510. struct amf_comp* comp;
  511. su->saAmfSUOperState = oper_state;
  512. log_printf (LOG_NOTICE, "Setting SU '%s' operational state: %s\n",
  513. su->name.value, amf_op_state (oper_state));
  514. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  515. su_readiness_state_set (su, SA_AMF_READINESS_IN_SERVICE);
  516. for (comp = su->comp_head; comp; comp = comp->next) {
  517. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_IN_SERVICE);
  518. }
  519. } else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
  520. su_readiness_state_set (su, SA_AMF_READINESS_OUT_OF_SERVICE);
  521. for (comp = su->comp_head; comp; comp = comp->next) {
  522. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_OUT_OF_SERVICE);
  523. }
  524. }
  525. }
  526. /**
  527. * This function creates a new csi-assignment object and initializes it. The
  528. * function also links the new csi-assignment object to the list of assignments
  529. * held by the specified csi object, sets a pointer to the specified component
  530. * and a pointer to the specified si-assignment.
  531. * @param comp
  532. * @param csi
  533. * @param si_assignment
  534. * @param ha_state - new value of ha-state
  535. */
  536. static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
  537. struct amf_si_assignment *si_assignment, SaAmfHAStateT ha_state)
  538. {
  539. struct amf_csi_assignment *csi_assignment;
  540. dprintf (" Creating CSI '%s' to comp '%s' with hastate %s\n",
  541. getSaNameT (&csi->name), getSaNameT (&comp->name),
  542. amf_ha_state (ha_state));
  543. csi_assignment = amf_malloc (sizeof (struct amf_csi_assignment));
  544. csi_assignment->next = csi->assigned_csis;
  545. csi->assigned_csis = csi_assignment;
  546. amf_comp_dn_make (comp, &csi_assignment->name);
  547. csi_assignment->comp = comp;
  548. csi_assignment->csi = csi;
  549. csi_assignment->saAmfCSICompHAState = 0; /* undefined confirmed HA state */
  550. csi_assignment->requested_ha_state = ha_state;
  551. csi_assignment->si_assignment = si_assignment;
  552. }
  553. static void comp_restart (struct amf_comp *comp)
  554. {
  555. SaNameT dn;
  556. ENTER ("'%s'", comp->name.value);
  557. amf_comp_dn_make (comp, &dn);
  558. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  559. "action: Component restart", dn.value);
  560. comp->su->restart_control_state = SU_RC_RESTART_COMP_DEACTIVATING;
  561. comp->su->restart_control_state = SU_RC_RESTART_COMP_RESTARTING;
  562. comp->su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  563. amf_comp_restart (comp);
  564. }
  565. /**
  566. * Set the same HA-state as the before the restart to the SI-assignments
  567. * associated with current SU. As a side effect, this HA-state will also be set
  568. * to all components which are associated with the csi-assignments associated to
  569. * the specified su via its csi and si objects.
  570. * @param su
  571. * @param current_instantiation_level
  572. *
  573. * @return - 1 if there were no components on the specified instantiation level
  574. */
  575. static void reassume_ha_state(struct amf_su *su)
  576. {
  577. struct amf_si_assignment *si_assignment;
  578. ENTER ("");
  579. si_assignment = amf_su_get_next_si_assignment(su, NULL);
  580. while (si_assignment != NULL) {
  581. si_assignment->saAmfSISUHAState = 0; /* unknown */
  582. amf_si_ha_state_assume (si_assignment, si_ha_state_assumed_cbfn);
  583. si_assignment = amf_su_get_next_si_assignment(su, si_assignment);
  584. }
  585. }
  586. static int is_any_component_instantiating (amf_su_t *su)
  587. {
  588. amf_comp_t *component;
  589. int any_component_instantiating = 0;
  590. for (component = su->comp_head; component != NULL;
  591. component = component->next) {
  592. if (component->saAmfCompPresenceState ==
  593. SA_AMF_PRESENCE_INSTANTIATING) {
  594. any_component_instantiating = 1;
  595. break;
  596. }
  597. }
  598. return any_component_instantiating;
  599. }
  600. static int is_any_component_terminating (amf_su_t *su)
  601. {
  602. amf_comp_t *component;
  603. int any_component_terminating = 0;
  604. for (component = su->comp_head; component != NULL;
  605. component = component->next) {
  606. if (component->saAmfCompPresenceState ==
  607. SA_AMF_PRESENCE_TERMINATING) {
  608. any_component_terminating = 1;
  609. break;
  610. }
  611. }
  612. return any_component_terminating;
  613. }
  614. static int is_any_comp_instantiation_failed (amf_su_t *su)
  615. {
  616. amf_comp_t *comp_;
  617. int comp_instantiation_failed = 0;
  618. for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
  619. if (comp_->saAmfCompPresenceState ==
  620. SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  621. comp_instantiation_failed = 1;
  622. break;
  623. }
  624. }
  625. return comp_instantiation_failed;
  626. }
  627. static int is_any_comp_termination_failed (amf_su_t *su)
  628. {
  629. amf_comp_t *comp_;
  630. int comp_instantiation_failed = 0;
  631. for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
  632. if (comp_->saAmfCompPresenceState ==
  633. SA_AMF_PRESENCE_TERMINATION_FAILED) {
  634. comp_instantiation_failed = 1;
  635. break;
  636. }
  637. }
  638. return comp_instantiation_failed;
  639. }
  640. /**
  641. * Finds the component within the specified su that has the highest value of it
  642. * presence state. With current definition of values the highest value can also
  643. * be regarded as the 'worst' in the sence of capability to be assigned
  644. * workload. In the 'best' presence state (INSTANTIATED) the component is
  645. * immediately available to take workload while in the 'worst' state
  646. * (TERMINATION_FAILED) it can not take any workload before it has been manually
  647. * repaired.
  648. * @param su
  649. *
  650. * @return - worst presence state
  651. */
  652. static SaAmfPresenceStateT get_worst_comps_presence_state_in_su (amf_su_t *su)
  653. {
  654. amf_comp_t *component;
  655. SaAmfPresenceStateT worst_presence_state = 0;
  656. for (component = su->comp_head; component != NULL;
  657. component = component->next) {
  658. if (component->saAmfCompPresenceState > worst_presence_state) {
  659. worst_presence_state = component->saAmfCompPresenceState;
  660. }
  661. }
  662. return worst_presence_state;
  663. }
  664. /**
  665. *
  666. * @param su
  667. */
  668. void su_history_state_set(struct amf_su *su, SaAmfPresenceStateT state)
  669. {
  670. su->restart_control_state = su->escalation_level_history_state;
  671. su->saAmfSUPresenceState = state;
  672. }
  673. /**
  674. * A component notifies its parent su that its presence state has changed.
  675. * @param su
  676. * @param comp - component which has changed its presence state
  677. * @param state - new value of presence state
  678. */
  679. static void su_comp_presence_state_changed (struct amf_su *su,
  680. struct amf_comp *comp, int state)
  681. {
  682. ENTER ("'%s', '%s' %d %d", su->name.value, comp->name.value, state,
  683. su->restart_control_state);
  684. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  685. switch (state) {
  686. case SA_AMF_PRESENCE_INSTANTIATED:
  687. switch (su->restart_control_state) {
  688. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  689. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  690. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  691. if (!is_any_component_instantiating (su)) {
  692. if (are_all_comps_in_level_instantiated (su)) {
  693. if (instantiate_all_components_in_level (su,
  694. ++comp->su->current_comp_instantiation_level)) {
  695. /* All levels of instantiation is done */
  696. su_presence_state_set (comp->su,
  697. SA_AMF_PRESENCE_INSTANTIATED);
  698. }
  699. } else {
  700. if (is_any_comp_instantiation_failed (su)) {
  701. su_presence_state_set (su,
  702. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  703. } else {
  704. assert (0);
  705. }
  706. }
  707. }
  708. break;
  709. case SU_RC_RESTART_COMP_RESTARTING:
  710. su->restart_control_state = SU_RC_RESTART_COMP_SETTING;
  711. reassume_ha_state (comp->su);
  712. break;
  713. case SU_RC_RESTART_SU_INSTANTIATING:
  714. if (!is_any_component_instantiating(su)) {
  715. if (are_all_comps_in_level_instantiated (su)) {
  716. if (instantiate_all_components_in_level (su,
  717. ++comp->su->current_comp_instantiation_level)) {
  718. su->restart_control_state = SU_RC_RESTART_SU_SETTING;
  719. su_presence_state_set (comp->su,
  720. SA_AMF_PRESENCE_INSTANTIATED);
  721. reassume_ha_state (comp->su);
  722. }
  723. } else if (is_any_comp_instantiation_failed (su)) {
  724. su->restart_control_state =
  725. SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
  726. terminate_all_components_in_level (su,
  727. su->current_comp_instantiation_level);
  728. } else {
  729. assert (0);
  730. }
  731. }
  732. break;
  733. default:
  734. dprintf ("state %d", su->restart_control_state);
  735. assert (0);
  736. break;
  737. }
  738. break;
  739. case SA_AMF_PRESENCE_UNINSTANTIATED:
  740. switch (su->restart_control_state) {
  741. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  742. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  743. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  744. if (!is_any_component_terminating (su)) {
  745. if (are_all_comps_in_level_uninst_or_term_failed (su)) {
  746. if (terminate_all_components_in_level (su,
  747. --su->current_comp_instantiation_level)) {
  748. su_presence_state_set (su,
  749. get_worst_comps_presence_state_in_su (su));
  750. } else {
  751. if (is_any_comp_termination_failed (su)) {
  752. su_presence_state_set (comp->su,
  753. SA_AMF_PRESENCE_TERMINATION_FAILED);
  754. } else {
  755. assert (0);
  756. }
  757. }
  758. }
  759. }
  760. break;
  761. case SU_RC_RESTART_SU_INSTANTIATING:
  762. break;
  763. case SU_RC_RESTART_COMP_RESTARTING:
  764. break;
  765. case SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED:
  766. if (!is_any_component_terminating (su)) {
  767. if (terminate_all_components_in_level (su,
  768. --su->current_comp_instantiation_level)) {
  769. if (!is_any_comp_termination_failed (su)) {
  770. su_presence_state_set (su,
  771. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  772. if (node->saAmfNodeRebootOnInstantiationFailure) {
  773. amf_node_failover(node);
  774. } else {
  775. amf_node_comp_failover_req(node, comp);
  776. }
  777. enter_idle (su);
  778. } else {
  779. if (!node->saAmfNodeRebootOnTerminationFailure) {
  780. su_presence_state_set (su,
  781. get_worst_comps_presence_state_in_su (su));
  782. } else {
  783. /* TODO Implement and request Node Failed Fast */
  784. ;
  785. }
  786. enter_idle_with_recall (su);
  787. }
  788. }
  789. }
  790. break;
  791. case SU_RC_RESTART_SU_TERMINATING:
  792. if (!is_any_component_terminating (su)) {
  793. if (terminate_all_components_in_level (su,
  794. --su->current_comp_instantiation_level)) {
  795. if (!is_any_comp_termination_failed (su)) {
  796. su->restart_control_state =
  797. SU_RC_RESTART_SU_INSTANTIATING;
  798. instantiate_all_components_in_level (su,
  799. su_lowest_comp_instantiation_level_set (
  800. su));
  801. } else {
  802. if (!node->saAmfNodeRebootOnTerminationFailure) {
  803. su_presence_state_set (su,
  804. get_worst_comps_presence_state_in_su (su));
  805. } else {
  806. /* TODO Implement and request Node Failed Fast */
  807. ;
  808. }
  809. enter_idle_with_recall (su);
  810. }
  811. }
  812. }
  813. break;
  814. default:
  815. dprintf ("state %d", su->restart_control_state);
  816. assert (0);
  817. break;
  818. }
  819. break;
  820. case SA_AMF_PRESENCE_INSTANTIATING:
  821. su_presence_state_set (comp->su,SA_AMF_PRESENCE_INSTANTIATING);
  822. break;
  823. case SA_AMF_PRESENCE_RESTARTING:
  824. if (amf_su_are_all_comps_in_su (su, SA_AMF_PRESENCE_RESTARTING)) {
  825. su_presence_state_set (comp->su, SA_AMF_PRESENCE_RESTARTING);
  826. }
  827. break;
  828. case SA_AMF_PRESENCE_TERMINATING:
  829. su_presence_state_set (comp->su, SA_AMF_PRESENCE_TERMINATING);
  830. break;
  831. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  832. switch (su->restart_control_state) {
  833. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  834. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  835. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  836. if (!is_any_component_instantiating (su)) {
  837. su_presence_state_set (su,
  838. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  839. }
  840. break;
  841. case SU_RC_RESTART_COMP_RESTARTING:
  842. su->restart_control_state =
  843. SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
  844. amf_su_terminate (su);
  845. break;
  846. case SU_RC_RESTART_SU_INSTANTIATING:
  847. if (!is_any_component_instantiating (su)) {
  848. su->restart_control_state =
  849. SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
  850. su_presence_state_set (su,
  851. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  852. terminate_all_components_in_level (su,
  853. su->current_comp_instantiation_level);
  854. }
  855. break;
  856. default:
  857. dprintf ("state %d", su->restart_control_state);
  858. assert (0);
  859. break;
  860. }
  861. break;
  862. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  863. switch (su->restart_control_state) {
  864. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  865. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  866. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  867. break;
  868. case SU_RC_RESTART_COMP_RESTARTING:
  869. if (!node->saAmfNodeRebootOnTerminationFailure) {
  870. su_presence_state_set (su,
  871. SA_AMF_PRESENCE_TERMINATION_FAILED);
  872. enter_idle_with_recall (su);
  873. } else {
  874. /* TODO Implement and request Node Failed Fast */
  875. ;
  876. }
  877. break;
  878. case SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED:
  879. case SU_RC_RESTART_SU_TERMINATING:
  880. if (!is_any_component_terminating (su)) {
  881. if (terminate_all_components_in_level (su,
  882. --su->current_comp_instantiation_level)) {
  883. if (!node->saAmfNodeRebootOnTerminationFailure) {
  884. su_presence_state_set (su,
  885. get_worst_comps_presence_state_in_su (su));
  886. enter_idle_with_recall (su);
  887. } else {
  888. /* TODO Implement and request Node Failed Fast */
  889. ;
  890. }
  891. }
  892. }
  893. break;
  894. default:
  895. log_printf (LOG_LEVEL_NOTICE,"%s %d",su->name.value,
  896. su->restart_control_state);
  897. dprintf ("state %d", su->restart_control_state);
  898. assert (0);
  899. break;
  900. }
  901. break;
  902. default:
  903. assert (0);
  904. break;
  905. }
  906. }
  907. /**
  908. * A component notifies its parent su that its operational state has changed.
  909. * @param su
  910. * @param comp - component which has changed its operational state
  911. * @param state - new value of operational state
  912. */
  913. static void su_comp_op_state_changed (
  914. struct amf_su *su, struct amf_comp *comp, int state)
  915. {
  916. ENTER ("'%s', '%s' %d", su->name.value, comp->name.value, state);
  917. switch (state) {
  918. case SA_AMF_OPERATIONAL_ENABLED:
  919. {
  920. struct amf_comp *comp_compare;
  921. int all_set = 1;
  922. for (comp_compare = comp->su->comp_head;
  923. comp_compare != NULL; comp_compare = comp_compare->next) {
  924. if (comp_compare->saAmfCompOperState !=
  925. SA_AMF_OPERATIONAL_ENABLED) {
  926. all_set = 0;
  927. break;
  928. }
  929. }
  930. if (all_set) {
  931. amf_su_operational_state_set (comp->su,
  932. SA_AMF_OPERATIONAL_ENABLED);
  933. } else {
  934. amf_su_operational_state_set (comp->su,
  935. SA_AMF_OPERATIONAL_DISABLED);
  936. }
  937. break;
  938. }
  939. case SA_AMF_OPERATIONAL_DISABLED:
  940. amf_su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_DISABLED);
  941. break;
  942. default:
  943. assert (0);
  944. break;
  945. }
  946. return;
  947. }
  948. /**
  949. * Instantiates all components on specified instantiation level.
  950. * @param su
  951. * @param current_instantiation_level
  952. *
  953. * @return - 1 if there were no components on the specified instantiation level
  954. */
  955. static int instantiate_all_components_in_level (struct amf_su *su,
  956. SaUint32T current_instantiation_level)
  957. {
  958. amf_comp_t *comp;
  959. SaUint32T all_components_instantiated = 1;
  960. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  961. if (su->current_comp_instantiation_level ==
  962. comp->saAmfCompInstantiationLevel) {
  963. all_components_instantiated = 0;
  964. amf_comp_instantiate (comp);
  965. }
  966. }
  967. return all_components_instantiated;
  968. }
  969. static int are_all_comps_in_level_instantiated (struct amf_su *su)
  970. {
  971. SaUint32T level = su->current_comp_instantiation_level;
  972. amf_comp_t *comp;
  973. int all = 1;
  974. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  975. if (level == comp->saAmfCompInstantiationLevel) {
  976. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
  977. all = 0;
  978. break;
  979. }
  980. }
  981. }
  982. return all;
  983. }
  984. static int are_all_comps_in_level_uninst_or_term_failed(
  985. struct amf_su *su)
  986. {
  987. SaUint32T level = su->current_comp_instantiation_level;
  988. amf_comp_t *comp;
  989. int all = 1;
  990. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  991. if (level == comp->saAmfCompInstantiationLevel) {
  992. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_UNINSTANTIATED &&
  993. comp->saAmfCompPresenceState != SA_AMF_PRESENCE_TERMINATION_FAILED) {
  994. all = 0;
  995. break;
  996. }
  997. }
  998. }
  999. return all;
  1000. }
  1001. static void su_rc_enter_idle_escalation_level_1 (amf_comp_t *component,
  1002. SaAmfRecommendedRecoveryT recommended_recovery)
  1003. {
  1004. ENTER("");
  1005. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  1006. if (has_component_restarted_max_times (component, component->su)) {
  1007. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1008. amf_su_comp_error_suspected (component->su, component, recommended_recovery);
  1009. } else {
  1010. comp_restart (component);
  1011. }
  1012. }
  1013. static void su_rc_enter_idle_escalation_level_2 (amf_comp_t *component,
  1014. SaAmfRecommendedRecoveryT recommended_recovery)
  1015. {
  1016. ENTER("");
  1017. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1018. amf_node_t *node = amf_node_find (&component->su->saAmfSUHostedByNode);
  1019. amf_node_comp_restart_req (node, component);
  1020. }
  1021. static int get_instantiation_max_level (amf_su_t *su)
  1022. {
  1023. amf_comp_t *comp;
  1024. int instantiation_level = 0;
  1025. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1026. if (comp->saAmfCompInstantiationLevel > instantiation_level) {
  1027. instantiation_level = comp->saAmfCompInstantiationLevel;
  1028. }
  1029. }
  1030. return instantiation_level;
  1031. }
  1032. /**
  1033. * Initiates the termination of all components which have the specified
  1034. * instantiation level.
  1035. * @param su
  1036. * @param current_instantiation_level
  1037. *
  1038. * @return int -1 if no component has the specified instantiation level
  1039. */
  1040. static int terminate_all_components_in_level (struct amf_su *su,
  1041. SaUint32T current_instantiation_level)
  1042. {
  1043. amf_comp_t *comp;
  1044. int all_components_in_level = 1;
  1045. TRACE8("terminate comp->saAmfCompInstantiationLevel=%u",
  1046. current_instantiation_level);
  1047. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1048. /*
  1049. * Terminate all components in instantiation level in SU
  1050. * abruptly.
  1051. */
  1052. if (comp->saAmfCompInstantiationLevel == current_instantiation_level) {
  1053. amf_comp_error_suspected_set (comp);
  1054. amf_comp_terminate (comp);
  1055. all_components_in_level = 0;
  1056. }
  1057. }
  1058. return all_components_in_level;
  1059. }
  1060. /**
  1061. * su_current_instantiation_level_init
  1062. * @param su
  1063. *
  1064. * @return SaUint32T - the value of the instantiation level which has been set
  1065. */
  1066. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su)
  1067. {
  1068. amf_comp_t *component = su->comp_head;
  1069. int comp_instantiation_level = component->saAmfCompInstantiationLevel;
  1070. for (; component != NULL; component = component->next) {
  1071. TRACE1("component->saAmfCompInstantiationLevel=%d",
  1072. component->saAmfCompInstantiationLevel);
  1073. if (component->saAmfCompInstantiationLevel <
  1074. comp_instantiation_level) {
  1075. comp_instantiation_level =
  1076. component->saAmfCompInstantiationLevel;
  1077. }
  1078. }
  1079. su->current_comp_instantiation_level = comp_instantiation_level;
  1080. return comp_instantiation_level;
  1081. }
  1082. /**
  1083. * An order to SU to instantiate its components.
  1084. * @param su
  1085. *
  1086. * @return int - 1 if its state allows it to request its contained components to
  1087. * instantiate or its state indicates that its components are in
  1088. * the process of instantiation.
  1089. */
  1090. int amf_su_instantiate (struct amf_su *su)
  1091. {
  1092. int is_instantiating = 1;
  1093. ENTER ("'%s %d'", su->name.value, su->saAmfSUPresenceState);
  1094. switch (su->saAmfSUPresenceState) {
  1095. case SA_AMF_PRESENCE_UNINSTANTIATED:
  1096. instantiate_all_components_in_level(su,
  1097. su_lowest_comp_instantiation_level_set (su));
  1098. break;
  1099. case SA_AMF_PRESENCE_RESTARTING:
  1100. case SA_AMF_PRESENCE_INSTANTIATING:
  1101. break;
  1102. case SA_AMF_PRESENCE_INSTANTIATED:
  1103. case SA_AMF_PRESENCE_TERMINATING:
  1104. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  1105. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  1106. is_instantiating = 0;
  1107. break;
  1108. default:
  1109. assert (0);
  1110. break;
  1111. }
  1112. return is_instantiating;
  1113. }
  1114. /**
  1115. * An order to SU to terminate its components.
  1116. * @param su
  1117. */
  1118. void amf_su_terminate (struct amf_su *su)
  1119. {
  1120. ENTER ("'%s'", su->name.value);
  1121. su->current_comp_instantiation_level = get_instantiation_max_level (su);
  1122. terminate_all_components_in_level (su, su->current_comp_instantiation_level);
  1123. }
  1124. /**
  1125. * Called by a component to report a suspected error on a component
  1126. * @param su
  1127. * @param comp
  1128. * @param recommended_recovery
  1129. */
  1130. void amf_su_comp_error_suspected (
  1131. struct amf_su *su,
  1132. struct amf_comp *comp,
  1133. SaAmfRecommendedRecoveryT recommended_recovery)
  1134. {
  1135. ENTER ("Comp '%s', SU '%s' %d", comp->name.value, su->name.value,
  1136. su->restart_control_state);
  1137. switch (su->restart_control_state) {
  1138. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  1139. su_rc_enter_idle_escalation_level_1 (comp,
  1140. recommended_recovery);
  1141. break;
  1142. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  1143. if (has_component_restarted_max_times (comp, su)) {
  1144. su_rc_enter_idle_escalation_level_2 (comp,
  1145. recommended_recovery);
  1146. } else {
  1147. comp_restart (comp);
  1148. }
  1149. break;
  1150. case SU_RC_IDLE_ESCALATION_LEVEL_2: {
  1151. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  1152. amf_node_comp_restart_req (node, comp);
  1153. #ifdef COMPILE_OUT
  1154. if (su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax) {
  1155. /*
  1156. * TODO: delegate to node
  1157. */
  1158. SaNameT dn;
  1159. amf_comp_operational_state_set (comp,
  1160. SA_AMF_OPERATIONAL_DISABLED);
  1161. amf_su_operational_state_set (su,
  1162. SA_AMF_OPERATIONAL_DISABLED);
  1163. amf_comp_dn_make (comp, &dn);
  1164. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  1165. "action:\n\t\tSU failover", dn.value);
  1166. amf_sg_failover_su_req (comp->su->sg, comp->su, this_amf_node);
  1167. return;
  1168. } else {
  1169. su_restart (comp->su);
  1170. }
  1171. #endif
  1172. break;
  1173. }
  1174. case SU_RC_RESTART_SU_SETTING:
  1175. case SU_RC_RESTART_COMP_RESTARTING:
  1176. case SU_RC_RESTART_COMP_SETTING:
  1177. /* TODO: Complete the implementation of SU defer event */
  1178. su_defer_event (su, comp, recommended_recovery,
  1179. SU_COMP_ERROR_SUSPECTED_EV);
  1180. break;
  1181. default:
  1182. dprintf ("restart_control_state = %d",su->restart_control_state);
  1183. break;
  1184. }
  1185. }
  1186. /**
  1187. * An order to SU to unconditionally restart itself.
  1188. * @param su
  1189. */
  1190. void amf_su_restart (struct amf_su *su)
  1191. {
  1192. SaNameT dn;
  1193. ENTER ("'%s'", su->name.value);
  1194. amf_su_dn_make (su, &dn);
  1195. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  1196. "action: SU restart", dn.value);
  1197. su->restart_control_state = SU_RC_RESTART_SU_DEACTIVATING;
  1198. su->restart_control_state = SU_RC_RESTART_SU_TERMINATING;
  1199. su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1200. su->current_comp_instantiation_level = get_instantiation_max_level (su);
  1201. su->saAmfSURestartCount += 1;
  1202. terminate_all_components_in_level(su, su->current_comp_instantiation_level);
  1203. }
  1204. /******************************************************************************
  1205. * Event response methods
  1206. *****************************************************************************/
  1207. /**
  1208. * Used by a component to report a state change event
  1209. * @param su
  1210. * @param comp
  1211. * @param type type of state
  1212. * @param state new state
  1213. */
  1214. void amf_su_comp_state_changed (
  1215. struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state)
  1216. {
  1217. switch (type) {
  1218. case SA_AMF_PRESENCE_STATE:
  1219. su_comp_presence_state_changed (su, comp, state);
  1220. break;
  1221. case SA_AMF_OP_STATE:
  1222. su_comp_op_state_changed (su, comp, state);
  1223. break;
  1224. default:
  1225. assert (0);
  1226. break;
  1227. }
  1228. }
  1229. static void si_ha_state_assumed_cbfn (
  1230. struct amf_si_assignment *si_assignment, int result)
  1231. {
  1232. struct amf_si_assignment *tmp_si_assignment;
  1233. struct amf_comp *comp;
  1234. struct amf_csi_assignment *csi_assignment;
  1235. int all_confirmed = 1;
  1236. ENTER ("");
  1237. tmp_si_assignment = amf_su_get_next_si_assignment(si_assignment->su, NULL);
  1238. while (tmp_si_assignment != NULL) {
  1239. for (comp = tmp_si_assignment->su->comp_head; comp != NULL;
  1240. comp = comp->next) {
  1241. csi_assignment = amf_comp_get_next_csi_assignment(comp, NULL);
  1242. while (csi_assignment != NULL) {
  1243. if (csi_assignment->requested_ha_state !=
  1244. csi_assignment->saAmfCSICompHAState) {
  1245. all_confirmed = 0;
  1246. }
  1247. csi_assignment = amf_comp_get_next_csi_assignment(
  1248. comp, csi_assignment);
  1249. }
  1250. }
  1251. tmp_si_assignment = amf_su_get_next_si_assignment(
  1252. si_assignment->su, tmp_si_assignment);
  1253. }
  1254. if (all_confirmed) {
  1255. switch (si_assignment->su->restart_control_state) {
  1256. case SU_RC_RESTART_COMP_SETTING:
  1257. log_printf (LOG_NOTICE, "Component restart recovery finished");
  1258. break;
  1259. case SU_RC_RESTART_SU_SETTING:
  1260. log_printf (LOG_NOTICE, "SU restart recovery finished");
  1261. break;
  1262. default:
  1263. assert (0);
  1264. break;
  1265. }
  1266. enter_idle_with_recall (si_assignment->su);
  1267. }
  1268. }
  1269. /******************************************************************************
  1270. * General methods
  1271. *****************************************************************************/
  1272. void amf_su_init (void)
  1273. {
  1274. log_init ("AMF");
  1275. }
  1276. /**
  1277. * Constructor for SU objects. Adds SU last in the ordered
  1278. * list owned by the specified SG. Always returns a
  1279. * valid SU object, out-of-memory problems are handled here.
  1280. * Default values are initialized.
  1281. * @param sg
  1282. * @param name
  1283. *
  1284. * @return struct amf_su*
  1285. */
  1286. struct amf_su *amf_su_new (struct amf_sg *sg, char *name)
  1287. {
  1288. struct amf_su *tail = sg->su_head;
  1289. struct amf_su *su = amf_calloc (1, sizeof (struct amf_su));
  1290. while (tail != NULL) {
  1291. if (tail->next == NULL) {
  1292. break;
  1293. }
  1294. tail = tail->next;
  1295. }
  1296. if (tail == NULL) {
  1297. sg->su_head = su;
  1298. } else {
  1299. tail->next = su;
  1300. }
  1301. su->sg = sg;
  1302. /* setup default values from spec. */
  1303. su->saAmfSURank = 0;
  1304. su->saAmfSUIsExternal = 0;
  1305. su->saAmfSUFailover = 1;
  1306. su->saAmfSUAdminState = SA_AMF_ADMIN_UNLOCKED;
  1307. su->saAmfSUOperState = SA_AMF_OPERATIONAL_DISABLED;
  1308. su->saAmfSUPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
  1309. su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_0;
  1310. su->current_comp_instantiation_level = 0;
  1311. setSaNameT (&su->name, name);
  1312. return su;
  1313. }
  1314. void amf_su_delete (struct amf_su *su)
  1315. {
  1316. struct amf_comp *comp;
  1317. for (comp = su->comp_head; comp != NULL;) {
  1318. struct amf_comp *tmp = comp;
  1319. comp = comp->next;
  1320. amf_comp_delete (tmp);
  1321. }
  1322. free (su);
  1323. }
  1324. void *amf_su_serialize (struct amf_su *su, int *len)
  1325. {
  1326. char *buf = NULL;
  1327. int offset = 0, size = 0;
  1328. TRACE8 ("%s", su->name.value);
  1329. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->name);
  1330. buf = amf_serialize_SaUint32T (buf, &size, &offset, su->saAmfSURank);
  1331. buf = amf_serialize_SaUint32T (
  1332. buf, &size, &offset, su->saAmfSUNumComponents);
  1333. buf = amf_serialize_SaUint32T (
  1334. buf, &size, &offset, su->saAmfSUIsExternal);
  1335. buf = amf_serialize_SaUint32T (
  1336. buf, &size, &offset, su->saAmfSUFailover);
  1337. buf = amf_serialize_SaUint32T (
  1338. buf, &size, &offset, su->saAmfSUPreInstantiable);
  1339. buf = amf_serialize_SaUint32T (
  1340. buf, &size, &offset, su->saAmfSUOperState);
  1341. buf = amf_serialize_SaUint32T (
  1342. buf, &size, &offset, su->saAmfSUAdminState);
  1343. buf = amf_serialize_SaUint32T (
  1344. buf, &size, &offset, su->saAmfSUPresenceState);
  1345. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->saAmfSUHostedByNode);
  1346. buf = amf_serialize_SaUint32T (
  1347. buf, &size, &offset, su->saAmfSURestartCount);
  1348. buf = amf_serialize_SaUint32T (
  1349. buf, &size, &offset, su->restart_control_state);
  1350. buf = amf_serialize_SaUint32T (
  1351. buf, &size, &offset, su->escalation_level_history_state);
  1352. buf = amf_serialize_SaStringT (
  1353. buf, &size, &offset, su->clccli_path);
  1354. buf = amf_serialize_SaUint32T (
  1355. buf, &size, &offset, su->su_failover_cnt);
  1356. buf = amf_serialize_SaUint32T (
  1357. buf, &size, &offset, su->current_comp_instantiation_level);
  1358. *len = offset;
  1359. return buf;
  1360. }
  1361. struct amf_su *amf_su_deserialize (struct amf_sg *sg, char *buf)
  1362. {
  1363. char *tmp = buf;
  1364. struct amf_su *su = amf_su_new (sg, "");
  1365. tmp = amf_deserialize_SaNameT (tmp, &su->name);
  1366. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURank);
  1367. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUNumComponents);
  1368. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUIsExternal);
  1369. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUFailover);
  1370. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPreInstantiable);
  1371. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUOperState);
  1372. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUAdminState);
  1373. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPresenceState);
  1374. tmp = amf_deserialize_SaNameT (tmp, &su->saAmfSUHostedByNode);
  1375. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURestartCount);
  1376. tmp = amf_deserialize_SaUint32T (tmp, &su->restart_control_state);
  1377. tmp = amf_deserialize_SaUint32T (tmp, &su->escalation_level_history_state);
  1378. tmp = amf_deserialize_SaStringT (tmp, &su->clccli_path);
  1379. tmp = amf_deserialize_SaUint32T (tmp, &su->su_failover_cnt);
  1380. tmp = amf_deserialize_SaUint32T (tmp, &su->current_comp_instantiation_level);
  1381. return su;
  1382. }
  1383. struct amf_su *amf_su_find (struct amf_cluster *cluster, SaNameT *name)
  1384. {
  1385. struct amf_application *app;
  1386. struct amf_sg *sg;
  1387. struct amf_su *su = NULL;
  1388. char *app_name;
  1389. char *sg_name;
  1390. char *su_name;
  1391. char *ptrptr;
  1392. char *buf;
  1393. assert (cluster != NULL && name != NULL);
  1394. /* malloc new buffer since strtok_r writes to its first argument */
  1395. buf = amf_malloc (name->length + 1);
  1396. memcpy (buf, name->value, name->length + 1);
  1397. su_name = strtok_r(buf, ",", &ptrptr);
  1398. sg_name = strtok_r(NULL, ",", &ptrptr);
  1399. app_name = strtok_r(NULL, ",", &ptrptr);
  1400. if (su_name == NULL || sg_name == NULL || app_name == NULL) {
  1401. goto end;
  1402. }
  1403. su_name += 6;
  1404. sg_name += 6;
  1405. app_name += 7;
  1406. app = amf_application_find (cluster, app_name);
  1407. if (app == NULL) {
  1408. goto end;
  1409. }
  1410. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1411. if (strncmp (sg_name, (char*)sg->name.value,
  1412. sg->name.length) == 0) {
  1413. for (su = sg->su_head; su != NULL; su = su->next) {
  1414. if (su->name.length == strlen(su_name) &&
  1415. strncmp (su_name, (char*)su->name.value,
  1416. su->name.length) == 0) {
  1417. goto end;
  1418. }
  1419. }
  1420. }
  1421. }
  1422. end:
  1423. free (buf);
  1424. return su;
  1425. }
  1426. /**
  1427. * This function makes a distinguished name for specified su object.
  1428. * @param su
  1429. * @param name -[out] pointer to where the distinguished name shall be stored
  1430. *
  1431. * @return SaNameT* - distinguished name
  1432. */
  1433. char *amf_su_dn_make (struct amf_su *su, SaNameT *name)
  1434. {
  1435. int i;
  1436. assert (su != NULL);
  1437. i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  1438. "safSu=%s,safSg=%s,safApp=%s",
  1439. su->name.value, su->sg->name.value, su->sg->application->name.value);
  1440. assert (i <= SA_MAX_NAME_LENGTH);
  1441. name->length = i;
  1442. return (char *)name->value;
  1443. }
  1444. /**
  1445. * An order to SU to create an si-assignment object with a specified HA-state
  1446. * between it self and a specified si. The created si-assignment is initialized
  1447. * and linked to list of assignments held by the specified si.
  1448. * This function also orders creation of all csi-assignments required
  1449. * considering the cs-types specified for the components and csi objects
  1450. * respectively.
  1451. * @param su
  1452. * @param si
  1453. * @param ha_state
  1454. *
  1455. * @return amf_si_assignment_t*
  1456. */
  1457. amf_si_assignment_t *amf_su_assign_si (struct amf_su *su, struct amf_si *si,
  1458. SaAmfHAStateT ha_state)
  1459. {
  1460. struct amf_si_assignment *si_assignment;
  1461. dprintf ("Creating SI '%s' to SU '%s' with hastate %s\n",
  1462. getSaNameT (&si->name), getSaNameT (&su->name),
  1463. amf_ha_state (ha_state));
  1464. si_assignment = amf_malloc (sizeof (struct amf_si_assignment));
  1465. amf_su_dn_make (su, &si_assignment->name);
  1466. si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
  1467. si_assignment->requested_ha_state = ha_state;
  1468. si_assignment->next = si->assigned_sis;
  1469. si->assigned_sis = si_assignment;
  1470. si_assignment->si = si;
  1471. si_assignment->su = su;
  1472. {
  1473. struct amf_csi *csi;
  1474. struct amf_comp *comp;
  1475. SaNameT *cs_type;
  1476. int i;
  1477. /*
  1478. ** for each component in SU, find a CSI in the SI with the same type
  1479. */
  1480. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1481. int no_of_cs_types = 0;
  1482. for (i = 0; comp->saAmfCompCsTypes[i]; i++) {
  1483. cs_type = comp->saAmfCompCsTypes[i];
  1484. no_of_cs_types++;
  1485. int no_of_assignments = 0;
  1486. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  1487. if (!memcmp(csi->saAmfCSTypeName.value, cs_type->value,
  1488. cs_type->length)) {
  1489. comp_assign_csi (comp, csi, si_assignment, ha_state);
  1490. no_of_assignments++;
  1491. }
  1492. }
  1493. if (no_of_assignments == 0) {
  1494. log_printf (
  1495. LOG_WARNING, "\t No CSIs of type %s configured?!!\n",
  1496. getSaNameT (cs_type));
  1497. }
  1498. }
  1499. if (no_of_cs_types == 0) {
  1500. log_printf (LOG_LEVEL_ERROR,
  1501. "\t No CS types configured for comp %s ?!!\n",
  1502. getSaNameT (&comp->name));
  1503. }
  1504. }
  1505. }
  1506. return si_assignment;
  1507. }
  1508. struct amf_si_assignment *amf_su_get_next_si_assignment (
  1509. struct amf_su *su, const struct amf_si_assignment *si_assignment)
  1510. {
  1511. struct amf_si *si;
  1512. struct amf_si_assignment *tmp_si_assignment;
  1513. SaNameT dn;
  1514. amf_su_dn_make (su, &dn);
  1515. if (si_assignment == NULL) {
  1516. assert (su->sg);
  1517. assert (su->sg->application);
  1518. assert (su->sg->application->si_head);
  1519. si = su->sg->application->si_head;
  1520. tmp_si_assignment = si->assigned_sis;
  1521. } else {
  1522. tmp_si_assignment = si_assignment->next;
  1523. if (tmp_si_assignment == NULL) {
  1524. si = si_assignment->si->next;
  1525. if (si == NULL) {
  1526. return NULL;
  1527. } else {
  1528. tmp_si_assignment = si->assigned_sis;
  1529. }
  1530. } else {
  1531. si = tmp_si_assignment->si;
  1532. }
  1533. }
  1534. for (; si != NULL; si = si->next) {
  1535. if (tmp_si_assignment == NULL && si != NULL) {
  1536. tmp_si_assignment = si->assigned_sis;
  1537. }
  1538. for (; tmp_si_assignment != NULL;
  1539. tmp_si_assignment = tmp_si_assignment->next) {
  1540. if (name_match (&tmp_si_assignment->name, &dn)) {
  1541. return tmp_si_assignment;
  1542. }
  1543. }
  1544. }
  1545. return NULL;
  1546. }
  1547. void amf_su_foreach_si_assignment (
  1548. struct amf_su *su,
  1549. void (*foreach_fn)(struct amf_su *su,
  1550. struct amf_si_assignment *si_assignment))
  1551. {
  1552. struct amf_si_assignment *si_assignment;
  1553. assert (foreach_fn != NULL);
  1554. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1555. while (si_assignment != NULL) {
  1556. foreach_fn (su, si_assignment);
  1557. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1558. }
  1559. }
  1560. /**
  1561. * This function calculates the number of si-assignments with active HA-state
  1562. * which currently are associated with the specified su.
  1563. * TODO: Split into two functions and remove dependency to sg's avail_state
  1564. * @param su
  1565. *
  1566. * @return int
  1567. */
  1568. int amf_su_get_saAmfSUNumCurrActiveSIs(struct amf_su *su)
  1569. {
  1570. int cnt = 0;
  1571. struct amf_si_assignment *si_assignment;
  1572. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1573. while (si_assignment != NULL) {
  1574. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1575. si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
  1576. cnt++;
  1577. } else {
  1578. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
  1579. cnt++;
  1580. }
  1581. }
  1582. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1583. }
  1584. return cnt;
  1585. }
  1586. /**
  1587. * This function calculates the number of si-assignments with standby HA-state
  1588. * which currently are associated with the specified su.
  1589. * TODO: Split into two functions and remove dependency to sg's avail_state
  1590. * @param su
  1591. *
  1592. * @return int
  1593. */
  1594. int amf_su_get_saAmfSUNumCurrStandbySIs(struct amf_su *su)
  1595. {
  1596. int cnt = 0;
  1597. struct amf_si_assignment *si_assignment;
  1598. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1599. while (si_assignment != NULL) {
  1600. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1601. si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
  1602. cnt++;
  1603. } else {
  1604. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  1605. cnt++;
  1606. }
  1607. }
  1608. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1609. }
  1610. return cnt;
  1611. }
  1612. /**
  1613. * This function calculates the readiness state for specified su
  1614. * @param su
  1615. *
  1616. * @return SaAmfReadinessStateT
  1617. */
  1618. SaAmfReadinessStateT amf_su_get_saAmfSUReadinessState (struct amf_su *su)
  1619. {
  1620. if ((su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) &&
  1621. ((su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED) ||
  1622. (su->saAmfSUPresenceState == SA_AMF_PRESENCE_RESTARTING))) {
  1623. return SA_AMF_READINESS_IN_SERVICE;
  1624. } else if (su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) {
  1625. return SA_AMF_READINESS_STOPPING;
  1626. } else {
  1627. return SA_AMF_READINESS_OUT_OF_SERVICE;
  1628. }
  1629. }
  1630. /**
  1631. * Determine if the SU is hosted on the local node.
  1632. * @param su
  1633. *
  1634. * @return int
  1635. */
  1636. int amf_su_is_local (struct amf_su *su)
  1637. {
  1638. if (name_match (&this_amf_node->name, &su->saAmfSUHostedByNode)) {
  1639. return 1;
  1640. } else {
  1641. return 0;
  1642. }
  1643. }
  1644. /**
  1645. * Determine if all components have the specified HA-state.
  1646. * @param su
  1647. * @param state -specified HA-state
  1648. *
  1649. * @return int - return 0 if not all components have the specified HA-state
  1650. */
  1651. int amf_su_are_all_comps_in_su (struct amf_su *su,
  1652. SaAmfPresenceStateT state)
  1653. {
  1654. int all_comps_in_su_are_set = 1;
  1655. amf_comp_t *component;
  1656. for (component = su->comp_head; component != NULL;
  1657. component = component->next) {
  1658. if (component->saAmfCompPresenceState != state) {
  1659. all_comps_in_su_are_set = 0;
  1660. }
  1661. }
  1662. return all_comps_in_su_are_set;
  1663. }