amfsu.c 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672
  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_INSTANTIATING
  124. * IDLE_ESCALATION_0 error_suspected A1 IDLE_ESCALATION_1
  125. * IDLE_ESCALATION_1 error_suspected [!C3] A1 IDLE_ESCALATION_1
  126. * IDLE_ESCALATION_1 error_suspected [C3] A2 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 A19 IDLE_ESCALATION_x
  130. * RS_COMP_RESTARTING comp_term_failed A19 IDLE_ESCALATION_x
  131. * RS_COMP_RESTARTING error_suspected A18 RS_COMP_RESTARTING
  132. * RS_COMP_SETTING ha_state_assumed [C7] A19 IDLE_ESCALATION_x
  133. * RS_COMP_SETTING error_suspected A18 RS_COMP_SETTING
  134. * RS_SU_INSTANTIATING comp_instantiated [C12] A11 RS_SU_SETTING
  135. * RS_SU_INSTANTIATING comp_inst_failed [C12] A19 IDLE_ESCALATION_X
  136. * RS_SU_INSTANTIATING comp_term_failed [C12] A19 IDLE_ESCALATION_X
  137. * RS_SU_INSTANTIATING error_suspected A18 RS_SU_INSTANTIATING
  138. * RS_SU_SETTING ha_state_assumed [C10] A19 IDLE_ESCALATION_X
  139. * RS_SU_SETTING error_suspected A18 RS_SU_SETTING
  140. *
  141. * 1.2 State Description
  142. * =====================
  143. * IDLE_ESCALATION_x - This is just an abbreviated notation for
  144. * IDLE_ESCALATION_0, IDLE_ESCALATION_1 or IDLE_ESCALATION_2
  145. *
  146. * IDLE_ESCALATION_0 - SU_RC_IDLE_ESCALATION_LEVEL_0
  147. * Service unit is idle and the restart probation timer is
  148. * off.
  149. *
  150. * IDLE_ESCALATION_1 - SU_RC_IDLE_ESCALATION_LEVEL_1
  151. * Service unit is idle and the restart probation timer is
  152. * on. This indicates there has recently been an error
  153. * detected on at least one of its components which has been
  154. * recovered by a component restart but we are still in the
  155. * probation period which follows every restart.
  156. *
  157. * IDLE_ESCALATION_2 - SU_RC_IDLE_ESCALATION_LEVEL_2
  158. * Service unit is idle and handling on potential new error
  159. * indications on any of its components has been delegated
  160. * to the node object where the service unit is hosted.
  161. *
  162. * RS_COMP_DEACTIVATING - SU_RC_RESTART_COMP_DEACTIVATING
  163. * Service unit is busy handling restart of one of its
  164. * components. In this sub-state, the service unit is
  165. * waiting for acknowledgements that all components which
  166. * had csi-assignments that were dependent of csi-
  167. * assignments associated to the restarting component
  168. * have been de-activated. This is a neccesary step to
  169. * take before the component to restart is terminated,
  170. * to avoid that the csi or si dependency rules are
  171. * violated.
  172. *
  173. * RS_COMP_RESTARTING - SU_RC_RESTART_COMP_RESTARTING
  174. * Service unit is busy handling restart of one of its
  175. * components. In this sub-state, the service unit has
  176. * ordered one of its components to restart and waits for
  177. * the component to indicate that the restart is done.
  178. *
  179. * RS_COMP_SETTING - SU_RC_RESTART_COMP_SETTING
  180. * Service unit is busy handling restart of one of its
  181. * components. In this sub-state, the service unit has ordered
  182. * the component that just have been restarted to re-assume
  183. * the HA-states it had before, provided none of the states
  184. * were ACTIVE. It waits for an acknowledgement that the
  185. * setting of the HA-states are done.
  186. *
  187. * RS_COMP_ACTIVATING - SU_RC_RESTART_COMP_ACTIVATING
  188. * Service unit is busy handling restart of one of its
  189. * components. In this sub-state, the service unit has
  190. * ordered the component that just have been restarted to
  191. * re-assume the active HA-states it had before and also
  192. * to activate the csi-assignments that possibly were
  193. * de-activated because of this restart. The service unit
  194. * waits in this state for an acknowledgement of the
  195. * activation.
  196. *
  197. * RS_SU_DEACTIVATING - SU_RC_RESTART_SU_DEACTIVATING
  198. * Service unit is busy handling restart of all of its
  199. * components. In this sub-state, the service unit is
  200. * waiting for acknowledgements that all components which
  201. * had csi-assignments that were dependent of si-
  202. * assignments associated to this service unit
  203. * have been de-activated. This is a neccesary step to
  204. * take before all components of the service unit are
  205. * terminated, to avoid that the csi or si dependency rules
  206. * are violated.
  207. *
  208. * RS_SU_TERMINATING - SU_RC_RESTART_SU_TERMINATING
  209. * Service unit is busy handling restart of all of its
  210. * components. In this sub-state, the service unit has
  211. * ordered all its components to terminate and is waiting
  212. * for an acknowledgement that all components are done with
  213. * the termination.
  214. *
  215. * RS_SU_INSTANTIATING - SU_RC_RESTART_SU_INSTANTIATING
  216. * Service unit is busy handling restart of all of its
  217. * components. In this sub-state, the service unit has
  218. * ordered all components to instantiate and is waiting
  219. * for an acknowledgement that all components are done with
  220. * the instantiation.
  221. *
  222. * RS_SU_SETTING - SU_RC_RESTART_SU_SETTING
  223. * Service unit is busy handling restart of all of its
  224. * components. In this sub-state, the service unit has ordered
  225. * all components that just have been restarted to re-assume
  226. * the HA-states they had before, provided none of the states
  227. * were ACTIVE. The service unit waits for an acknowledgement
  228. * that the setting of the HA-states are done.
  229. *
  230. * RS_SU_ACTIVATING - SU_RC_RESTART_SU_ACTIVATING
  231. * Service unit is busy handling restart of all of its
  232. * components. In this sub-state, the service unit has
  233. * ordered all components that just have been restarted to
  234. * re-assume the active HA-states they had before and also
  235. * to activate the csi-assignments that possibly were
  236. * de-activated because of this restart. The service unit
  237. * waits in this state for an acknowledgement of the
  238. * activation.
  239. *
  240. * 1.3 Actions
  241. * ===========
  242. * A1 - generate event comp_restart
  243. * A2 - forward component restart request to the node which hosts current su
  244. * A3 -
  245. * A4 -
  246. * A5 -
  247. * A6 -
  248. * A7 -
  249. * A8 -
  250. * A9 - order component to restart
  251. * A10 -
  252. * A11 - initiate setting of the same HA-state as was set before the restart
  253. * A12 -
  254. * A13 -
  255. * A14 -
  256. * A15 -
  257. * A16 -
  258. * A17 -
  259. * A18 - defer the event
  260. * A19 - recall deferred event
  261. * A20 - restart all components contained in current su
  262. *
  263. * 1.4 Guards
  264. * ==========
  265. * C1 -
  266. * C2 -
  267. * C3 - the component has been restarted SaAmfSGCompRestartMax number of times
  268. * C4 -
  269. * C5 - for each si-assignment related to the restarting component where
  270. * requested-ha-state != confirmed-ha-state
  271. * C6 -
  272. * C7 - all si-assignments related to the restarting component have
  273. * requested-ha-state == confirmed-ha-state or the operation has failed
  274. * C8 -
  275. * C9 -
  276. * C10 - all si-assignments related to current service unit have
  277. * requested-ha-state == confirmed-ha-state or the operation has failed
  278. * C11 -
  279. * C12 - for each si-assignment related to current su where
  280. * requested-ha-state != confirmed-ha-state
  281. *
  282. */
  283. #include <stdlib.h>
  284. #include <assert.h>
  285. #include <string.h>
  286. #include <errno.h>
  287. #include "amf.h"
  288. #include "util.h"
  289. #include "print.h"
  290. #include "main.h"
  291. static int terminate_all_components_in_level (struct amf_su *su,
  292. SaUint32T current_instantiation_level);
  293. static int are_all_comps_in_level_uninst_or_term_failed (struct amf_su *su);
  294. static int are_all_comps_in_level_uninst (struct amf_su *su);
  295. static int are_all_comps_in_level_instantiated (struct amf_su *su);
  296. static int instantiate_all_components_in_level (struct amf_su *su,
  297. SaUint32T current_instantiation_level);
  298. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su);
  299. static void si_ha_state_assumed_cbfn (
  300. struct amf_si_assignment *si_assignment, int result);
  301. static int is_any_component_instantiating (amf_su_t *su);
  302. typedef struct su_event {
  303. amf_su_event_type_t event_type;
  304. amf_su_t *su;
  305. amf_comp_t *comp;
  306. SaAmfRecommendedRecoveryT recommended_recovery;
  307. } su_event_t;
  308. /******************************************************************************
  309. * Internal (static) utility functions
  310. *****************************************************************************/
  311. static void su_event_set(struct amf_su *su, struct amf_comp *comp,
  312. SaAmfRecommendedRecoveryT recommended_recovery,
  313. su_event_t *su_event, amf_su_event_type_t event_type)
  314. {
  315. su_event->event_type = event_type;
  316. su_event->comp = comp;
  317. su_event->su = su;
  318. su_event->recommended_recovery = recommended_recovery;
  319. }
  320. static void su_defer_event (amf_su_t *su, amf_comp_t *comp,
  321. SaAmfRecommendedRecoveryT recommended_recovery,
  322. amf_su_event_type_t su_event_type)
  323. {
  324. su_event_t event;
  325. su_event_set(su, comp, recommended_recovery,&event, su_event_type);
  326. ENTER("event_type = %d", event.event_type);
  327. amf_fifo_put (event.event_type, &event.su->deferred_events,
  328. sizeof (su_event_t), &event);
  329. }
  330. static void su_recall_deferred_events (amf_su_t *su)
  331. {
  332. su_event_t su_event;
  333. ENTER ("%s", su->name.value);
  334. if (amf_fifo_get (&su->deferred_events, &su_event)) {
  335. switch (su_event.event_type) {
  336. case SU_COMP_ERROR_SUSPECTED_EV:
  337. amf_su_comp_error_suspected (su_event.su,su_event.comp,
  338. su_event.recommended_recovery);
  339. break;
  340. default:
  341. dprintf("event_type = %d", su_event.event_type);
  342. break;
  343. }
  344. }
  345. }
  346. static int has_component_restarted_max_times (amf_comp_t *comp, amf_su_t *su)
  347. {
  348. return comp->saAmfCompRestartCount >= su->sg->saAmfSGCompRestartMax;
  349. }
  350. #ifdef COMPILE_OUT
  351. static int has_su_restarted_max_times (amf_su_t *su)
  352. {
  353. return su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax;
  354. }
  355. #endif
  356. /**
  357. * This function only logs since the readiness state is runtime
  358. * calculated.
  359. * @param su
  360. * @param amf_readiness_state
  361. */
  362. static void su_readiness_state_set (struct amf_su *su,
  363. SaAmfReadinessStateT readiness_state)
  364. {
  365. log_printf (LOG_NOTICE, "Setting SU '%s' readiness state: %s\n",
  366. su->name.value, amf_readiness_state (readiness_state));
  367. }
  368. static void clear_ha_state (
  369. struct amf_su *su, struct amf_si_assignment *si_assignment)
  370. {
  371. ENTER ("");
  372. si_assignment->saAmfSISUHAState = 0;
  373. }
  374. /**
  375. * This function sets presence state to the specified value. It also has the
  376. * following intentional side effects:
  377. * - sets HA-state to unknown when presence state is set to UNINSTANTIATED
  378. * - reports the change of presence state to the sg in which su is contained
  379. * when the new state is 'stable'
  380. * @param su
  381. * @param presence_state - new value of presence state
  382. */
  383. static void su_presence_state_set (struct amf_su *su,
  384. SaAmfPresenceStateT presence_state)
  385. {
  386. /*
  387. * Set all SI's confirmed HA state to unknown if uninstantiated
  388. */
  389. if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) {
  390. amf_su_foreach_si_assignment (su, clear_ha_state);
  391. }
  392. su->saAmfSUPresenceState = presence_state;
  393. log_printf (LOG_NOTICE, "Setting SU '%s' presence state: %s\n",
  394. su->name.value, amf_presence_state (presence_state));
  395. if (su->restart_control_state != SU_RC_RESTART_SU_SETTING &&
  396. su->restart_control_state != SU_RC_RESTART_COMP_RESTARTING) {
  397. amf_sg_su_state_changed (su->sg, su, SA_AMF_PRESENCE_STATE,
  398. presence_state);
  399. }
  400. }
  401. /**
  402. * This function sets operational state to the specified value. It also has the
  403. * following side effects:
  404. * - sets the readiness state for su
  405. * - sets the readiness state for all components contained in the su
  406. * @param su
  407. * @param oper_state - new value of operational state
  408. */
  409. void amf_su_operational_state_set (struct amf_su *su,
  410. SaAmfOperationalStateT oper_state)
  411. {
  412. struct amf_comp* comp;
  413. su->saAmfSUOperState = oper_state;
  414. log_printf (LOG_NOTICE, "Setting SU '%s' operational state: %s\n",
  415. su->name.value, amf_op_state (oper_state));
  416. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  417. su_readiness_state_set (su, SA_AMF_READINESS_IN_SERVICE);
  418. for (comp = su->comp_head; comp; comp = comp->next) {
  419. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_IN_SERVICE);
  420. }
  421. } else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
  422. su_readiness_state_set (su, SA_AMF_READINESS_OUT_OF_SERVICE);
  423. for (comp = su->comp_head; comp; comp = comp->next) {
  424. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_OUT_OF_SERVICE);
  425. }
  426. }
  427. }
  428. /**
  429. * This function creates a new csi-assignment object and initializes it. The
  430. * function also links the new csi-assignment object to the list of assignments
  431. * held by the specified csi object, sets a pointer to the specified component
  432. * and a pointer to the specified si-assignment.
  433. * @param comp
  434. * @param csi
  435. * @param si_assignment
  436. * @param ha_state - new value of ha-state
  437. */
  438. static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
  439. struct amf_si_assignment *si_assignment, SaAmfHAStateT ha_state)
  440. {
  441. struct amf_csi_assignment *csi_assignment;
  442. dprintf (" Creating CSI '%s' to comp '%s' with hastate %s\n",
  443. getSaNameT (&csi->name), getSaNameT (&comp->name),
  444. amf_ha_state (ha_state));
  445. csi_assignment = amf_malloc (sizeof (struct amf_csi_assignment));
  446. csi_assignment->next = csi->assigned_csis;
  447. csi->assigned_csis = csi_assignment;
  448. amf_comp_dn_make (comp, &csi_assignment->name);
  449. csi_assignment->comp = comp;
  450. csi_assignment->csi = csi;
  451. csi_assignment->saAmfCSICompHAState = 0; /* undefined confirmed HA state */
  452. csi_assignment->requested_ha_state = ha_state;
  453. csi_assignment->si_assignment = si_assignment;
  454. }
  455. static void comp_restart (struct amf_comp *comp)
  456. {
  457. SaNameT dn;
  458. ENTER ("'%s'", comp->name.value);
  459. amf_comp_dn_make (comp, &dn);
  460. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  461. "action: Component restart", dn.value);
  462. comp->su->restart_control_state = SU_RC_RESTART_COMP_DEACTIVATING;
  463. comp->su->restart_control_state = SU_RC_RESTART_COMP_RESTARTING;
  464. comp->su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  465. amf_comp_restart (comp);
  466. }
  467. /**
  468. * Set the same HA-state as the before the restart to the SI-assignments
  469. * associated with current SU. As a side effect, this HA-state will also be set
  470. * to all components which are associated with the csi-assignments associated to
  471. * the specified su via its csi and si objects.
  472. * @param su
  473. * @param current_instantiation_level
  474. *
  475. * @return - 1 if there were no components on the specified instantiation level
  476. */
  477. static void reassume_ha_state(struct amf_su *su)
  478. {
  479. struct amf_si_assignment *si_assignment;
  480. ENTER ("");
  481. si_assignment = amf_su_get_next_si_assignment(su, NULL);
  482. while (si_assignment != NULL) {
  483. si_assignment->saAmfSISUHAState = 0; /* unknown */
  484. amf_si_ha_state_assume (si_assignment, si_ha_state_assumed_cbfn);
  485. si_assignment = amf_su_get_next_si_assignment(su, si_assignment);
  486. }
  487. }
  488. static int is_any_component_instantiating (amf_su_t *su)
  489. {
  490. amf_comp_t *component;
  491. int any_component_instantiating = 0;
  492. for (component = su->comp_head; component != NULL;
  493. component = component->next) {
  494. if (component->saAmfCompPresenceState ==
  495. SA_AMF_PRESENCE_INSTANTIATING) {
  496. any_component_instantiating = 1;
  497. break;
  498. }
  499. }
  500. return any_component_instantiating;
  501. }
  502. static int is_any_component_terminating (amf_su_t *su)
  503. {
  504. amf_comp_t *component;
  505. int any_component_terminating = 0;
  506. for (component = su->comp_head; component != NULL;
  507. component = component->next) {
  508. if (component->saAmfCompPresenceState ==
  509. SA_AMF_PRESENCE_TERMINATING) {
  510. any_component_terminating = 1;
  511. break;
  512. }
  513. }
  514. return any_component_terminating;
  515. }
  516. static int is_any_comp_instantiation_failed (amf_su_t *su)
  517. {
  518. amf_comp_t *comp_;
  519. int comp_instantiation_failed = 0;
  520. for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
  521. if (comp_->saAmfCompPresenceState ==
  522. SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  523. comp_instantiation_failed = 1;
  524. break;
  525. }
  526. }
  527. return comp_instantiation_failed;
  528. }
  529. /**
  530. * Finds the component within the specified su that has the highest value of it
  531. * presence state. With current definition of values the highest value can also
  532. * be regarded as the 'worst' in the sence of capability to be assigned
  533. * workload. In the 'best' presence state (INSTANTIATED) the component is
  534. * immediately available to take workload while in the 'worst' state
  535. * (TERMINATION_FAILED) it can not take any workload before it has been manually
  536. * repaired.
  537. * @param su
  538. *
  539. * @return - worst presence state
  540. */
  541. static SaAmfPresenceStateT get_worst_comps_presence_state_in_su (amf_su_t *su)
  542. {
  543. amf_comp_t *component;
  544. SaAmfPresenceStateT worst_presence_state = 0;
  545. for (component = su->comp_head; component != NULL;
  546. component = component->next) {
  547. if (component->saAmfCompPresenceState > worst_presence_state) {
  548. worst_presence_state = component->saAmfCompPresenceState;
  549. }
  550. }
  551. return worst_presence_state;
  552. }
  553. /**
  554. *
  555. * @param su
  556. */
  557. void su_history_state_set(struct amf_su *su, SaAmfPresenceStateT state)
  558. {
  559. su->restart_control_state = su->escalation_level_history_state;
  560. su->saAmfSUPresenceState = state;
  561. }
  562. /**
  563. * A component notifies its parent su that its presence state has changed.
  564. * @param su
  565. * @param comp - component which has changed its presence state
  566. * @param state - new value of presence state
  567. */
  568. static void su_comp_presence_state_changed (struct amf_su *su,
  569. struct amf_comp *comp, int state)
  570. {
  571. ENTER ("'%s', '%s' %d %d", su->name.value, comp->name.value, state,
  572. su->restart_control_state);
  573. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  574. switch (state) {
  575. case SA_AMF_PRESENCE_INSTANTIATED:
  576. switch (su->restart_control_state) {
  577. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  578. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  579. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  580. if (!is_any_component_instantiating (su)) {
  581. if (are_all_comps_in_level_instantiated (su)) {
  582. if (instantiate_all_components_in_level (su,
  583. ++comp->su->current_comp_instantiation_level)) {
  584. /* All levels of instantiation is done */
  585. su_presence_state_set (comp->su,
  586. SA_AMF_PRESENCE_INSTANTIATED);
  587. }
  588. } else {
  589. if (is_any_comp_instantiation_failed (su)) {
  590. su_presence_state_set (comp->su,
  591. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  592. } else {
  593. assert (0);
  594. }
  595. }
  596. }
  597. break;
  598. case SU_RC_RESTART_COMP_RESTARTING:
  599. su->restart_control_state = SU_RC_RESTART_COMP_SETTING;
  600. reassume_ha_state (comp->su);
  601. break;
  602. case SU_RC_RESTART_SU_INSTANTIATING:
  603. if (!is_any_component_instantiating(su)) {
  604. if (amf_su_are_all_comps_in_su (
  605. comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
  606. su->restart_control_state = SU_RC_RESTART_SU_SETTING;
  607. su_presence_state_set (comp->su,
  608. SA_AMF_PRESENCE_INSTANTIATED);
  609. reassume_ha_state (comp->su);
  610. } else {
  611. if (is_any_comp_instantiation_failed (su)) {
  612. su_presence_state_set (comp->su,
  613. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  614. } else {
  615. TRACE1("%s,%s",comp->su->name.value,
  616. comp->name.value);
  617. assert (0);
  618. }
  619. }
  620. }
  621. break;
  622. default:
  623. dprintf ("state %d", su->restart_control_state);
  624. assert (0);
  625. break;
  626. }
  627. break;
  628. case SA_AMF_PRESENCE_UNINSTANTIATED:
  629. switch (su->restart_control_state) {
  630. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  631. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  632. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  633. if (!is_any_component_terminating (su)) {
  634. if (are_all_comps_in_level_uninst_or_term_failed (su)) {
  635. if (terminate_all_components_in_level (su,
  636. --su->current_comp_instantiation_level)) {
  637. su_presence_state_set (su,
  638. get_worst_comps_presence_state_in_su (su));
  639. }
  640. }
  641. }
  642. break;
  643. case SU_RC_RESTART_SU_INSTANTIATING:
  644. break;
  645. case SU_RC_RESTART_COMP_RESTARTING:
  646. break;
  647. case SU_RC_RESTART_SU_TERMINATING:
  648. if (!is_any_component_terminating (su)) {
  649. if (are_all_comps_in_level_uninst (su)) {
  650. if (terminate_all_components_in_level (su,
  651. --su->current_comp_instantiation_level)) {
  652. su->restart_control_state =
  653. SU_RC_RESTART_SU_INSTANTIATING;
  654. instantiate_all_components_in_level (su,
  655. su_lowest_comp_instantiation_level_set (su));
  656. }
  657. } else {
  658. su_history_state_set (su,
  659. SA_AMF_PRESENCE_TERMINATION_FAILED);
  660. }
  661. }
  662. break;
  663. default:
  664. break;
  665. }
  666. break;
  667. case SA_AMF_PRESENCE_INSTANTIATING:
  668. su_presence_state_set (comp->su,SA_AMF_PRESENCE_INSTANTIATING);
  669. break;
  670. case SA_AMF_PRESENCE_RESTARTING:
  671. break;
  672. case SA_AMF_PRESENCE_TERMINATING:
  673. break;
  674. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  675. switch (su->restart_control_state) {
  676. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  677. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  678. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  679. if (!is_any_component_instantiating (su)) {
  680. su_presence_state_set (comp->su,
  681. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  682. }
  683. break;
  684. case SU_RC_RESTART_COMP_RESTARTING:
  685. if (!is_any_component_instantiating (su)) {
  686. if (node->saAmfNodeRebootOnInstantiationFailure) {
  687. su_history_state_set (su,
  688. AMF_PRESENCE_TERMINATION_FAILED_REBOOT);
  689. amf_node_failover(node);
  690. }else{
  691. su_history_state_set (su,
  692. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  693. amf_node_comp_failover_req(node, comp);
  694. }
  695. }
  696. break;
  697. case SU_RC_RESTART_SU_INSTANTIATING:
  698. if (!is_any_component_instantiating (su)) {
  699. if (node->saAmfNodeRebootOnInstantiationFailure) {
  700. su_history_state_set (su,
  701. AMF_PRESENCE_TERMINATION_FAILED_REBOOT);
  702. amf_node_failover(node);
  703. }else{
  704. su_history_state_set (su,
  705. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  706. amf_sg_failover_su_req(comp->su->sg, comp->su, node);
  707. }
  708. }
  709. break;
  710. default:
  711. assert (0);
  712. break;
  713. }
  714. #ifdef COMPILE_OUT
  715. su_presence_state_set (comp->su,
  716. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  717. #endif
  718. break;
  719. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  720. switch (su->restart_control_state) {
  721. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  722. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  723. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  724. break;
  725. case SU_RC_RESTART_COMP_RESTARTING:
  726. case SU_RC_RESTART_SU_INSTANTIATING:
  727. if (!node->saAmfNodeRebootOnInstantiationFailure) {
  728. su_history_state_set (su,
  729. SA_AMF_PRESENCE_TERMINATION_FAILED);
  730. } else {
  731. /* TODO Implement and request Node Failed Fast */
  732. ;
  733. }
  734. break;
  735. case SU_RC_RESTART_SU_TERMINATING:
  736. if (!node->saAmfNodeRebootOnInstantiationFailure) {
  737. su_history_state_set (su,
  738. SA_AMF_PRESENCE_TERMINATION_FAILED);
  739. } else {
  740. /* TODO Implement and request Node Failed Fast */
  741. ;
  742. }
  743. break;
  744. default:
  745. assert (0);
  746. break;
  747. }
  748. break;
  749. default:
  750. assert (0);
  751. break;
  752. }
  753. }
  754. /**
  755. * A component notifies its parent su that its operational state has changed.
  756. * @param su
  757. * @param comp - component which has changed its operational state
  758. * @param state - new value of operational state
  759. */
  760. static void su_comp_op_state_changed (
  761. struct amf_su *su, struct amf_comp *comp, int state)
  762. {
  763. ENTER ("'%s', '%s' %d", su->name.value, comp->name.value, state);
  764. switch (state) {
  765. case SA_AMF_OPERATIONAL_ENABLED:
  766. {
  767. struct amf_comp *comp_compare;
  768. int all_set = 1;
  769. for (comp_compare = comp->su->comp_head;
  770. comp_compare != NULL; comp_compare = comp_compare->next) {
  771. if (comp_compare->saAmfCompOperState !=
  772. SA_AMF_OPERATIONAL_ENABLED) {
  773. all_set = 0;
  774. break;
  775. }
  776. }
  777. if (all_set) {
  778. amf_su_operational_state_set (comp->su,
  779. SA_AMF_OPERATIONAL_ENABLED);
  780. } else {
  781. amf_su_operational_state_set (comp->su,
  782. SA_AMF_OPERATIONAL_DISABLED);
  783. }
  784. break;
  785. }
  786. case SA_AMF_OPERATIONAL_DISABLED:
  787. amf_su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_DISABLED);
  788. break;
  789. default:
  790. assert (0);
  791. break;
  792. }
  793. return;
  794. }
  795. /**
  796. * Instantiates all components on specified instantiation level.
  797. * @param su
  798. * @param current_instantiation_level
  799. *
  800. * @return - 1 if there were no components on the specified instantiation level
  801. */
  802. static int instantiate_all_components_in_level (struct amf_su *su,
  803. SaUint32T current_instantiation_level)
  804. {
  805. amf_comp_t *comp;
  806. SaUint32T all_components_instantiated = 1;
  807. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  808. if (su->current_comp_instantiation_level ==
  809. comp->saAmfCompInstantiationLevel) {
  810. all_components_instantiated = 0;
  811. amf_comp_instantiate (comp);
  812. }
  813. }
  814. return all_components_instantiated;
  815. }
  816. static int are_all_comps_in_level_instantiated (struct amf_su *su)
  817. {
  818. SaUint32T level = su->current_comp_instantiation_level;
  819. amf_comp_t *comp;
  820. int all = 1;
  821. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  822. if (level == comp->saAmfCompInstantiationLevel) {
  823. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
  824. all = 0;
  825. break;
  826. }
  827. }
  828. }
  829. return all;
  830. }
  831. static int are_all_comps_in_level_uninst_or_term_failed(
  832. struct amf_su *su)
  833. {
  834. SaUint32T level = su->current_comp_instantiation_level;
  835. amf_comp_t *comp;
  836. int all = 1;
  837. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  838. if (level == comp->saAmfCompInstantiationLevel) {
  839. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_UNINSTANTIATED &&
  840. comp->saAmfCompPresenceState != SA_AMF_PRESENCE_TERMINATION_FAILED) {
  841. all = 0;
  842. break;
  843. }
  844. }
  845. }
  846. return all;
  847. }
  848. static void su_rc_enter_idle_escalation_level_1 (amf_comp_t *component,
  849. SaAmfRecommendedRecoveryT recommended_recovery)
  850. {
  851. ENTER("");
  852. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  853. if (has_component_restarted_max_times (component, component->su)) {
  854. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  855. amf_su_comp_error_suspected (component->su, component, recommended_recovery);
  856. } else {
  857. comp_restart (component);
  858. }
  859. }
  860. static void su_rc_enter_idle_escalation_level_2 (amf_comp_t *component,
  861. SaAmfRecommendedRecoveryT recommended_recovery)
  862. {
  863. ENTER("");
  864. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  865. amf_node_t *node = amf_node_find (&component->su->saAmfSUHostedByNode);
  866. amf_node_comp_restart_req (node, component);
  867. }
  868. static int get_instantiation_max_level (amf_su_t *su)
  869. {
  870. amf_comp_t *comp;
  871. int instantiation_level = 0;
  872. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  873. if (comp->saAmfCompInstantiationLevel > instantiation_level) {
  874. instantiation_level = comp->saAmfCompInstantiationLevel;
  875. }
  876. }
  877. return instantiation_level;
  878. }
  879. /**
  880. * Initiates the termination of all components which have the specified
  881. * instantiation level.
  882. * @param su
  883. * @param current_instantiation_level
  884. *
  885. * @return int -1 if no component has the specified instantiation level
  886. */
  887. static int terminate_all_components_in_level (struct amf_su *su,
  888. SaUint32T current_instantiation_level)
  889. {
  890. amf_comp_t *comp;
  891. int all_components_in_level = 1;
  892. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  893. /*
  894. * Terminate all components in instantiation level in SU
  895. * abruptly.
  896. */
  897. if (comp->saAmfCompInstantiationLevel == current_instantiation_level) {
  898. amf_comp_error_suspected_set (comp);
  899. amf_comp_terminate (comp);
  900. all_components_in_level = 0;
  901. }
  902. }
  903. return all_components_in_level;
  904. }
  905. /**
  906. * su_current_instantiation_level_init
  907. * @param su
  908. *
  909. * @return SaUint32T - the value of the instantiation level which has been set
  910. */
  911. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su)
  912. {
  913. amf_comp_t *component = su->comp_head;
  914. int comp_instantiation_level = component->saAmfCompInstantiationLevel;
  915. for (; component != NULL; component = component->next) {
  916. TRACE1("component->saAmfCompInstantiationLevel=%d",
  917. component->saAmfCompInstantiationLevel);
  918. if (component->saAmfCompInstantiationLevel <
  919. comp_instantiation_level) {
  920. comp_instantiation_level =
  921. component->saAmfCompInstantiationLevel;
  922. }
  923. }
  924. su->current_comp_instantiation_level = comp_instantiation_level;
  925. return comp_instantiation_level;
  926. }
  927. static int are_all_comps_in_level_uninst (
  928. struct amf_su *su)
  929. {
  930. SaUint32T level = su->current_comp_instantiation_level;
  931. amf_comp_t *comp;
  932. int all = 1;
  933. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  934. if (level == comp->saAmfCompInstantiationLevel) {
  935. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_UNINSTANTIATED) {
  936. all = 0;
  937. break;
  938. }
  939. }
  940. }
  941. return all;
  942. }
  943. /**
  944. * An order to SU to instantiate its components.
  945. * @param su
  946. *
  947. * @return int - 1 if its state allows it to request its contained components to
  948. * instantiate or its state indicates that its components are in
  949. * the process of instantiation.
  950. */
  951. int amf_su_instantiate (struct amf_su *su)
  952. {
  953. int is_instantiating = 1;
  954. ENTER ("'%s %d'", su->name.value, su->saAmfSUPresenceState);
  955. switch (su->saAmfSUPresenceState) {
  956. case SA_AMF_PRESENCE_UNINSTANTIATED:
  957. instantiate_all_components_in_level(su,
  958. su_lowest_comp_instantiation_level_set (su));
  959. break;
  960. case SA_AMF_PRESENCE_RESTARTING:
  961. case SA_AMF_PRESENCE_INSTANTIATING:
  962. break;
  963. case SA_AMF_PRESENCE_INSTANTIATED:
  964. case SA_AMF_PRESENCE_TERMINATING:
  965. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  966. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  967. is_instantiating = 0;
  968. break;
  969. default:
  970. assert (0);
  971. break;
  972. }
  973. return is_instantiating;
  974. }
  975. /**
  976. * An order to SU to terminate its components.
  977. * @param su
  978. */
  979. void amf_su_terminate (struct amf_su *su)
  980. {
  981. ENTER ("'%s'", su->name.value);
  982. su->current_comp_instantiation_level = get_instantiation_max_level (su);
  983. terminate_all_components_in_level (su, su->current_comp_instantiation_level);
  984. }
  985. /**
  986. * Called by a component to report a suspected error on a component
  987. * @param su
  988. * @param comp
  989. * @param recommended_recovery
  990. */
  991. void amf_su_comp_error_suspected (
  992. struct amf_su *su,
  993. struct amf_comp *comp,
  994. SaAmfRecommendedRecoveryT recommended_recovery)
  995. {
  996. ENTER ("Comp '%s', SU '%s' %d", comp->name.value, su->name.value,
  997. su->restart_control_state);
  998. switch (su->restart_control_state) {
  999. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  1000. su_rc_enter_idle_escalation_level_1 (comp,
  1001. recommended_recovery);
  1002. break;
  1003. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  1004. if (has_component_restarted_max_times (comp, su)) {
  1005. su_rc_enter_idle_escalation_level_2 (comp,
  1006. recommended_recovery);
  1007. } else {
  1008. comp_restart (comp);
  1009. }
  1010. break;
  1011. case SU_RC_IDLE_ESCALATION_LEVEL_2: {
  1012. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  1013. amf_node_comp_restart_req (node, comp);
  1014. #ifdef COMPILE_OUT
  1015. if (su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax) {
  1016. /*
  1017. * TODO: delegate to node
  1018. */
  1019. SaNameT dn;
  1020. amf_comp_operational_state_set (comp,
  1021. SA_AMF_OPERATIONAL_DISABLED);
  1022. amf_su_operational_state_set (su,
  1023. SA_AMF_OPERATIONAL_DISABLED);
  1024. amf_comp_dn_make (comp, &dn);
  1025. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  1026. "action:\n\t\tSU failover", dn.value);
  1027. amf_sg_failover_su_req (comp->su->sg, comp->su, this_amf_node);
  1028. return;
  1029. } else {
  1030. su_restart (comp->su);
  1031. }
  1032. #endif
  1033. break;
  1034. }
  1035. case SU_RC_RESTART_SU_SETTING:
  1036. case SU_RC_RESTART_COMP_RESTARTING:
  1037. case SU_RC_RESTART_COMP_SETTING:
  1038. /* TODO: Complete the implementation of SU defer event */
  1039. su_defer_event (su, comp, recommended_recovery,
  1040. SU_COMP_ERROR_SUSPECTED_EV);
  1041. break;
  1042. default:
  1043. dprintf ("restart_control_state = %d",su->restart_control_state);
  1044. break;
  1045. }
  1046. }
  1047. /**
  1048. * An order to SU to unconditionally restart itself.
  1049. * @param su
  1050. */
  1051. void amf_su_restart (struct amf_su *su)
  1052. {
  1053. struct amf_comp *comp;
  1054. SaNameT dn;
  1055. ENTER ("'%s'", su->name.value);
  1056. amf_su_dn_make (su, &dn);
  1057. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  1058. "action: SU restart", dn.value);
  1059. /*
  1060. * TODO: Find out what the three lines below means !
  1061. */
  1062. su->restart_control_state = SU_RC_RESTART_SU_DEACTIVATING;
  1063. su->restart_control_state = SU_RC_RESTART_SU_TERMINATING;
  1064. su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  1065. su->saAmfSURestartCount += 1;
  1066. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1067. amf_comp_terminate (comp);
  1068. }
  1069. }
  1070. /******************************************************************************
  1071. * Event response methods
  1072. *****************************************************************************/
  1073. /**
  1074. * Used by a component to report a state change event
  1075. * @param su
  1076. * @param comp
  1077. * @param type type of state
  1078. * @param state new state
  1079. */
  1080. void amf_su_comp_state_changed (
  1081. struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state)
  1082. {
  1083. switch (type) {
  1084. case SA_AMF_PRESENCE_STATE:
  1085. su_comp_presence_state_changed (su, comp, state);
  1086. break;
  1087. case SA_AMF_OP_STATE:
  1088. su_comp_op_state_changed (su, comp, state);
  1089. break;
  1090. default:
  1091. assert (0);
  1092. break;
  1093. }
  1094. }
  1095. static void si_ha_state_assumed_cbfn (
  1096. struct amf_si_assignment *si_assignment, int result)
  1097. {
  1098. struct amf_si_assignment *tmp_si_assignment;
  1099. struct amf_comp *comp;
  1100. struct amf_csi_assignment *csi_assignment;
  1101. int all_confirmed = 1;
  1102. ENTER ("");
  1103. tmp_si_assignment = amf_su_get_next_si_assignment(si_assignment->su, NULL);
  1104. while (tmp_si_assignment != NULL) {
  1105. for (comp = tmp_si_assignment->su->comp_head; comp != NULL;
  1106. comp = comp->next) {
  1107. csi_assignment = amf_comp_get_next_csi_assignment(comp, NULL);
  1108. while (csi_assignment != NULL) {
  1109. if (csi_assignment->requested_ha_state !=
  1110. csi_assignment->saAmfCSICompHAState) {
  1111. all_confirmed = 0;
  1112. }
  1113. csi_assignment = amf_comp_get_next_csi_assignment(
  1114. comp, csi_assignment);
  1115. }
  1116. }
  1117. tmp_si_assignment = amf_su_get_next_si_assignment(
  1118. si_assignment->su, tmp_si_assignment);
  1119. }
  1120. if (all_confirmed) {
  1121. switch (si_assignment->su->restart_control_state) {
  1122. case SU_RC_RESTART_COMP_SETTING:
  1123. log_printf (LOG_NOTICE, "Component restart recovery finished");
  1124. break;
  1125. case SU_RC_RESTART_SU_SETTING:
  1126. log_printf (LOG_NOTICE, "SU restart recovery finished");
  1127. break;
  1128. default:
  1129. assert (0);
  1130. break;
  1131. }
  1132. si_assignment->su->restart_control_state =
  1133. si_assignment->su->escalation_level_history_state;
  1134. su_recall_deferred_events (si_assignment->su);
  1135. }
  1136. }
  1137. /******************************************************************************
  1138. * General methods
  1139. *****************************************************************************/
  1140. void amf_su_init (void)
  1141. {
  1142. log_init ("AMF");
  1143. }
  1144. /**
  1145. * Constructor for SU objects. Adds SU last in the ordered
  1146. * list owned by the specified SG. Always returns a
  1147. * valid SU object, out-of-memory problems are handled here.
  1148. * Default values are initialized.
  1149. * @param sg
  1150. * @param name
  1151. *
  1152. * @return struct amf_su*
  1153. */
  1154. struct amf_su *amf_su_new (struct amf_sg *sg, char *name)
  1155. {
  1156. struct amf_su *tail = sg->su_head;
  1157. struct amf_su *su = amf_calloc (1, sizeof (struct amf_su));
  1158. while (tail != NULL) {
  1159. if (tail->next == NULL) {
  1160. break;
  1161. }
  1162. tail = tail->next;
  1163. }
  1164. if (tail == NULL) {
  1165. sg->su_head = su;
  1166. } else {
  1167. tail->next = su;
  1168. }
  1169. su->sg = sg;
  1170. /* setup default values from spec. */
  1171. su->saAmfSURank = 0;
  1172. su->saAmfSUIsExternal = 0;
  1173. su->saAmfSUFailover = 1;
  1174. su->saAmfSUAdminState = SA_AMF_ADMIN_UNLOCKED;
  1175. su->saAmfSUOperState = SA_AMF_OPERATIONAL_DISABLED;
  1176. su->saAmfSUPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
  1177. su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_0;
  1178. su->current_comp_instantiation_level = 0;
  1179. setSaNameT (&su->name, name);
  1180. return su;
  1181. }
  1182. void amf_su_delete (struct amf_su *su)
  1183. {
  1184. struct amf_comp *comp;
  1185. for (comp = su->comp_head; comp != NULL;) {
  1186. struct amf_comp *tmp = comp;
  1187. comp = comp->next;
  1188. amf_comp_delete (tmp);
  1189. }
  1190. free (su);
  1191. }
  1192. void *amf_su_serialize (struct amf_su *su, int *len)
  1193. {
  1194. char *buf = NULL;
  1195. int offset = 0, size = 0;
  1196. TRACE8 ("%s", su->name.value);
  1197. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->name);
  1198. buf = amf_serialize_SaUint32T (buf, &size, &offset, su->saAmfSURank);
  1199. buf = amf_serialize_SaUint32T (
  1200. buf, &size, &offset, su->saAmfSUNumComponents);
  1201. buf = amf_serialize_SaUint32T (
  1202. buf, &size, &offset, su->saAmfSUIsExternal);
  1203. buf = amf_serialize_SaUint32T (
  1204. buf, &size, &offset, su->saAmfSUFailover);
  1205. buf = amf_serialize_SaUint32T (
  1206. buf, &size, &offset, su->saAmfSUPreInstantiable);
  1207. buf = amf_serialize_SaUint32T (
  1208. buf, &size, &offset, su->saAmfSUOperState);
  1209. buf = amf_serialize_SaUint32T (
  1210. buf, &size, &offset, su->saAmfSUAdminState);
  1211. buf = amf_serialize_SaUint32T (
  1212. buf, &size, &offset, su->saAmfSUPresenceState);
  1213. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->saAmfSUHostedByNode);
  1214. buf = amf_serialize_SaUint32T (
  1215. buf, &size, &offset, su->saAmfSURestartCount);
  1216. buf = amf_serialize_SaUint32T (
  1217. buf, &size, &offset, su->restart_control_state);
  1218. buf = amf_serialize_SaUint32T (
  1219. buf, &size, &offset, su->escalation_level_history_state);
  1220. buf = amf_serialize_SaStringT (
  1221. buf, &size, &offset, su->clccli_path);
  1222. buf = amf_serialize_SaUint32T (
  1223. buf, &size, &offset, su->su_failover_cnt);
  1224. buf = amf_serialize_SaUint32T (
  1225. buf, &size, &offset, su->current_comp_instantiation_level);
  1226. *len = offset;
  1227. return buf;
  1228. }
  1229. struct amf_su *amf_su_deserialize (struct amf_sg *sg, char *buf)
  1230. {
  1231. char *tmp = buf;
  1232. struct amf_su *su = amf_su_new (sg, "");
  1233. tmp = amf_deserialize_SaNameT (tmp, &su->name);
  1234. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURank);
  1235. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUNumComponents);
  1236. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUIsExternal);
  1237. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUFailover);
  1238. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPreInstantiable);
  1239. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUOperState);
  1240. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUAdminState);
  1241. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPresenceState);
  1242. tmp = amf_deserialize_SaNameT (tmp, &su->saAmfSUHostedByNode);
  1243. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURestartCount);
  1244. tmp = amf_deserialize_SaUint32T (tmp, &su->restart_control_state);
  1245. tmp = amf_deserialize_SaUint32T (tmp, &su->escalation_level_history_state);
  1246. tmp = amf_deserialize_SaStringT (tmp, &su->clccli_path);
  1247. tmp = amf_deserialize_SaUint32T (tmp, &su->su_failover_cnt);
  1248. tmp = amf_deserialize_SaUint32T (tmp, &su->current_comp_instantiation_level);
  1249. return su;
  1250. }
  1251. struct amf_su *amf_su_find (struct amf_cluster *cluster, SaNameT *name)
  1252. {
  1253. struct amf_application *app;
  1254. struct amf_sg *sg;
  1255. struct amf_su *su = NULL;
  1256. char *app_name;
  1257. char *sg_name;
  1258. char *su_name;
  1259. char *ptrptr;
  1260. char *buf;
  1261. assert (cluster != NULL && name != NULL);
  1262. /* malloc new buffer since strtok_r writes to its first argument */
  1263. buf = amf_malloc (name->length + 1);
  1264. memcpy (buf, name->value, name->length + 1);
  1265. su_name = strtok_r(buf, ",", &ptrptr);
  1266. sg_name = strtok_r(NULL, ",", &ptrptr);
  1267. app_name = strtok_r(NULL, ",", &ptrptr);
  1268. if (su_name == NULL || sg_name == NULL || app_name == NULL) {
  1269. goto end;
  1270. }
  1271. su_name += 6;
  1272. sg_name += 6;
  1273. app_name += 7;
  1274. app = amf_application_find (cluster, app_name);
  1275. if (app == NULL) {
  1276. goto end;
  1277. }
  1278. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1279. if (strncmp (sg_name, (char*)sg->name.value,
  1280. sg->name.length) == 0) {
  1281. for (su = sg->su_head; su != NULL; su = su->next) {
  1282. if (su->name.length == strlen(su_name) &&
  1283. strncmp (su_name, (char*)su->name.value,
  1284. su->name.length) == 0) {
  1285. goto end;
  1286. }
  1287. }
  1288. }
  1289. }
  1290. end:
  1291. free (buf);
  1292. return su;
  1293. }
  1294. /**
  1295. * This function makes a distinguished name for specified su object.
  1296. * @param su
  1297. * @param name -[out] pointer to where the distinguished name shall be stored
  1298. *
  1299. * @return SaNameT* - distinguished name
  1300. */
  1301. char *amf_su_dn_make (struct amf_su *su, SaNameT *name)
  1302. {
  1303. int i;
  1304. assert (su != NULL);
  1305. i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  1306. "safSu=%s,safSg=%s,safApp=%s",
  1307. su->name.value, su->sg->name.value, su->sg->application->name.value);
  1308. assert (i <= SA_MAX_NAME_LENGTH);
  1309. name->length = i;
  1310. return (char *)name->value;
  1311. }
  1312. /**
  1313. * An order to SU to create an si-assignment object with a specified HA-state
  1314. * between it self and a specified si. The created si-assignment is initialized
  1315. * and linked to list of assignments held by the specified si.
  1316. * This function also orders creation of all csi-assignments required
  1317. * considering the cs-types specified for the components and csi objects
  1318. * respectively.
  1319. * @param su
  1320. * @param si
  1321. * @param ha_state
  1322. *
  1323. * @return amf_si_assignment_t*
  1324. */
  1325. amf_si_assignment_t *amf_su_assign_si (struct amf_su *su, struct amf_si *si,
  1326. SaAmfHAStateT ha_state)
  1327. {
  1328. struct amf_si_assignment *si_assignment;
  1329. dprintf ("Creating SI '%s' to SU '%s' with hastate %s\n",
  1330. getSaNameT (&si->name), getSaNameT (&su->name),
  1331. amf_ha_state (ha_state));
  1332. si_assignment = amf_malloc (sizeof (struct amf_si_assignment));
  1333. amf_su_dn_make (su, &si_assignment->name);
  1334. si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
  1335. si_assignment->requested_ha_state = ha_state;
  1336. si_assignment->next = si->assigned_sis;
  1337. si->assigned_sis = si_assignment;
  1338. si_assignment->si = si;
  1339. si_assignment->su = su;
  1340. {
  1341. struct amf_csi *csi;
  1342. struct amf_comp *comp;
  1343. SaNameT *cs_type;
  1344. int i;
  1345. /*
  1346. ** for each component in SU, find a CSI in the SI with the same type
  1347. */
  1348. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1349. int no_of_cs_types = 0;
  1350. for (i = 0; comp->saAmfCompCsTypes[i]; i++) {
  1351. cs_type = comp->saAmfCompCsTypes[i];
  1352. no_of_cs_types++;
  1353. int no_of_assignments = 0;
  1354. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  1355. if (!memcmp(csi->saAmfCSTypeName.value, cs_type->value,
  1356. cs_type->length)) {
  1357. comp_assign_csi (comp, csi, si_assignment, ha_state);
  1358. no_of_assignments++;
  1359. }
  1360. }
  1361. if (no_of_assignments == 0) {
  1362. log_printf (
  1363. LOG_WARNING, "\t No CSIs of type %s configured?!!\n",
  1364. getSaNameT (cs_type));
  1365. }
  1366. }
  1367. if (no_of_cs_types == 0) {
  1368. log_printf (LOG_LEVEL_ERROR,
  1369. "\t No CS types configured for comp %s ?!!\n",
  1370. getSaNameT (&comp->name));
  1371. }
  1372. }
  1373. }
  1374. return si_assignment;
  1375. }
  1376. struct amf_si_assignment *amf_su_get_next_si_assignment (
  1377. struct amf_su *su, const struct amf_si_assignment *si_assignment)
  1378. {
  1379. struct amf_si *si;
  1380. struct amf_si_assignment *tmp_si_assignment;
  1381. SaNameT dn;
  1382. amf_su_dn_make (su, &dn);
  1383. if (si_assignment == NULL) {
  1384. assert (su->sg);
  1385. assert (su->sg->application);
  1386. assert (su->sg->application->si_head);
  1387. si = su->sg->application->si_head;
  1388. tmp_si_assignment = si->assigned_sis;
  1389. } else {
  1390. tmp_si_assignment = si_assignment->next;
  1391. if (tmp_si_assignment == NULL) {
  1392. si = si_assignment->si->next;
  1393. if (si == NULL) {
  1394. return NULL;
  1395. } else {
  1396. tmp_si_assignment = si->assigned_sis;
  1397. }
  1398. } else {
  1399. si = tmp_si_assignment->si;
  1400. }
  1401. }
  1402. for (; si != NULL; si = si->next) {
  1403. if (tmp_si_assignment == NULL && si != NULL) {
  1404. tmp_si_assignment = si->assigned_sis;
  1405. }
  1406. for (; tmp_si_assignment != NULL;
  1407. tmp_si_assignment = tmp_si_assignment->next) {
  1408. if (name_match (&tmp_si_assignment->name, &dn)) {
  1409. return tmp_si_assignment;
  1410. }
  1411. }
  1412. }
  1413. return NULL;
  1414. }
  1415. void amf_su_foreach_si_assignment (
  1416. struct amf_su *su,
  1417. void (*foreach_fn)(struct amf_su *su,
  1418. struct amf_si_assignment *si_assignment))
  1419. {
  1420. struct amf_si_assignment *si_assignment;
  1421. assert (foreach_fn != NULL);
  1422. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1423. while (si_assignment != NULL) {
  1424. foreach_fn (su, si_assignment);
  1425. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1426. }
  1427. }
  1428. /**
  1429. * This function calculates the number of si-assignments with active HA-state
  1430. * which currently are associated with the specified su.
  1431. * TODO: Split into two functions and remove dependency to sg's avail_state
  1432. * @param su
  1433. *
  1434. * @return int
  1435. */
  1436. int amf_su_get_saAmfSUNumCurrActiveSIs(struct amf_su *su)
  1437. {
  1438. int cnt = 0;
  1439. struct amf_si_assignment *si_assignment;
  1440. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1441. while (si_assignment != NULL) {
  1442. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1443. si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
  1444. cnt++;
  1445. } else {
  1446. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
  1447. cnt++;
  1448. }
  1449. }
  1450. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1451. }
  1452. return cnt;
  1453. }
  1454. /**
  1455. * This function calculates the number of si-assignments with standby HA-state
  1456. * which currently are associated with the specified su.
  1457. * TODO: Split into two functions and remove dependency to sg's avail_state
  1458. * @param su
  1459. *
  1460. * @return int
  1461. */
  1462. int amf_su_get_saAmfSUNumCurrStandbySIs(struct amf_su *su)
  1463. {
  1464. int cnt = 0;
  1465. struct amf_si_assignment *si_assignment;
  1466. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1467. while (si_assignment != NULL) {
  1468. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1469. si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
  1470. cnt++;
  1471. } else {
  1472. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  1473. cnt++;
  1474. }
  1475. }
  1476. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1477. }
  1478. return cnt;
  1479. }
  1480. /**
  1481. * This function calculates the readiness state for specified su
  1482. * @param su
  1483. *
  1484. * @return SaAmfReadinessStateT
  1485. */
  1486. SaAmfReadinessStateT amf_su_get_saAmfSUReadinessState (struct amf_su *su)
  1487. {
  1488. if ((su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) &&
  1489. ((su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED) ||
  1490. (su->saAmfSUPresenceState == SA_AMF_PRESENCE_RESTARTING))) {
  1491. return SA_AMF_READINESS_IN_SERVICE;
  1492. } else if (su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) {
  1493. return SA_AMF_READINESS_STOPPING;
  1494. } else {
  1495. return SA_AMF_READINESS_OUT_OF_SERVICE;
  1496. }
  1497. }
  1498. /**
  1499. * Determine if the SU is hosted on the local node.
  1500. * @param su
  1501. *
  1502. * @return int
  1503. */
  1504. int amf_su_is_local (struct amf_su *su)
  1505. {
  1506. if (name_match (&this_amf_node->name, &su->saAmfSUHostedByNode)) {
  1507. return 1;
  1508. } else {
  1509. return 0;
  1510. }
  1511. }
  1512. /**
  1513. * Determine if all components have the specified HA-state.
  1514. * @param su
  1515. * @param state -specified HA-state
  1516. *
  1517. * @return int - return 0 if not all components have the specified HA-state
  1518. */
  1519. int amf_su_are_all_comps_in_su (struct amf_su *su,
  1520. SaAmfPresenceStateT state)
  1521. {
  1522. int all_comps_in_su_are_set = 1;
  1523. amf_comp_t *component;
  1524. for (component = su->comp_head; component != NULL;
  1525. component = component->next) {
  1526. if (component->saAmfCompPresenceState != state) {
  1527. all_comps_in_su_are_set = 0;
  1528. }
  1529. }
  1530. return all_comps_in_su_are_set;
  1531. }