amfsu.c 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804
  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 <stdlib.h>
  373. #include <assert.h>
  374. #include <string.h>
  375. #include <errno.h>
  376. #include "amf.h"
  377. #include "util.h"
  378. #include "print.h"
  379. #include "main.h"
  380. static int terminate_all_components_in_level (struct amf_su *su,
  381. SaUint32T current_instantiation_level);
  382. static int are_all_comps_in_level_uninst_or_term_failed (struct amf_su *su);
  383. static int are_all_comps_in_level_instantiated (struct amf_su *su);
  384. static int instantiate_all_components_in_level (struct amf_su *su,
  385. SaUint32T current_instantiation_level);
  386. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su);
  387. static void si_ha_state_assumed_cbfn (
  388. struct amf_si_assignment *si_assignment, int result);
  389. static int is_any_component_instantiating (amf_su_t *su);
  390. typedef struct su_event {
  391. amf_su_event_type_t event_type;
  392. amf_su_t *su;
  393. amf_comp_t *comp;
  394. SaAmfRecommendedRecoveryT recommended_recovery;
  395. } su_event_t;
  396. /******************************************************************************
  397. * Internal (static) utility functions
  398. *****************************************************************************/
  399. static void su_event_set(struct amf_su *su, struct amf_comp *comp,
  400. SaAmfRecommendedRecoveryT recommended_recovery,
  401. su_event_t *su_event, amf_su_event_type_t event_type)
  402. {
  403. su_event->event_type = event_type;
  404. su_event->comp = comp;
  405. su_event->su = su;
  406. su_event->recommended_recovery = recommended_recovery;
  407. }
  408. static void su_defer_event (amf_su_t *su, amf_comp_t *comp,
  409. SaAmfRecommendedRecoveryT recommended_recovery,
  410. amf_su_event_type_t su_event_type)
  411. {
  412. su_event_t event;
  413. su_event_set(su, comp, recommended_recovery,&event, su_event_type);
  414. ENTER("event_type = %d", event.event_type);
  415. amf_fifo_put (event.event_type, &event.su->deferred_events,
  416. sizeof (su_event_t), &event);
  417. }
  418. static void su_recall_deferred_events (amf_su_t *su)
  419. {
  420. su_event_t su_event;
  421. ENTER ("%s", su->name.value);
  422. if (amf_fifo_get (&su->deferred_events, &su_event)) {
  423. switch (su_event.event_type) {
  424. case SU_COMP_ERROR_SUSPECTED_EV:
  425. amf_su_comp_error_suspected (su_event.su,su_event.comp,
  426. su_event.recommended_recovery);
  427. break;
  428. default:
  429. dprintf("event_type = %d", su_event.event_type);
  430. break;
  431. }
  432. }
  433. }
  434. static int has_component_restarted_max_times (amf_comp_t *comp, amf_su_t *su)
  435. {
  436. return comp->saAmfCompRestartCount >= su->sg->saAmfSGCompRestartMax;
  437. }
  438. #ifdef COMPILE_OUT
  439. static int has_su_restarted_max_times (amf_su_t *su)
  440. {
  441. return su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax;
  442. }
  443. #endif
  444. /**
  445. * This function only logs since the readiness state is runtime
  446. * calculated.
  447. * @param su
  448. * @param amf_readiness_state
  449. */
  450. static void su_readiness_state_set (struct amf_su *su,
  451. SaAmfReadinessStateT readiness_state)
  452. {
  453. log_printf (LOG_NOTICE, "Setting SU '%s' readiness state: %s\n",
  454. su->name.value, amf_readiness_state (readiness_state));
  455. }
  456. static void clear_ha_state (
  457. struct amf_su *su, struct amf_si_assignment *si_assignment)
  458. {
  459. ENTER ("");
  460. si_assignment->saAmfSISUHAState = 0;
  461. }
  462. /**
  463. * This function sets presence state to the specified value. It also has the
  464. * following intentional side effects:
  465. * - sets HA-state to unknown when presence state is set to UNINSTANTIATED
  466. * - reports the change of presence state to the sg in which su is contained
  467. * when the new state is 'stable'
  468. * @param su
  469. * @param presence_state - new value of presence state
  470. */
  471. static void su_presence_state_set (struct amf_su *su,
  472. SaAmfPresenceStateT presence_state)
  473. {
  474. /*
  475. * Set all SI's confirmed HA state to unknown if uninstantiated
  476. */
  477. if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) {
  478. amf_su_foreach_si_assignment (su, clear_ha_state);
  479. }
  480. su->saAmfSUPresenceState = presence_state;
  481. log_printf (LOG_NOTICE, "Setting SU '%s' presence state: %s\n",
  482. su->name.value, amf_presence_state (presence_state));
  483. if (su->restart_control_state != SU_RC_RESTART_SU_SETTING &&
  484. su->restart_control_state != SU_RC_RESTART_COMP_RESTARTING) {
  485. amf_sg_su_state_changed (su->sg, su, SA_AMF_PRESENCE_STATE,
  486. presence_state);
  487. }
  488. }
  489. static void enter_idle (struct amf_su *su)
  490. {
  491. su->restart_control_state = su->escalation_level_history_state;
  492. }
  493. static void enter_idle_with_recall (struct amf_su *su)
  494. {
  495. su->restart_control_state = su->escalation_level_history_state;
  496. su_recall_deferred_events (su);
  497. }
  498. /**
  499. * This function sets operational state to the specified value. It also has the
  500. * following side effects:
  501. * - sets the readiness state for su
  502. * - sets the readiness state for all components contained in the su
  503. * @param su
  504. * @param oper_state - new value of operational state
  505. */
  506. void amf_su_operational_state_set (struct amf_su *su,
  507. SaAmfOperationalStateT oper_state)
  508. {
  509. struct amf_comp* comp;
  510. su->saAmfSUOperState = oper_state;
  511. log_printf (LOG_NOTICE, "Setting SU '%s' operational state: %s\n",
  512. su->name.value, amf_op_state (oper_state));
  513. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  514. su_readiness_state_set (su, SA_AMF_READINESS_IN_SERVICE);
  515. for (comp = su->comp_head; comp; comp = comp->next) {
  516. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_IN_SERVICE);
  517. }
  518. } else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
  519. su_readiness_state_set (su, SA_AMF_READINESS_OUT_OF_SERVICE);
  520. for (comp = su->comp_head; comp; comp = comp->next) {
  521. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_OUT_OF_SERVICE);
  522. }
  523. }
  524. }
  525. /**
  526. * This function creates a new csi-assignment object and initializes it. The
  527. * function also links the new csi-assignment object to the list of assignments
  528. * held by the specified csi object, sets a pointer to the specified component
  529. * and a pointer to the specified si-assignment.
  530. * @param comp
  531. * @param csi
  532. * @param si_assignment
  533. * @param ha_state - new value of ha-state
  534. */
  535. static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
  536. struct amf_si_assignment *si_assignment, SaAmfHAStateT ha_state)
  537. {
  538. struct amf_csi_assignment *csi_assignment;
  539. dprintf (" Creating CSI '%s' to comp '%s' with hastate %s\n",
  540. getSaNameT (&csi->name), getSaNameT (&comp->name),
  541. amf_ha_state (ha_state));
  542. csi_assignment = amf_malloc (sizeof (struct amf_csi_assignment));
  543. csi_assignment->next = csi->assigned_csis;
  544. csi->assigned_csis = csi_assignment;
  545. amf_comp_dn_make (comp, &csi_assignment->name);
  546. csi_assignment->comp = comp;
  547. csi_assignment->csi = csi;
  548. csi_assignment->saAmfCSICompHAState = 0; /* undefined confirmed HA state */
  549. csi_assignment->requested_ha_state = ha_state;
  550. csi_assignment->si_assignment = si_assignment;
  551. }
  552. static void comp_restart (struct amf_comp *comp)
  553. {
  554. SaNameT dn;
  555. ENTER ("'%s'", comp->name.value);
  556. amf_comp_dn_make (comp, &dn);
  557. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  558. "action: Component restart", dn.value);
  559. comp->su->restart_control_state = SU_RC_RESTART_COMP_DEACTIVATING;
  560. comp->su->restart_control_state = SU_RC_RESTART_COMP_RESTARTING;
  561. comp->su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  562. amf_comp_restart (comp);
  563. }
  564. /**
  565. * Set the same HA-state as the before the restart to the SI-assignments
  566. * associated with current SU. As a side effect, this HA-state will also be set
  567. * to all components which are associated with the csi-assignments associated to
  568. * the specified su via its csi and si objects.
  569. * @param su
  570. * @param current_instantiation_level
  571. *
  572. * @return - 1 if there were no components on the specified instantiation level
  573. */
  574. static void reassume_ha_state(struct amf_su *su)
  575. {
  576. struct amf_si_assignment *si_assignment;
  577. ENTER ("");
  578. si_assignment = amf_su_get_next_si_assignment(su, NULL);
  579. while (si_assignment != NULL) {
  580. si_assignment->saAmfSISUHAState = 0; /* unknown */
  581. amf_si_ha_state_assume (si_assignment, si_ha_state_assumed_cbfn);
  582. si_assignment = amf_su_get_next_si_assignment(su, si_assignment);
  583. }
  584. }
  585. static int is_any_component_instantiating (amf_su_t *su)
  586. {
  587. amf_comp_t *component;
  588. int any_component_instantiating = 0;
  589. for (component = su->comp_head; component != NULL;
  590. component = component->next) {
  591. if (component->saAmfCompPresenceState ==
  592. SA_AMF_PRESENCE_INSTANTIATING) {
  593. any_component_instantiating = 1;
  594. break;
  595. }
  596. }
  597. return any_component_instantiating;
  598. }
  599. static int is_any_component_terminating (amf_su_t *su)
  600. {
  601. amf_comp_t *component;
  602. int any_component_terminating = 0;
  603. for (component = su->comp_head; component != NULL;
  604. component = component->next) {
  605. if (component->saAmfCompPresenceState ==
  606. SA_AMF_PRESENCE_TERMINATING) {
  607. any_component_terminating = 1;
  608. break;
  609. }
  610. }
  611. return any_component_terminating;
  612. }
  613. static int is_any_comp_instantiation_failed (amf_su_t *su)
  614. {
  615. amf_comp_t *comp_;
  616. int comp_instantiation_failed = 0;
  617. for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
  618. if (comp_->saAmfCompPresenceState ==
  619. SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  620. comp_instantiation_failed = 1;
  621. break;
  622. }
  623. }
  624. return comp_instantiation_failed;
  625. }
  626. static int is_any_comp_termination_failed (amf_su_t *su)
  627. {
  628. amf_comp_t *comp_;
  629. int comp_instantiation_failed = 0;
  630. for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
  631. if (comp_->saAmfCompPresenceState ==
  632. SA_AMF_PRESENCE_TERMINATION_FAILED) {
  633. comp_instantiation_failed = 1;
  634. break;
  635. }
  636. }
  637. return comp_instantiation_failed;
  638. }
  639. /**
  640. * Finds the component within the specified su that has the highest value of it
  641. * presence state. With current definition of values the highest value can also
  642. * be regarded as the 'worst' in the sence of capability to be assigned
  643. * workload. In the 'best' presence state (INSTANTIATED) the component is
  644. * immediately available to take workload while in the 'worst' state
  645. * (TERMINATION_FAILED) it can not take any workload before it has been manually
  646. * repaired.
  647. * @param su
  648. *
  649. * @return - worst presence state
  650. */
  651. static SaAmfPresenceStateT get_worst_comps_presence_state_in_su (amf_su_t *su)
  652. {
  653. amf_comp_t *component;
  654. SaAmfPresenceStateT worst_presence_state = 0;
  655. for (component = su->comp_head; component != NULL;
  656. component = component->next) {
  657. if (component->saAmfCompPresenceState > worst_presence_state) {
  658. worst_presence_state = component->saAmfCompPresenceState;
  659. }
  660. }
  661. return worst_presence_state;
  662. }
  663. /**
  664. *
  665. * @param su
  666. */
  667. void su_history_state_set(struct amf_su *su, SaAmfPresenceStateT state)
  668. {
  669. su->restart_control_state = su->escalation_level_history_state;
  670. su->saAmfSUPresenceState = state;
  671. }
  672. /**
  673. * A component notifies its parent su that its presence state has changed.
  674. * @param su
  675. * @param comp - component which has changed its presence state
  676. * @param state - new value of presence state
  677. */
  678. static void su_comp_presence_state_changed (struct amf_su *su,
  679. struct amf_comp *comp, int state)
  680. {
  681. ENTER ("'%s', '%s' %d %d", su->name.value, comp->name.value, state,
  682. su->restart_control_state);
  683. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  684. switch (state) {
  685. case SA_AMF_PRESENCE_INSTANTIATED:
  686. switch (su->restart_control_state) {
  687. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  688. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  689. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  690. if (!is_any_component_instantiating (su)) {
  691. if (are_all_comps_in_level_instantiated (su)) {
  692. if (instantiate_all_components_in_level (su,
  693. ++comp->su->current_comp_instantiation_level)) {
  694. /* All levels of instantiation is done */
  695. su_presence_state_set (comp->su,
  696. SA_AMF_PRESENCE_INSTANTIATED);
  697. }
  698. } else {
  699. if (is_any_comp_instantiation_failed (su)) {
  700. su_presence_state_set (su,
  701. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  702. } else {
  703. assert (0);
  704. }
  705. }
  706. }
  707. break;
  708. case SU_RC_RESTART_COMP_RESTARTING:
  709. su->restart_control_state = SU_RC_RESTART_COMP_SETTING;
  710. reassume_ha_state (comp->su);
  711. break;
  712. case SU_RC_RESTART_SU_INSTANTIATING:
  713. if (!is_any_component_instantiating(su)) {
  714. if (are_all_comps_in_level_instantiated (su)) {
  715. if (instantiate_all_components_in_level (su,
  716. ++comp->su->current_comp_instantiation_level)) {
  717. su->restart_control_state = SU_RC_RESTART_SU_SETTING;
  718. su_presence_state_set (comp->su,
  719. SA_AMF_PRESENCE_INSTANTIATED);
  720. reassume_ha_state (comp->su);
  721. }
  722. } else if (is_any_comp_instantiation_failed (su)) {
  723. su->restart_control_state =
  724. SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
  725. terminate_all_components_in_level (su,
  726. su->current_comp_instantiation_level);
  727. } else {
  728. assert (0);
  729. }
  730. }
  731. break;
  732. default:
  733. dprintf ("state %d", su->restart_control_state);
  734. assert (0);
  735. break;
  736. }
  737. break;
  738. case SA_AMF_PRESENCE_UNINSTANTIATED:
  739. switch (su->restart_control_state) {
  740. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  741. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  742. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  743. if (!is_any_component_terminating (su)) {
  744. if (are_all_comps_in_level_uninst_or_term_failed (su)) {
  745. if (terminate_all_components_in_level (su,
  746. --su->current_comp_instantiation_level)) {
  747. su_presence_state_set (su,
  748. get_worst_comps_presence_state_in_su (su));
  749. } else {
  750. if (is_any_comp_termination_failed (su)) {
  751. su_presence_state_set (comp->su,
  752. SA_AMF_PRESENCE_TERMINATION_FAILED);
  753. } else {
  754. assert (0);
  755. }
  756. }
  757. }
  758. }
  759. break;
  760. case SU_RC_RESTART_SU_INSTANTIATING:
  761. break;
  762. case SU_RC_RESTART_COMP_RESTARTING:
  763. break;
  764. case SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED:
  765. if (!is_any_component_terminating (su)) {
  766. if (terminate_all_components_in_level (su,
  767. --su->current_comp_instantiation_level)) {
  768. if (!is_any_comp_termination_failed (su)) {
  769. su_presence_state_set (su,
  770. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  771. if (node->saAmfNodeRebootOnInstantiationFailure) {
  772. amf_node_failover(node);
  773. } else {
  774. amf_node_comp_failover_req(node, comp);
  775. }
  776. enter_idle (su);
  777. } else {
  778. if (!node->saAmfNodeRebootOnTerminationFailure) {
  779. su_presence_state_set (su,
  780. get_worst_comps_presence_state_in_su (su));
  781. } else {
  782. /* TODO Implement and request Node Failed Fast */
  783. ;
  784. }
  785. enter_idle_with_recall (su);
  786. }
  787. }
  788. }
  789. break;
  790. case SU_RC_RESTART_SU_TERMINATING:
  791. if (!is_any_component_terminating (su)) {
  792. if (terminate_all_components_in_level (su,
  793. --su->current_comp_instantiation_level)) {
  794. if (!is_any_comp_termination_failed (su)) {
  795. su->restart_control_state =
  796. SU_RC_RESTART_SU_INSTANTIATING;
  797. instantiate_all_components_in_level (su,
  798. su_lowest_comp_instantiation_level_set (
  799. su));
  800. } else {
  801. if (!node->saAmfNodeRebootOnTerminationFailure) {
  802. su_presence_state_set (su,
  803. get_worst_comps_presence_state_in_su (su));
  804. } else {
  805. /* TODO Implement and request Node Failed Fast */
  806. ;
  807. }
  808. enter_idle_with_recall (su);
  809. }
  810. }
  811. }
  812. break;
  813. default:
  814. dprintf ("state %d", su->restart_control_state);
  815. assert (0);
  816. break;
  817. }
  818. break;
  819. case SA_AMF_PRESENCE_INSTANTIATING:
  820. su_presence_state_set (comp->su,SA_AMF_PRESENCE_INSTANTIATING);
  821. break;
  822. case SA_AMF_PRESENCE_RESTARTING:
  823. if (amf_su_are_all_comps_in_su (su, SA_AMF_PRESENCE_RESTARTING)) {
  824. su_presence_state_set (comp->su, SA_AMF_PRESENCE_RESTARTING);
  825. }
  826. break;
  827. case SA_AMF_PRESENCE_TERMINATING:
  828. su_presence_state_set (comp->su, SA_AMF_PRESENCE_TERMINATING);
  829. break;
  830. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  831. switch (su->restart_control_state) {
  832. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  833. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  834. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  835. if (!is_any_component_instantiating (su)) {
  836. su_presence_state_set (su,
  837. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  838. }
  839. break;
  840. case SU_RC_RESTART_COMP_RESTARTING:
  841. su->restart_control_state =
  842. SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
  843. amf_su_terminate (su);
  844. break;
  845. case SU_RC_RESTART_SU_INSTANTIATING:
  846. if (!is_any_component_instantiating (su)) {
  847. su->restart_control_state =
  848. SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED;
  849. su_presence_state_set (su,
  850. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  851. terminate_all_components_in_level (su,
  852. su->current_comp_instantiation_level);
  853. }
  854. break;
  855. default:
  856. dprintf ("state %d", su->restart_control_state);
  857. assert (0);
  858. break;
  859. }
  860. break;
  861. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  862. switch (su->restart_control_state) {
  863. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  864. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  865. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  866. break;
  867. case SU_RC_RESTART_COMP_RESTARTING:
  868. if (!node->saAmfNodeRebootOnTerminationFailure) {
  869. su_presence_state_set (su,
  870. SA_AMF_PRESENCE_TERMINATION_FAILED);
  871. enter_idle_with_recall (su);
  872. } else {
  873. /* TODO Implement and request Node Failed Fast */
  874. ;
  875. }
  876. break;
  877. case SU_RC_TERMINATING_AFTER_INSTANTIATION_FAILED:
  878. case SU_RC_RESTART_SU_TERMINATING:
  879. if (!is_any_component_terminating (su)) {
  880. if (terminate_all_components_in_level (su,
  881. --su->current_comp_instantiation_level)) {
  882. if (!node->saAmfNodeRebootOnTerminationFailure) {
  883. su_presence_state_set (su,
  884. get_worst_comps_presence_state_in_su (su));
  885. enter_idle_with_recall (su);
  886. } else {
  887. /* TODO Implement and request Node Failed Fast */
  888. ;
  889. }
  890. }
  891. }
  892. break;
  893. default:
  894. log_printf (LOG_LEVEL_NOTICE,"%s %d",su->name.value,
  895. su->restart_control_state);
  896. dprintf ("state %d", su->restart_control_state);
  897. assert (0);
  898. break;
  899. }
  900. break;
  901. default:
  902. assert (0);
  903. break;
  904. }
  905. }
  906. /**
  907. * A component notifies its parent su that its operational state has changed.
  908. * @param su
  909. * @param comp - component which has changed its operational state
  910. * @param state - new value of operational state
  911. */
  912. static void su_comp_op_state_changed (
  913. struct amf_su *su, struct amf_comp *comp, int state)
  914. {
  915. ENTER ("'%s', '%s' %d", su->name.value, comp->name.value, state);
  916. switch (state) {
  917. case SA_AMF_OPERATIONAL_ENABLED:
  918. {
  919. struct amf_comp *comp_compare;
  920. int all_set = 1;
  921. for (comp_compare = comp->su->comp_head;
  922. comp_compare != NULL; comp_compare = comp_compare->next) {
  923. if (comp_compare->saAmfCompOperState !=
  924. SA_AMF_OPERATIONAL_ENABLED) {
  925. all_set = 0;
  926. break;
  927. }
  928. }
  929. if (all_set) {
  930. amf_su_operational_state_set (comp->su,
  931. SA_AMF_OPERATIONAL_ENABLED);
  932. } else {
  933. amf_su_operational_state_set (comp->su,
  934. SA_AMF_OPERATIONAL_DISABLED);
  935. }
  936. break;
  937. }
  938. case SA_AMF_OPERATIONAL_DISABLED:
  939. amf_su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_DISABLED);
  940. break;
  941. default:
  942. assert (0);
  943. break;
  944. }
  945. return;
  946. }
  947. /**
  948. * Instantiates all components on specified instantiation level.
  949. * @param su
  950. * @param current_instantiation_level
  951. *
  952. * @return - 1 if there were no components on the specified instantiation level
  953. */
  954. static int instantiate_all_components_in_level (struct amf_su *su,
  955. SaUint32T current_instantiation_level)
  956. {
  957. amf_comp_t *comp;
  958. SaUint32T all_components_instantiated = 1;
  959. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  960. if (su->current_comp_instantiation_level ==
  961. comp->saAmfCompInstantiationLevel) {
  962. all_components_instantiated = 0;
  963. amf_comp_instantiate (comp);
  964. }
  965. }
  966. return all_components_instantiated;
  967. }
  968. static int are_all_comps_in_level_instantiated (struct amf_su *su)
  969. {
  970. SaUint32T level = su->current_comp_instantiation_level;
  971. amf_comp_t *comp;
  972. int all = 1;
  973. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  974. if (level == comp->saAmfCompInstantiationLevel) {
  975. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
  976. all = 0;
  977. break;
  978. }
  979. }
  980. }
  981. return all;
  982. }
  983. static int are_all_comps_in_level_uninst_or_term_failed(
  984. struct amf_su *su)
  985. {
  986. SaUint32T level = su->current_comp_instantiation_level;
  987. amf_comp_t *comp;
  988. int all = 1;
  989. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  990. if (level == comp->saAmfCompInstantiationLevel) {
  991. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_UNINSTANTIATED &&
  992. comp->saAmfCompPresenceState != SA_AMF_PRESENCE_TERMINATION_FAILED) {
  993. all = 0;
  994. break;
  995. }
  996. }
  997. }
  998. return all;
  999. }
  1000. static void su_rc_enter_idle_escalation_level_1 (amf_comp_t *component,
  1001. SaAmfRecommendedRecoveryT recommended_recovery)
  1002. {
  1003. ENTER("");
  1004. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  1005. if (has_component_restarted_max_times (component, component->su)) {
  1006. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1007. amf_su_comp_error_suspected (component->su, component, recommended_recovery);
  1008. } else {
  1009. comp_restart (component);
  1010. }
  1011. }
  1012. static void su_rc_enter_idle_escalation_level_2 (amf_comp_t *component,
  1013. SaAmfRecommendedRecoveryT recommended_recovery)
  1014. {
  1015. ENTER("");
  1016. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1017. amf_node_t *node = amf_node_find (&component->su->saAmfSUHostedByNode);
  1018. amf_node_comp_restart_req (node, component);
  1019. }
  1020. static int get_instantiation_max_level (amf_su_t *su)
  1021. {
  1022. amf_comp_t *comp;
  1023. int instantiation_level = 0;
  1024. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1025. if (comp->saAmfCompInstantiationLevel > instantiation_level) {
  1026. instantiation_level = comp->saAmfCompInstantiationLevel;
  1027. }
  1028. }
  1029. return instantiation_level;
  1030. }
  1031. /**
  1032. * Initiates the termination of all components which have the specified
  1033. * instantiation level.
  1034. * @param su
  1035. * @param current_instantiation_level
  1036. *
  1037. * @return int -1 if no component has the specified instantiation level
  1038. */
  1039. static int terminate_all_components_in_level (struct amf_su *su,
  1040. SaUint32T current_instantiation_level)
  1041. {
  1042. amf_comp_t *comp;
  1043. int all_components_in_level = 1;
  1044. TRACE8("terminate comp->saAmfCompInstantiationLevel=%u",
  1045. current_instantiation_level);
  1046. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1047. /*
  1048. * Terminate all components in instantiation level in SU
  1049. * abruptly.
  1050. */
  1051. if (comp->saAmfCompInstantiationLevel == current_instantiation_level) {
  1052. amf_comp_error_suspected_set (comp);
  1053. amf_comp_terminate (comp);
  1054. all_components_in_level = 0;
  1055. }
  1056. }
  1057. return all_components_in_level;
  1058. }
  1059. /**
  1060. * su_current_instantiation_level_init
  1061. * @param su
  1062. *
  1063. * @return SaUint32T - the value of the instantiation level which has been set
  1064. */
  1065. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su)
  1066. {
  1067. amf_comp_t *component = su->comp_head;
  1068. int comp_instantiation_level = component->saAmfCompInstantiationLevel;
  1069. for (; component != NULL; component = component->next) {
  1070. TRACE1("component->saAmfCompInstantiationLevel=%d",
  1071. component->saAmfCompInstantiationLevel);
  1072. if (component->saAmfCompInstantiationLevel <
  1073. comp_instantiation_level) {
  1074. comp_instantiation_level =
  1075. component->saAmfCompInstantiationLevel;
  1076. }
  1077. }
  1078. su->current_comp_instantiation_level = comp_instantiation_level;
  1079. return comp_instantiation_level;
  1080. }
  1081. /**
  1082. * An order to SU to instantiate its components.
  1083. * @param su
  1084. *
  1085. * @return int - 1 if its state allows it to request its contained components to
  1086. * instantiate or its state indicates that its components are in
  1087. * the process of instantiation.
  1088. */
  1089. int amf_su_instantiate (struct amf_su *su)
  1090. {
  1091. int is_instantiating = 1;
  1092. ENTER ("'%s %d'", su->name.value, su->saAmfSUPresenceState);
  1093. switch (su->saAmfSUPresenceState) {
  1094. case SA_AMF_PRESENCE_UNINSTANTIATED:
  1095. instantiate_all_components_in_level(su,
  1096. su_lowest_comp_instantiation_level_set (su));
  1097. break;
  1098. case SA_AMF_PRESENCE_RESTARTING:
  1099. case SA_AMF_PRESENCE_INSTANTIATING:
  1100. break;
  1101. case SA_AMF_PRESENCE_INSTANTIATED:
  1102. case SA_AMF_PRESENCE_TERMINATING:
  1103. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  1104. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  1105. is_instantiating = 0;
  1106. break;
  1107. default:
  1108. assert (0);
  1109. break;
  1110. }
  1111. return is_instantiating;
  1112. }
  1113. /**
  1114. * An order to SU to terminate its components.
  1115. * @param su
  1116. */
  1117. void amf_su_terminate (struct amf_su *su)
  1118. {
  1119. ENTER ("'%s'", su->name.value);
  1120. su->current_comp_instantiation_level = get_instantiation_max_level (su);
  1121. terminate_all_components_in_level (su, su->current_comp_instantiation_level);
  1122. }
  1123. /**
  1124. * Called by a component to report a suspected error on a component
  1125. * @param su
  1126. * @param comp
  1127. * @param recommended_recovery
  1128. */
  1129. void amf_su_comp_error_suspected (
  1130. struct amf_su *su,
  1131. struct amf_comp *comp,
  1132. SaAmfRecommendedRecoveryT recommended_recovery)
  1133. {
  1134. ENTER ("Comp '%s', SU '%s' %d", comp->name.value, su->name.value,
  1135. su->restart_control_state);
  1136. switch (su->restart_control_state) {
  1137. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  1138. su_rc_enter_idle_escalation_level_1 (comp,
  1139. recommended_recovery);
  1140. break;
  1141. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  1142. if (has_component_restarted_max_times (comp, su)) {
  1143. su_rc_enter_idle_escalation_level_2 (comp,
  1144. recommended_recovery);
  1145. } else {
  1146. comp_restart (comp);
  1147. }
  1148. break;
  1149. case SU_RC_IDLE_ESCALATION_LEVEL_2: {
  1150. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  1151. amf_node_comp_restart_req (node, comp);
  1152. #ifdef COMPILE_OUT
  1153. if (su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax) {
  1154. /*
  1155. * TODO: delegate to node
  1156. */
  1157. SaNameT dn;
  1158. amf_comp_operational_state_set (comp,
  1159. SA_AMF_OPERATIONAL_DISABLED);
  1160. amf_su_operational_state_set (su,
  1161. SA_AMF_OPERATIONAL_DISABLED);
  1162. amf_comp_dn_make (comp, &dn);
  1163. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  1164. "action:\n\t\tSU failover", dn.value);
  1165. amf_sg_failover_su_req (comp->su->sg, comp->su, this_amf_node);
  1166. return;
  1167. } else {
  1168. su_restart (comp->su);
  1169. }
  1170. #endif
  1171. break;
  1172. }
  1173. case SU_RC_RESTART_SU_SETTING:
  1174. case SU_RC_RESTART_COMP_RESTARTING:
  1175. case SU_RC_RESTART_COMP_SETTING:
  1176. /* TODO: Complete the implementation of SU defer event */
  1177. su_defer_event (su, comp, recommended_recovery,
  1178. SU_COMP_ERROR_SUSPECTED_EV);
  1179. break;
  1180. default:
  1181. dprintf ("restart_control_state = %d",su->restart_control_state);
  1182. break;
  1183. }
  1184. }
  1185. /**
  1186. * An order to SU to unconditionally restart itself.
  1187. * @param su
  1188. */
  1189. void amf_su_restart (struct amf_su *su)
  1190. {
  1191. SaNameT dn;
  1192. ENTER ("'%s'", su->name.value);
  1193. amf_su_dn_make (su, &dn);
  1194. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  1195. "action: SU restart", dn.value);
  1196. su->restart_control_state = SU_RC_RESTART_SU_DEACTIVATING;
  1197. su->restart_control_state = SU_RC_RESTART_SU_TERMINATING;
  1198. su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1199. su->current_comp_instantiation_level = get_instantiation_max_level (su);
  1200. su->saAmfSURestartCount += 1;
  1201. terminate_all_components_in_level(su, su->current_comp_instantiation_level);
  1202. }
  1203. /******************************************************************************
  1204. * Event response methods
  1205. *****************************************************************************/
  1206. /**
  1207. * Used by a component to report a state change event
  1208. * @param su
  1209. * @param comp
  1210. * @param type type of state
  1211. * @param state new state
  1212. */
  1213. void amf_su_comp_state_changed (
  1214. struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state)
  1215. {
  1216. switch (type) {
  1217. case SA_AMF_PRESENCE_STATE:
  1218. su_comp_presence_state_changed (su, comp, state);
  1219. break;
  1220. case SA_AMF_OP_STATE:
  1221. su_comp_op_state_changed (su, comp, state);
  1222. break;
  1223. default:
  1224. assert (0);
  1225. break;
  1226. }
  1227. }
  1228. static void si_ha_state_assumed_cbfn (
  1229. struct amf_si_assignment *si_assignment, int result)
  1230. {
  1231. struct amf_si_assignment *tmp_si_assignment;
  1232. struct amf_comp *comp;
  1233. struct amf_csi_assignment *csi_assignment;
  1234. int all_confirmed = 1;
  1235. ENTER ("");
  1236. tmp_si_assignment = amf_su_get_next_si_assignment(si_assignment->su, NULL);
  1237. while (tmp_si_assignment != NULL) {
  1238. for (comp = tmp_si_assignment->su->comp_head; comp != NULL;
  1239. comp = comp->next) {
  1240. csi_assignment = amf_comp_get_next_csi_assignment(comp, NULL);
  1241. while (csi_assignment != NULL) {
  1242. if (csi_assignment->requested_ha_state !=
  1243. csi_assignment->saAmfCSICompHAState) {
  1244. all_confirmed = 0;
  1245. }
  1246. csi_assignment = amf_comp_get_next_csi_assignment(
  1247. comp, csi_assignment);
  1248. }
  1249. }
  1250. tmp_si_assignment = amf_su_get_next_si_assignment(
  1251. si_assignment->su, tmp_si_assignment);
  1252. }
  1253. if (all_confirmed) {
  1254. switch (si_assignment->su->restart_control_state) {
  1255. case SU_RC_RESTART_COMP_SETTING:
  1256. log_printf (LOG_NOTICE, "Component restart recovery finished");
  1257. break;
  1258. case SU_RC_RESTART_SU_SETTING:
  1259. log_printf (LOG_NOTICE, "SU restart recovery finished");
  1260. break;
  1261. default:
  1262. assert (0);
  1263. break;
  1264. }
  1265. enter_idle_with_recall (si_assignment->su);
  1266. }
  1267. }
  1268. /******************************************************************************
  1269. * General methods
  1270. *****************************************************************************/
  1271. void amf_su_init (void)
  1272. {
  1273. log_init ("AMF");
  1274. }
  1275. /**
  1276. * Constructor for SU objects. Adds SU last in the ordered
  1277. * list owned by the specified SG. Always returns a
  1278. * valid SU object, out-of-memory problems are handled here.
  1279. * Default values are initialized.
  1280. * @param sg
  1281. * @param name
  1282. *
  1283. * @return struct amf_su*
  1284. */
  1285. struct amf_su *amf_su_new (struct amf_sg *sg, char *name)
  1286. {
  1287. struct amf_su *tail = sg->su_head;
  1288. struct amf_su *su = amf_calloc (1, sizeof (struct amf_su));
  1289. while (tail != NULL) {
  1290. if (tail->next == NULL) {
  1291. break;
  1292. }
  1293. tail = tail->next;
  1294. }
  1295. if (tail == NULL) {
  1296. sg->su_head = su;
  1297. } else {
  1298. tail->next = su;
  1299. }
  1300. su->sg = sg;
  1301. /* setup default values from spec. */
  1302. su->saAmfSURank = 0;
  1303. su->saAmfSUIsExternal = 0;
  1304. su->saAmfSUFailover = 1;
  1305. su->saAmfSUAdminState = SA_AMF_ADMIN_UNLOCKED;
  1306. su->saAmfSUOperState = SA_AMF_OPERATIONAL_DISABLED;
  1307. su->saAmfSUPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
  1308. su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_0;
  1309. su->current_comp_instantiation_level = 0;
  1310. setSaNameT (&su->name, name);
  1311. return su;
  1312. }
  1313. void amf_su_delete (struct amf_su *su)
  1314. {
  1315. struct amf_comp *comp;
  1316. for (comp = su->comp_head; comp != NULL;) {
  1317. struct amf_comp *tmp = comp;
  1318. comp = comp->next;
  1319. amf_comp_delete (tmp);
  1320. }
  1321. free (su);
  1322. }
  1323. void *amf_su_serialize (struct amf_su *su, int *len)
  1324. {
  1325. char *buf = NULL;
  1326. int offset = 0, size = 0;
  1327. TRACE8 ("%s", su->name.value);
  1328. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->name);
  1329. buf = amf_serialize_SaUint32T (buf, &size, &offset, su->saAmfSURank);
  1330. buf = amf_serialize_SaUint32T (
  1331. buf, &size, &offset, su->saAmfSUNumComponents);
  1332. buf = amf_serialize_SaUint32T (
  1333. buf, &size, &offset, su->saAmfSUIsExternal);
  1334. buf = amf_serialize_SaUint32T (
  1335. buf, &size, &offset, su->saAmfSUFailover);
  1336. buf = amf_serialize_SaUint32T (
  1337. buf, &size, &offset, su->saAmfSUPreInstantiable);
  1338. buf = amf_serialize_SaUint32T (
  1339. buf, &size, &offset, su->saAmfSUOperState);
  1340. buf = amf_serialize_SaUint32T (
  1341. buf, &size, &offset, su->saAmfSUAdminState);
  1342. buf = amf_serialize_SaUint32T (
  1343. buf, &size, &offset, su->saAmfSUPresenceState);
  1344. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->saAmfSUHostedByNode);
  1345. buf = amf_serialize_SaUint32T (
  1346. buf, &size, &offset, su->saAmfSURestartCount);
  1347. buf = amf_serialize_SaUint32T (
  1348. buf, &size, &offset, su->restart_control_state);
  1349. buf = amf_serialize_SaUint32T (
  1350. buf, &size, &offset, su->escalation_level_history_state);
  1351. buf = amf_serialize_SaStringT (
  1352. buf, &size, &offset, su->clccli_path);
  1353. buf = amf_serialize_SaUint32T (
  1354. buf, &size, &offset, su->su_failover_cnt);
  1355. buf = amf_serialize_SaUint32T (
  1356. buf, &size, &offset, su->current_comp_instantiation_level);
  1357. *len = offset;
  1358. return buf;
  1359. }
  1360. struct amf_su *amf_su_deserialize (struct amf_sg *sg, char *buf)
  1361. {
  1362. char *tmp = buf;
  1363. struct amf_su *su = amf_su_new (sg, "");
  1364. tmp = amf_deserialize_SaNameT (tmp, &su->name);
  1365. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURank);
  1366. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUNumComponents);
  1367. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUIsExternal);
  1368. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUFailover);
  1369. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPreInstantiable);
  1370. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUOperState);
  1371. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUAdminState);
  1372. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPresenceState);
  1373. tmp = amf_deserialize_SaNameT (tmp, &su->saAmfSUHostedByNode);
  1374. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURestartCount);
  1375. tmp = amf_deserialize_SaUint32T (tmp, &su->restart_control_state);
  1376. tmp = amf_deserialize_SaUint32T (tmp, &su->escalation_level_history_state);
  1377. tmp = amf_deserialize_SaStringT (tmp, &su->clccli_path);
  1378. tmp = amf_deserialize_SaUint32T (tmp, &su->su_failover_cnt);
  1379. tmp = amf_deserialize_SaUint32T (tmp, &su->current_comp_instantiation_level);
  1380. return su;
  1381. }
  1382. struct amf_su *amf_su_find (struct amf_cluster *cluster, SaNameT *name)
  1383. {
  1384. struct amf_application *app;
  1385. struct amf_sg *sg;
  1386. struct amf_su *su = NULL;
  1387. char *app_name;
  1388. char *sg_name;
  1389. char *su_name;
  1390. char *ptrptr;
  1391. char *buf;
  1392. assert (cluster != NULL && name != NULL);
  1393. /* malloc new buffer since strtok_r writes to its first argument */
  1394. buf = amf_malloc (name->length + 1);
  1395. memcpy (buf, name->value, name->length + 1);
  1396. su_name = strtok_r(buf, ",", &ptrptr);
  1397. sg_name = strtok_r(NULL, ",", &ptrptr);
  1398. app_name = strtok_r(NULL, ",", &ptrptr);
  1399. if (su_name == NULL || sg_name == NULL || app_name == NULL) {
  1400. goto end;
  1401. }
  1402. su_name += 6;
  1403. sg_name += 6;
  1404. app_name += 7;
  1405. app = amf_application_find (cluster, app_name);
  1406. if (app == NULL) {
  1407. goto end;
  1408. }
  1409. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1410. if (strncmp (sg_name, (char*)sg->name.value,
  1411. sg->name.length) == 0) {
  1412. for (su = sg->su_head; su != NULL; su = su->next) {
  1413. if (su->name.length == strlen(su_name) &&
  1414. strncmp (su_name, (char*)su->name.value,
  1415. su->name.length) == 0) {
  1416. goto end;
  1417. }
  1418. }
  1419. }
  1420. }
  1421. end:
  1422. free (buf);
  1423. return su;
  1424. }
  1425. /**
  1426. * This function makes a distinguished name for specified su object.
  1427. * @param su
  1428. * @param name -[out] pointer to where the distinguished name shall be stored
  1429. *
  1430. * @return SaNameT* - distinguished name
  1431. */
  1432. char *amf_su_dn_make (struct amf_su *su, SaNameT *name)
  1433. {
  1434. int i;
  1435. assert (su != NULL);
  1436. i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  1437. "safSu=%s,safSg=%s,safApp=%s",
  1438. su->name.value, su->sg->name.value, su->sg->application->name.value);
  1439. assert (i <= SA_MAX_NAME_LENGTH);
  1440. name->length = i;
  1441. return (char *)name->value;
  1442. }
  1443. /**
  1444. * An order to SU to create an si-assignment object with a specified HA-state
  1445. * between it self and a specified si. The created si-assignment is initialized
  1446. * and linked to list of assignments held by the specified si.
  1447. * This function also orders creation of all csi-assignments required
  1448. * considering the cs-types specified for the components and csi objects
  1449. * respectively.
  1450. * @param su
  1451. * @param si
  1452. * @param ha_state
  1453. *
  1454. * @return amf_si_assignment_t*
  1455. */
  1456. amf_si_assignment_t *amf_su_assign_si (struct amf_su *su, struct amf_si *si,
  1457. SaAmfHAStateT ha_state)
  1458. {
  1459. struct amf_si_assignment *si_assignment;
  1460. dprintf ("Creating SI '%s' to SU '%s' with hastate %s\n",
  1461. getSaNameT (&si->name), getSaNameT (&su->name),
  1462. amf_ha_state (ha_state));
  1463. si_assignment = amf_malloc (sizeof (struct amf_si_assignment));
  1464. amf_su_dn_make (su, &si_assignment->name);
  1465. si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
  1466. si_assignment->requested_ha_state = ha_state;
  1467. si_assignment->next = si->assigned_sis;
  1468. si->assigned_sis = si_assignment;
  1469. si_assignment->si = si;
  1470. si_assignment->su = su;
  1471. {
  1472. struct amf_csi *csi;
  1473. struct amf_comp *comp;
  1474. SaNameT *cs_type;
  1475. int i;
  1476. /*
  1477. ** for each component in SU, find a CSI in the SI with the same type
  1478. */
  1479. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1480. int no_of_cs_types = 0;
  1481. for (i = 0; comp->saAmfCompCsTypes[i]; i++) {
  1482. cs_type = comp->saAmfCompCsTypes[i];
  1483. no_of_cs_types++;
  1484. int no_of_assignments = 0;
  1485. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  1486. if (!memcmp(csi->saAmfCSTypeName.value, cs_type->value,
  1487. cs_type->length)) {
  1488. comp_assign_csi (comp, csi, si_assignment, ha_state);
  1489. no_of_assignments++;
  1490. }
  1491. }
  1492. if (no_of_assignments == 0) {
  1493. log_printf (
  1494. LOG_WARNING, "\t No CSIs of type %s configured?!!\n",
  1495. getSaNameT (cs_type));
  1496. }
  1497. }
  1498. if (no_of_cs_types == 0) {
  1499. log_printf (LOG_LEVEL_ERROR,
  1500. "\t No CS types configured for comp %s ?!!\n",
  1501. getSaNameT (&comp->name));
  1502. }
  1503. }
  1504. }
  1505. return si_assignment;
  1506. }
  1507. struct amf_si_assignment *amf_su_get_next_si_assignment (
  1508. struct amf_su *su, const struct amf_si_assignment *si_assignment)
  1509. {
  1510. struct amf_si *si;
  1511. struct amf_si_assignment *tmp_si_assignment;
  1512. SaNameT dn;
  1513. amf_su_dn_make (su, &dn);
  1514. if (si_assignment == NULL) {
  1515. assert (su->sg);
  1516. assert (su->sg->application);
  1517. assert (su->sg->application->si_head);
  1518. si = su->sg->application->si_head;
  1519. tmp_si_assignment = si->assigned_sis;
  1520. } else {
  1521. tmp_si_assignment = si_assignment->next;
  1522. if (tmp_si_assignment == NULL) {
  1523. si = si_assignment->si->next;
  1524. if (si == NULL) {
  1525. return NULL;
  1526. } else {
  1527. tmp_si_assignment = si->assigned_sis;
  1528. }
  1529. } else {
  1530. si = tmp_si_assignment->si;
  1531. }
  1532. }
  1533. for (; si != NULL; si = si->next) {
  1534. if (tmp_si_assignment == NULL && si != NULL) {
  1535. tmp_si_assignment = si->assigned_sis;
  1536. }
  1537. for (; tmp_si_assignment != NULL;
  1538. tmp_si_assignment = tmp_si_assignment->next) {
  1539. if (name_match (&tmp_si_assignment->name, &dn)) {
  1540. return tmp_si_assignment;
  1541. }
  1542. }
  1543. }
  1544. return NULL;
  1545. }
  1546. void amf_su_foreach_si_assignment (
  1547. struct amf_su *su,
  1548. void (*foreach_fn)(struct amf_su *su,
  1549. struct amf_si_assignment *si_assignment))
  1550. {
  1551. struct amf_si_assignment *si_assignment;
  1552. assert (foreach_fn != NULL);
  1553. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1554. while (si_assignment != NULL) {
  1555. foreach_fn (su, si_assignment);
  1556. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1557. }
  1558. }
  1559. /**
  1560. * This function calculates the number of si-assignments with active HA-state
  1561. * which currently are associated with the specified su.
  1562. * TODO: Split into two functions and remove dependency to sg's avail_state
  1563. * @param su
  1564. *
  1565. * @return int
  1566. */
  1567. int amf_su_get_saAmfSUNumCurrActiveSIs(struct amf_su *su)
  1568. {
  1569. int cnt = 0;
  1570. struct amf_si_assignment *si_assignment;
  1571. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1572. while (si_assignment != NULL) {
  1573. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1574. si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
  1575. cnt++;
  1576. } else {
  1577. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
  1578. cnt++;
  1579. }
  1580. }
  1581. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1582. }
  1583. return cnt;
  1584. }
  1585. /**
  1586. * This function calculates the number of si-assignments with standby HA-state
  1587. * which currently are associated with the specified su.
  1588. * TODO: Split into two functions and remove dependency to sg's avail_state
  1589. * @param su
  1590. *
  1591. * @return int
  1592. */
  1593. int amf_su_get_saAmfSUNumCurrStandbySIs(struct amf_su *su)
  1594. {
  1595. int cnt = 0;
  1596. struct amf_si_assignment *si_assignment;
  1597. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1598. while (si_assignment != NULL) {
  1599. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1600. si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
  1601. cnt++;
  1602. } else {
  1603. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  1604. cnt++;
  1605. }
  1606. }
  1607. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1608. }
  1609. return cnt;
  1610. }
  1611. /**
  1612. * This function calculates the readiness state for specified su
  1613. * @param su
  1614. *
  1615. * @return SaAmfReadinessStateT
  1616. */
  1617. SaAmfReadinessStateT amf_su_get_saAmfSUReadinessState (struct amf_su *su)
  1618. {
  1619. if ((su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) &&
  1620. ((su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED) ||
  1621. (su->saAmfSUPresenceState == SA_AMF_PRESENCE_RESTARTING))) {
  1622. return SA_AMF_READINESS_IN_SERVICE;
  1623. } else if (su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) {
  1624. return SA_AMF_READINESS_STOPPING;
  1625. } else {
  1626. return SA_AMF_READINESS_OUT_OF_SERVICE;
  1627. }
  1628. }
  1629. /**
  1630. * Determine if the SU is hosted on the local node.
  1631. * @param su
  1632. *
  1633. * @return int
  1634. */
  1635. int amf_su_is_local (struct amf_su *su)
  1636. {
  1637. if (name_match (&this_amf_node->name, &su->saAmfSUHostedByNode)) {
  1638. return 1;
  1639. } else {
  1640. return 0;
  1641. }
  1642. }
  1643. /**
  1644. * Determine if all components have the specified HA-state.
  1645. * @param su
  1646. * @param state -specified HA-state
  1647. *
  1648. * @return int - return 0 if not all components have the specified HA-state
  1649. */
  1650. int amf_su_are_all_comps_in_su (struct amf_su *su,
  1651. SaAmfPresenceStateT state)
  1652. {
  1653. int all_comps_in_su_are_set = 1;
  1654. amf_comp_t *component;
  1655. for (component = su->comp_head; component != NULL;
  1656. component = component->next) {
  1657. if (component->saAmfCompPresenceState != state) {
  1658. all_comps_in_su_are_set = 0;
  1659. }
  1660. }
  1661. return all_comps_in_su_are_set;
  1662. }