amfsg.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191
  1. /** @file amfsg.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 Group Class Implementation
  46. *
  47. * This file contains functions for handling AMF-service groups(SGs). It can be
  48. * viewed as the implementation of the AMF Service Group class (called SG)
  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. * -on request start the service group by instantiating the contained SUs
  55. * -on request assign the service instances it protects to the in-service
  56. * service units it contains respecting as many as possible of the configured
  57. * requirements for the group
  58. * -create and delete an SI-assignment object for each relation between
  59. * an SI and an SU
  60. * -order each contained SU to create and delete CSI-assignments
  61. * -request the Service Instance class (SI) to execute the transfer of the
  62. * HA-state set/remove requests to each component involved
  63. * -fully control the execution of component failover and SU failover
  64. * -on request control the execution of the initial steps of node switchover
  65. * and node failover
  66. * -fully handle the auto adjust procedure
  67. *
  68. * Currently only the 'n+m' redundancy model is implemented. It is the
  69. * ambition to identify n+m specific variables and functions and add the suffix
  70. * '_nplusm' to them so that they can be easily recognized.
  71. *
  72. * When SG is requested to assign workload to all SUs or all SUs hosted on
  73. * a specific node, a procedure containing several steps is executed:
  74. * <1> An algorithm is executed which assigns SIs to SUs respecting the rules
  75. * that has been configured for SG. The algorithm also has to consider
  76. * if assignments between som SIs and SUs already exist. The scope of this
  77. * algorithm is to create SI-assignments and set up requested HA-state for
  78. * each assignment but not to transfer those HA-states to the components.
  79. * <2> All SI-assignments with a requested HA state == ACTIVE are transferred
  80. * to the components concerned before any STANDBY assignments are
  81. * transferred. All components have to acknowledge the setting of the
  82. * ACTIVE HA state before the transfer of any STANDBY assignment is
  83. * initiated.
  84. * <3> All active assignments can not be transferred at the same time to the
  85. * different components because the rules for dependencies between SI and
  86. * SI application wide and CSI and CSI within one SI, has to be respected.
  87. *
  88. * SG is fully responsible for step <1> but not fully responsible for handling
  89. * step <2> and <3>. However, SG uses an attribute called 'dependency level'
  90. * when requsted to assign workload. This parameter refers to an integer that
  91. * has been calculated initially for each SI. The 'dependency level' indicates
  92. * to which extent an SI depends on other SIs such that an SI that depends on
  93. * no other SI is on dependecy_level == 1, an SI that depends only on an SI on
  94. * dependency_level == 1 is on dependency-level == 2.
  95. * An SI that depends on several SIs gets a
  96. * dependency_level that is one unit higher than the SI with the highest
  97. * dependency_level it depends on. When SG is requested to assign the workload
  98. * on a certain dependency level, it requests all SI objects on that level to
  99. * activate (all) SI-assignments that during step <1> has been requested to
  100. * assume the active HA state.
  101. *
  102. * SG contains the following state machines:
  103. * - administrative state machine (ADSM) (NOT IN THIS RELEASE)
  104. * - availability control state machine (ACSM)
  105. *
  106. * The availability control state machine contains two states and one of them
  107. * is composite. Being a composite state means that it contains substates.
  108. * The states are:
  109. * - IDLE (non composite state)
  110. * - MANAGING_SG (composite state)
  111. * MANAGING_SG is entered at several different events which has in common
  112. * the need to set up or change the assignment of SIs to SUs. Only one such
  113. * event can be handled at the time. If new events occur while one event is
  114. * being handled then the new event is saved and will be handled after the
  115. * handling of the first event is ready (return to IDLE state has been done).
  116. * MANAGING_SG handles the following events:
  117. * - start (requests SG to order SU to instantiate all SUs in SG and waits
  118. * for SU to indicate presence state change reports from the SUs and
  119. * finally responds 'started' to the requester)
  120. * - assign (requests SG to assign SIs to SUs according to pre-configured
  121. * rules (if not already done) and transfer the HA state of
  122. * the SIs on the requested SI dependency level. Then SG waits for
  123. * confirmation that the HA state has been succesfully set and
  124. * finally responds 'assigned' to the reqeuster)
  125. * - auto_adjust (this event indicates that the auto-adjust probation timer has
  126. * expired and that SG should evaluate current assignments of
  127. * SIs to SUs and if needed remove current assignments and
  128. * create new according to what is specified in paragraph
  129. * 3.7.1.2)
  130. * - failover_comp (requests SG to failover a specific component according to
  131. * the procedure described in paragraph 3.12.1.3)
  132. * - failover_su (requests SG to failover a specific SU according to the
  133. * procedure described in paragraph 3.12.1.3 and 3.12.1.4)
  134. * - switchover_node (requests SG to execute the recovery actions described
  135. * in 3.12.1.3 and respond to the requester when recovery
  136. * is completed)
  137. * - failover_node (requests SG to execute the recovery actions described
  138. * in 3.12.1.3 and respond to the requester when recovery is
  139. * completed)
  140. *
  141. */
  142. #include <stdlib.h>
  143. #include <errno.h>
  144. #include "amf.h"
  145. #include "print.h"
  146. #include "main.h"
  147. #include "util.h"
  148. static int assign_si (struct amf_sg *sg, int dependency_level);
  149. static void acsm_enter_activating_standby (struct amf_sg *sg);
  150. static void delete_si_assignments_in_scope (struct amf_sg *sg);
  151. static void acsm_enter_repairing_su (struct amf_sg *sg);
  152. static void standby_su_activated_cbfn (
  153. struct amf_si_assignment *si_assignment, int result);
  154. static void dependent_si_deactivated_cbfn (
  155. struct amf_si_assignment *si_assignment, int result);
  156. static const char *sg_event_type_text[] = {
  157. "Unknown",
  158. "Failover SU",
  159. "Failover node",
  160. "Failover comp",
  161. "Switchover node",
  162. "Start",
  163. "Autoadjust",
  164. "Assign SI"
  165. };
  166. typedef struct sg_event {
  167. amf_sg_event_type_t event_type;
  168. amf_sg_t *sg;
  169. amf_su_t *su;
  170. amf_comp_t *comp;
  171. amf_node_t *node;
  172. } sg_event_t;
  173. static void sg_set_event (amf_sg_event_type_t sg_event_type,
  174. amf_sg_t *sg, amf_su_t *su, amf_comp_t *comp, amf_node_t * node,
  175. sg_event_t *sg_event)
  176. {
  177. sg_event->event_type = sg_event_type;
  178. sg_event->node = node;
  179. sg_event->su = su;
  180. sg_event->comp = comp;
  181. sg_event->sg = sg;
  182. }
  183. static void sg_defer_event (amf_sg_event_type_t event_type,
  184. sg_event_t *sg_event)
  185. {
  186. amf_fifo_put (event_type, &sg_event->sg->deferred_events,
  187. sizeof (sg_event_t),
  188. sg_event);
  189. }
  190. static void sg_recall_deferred_events (amf_sg_t *sg)
  191. {
  192. sg_event_t sg_event;
  193. ENTER ("SG: %s", sg->name.value);
  194. if (amf_fifo_get (&sg->deferred_events, &sg_event)) {
  195. switch (sg_event.event_type) {
  196. case SG_FAILOVER_SU_EV:
  197. amf_sg_failover_su_req (sg_event.sg,
  198. sg_event.su, sg_event.node);
  199. break;
  200. case SG_FAILOVER_NODE_EV:
  201. amf_sg_failover_node_req (sg_event.sg,
  202. sg_event.node);
  203. break;
  204. case SG_FAILOVER_COMP_EV:
  205. case SG_SWITCH_OVER_NODE_EV:
  206. case SG_START_EV:
  207. case SG_AUTO_ADJUST_EV:
  208. default:
  209. break;
  210. }
  211. }
  212. }
  213. static void timer_function_sg_recall_deferred_events (void *data)
  214. {
  215. amf_sg_t *sg = (amf_sg_t*)data;
  216. ENTER ("");
  217. sg_recall_deferred_events (sg);
  218. }
  219. static void acsm_enter_idle (amf_sg_t *sg)
  220. {
  221. SaNameT dn;
  222. ENTER ("sg: %s state: %d", sg->name.value, sg->avail_state);
  223. sg->avail_state = SG_AC_Idle;
  224. if (sg->recovery_scope.event_type != 0) {
  225. switch (sg->recovery_scope.event_type) {
  226. case SG_FAILOVER_SU_EV:
  227. assert (sg->recovery_scope.sus[0] != NULL);
  228. amf_su_dn_make (sg->recovery_scope.sus[0], &dn);
  229. log_printf (
  230. LOG_NOTICE,
  231. "'%s' %s recovery action finished",
  232. dn.value,
  233. sg_event_type_text[sg->recovery_scope.event_type]);
  234. break;
  235. case SG_FAILOVER_NODE_EV:
  236. amf_node_sg_failed_over (
  237. sg->recovery_scope.node, sg);
  238. log_printf (
  239. LOG_NOTICE,
  240. "'%s for %s' recovery action finished",
  241. sg_event_type_text[sg->recovery_scope.event_type],
  242. sg->name.value);
  243. break;
  244. case SG_START_EV:
  245. amf_application_sg_started (sg->application,
  246. sg, this_amf_node);
  247. break;
  248. case SG_ASSIGN_SI_EV:
  249. log_printf (LOG_NOTICE, "All SI assigned");
  250. break;
  251. default:
  252. log_printf (
  253. LOG_NOTICE,
  254. "'%s' recovery action finished",
  255. sg_event_type_text[sg->recovery_scope.event_type]);
  256. break;
  257. }
  258. }
  259. if (sg->recovery_scope.sus != NULL) {
  260. free ((void *)sg->recovery_scope.sus);
  261. }
  262. if (sg->recovery_scope.sis != NULL) {
  263. free ((void *)sg->recovery_scope.sis);
  264. }
  265. memset (&sg->recovery_scope, 0, sizeof (struct sg_recovery_scope));
  266. sg->node_to_start = NULL;
  267. amf_call_function_asynchronous (
  268. timer_function_sg_recall_deferred_events, sg);
  269. }
  270. static int su_instantiated_count (struct amf_sg *sg)
  271. {
  272. int cnt = 0;
  273. struct amf_su *su;
  274. for (su = sg->su_head; su != NULL; su = su->next) {
  275. if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED)
  276. cnt++;
  277. }
  278. return cnt;
  279. }
  280. static int has_any_su_in_scope_active_workload (struct amf_sg *sg)
  281. {
  282. struct amf_su **sus= sg->recovery_scope.sus;
  283. struct amf_si_assignment *si_assignment;
  284. while (*sus != NULL) {
  285. si_assignment = amf_su_get_next_si_assignment (*sus, NULL);
  286. while (si_assignment != NULL) {
  287. if (si_assignment->saAmfSISUHAState !=
  288. SA_AMF_HA_ACTIVE) {
  289. break;
  290. }
  291. si_assignment = amf_su_get_next_si_assignment (
  292. *sus, si_assignment);
  293. }
  294. if (si_assignment != NULL) {
  295. break;
  296. }
  297. sus++;
  298. }
  299. return(*sus == NULL);
  300. }
  301. static int is_any_si_in_scope_assigned_stanby (struct amf_sg *sg)
  302. {
  303. struct amf_si **sis= sg->recovery_scope.sis;
  304. struct amf_si_assignment *si_assignment;
  305. /*
  306. * Check if there is any si in the scope which has no active assignment
  307. * and at least one standby assignment.
  308. */
  309. while (*sis != NULL) {
  310. si_assignment = (*sis)->assigned_sis;
  311. while (si_assignment != NULL) {
  312. if (si_assignment->saAmfSISUHAState ==
  313. SA_AMF_HA_ACTIVE) {
  314. break;
  315. }
  316. si_assignment = si_assignment->next;
  317. }
  318. if (si_assignment == NULL) {
  319. /* There is no ACTIVE assignment ..*/
  320. si_assignment = (*sis)->assigned_sis;
  321. while (si_assignment != NULL) {
  322. if (si_assignment->saAmfSISUHAState ==
  323. SA_AMF_HA_STANDBY) {
  324. break;
  325. }
  326. si_assignment = si_assignment->next;
  327. }
  328. if (si_assignment != NULL) {
  329. /* .. and one STANDBY assignment*/
  330. break;
  331. }
  332. }
  333. sis++;
  334. }
  335. return(*sis != NULL);
  336. }
  337. static void acsm_enter_terminating_suspected (struct amf_sg *sg)
  338. {
  339. struct amf_su **sus= sg->recovery_scope.sus;
  340. sg->avail_state = SG_AC_TerminatingSuspected;
  341. /*
  342. * Terminate suspected SU(s)
  343. */
  344. while (*sus != 0) {
  345. amf_su_terminate (*sus);
  346. sus++;
  347. }
  348. }
  349. static inline int su_presense_state_is_ored (amf_su_t *su,
  350. SaAmfPresenceStateT state1,SaAmfPresenceStateT state2,
  351. SaAmfPresenceStateT state3)
  352. {
  353. return(su->saAmfSUPresenceState == state1 || su->saAmfSUPresenceState ==
  354. state2 || su->saAmfSUPresenceState == state3) ? 1 : 0;
  355. }
  356. static inline int su_presense_state_is_not (amf_su_t *su,
  357. SaAmfPresenceStateT state1,SaAmfPresenceStateT state2,
  358. SaAmfPresenceStateT state3)
  359. {
  360. return(su->saAmfSUPresenceState != state1 && su->saAmfSUPresenceState !=
  361. state2 && su->saAmfSUPresenceState != state3) ? 1 : 0;
  362. }
  363. /**
  364. * Callback function used by SI when there is no dependent SI to
  365. * deactivate.
  366. * @param sg
  367. */
  368. static void dependent_si_deactivated_cbfn2 (struct amf_sg *sg)
  369. {
  370. struct amf_su **sus = sg->recovery_scope.sus;
  371. ENTER("'%s'", sg->name.value);
  372. /*
  373. * Select next state depending on if some
  374. * SU in the scope is needs to be terminated.
  375. */
  376. while (*sus != NULL) {
  377. amf_su_t *su = *sus;
  378. ENTER("SU %s pr_state='%d'",su->name.value,
  379. su->saAmfSUPresenceState);
  380. if (su_presense_state_is_ored (su,
  381. SA_AMF_PRESENCE_UNINSTANTIATED,
  382. SA_AMF_PRESENCE_TERMINATION_FAILED,
  383. SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
  384. sus++;
  385. continue;
  386. }
  387. break;
  388. }
  389. if (*sus != NULL) {
  390. acsm_enter_terminating_suspected (sg);
  391. } else {
  392. delete_si_assignments_in_scope(sg);
  393. acsm_enter_activating_standby (sg);
  394. }
  395. }
  396. static void timer_function_dependent_si_deactivated2 (void *data)
  397. {
  398. amf_sg_t *sg = (amf_sg_t *)data;
  399. ENTER ("");
  400. dependent_si_deactivated_cbfn2 (sg);
  401. }
  402. static struct amf_si *si_get_dependent (struct amf_si *si)
  403. {
  404. struct amf_si *tmp_si = NULL;
  405. if (si->depends_on != NULL) {
  406. SaNameT res_arr[2];
  407. int is_match;
  408. if (si->depends_on->name.length < SA_MAX_NAME_LENGTH) {
  409. si->depends_on->name.value[si->depends_on->name.length] = '\0';
  410. }
  411. is_match = sa_amf_grep ((char*)si->depends_on->name.value,
  412. "safDepend=.*,safSi=(.*),safApp=.*",
  413. 2, res_arr);
  414. if (is_match) {
  415. tmp_si = amf_si_find (si->application, (char*)res_arr[1].value);
  416. } else {
  417. log_printf (LOG_LEVEL_ERROR, "distinguished name for "
  418. "amf_si_depedency failed\n");
  419. openais_exit_error (AIS_DONE_FATAL_ERR);
  420. }
  421. }
  422. return tmp_si;
  423. }
  424. static struct amf_si *amf_dependent_get_next (struct amf_si *si,
  425. struct amf_si *si_iter)
  426. {
  427. struct amf_si *tmp_si;
  428. struct amf_application *application;
  429. if (si_iter == NULL) {
  430. assert(amf_cluster != NULL);
  431. application = amf_cluster->application_head;
  432. assert(application != NULL);
  433. tmp_si = application->si_head;
  434. } else {
  435. tmp_si = si_iter->next;
  436. if (tmp_si == NULL) {
  437. application = si->application->next;
  438. if (application == NULL) {
  439. goto out;
  440. }
  441. }
  442. }
  443. for (; tmp_si != NULL; tmp_si = tmp_si->next) {
  444. struct amf_si *depends_on_si = si_get_dependent (tmp_si);
  445. while (depends_on_si != NULL) {
  446. if (depends_on_si == si) {
  447. goto out;
  448. }
  449. depends_on_si = depends_on_si->next;
  450. }
  451. }
  452. out:
  453. return tmp_si;
  454. }
  455. static void acsm_enter_deactivating_dependent_workload (amf_sg_t *sg)
  456. {
  457. struct amf_si **sis= sg->recovery_scope.sis;
  458. struct amf_si_assignment *si_assignment;
  459. int callback_pending = 0;
  460. sg->avail_state = SG_AC_DeactivatingDependantWorkload;
  461. ENTER("'%s'",sg->name.value);
  462. /*
  463. * For each SI in the recovery scope, find all active
  464. * assignments and request them to be deactivated.
  465. */
  466. while (*sis != NULL) {
  467. struct amf_si *dependent_si;
  468. struct amf_si *si = *sis;
  469. si_assignment = si->assigned_sis;
  470. dependent_si = amf_dependent_get_next (si, NULL);
  471. while (dependent_si != NULL) {
  472. si_assignment = dependent_si->assigned_sis;
  473. while (si_assignment != NULL) {
  474. if (si_assignment->saAmfSISUHAState ==
  475. SA_AMF_HA_ACTIVE) {
  476. si_assignment->requested_ha_state =
  477. SA_AMF_HA_QUIESCED;
  478. callback_pending = 1;
  479. amf_si_ha_state_assume (
  480. si_assignment,
  481. dependent_si_deactivated_cbfn);
  482. }
  483. si_assignment = si_assignment->next;
  484. }
  485. dependent_si = amf_dependent_get_next (si, dependent_si);
  486. }
  487. sis++;
  488. }
  489. if (callback_pending == 0) {
  490. static poll_timer_handle dependent_si_deactivated_handle;
  491. ENTER("");
  492. poll_timer_add (aisexec_poll_handle, 0, sg,
  493. timer_function_dependent_si_deactivated2,
  494. &dependent_si_deactivated_handle);
  495. }
  496. }
  497. /**
  498. * Enter function for state SG_AC_ActivatingStandby. It activates
  499. * one STANDBY assignment for each SI in the recovery scope.
  500. * @param sg
  501. */
  502. static void acsm_enter_activating_standby (struct amf_sg *sg)
  503. {
  504. struct amf_si **sis= sg->recovery_scope.sis;
  505. struct amf_si_assignment *si_assignment;
  506. int is_no_standby_activated = 1;
  507. ENTER("'%s'",sg->name.value);
  508. sg->avail_state = SG_AC_ActivatingStandby;
  509. /*
  510. * For each SI in the recovery scope, find one standby
  511. * SI assignment and activate it.
  512. */
  513. while (*sis != NULL) {
  514. si_assignment = (*sis)->assigned_sis;
  515. while (si_assignment != NULL) {
  516. if (si_assignment->saAmfSISUHAState ==
  517. SA_AMF_HA_STANDBY) {
  518. si_assignment->requested_ha_state =
  519. SA_AMF_HA_ACTIVE;
  520. amf_si_ha_state_assume (
  521. si_assignment, standby_su_activated_cbfn);
  522. is_no_standby_activated = 0;
  523. break;
  524. }
  525. si_assignment = si_assignment->next;
  526. }
  527. sis++;
  528. }
  529. if (is_no_standby_activated) {
  530. acsm_enter_activating_standby (sg);
  531. }
  532. }
  533. static void acsm_enter_repairing_su (struct amf_sg *sg)
  534. {
  535. struct amf_su **sus= sg->recovery_scope.sus;
  536. int is_any_su_instantiated = 0;
  537. ENTER("'%s'",sg->name.value);
  538. sg->avail_state = SG_AC_ReparingSu;
  539. /*
  540. * Instantiate SUs in current recovery scope until the configured
  541. * preference is fulfiled.
  542. */
  543. while (*sus != NULL) {
  544. if (su_instantiated_count ((*sus)->sg) <
  545. (*sus)->sg->saAmfSGNumPrefInserviceSUs) {
  546. struct amf_node *node =
  547. amf_node_find(&((*sus)->saAmfSUHostedByNode));
  548. if (node == NULL) {
  549. log_printf (LOG_LEVEL_ERROR,
  550. "no node to hosted on su found"
  551. "amf_si_depedency failed\n");
  552. openais_exit_error (AIS_DONE_FATAL_ERR);
  553. }
  554. if (node->saAmfNodeOperState == SA_AMF_OPERATIONAL_ENABLED) {
  555. /* node is synchronized */
  556. is_any_su_instantiated = 1;
  557. amf_su_instantiate ((*sus));
  558. }
  559. }
  560. sus++;
  561. }
  562. if (is_any_su_instantiated == 0) {
  563. acsm_enter_idle (sg);
  564. }
  565. }
  566. static inline void remove_all_suspected_sus (amf_sg_t *sg)
  567. {
  568. amf_su_t *su;
  569. ENTER("");
  570. for (su = sg->su_head; su != NULL; su =su->next) {
  571. amf_comp_t *component;
  572. for (component = su->comp_head; component != NULL;
  573. component = component->next) {
  574. component->error_suspected = 0;
  575. }
  576. }
  577. }
  578. static int is_all_si_assigned (amf_sg_t *sg)
  579. {
  580. struct amf_si_assignment *si_assignment;
  581. int si_assignment_cnt = 0;
  582. int confirmed_assignments = 0;
  583. amf_si_t *si;
  584. for (si = sg->application->si_head; si != NULL; si = si->next) {
  585. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  586. for (si_assignment = si->assigned_sis;
  587. si_assignment != NULL;
  588. si_assignment = si_assignment->next) {
  589. si_assignment_cnt++;
  590. if (si_assignment->requested_ha_state ==
  591. si_assignment->saAmfSISUHAState) {
  592. confirmed_assignments++;
  593. }
  594. }
  595. }
  596. }
  597. return (confirmed_assignments == si_assignment_cnt);
  598. }
  599. static void assign_si_assumed_cbfn (
  600. struct amf_si_assignment *si_assignment, int result)
  601. {
  602. struct amf_sg *sg = si_assignment->su->sg;
  603. int si_assignment_cnt = 0;
  604. int confirmed_assignments = 0;
  605. ENTER ("'%s', %d", si_assignment->si->name.value, result);
  606. switch (sg->avail_state) {
  607. case SG_AC_AssigningOnRequest:
  608. if (is_all_si_assigned (sg)) {
  609. acsm_enter_idle (sg);
  610. amf_application_sg_assigned (sg->application, sg);
  611. } else {
  612. dprintf ("%d, %d", si_assignment_cnt, confirmed_assignments);
  613. }
  614. break;
  615. case SG_AC_AssigningStandBy:
  616. {
  617. if (is_all_si_assigned(sg)) {
  618. acsm_enter_idle (sg);
  619. }
  620. break;
  621. }
  622. case SG_AC_AssigningStandbyToSpare:
  623. {
  624. if(is_all_si_assigned (sg)) {
  625. /*
  626. * All si_assignments has asumed
  627. * Prescense state SA_AMF_HA_STANDBY
  628. */
  629. switch (sg->recovery_scope.event_type) {
  630. case SG_FAILOVER_NODE_EV:
  631. acsm_enter_idle (sg);
  632. break;
  633. case SG_FAILOVER_SU_EV:
  634. if (sg->saAmfSGAutoRepair == SA_TRUE) {
  635. acsm_enter_repairing_su (sg);
  636. }
  637. break;
  638. default:
  639. assert (0);
  640. break;
  641. }
  642. } else {
  643. si_assignment->saAmfSISUHAState = SA_AMF_HA_STANDBY;
  644. }
  645. }
  646. break;
  647. default:
  648. dprintf ("%d, %d, %d", sg->avail_state, si_assignment_cnt,
  649. confirmed_assignments);
  650. amf_runtime_attributes_print (amf_cluster);
  651. assert (0);
  652. break;
  653. }
  654. }
  655. /**
  656. * Inquire if SI is assigned to SU
  657. * @param si
  658. * @param su
  659. *
  660. * @return int
  661. */
  662. static int is_si_assigned_to_su (amf_si_t *si, amf_su_t *su)
  663. {
  664. amf_si_assignment_t *si_assignment = 0;
  665. int si_assignment_assigned_to_su = 0;
  666. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  667. si_assignment = si_assignment->next) {
  668. if (si_assignment->su == su) {
  669. si_assignment_assigned_to_su = 1;
  670. break;
  671. }
  672. }
  673. return si_assignment_assigned_to_su;
  674. }
  675. /**
  676. * Inquire if SU is a spare.
  677. * @param sg
  678. * @param su
  679. *
  680. * @return int
  681. */
  682. static int is_spare_su (amf_sg_t *sg, amf_su_t *su)
  683. {
  684. amf_si_t *si;
  685. int spare_su = 1;
  686. for (si = sg->application->si_head; si != NULL; si = si->next) {
  687. if(name_match(&sg->name, &si->saAmfSIProtectedbySG)) {
  688. if (is_si_assigned_to_su (si, su)) {
  689. spare_su = 0;
  690. break;
  691. }
  692. }
  693. }
  694. return (spare_su && su->saAmfSUPresenceState ==
  695. SA_AMF_PRESENCE_INSTANTIATED);
  696. }
  697. /**
  698. * Inqure if it is any spare SUs covered by SG
  699. * @param sg
  700. *
  701. * @return int
  702. */
  703. static int is_spare_sus (amf_sg_t *sg)
  704. {
  705. amf_su_t *su = NULL;
  706. int spare_sus = 0;
  707. for (su = sg->su_head; su != NULL; su = su->next) {
  708. if (is_spare_su(sg, su)) {
  709. spare_sus = 1;
  710. break;
  711. }
  712. }
  713. return spare_sus;
  714. }
  715. /**
  716. * Provide standby assignments for the spare SUs in SG
  717. * @param sg
  718. */
  719. static void assume_standby_si_assignment_for_spare_sus (amf_sg_t *sg)
  720. {
  721. ENTER("");
  722. assign_si (sg, 0);
  723. }
  724. /**
  725. * Enter the AssigningStandbyToSpare state.
  726. * @param sg
  727. */
  728. static void acsm_enter_assigning_standby_to_spare (amf_sg_t *sg)
  729. {
  730. ENTER("%s", sg->name.value);
  731. sg->avail_state = SG_AC_AssigningStandbyToSpare;
  732. if (is_spare_sus (sg)) {
  733. assume_standby_si_assignment_for_spare_sus (sg);
  734. } else {
  735. acsm_enter_repairing_su (sg);
  736. }
  737. }
  738. /**
  739. * Checks if the si pointed out is already in the scope.
  740. * @param sg
  741. * @param si
  742. */
  743. static int is_si_in_scope(struct amf_sg *sg, struct amf_si *si)
  744. {
  745. struct amf_si **tmp_sis= sg->recovery_scope.sis;
  746. while (*tmp_sis != NULL) {
  747. if (*tmp_sis == si) {
  748. break;
  749. }
  750. tmp_sis++;
  751. }
  752. return(*tmp_sis == si);
  753. }
  754. /**
  755. * Adds the si pointed out to the scope.
  756. * @param sg
  757. * @param si
  758. */
  759. static void add_si_to_scope ( struct amf_sg *sg, struct amf_si *si)
  760. {
  761. int number_of_si = 2; /* It shall be at least two */
  762. struct amf_si **tmp_sis= sg->recovery_scope.sis;
  763. ENTER ("'%s'", si->name.value);
  764. while (*tmp_sis != NULL) {
  765. number_of_si++;
  766. tmp_sis++;
  767. }
  768. sg->recovery_scope.sis = (struct amf_si **)
  769. realloc((void *)sg->recovery_scope.sis,
  770. sizeof (struct amf_si *)*number_of_si);
  771. assert (sg->recovery_scope.sis != NULL);
  772. tmp_sis= sg->recovery_scope.sis;
  773. while (*tmp_sis != NULL) {
  774. tmp_sis++;
  775. }
  776. *tmp_sis = si;
  777. *(++tmp_sis) = NULL;
  778. }
  779. /**
  780. * Adds the ssu pointed out to the scope.
  781. * @param sg
  782. * @param su
  783. */
  784. static void add_su_to_scope (struct amf_sg *sg, struct amf_su *su)
  785. {
  786. int number_of_su = 2; /* It shall be at least two */
  787. struct amf_su **tmp_sus= sg->recovery_scope.sus;
  788. ENTER ("'%s'", su->name.value);
  789. while (*tmp_sus != NULL) {
  790. number_of_su++;
  791. tmp_sus++;
  792. }
  793. sg->recovery_scope.sus = (struct amf_su **)
  794. realloc((void *)sg->recovery_scope.sus,
  795. sizeof (struct amf_su *)*number_of_su);
  796. assert (sg->recovery_scope.sus != NULL);
  797. tmp_sus= sg->recovery_scope.sus;
  798. while (*tmp_sus != NULL) {
  799. tmp_sus++;
  800. }
  801. *tmp_sus = su;
  802. *(++tmp_sus) = NULL;
  803. }
  804. /**
  805. * Set recovery scope for failover SU.
  806. * @param sg
  807. * @param su
  808. */
  809. static void set_scope_for_failover_su (struct amf_sg *sg, struct amf_su *su)
  810. {
  811. struct amf_si_assignment *si_assignment;
  812. struct amf_si **sis;
  813. struct amf_su **sus;
  814. SaNameT dn;
  815. sg->recovery_scope.event_type = SG_FAILOVER_SU_EV;
  816. sg->recovery_scope.node = NULL;
  817. sg->recovery_scope.comp = NULL;
  818. sg->recovery_scope.sus = (struct amf_su **)
  819. calloc (2, sizeof (struct amf_su *));
  820. sg->recovery_scope.sis = (struct amf_si **)
  821. calloc (1, sizeof (struct amf_si *));
  822. assert ((sg->recovery_scope.sus != NULL) &&
  823. (sg->recovery_scope.sis != NULL));
  824. sg->recovery_scope.sus[0] = su;
  825. amf_su_dn_make (sg->recovery_scope.sus[0], &dn);
  826. log_printf (
  827. LOG_NOTICE, "'%s' for %s recovery action started",
  828. sg_event_type_text[sg->recovery_scope.event_type],
  829. dn.value);
  830. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  831. while (si_assignment != NULL) {
  832. if (is_si_in_scope(sg, si_assignment->si) == 0) {
  833. add_si_to_scope(sg,si_assignment->si );
  834. }
  835. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  836. }
  837. sus = sg->recovery_scope.sus;
  838. dprintf("The following sus are within the scope:\n");
  839. while (*sus != NULL) {
  840. dprintf("%s\n", (*sus)->name.value);
  841. sus++;
  842. }
  843. sis= sg->recovery_scope.sis;
  844. dprintf("The following sis are within the scope:\n");
  845. while (*sis != NULL) {
  846. dprintf("%s\n", (*sis)->name.value);
  847. sis++;
  848. }
  849. }
  850. static void set_scope_for_failover_node (struct amf_sg *sg, struct amf_node *node)
  851. {
  852. struct amf_si_assignment *si_assignment;
  853. struct amf_si **sis;
  854. struct amf_su **sus;
  855. struct amf_su *su;
  856. ENTER ("'%s'", node->name.value);
  857. sg->recovery_scope.event_type = SG_FAILOVER_NODE_EV;
  858. sg->recovery_scope.node = node;
  859. sg->recovery_scope.comp = NULL;
  860. sg->recovery_scope.sus = (struct amf_su **)
  861. calloc (1, sizeof (struct amf_su *));
  862. sg->recovery_scope.sis = (struct amf_si **)
  863. calloc (1, sizeof (struct amf_si *));
  864. log_printf (
  865. LOG_NOTICE, "'%s' for node %s recovery action started",
  866. sg_event_type_text[sg->recovery_scope.event_type],
  867. node->name.value);
  868. assert ((sg->recovery_scope.sus != NULL) &&
  869. (sg->recovery_scope.sis != NULL));
  870. for (su = sg->su_head; su != NULL; su = su->next) {
  871. if (name_match (&node->name, &su->saAmfSUHostedByNode)) {
  872. add_su_to_scope (sg, su);
  873. }
  874. }
  875. sus = sg->recovery_scope.sus;
  876. while (*sus != 0) {
  877. su = *sus;
  878. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  879. while (si_assignment != NULL) {
  880. if (is_si_in_scope(sg, si_assignment->si) == 0) {
  881. add_si_to_scope(sg, si_assignment->si );
  882. }
  883. si_assignment = amf_su_get_next_si_assignment (
  884. su, si_assignment);
  885. }
  886. sus++;
  887. }
  888. sus = sg->recovery_scope.sus;
  889. dprintf("The following sus are within the scope:\n");
  890. while (*sus != NULL) {
  891. dprintf("%s\n", (*sus)->name.value);
  892. sus++;
  893. }
  894. sis = sg->recovery_scope.sis;
  895. dprintf("The following sis are within the scope:\n");
  896. while (*sis != NULL) {
  897. dprintf("%s\n", (*sis)->name.value);
  898. sis++;
  899. }
  900. }
  901. static void delete_si_assignment (amf_si_assignment_t *si_assignment)
  902. {
  903. amf_csi_t *csi;
  904. amf_si_assignment_t *si_assignment_tmp;
  905. amf_si_assignment_t **prev = &si_assignment->si->assigned_sis;
  906. for (csi = si_assignment->si->csi_head; csi != NULL; csi = csi->next) {
  907. amf_csi_delete_assignments (csi, si_assignment->su);
  908. }
  909. for (si_assignment_tmp = si_assignment->si->assigned_sis;
  910. si_assignment_tmp != NULL;
  911. si_assignment_tmp = si_assignment_tmp->next) {
  912. if (si_assignment_tmp == si_assignment) {
  913. amf_si_assignment_t *to_be_removed = si_assignment_tmp;
  914. *prev = si_assignment_tmp->next;
  915. dprintf ("SI assignment %s unlinked",
  916. to_be_removed->name.value);
  917. free (to_be_removed);
  918. } else {
  919. prev = &si_assignment_tmp->next;
  920. }
  921. }
  922. }
  923. /**
  924. * Delete all SI assignments and all CSI assignments
  925. * by requesting all contained components.
  926. * @param su
  927. */
  928. static void delete_si_assignments (struct amf_su *su)
  929. {
  930. struct amf_csi *csi;
  931. struct amf_si *si;
  932. struct amf_si_assignment *si_assignment;
  933. struct amf_si_assignment **prev;
  934. ENTER ("'%s'", su->name.value);
  935. for (si = su->sg->application->si_head; si != NULL; si = si->next) {
  936. prev = &si->assigned_sis;
  937. if (!name_match (&si->saAmfSIProtectedbySG, &su->sg->name)) {
  938. continue;
  939. }
  940. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  941. amf_csi_delete_assignments (csi, su);
  942. }
  943. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  944. si_assignment = si_assignment->next) {
  945. if (si_assignment->su == su) {
  946. struct amf_si_assignment *tmp = si_assignment;
  947. *prev = si_assignment->next;
  948. dprintf ("SI assignment %s unlinked", tmp->name.value);
  949. free (tmp);
  950. } else {
  951. prev = &si_assignment->next;
  952. }
  953. }
  954. }
  955. }
  956. /**
  957. * Delete all SI assignments and all CSI assignments in current
  958. * recovery scope.
  959. * @param sg
  960. */
  961. static void delete_si_assignments_in_scope (struct amf_sg *sg)
  962. {
  963. struct amf_su **sus= sg->recovery_scope.sus;
  964. while (*sus != NULL) {
  965. delete_si_assignments (*sus);
  966. sus++;
  967. }
  968. }
  969. /**
  970. * Given an SI, find and return the SU assigned as standby
  971. * @param si
  972. *
  973. * @return amf_su_t*
  974. */
  975. static amf_su_t *find_standby_su (amf_si_t *si)
  976. {
  977. amf_si_assignment_t *si_assignment;
  978. amf_su_t *standby_su = NULL;
  979. si_assignment = si->assigned_sis;
  980. while (si_assignment != NULL) {
  981. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  982. standby_su = si_assignment->su;
  983. break;
  984. }
  985. si_assignment = si_assignment->next;
  986. }
  987. return standby_su;
  988. }
  989. static int no_si_assignment_is_requested_to_be_removed (amf_sg_t *sg)
  990. {
  991. amf_si_t *si;
  992. int no_to_be_removed = 1;
  993. for (si = sg->application->si_head; si != NULL; si = si->next) {
  994. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  995. amf_si_assignment_t *si_assignment = 0;
  996. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  997. si_assignment = si_assignment->next) {
  998. if (si_assignment->requested_ha_state ==
  999. USR_AMF_HA_STATE_REMOVED) {
  1000. no_to_be_removed = 0;
  1001. goto out;
  1002. }
  1003. }
  1004. }
  1005. }
  1006. out:
  1007. return no_to_be_removed;
  1008. }
  1009. static void removed_si_assignment_callback_fn (void *si_assignment_in)
  1010. {
  1011. amf_si_assignment_t *si_assignment = si_assignment_in;
  1012. ENTER("");
  1013. delete_si_assignment (si_assignment);
  1014. /*
  1015. * if all si assignments are remove then change state
  1016. */
  1017. if (no_si_assignment_is_requested_to_be_removed (si_assignment->su->sg)) {
  1018. acsm_enter_activating_standby (si_assignment->su->sg);
  1019. }
  1020. }
  1021. /**
  1022. *
  1023. * @param sg
  1024. *
  1025. * @return int, number of removed SI assignments
  1026. */
  1027. static int remove_standby_si_assignments (amf_sg_t *sg)
  1028. {
  1029. struct amf_si **sis = sg->recovery_scope.sis;
  1030. struct amf_si_assignment *si_assignment;
  1031. amf_su_t *standby_su;
  1032. int removed = 0;
  1033. ENTER("'%s'", sg->name.value);
  1034. /*
  1035. * For each SI in the recovery scope, find a standby
  1036. * SU, then remove all 'standby SI assignment' not in
  1037. * the recovery scope.
  1038. */
  1039. while (*sis != NULL) {
  1040. standby_su = find_standby_su (*sis);
  1041. if (standby_su != NULL) {
  1042. si_assignment = amf_su_get_next_si_assignment (standby_su, NULL);
  1043. while (si_assignment != NULL) {
  1044. amf_si_t **sia;
  1045. int in_recovery_scope;
  1046. for (sia = sg->recovery_scope.sis, in_recovery_scope = 0;
  1047. *sia != NULL; sia++) {
  1048. if (name_match (&si_assignment->si->name, &(*sia)->name)) {
  1049. in_recovery_scope = 1;
  1050. }
  1051. }
  1052. /*
  1053. * The si_assignment found with standby hastate is not in the
  1054. * recovery scope. The found si_assignment will then be
  1055. * requested to be removed once.
  1056. */
  1057. if (!in_recovery_scope &&
  1058. si_assignment->requested_ha_state !=
  1059. USR_AMF_HA_STATE_REMOVED) {
  1060. amf_si_assignment_remove (si_assignment,
  1061. removed_si_assignment_callback_fn);
  1062. removed++;
  1063. }
  1064. si_assignment = amf_su_get_next_si_assignment (standby_su,
  1065. si_assignment);
  1066. }
  1067. }
  1068. sis++;
  1069. }
  1070. return removed;
  1071. }
  1072. /**
  1073. * Entry function for state 'removing standby assignments'
  1074. * @param sg
  1075. */
  1076. static void acsm_enter_removing_standby_assignments (amf_sg_t *sg)
  1077. {
  1078. ENTER("SG: %s", sg->name.value);
  1079. sg->avail_state = SG_AC_RemovingStandbyAssignments;
  1080. if (sg->saAmfSGRedundancyModel == SA_AMF_NPM_REDUNDANCY_MODEL) {
  1081. if (!remove_standby_si_assignments (sg)) {
  1082. acsm_enter_activating_standby (sg);
  1083. }
  1084. }
  1085. }
  1086. /**
  1087. * Callback function used by SI when an SI has been deactivated.
  1088. * @param si_assignment
  1089. * @param result
  1090. */
  1091. static void dependent_si_deactivated_cbfn (
  1092. struct amf_si_assignment *si_assignment, int result)
  1093. {
  1094. struct amf_sg *sg = si_assignment->su->sg;
  1095. struct amf_su **sus = sg->recovery_scope.sus;
  1096. struct amf_su *su;
  1097. ENTER ("'%s', %d", si_assignment->si->name.value, result);
  1098. /*
  1099. * If all SI assignments for all SUs in the SG are not pending,
  1100. * goto next state (TerminatingSuspected).
  1101. */
  1102. for (su = sg->su_head ; su != NULL; su = su->next) {
  1103. struct amf_si_assignment *si_assignment;
  1104. si_assignment = amf_su_get_next_si_assignment(su, NULL);
  1105. while (si_assignment != NULL) {
  1106. if (si_assignment->saAmfSISUHAState !=
  1107. si_assignment->requested_ha_state) {
  1108. goto still_wating;
  1109. }
  1110. si_assignment = amf_su_get_next_si_assignment(su,
  1111. si_assignment);
  1112. }
  1113. }
  1114. still_wating:
  1115. if (su == NULL) {
  1116. sus = si_assignment->su->sg->recovery_scope.sus;
  1117. /*
  1118. * Select next state depending on if some
  1119. * SU in the scope is needs to be terminated.
  1120. */
  1121. while (*sus != NULL) {
  1122. if (su_presense_state_is_not (*sus,
  1123. SA_AMF_PRESENCE_UNINSTANTIATED,
  1124. SA_AMF_PRESENCE_TERMINATION_FAILED,
  1125. SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
  1126. break;
  1127. }
  1128. sus++;
  1129. }
  1130. if (*sus != NULL) {
  1131. acsm_enter_terminating_suspected (sg);
  1132. } else {
  1133. acsm_enter_removing_standby_assignments (sg);
  1134. }
  1135. }
  1136. LEAVE("");
  1137. }
  1138. static void standby_su_activated_cbfn (
  1139. struct amf_si_assignment *si_assignment, int result)
  1140. {
  1141. struct amf_su **sus = si_assignment->su->sg->recovery_scope.sus;
  1142. struct amf_si **sis = si_assignment->su->sg->recovery_scope.sis;
  1143. ENTER ("'%s', %d", si_assignment->si->name.value, result);
  1144. /*
  1145. * If all SI assignments for all SIs in the scope are activated, goto next
  1146. * state.
  1147. */
  1148. while (*sis != NULL) {
  1149. if ((*sis)->assigned_sis != NULL &&
  1150. (*sis)->assigned_sis->saAmfSISUHAState != SA_AMF_HA_ACTIVE) {
  1151. break;
  1152. }
  1153. sis++;
  1154. }
  1155. if (*sis == NULL) {
  1156. acsm_enter_assigning_standby_to_spare ((*sus)->sg);
  1157. }
  1158. }
  1159. static inline int div_round (int a, int b)
  1160. {
  1161. int res;
  1162. assert (b != 0);
  1163. res = a / b;
  1164. if ((a % b) != 0)
  1165. res++;
  1166. return res;
  1167. }
  1168. static int no_su_has_presence_state (
  1169. struct amf_sg *sg, struct amf_node *node_to_start,
  1170. SaAmfPresenceStateT state)
  1171. {
  1172. struct amf_su *su;
  1173. int no_su_has_presence_state = 1;
  1174. for (su = sg->su_head; su != NULL; su = su->next) {
  1175. if (su->saAmfSUPresenceState == state) {
  1176. if (node_to_start == NULL) {
  1177. no_su_has_presence_state = 0;
  1178. break;
  1179. } else {
  1180. if (name_match(&node_to_start->name,
  1181. &su->saAmfSUHostedByNode)) {
  1182. no_su_has_presence_state = 0;
  1183. break;
  1184. }
  1185. }
  1186. }
  1187. }
  1188. return no_su_has_presence_state;
  1189. }
  1190. static int all_su_in_scope_has_presence_state (
  1191. struct amf_sg *sg, SaAmfPresenceStateT state)
  1192. {
  1193. struct amf_su **sus= sg->recovery_scope.sus;
  1194. while (*sus != NULL) {
  1195. if ((*sus)->saAmfSUPresenceState != state) {
  1196. break;
  1197. }
  1198. sus++;
  1199. }
  1200. return(*sus == NULL);
  1201. }
  1202. static int all_su_in_scope_has_either_presence_state (
  1203. amf_sg_t *sg,
  1204. SaAmfPresenceStateT state1,
  1205. SaAmfPresenceStateT state2)
  1206. {
  1207. return all_su_in_scope_has_presence_state (sg, state1) ||
  1208. all_su_in_scope_has_presence_state (sg, state2);
  1209. }
  1210. /**
  1211. * Get number of SIs protected by the specified SG.
  1212. * @param sg
  1213. *
  1214. * @return int
  1215. */
  1216. static int sg_si_count_get (struct amf_sg *sg)
  1217. {
  1218. struct amf_si *si;
  1219. int cnt = 0;
  1220. for (si = sg->application->si_head; si != NULL; si = si->next) {
  1221. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  1222. cnt += 1;
  1223. }
  1224. }
  1225. return(cnt);
  1226. }
  1227. static int amf_si_get_saAmfSINumReqActiveAssignments(struct amf_si *si)
  1228. {
  1229. struct amf_si_assignment *si_assignment = si->assigned_sis;
  1230. int number_of_req_active_assignments = 0;
  1231. for (; si_assignment != NULL; si_assignment = si_assignment->next) {
  1232. if (si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
  1233. number_of_req_active_assignments++;
  1234. }
  1235. }
  1236. return number_of_req_active_assignments;
  1237. }
  1238. static int amf_si_get_saAmfSINumReqStandbyAssignments(struct amf_si *si)
  1239. {
  1240. struct amf_si_assignment *si_assignment = si->assigned_sis;
  1241. int number_of_req_active_assignments = 0;
  1242. for (; si_assignment != NULL; si_assignment = si_assignment->next) {
  1243. if (si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
  1244. number_of_req_active_assignments++;
  1245. }
  1246. }
  1247. return number_of_req_active_assignments;
  1248. }
  1249. static int sg_assign_nm_active (struct amf_sg *sg, int su_active_assign)
  1250. {
  1251. struct amf_su *su;
  1252. struct amf_si *si;
  1253. int assigned = 0;
  1254. int assign_to_su = 0;
  1255. int total_assigned = 0;
  1256. int si_left;
  1257. int si_total;
  1258. int su_left_to_assign = su_active_assign;
  1259. ENTER("SG: %s", sg->name.value);
  1260. si_total = sg_si_count_get (sg);
  1261. si_left = si_total;
  1262. assign_to_su = div_round (si_left, su_active_assign);
  1263. if (assign_to_su > sg->saAmfSGMaxActiveSIsperSUs) {
  1264. assign_to_su = sg->saAmfSGMaxActiveSIsperSUs;
  1265. }
  1266. su = sg->su_head;
  1267. while (su != NULL && su_left_to_assign > 0) {
  1268. if (amf_su_get_saAmfSUReadinessState (su) !=
  1269. SA_AMF_READINESS_IN_SERVICE ||
  1270. amf_su_get_saAmfSUNumCurrActiveSIs (su) ==
  1271. assign_to_su ||
  1272. amf_su_get_saAmfSUNumCurrStandbySIs (su) > 0) {
  1273. su = su->next;
  1274. continue; /* Not in service */
  1275. }
  1276. si = sg->application->si_head;
  1277. assigned = 0;
  1278. assign_to_su = div_round (si_left, su_left_to_assign);
  1279. if (assign_to_su > sg->saAmfSGMaxActiveSIsperSUs) {
  1280. assign_to_su = sg->saAmfSGMaxActiveSIsperSUs;
  1281. }
  1282. while (si != NULL) {
  1283. if (name_match (&si->saAmfSIProtectedbySG, &sg->name) &&
  1284. assigned < assign_to_su &&
  1285. amf_si_get_saAmfSINumReqActiveAssignments(si) == 0) {
  1286. assigned += 1;
  1287. total_assigned += 1;
  1288. amf_su_assign_si (su, si, SA_AMF_HA_ACTIVE);
  1289. }
  1290. si = si->next;
  1291. }
  1292. su = su->next;
  1293. su_left_to_assign -= 1;
  1294. si_left -= assigned;
  1295. dprintf (" su_left_to_assign =%d, si_left=%d\n",
  1296. su_left_to_assign, si_left);
  1297. }
  1298. assert (total_assigned <= si_total);
  1299. if (total_assigned == 0) {
  1300. dprintf ("Info: No SIs assigned");
  1301. }
  1302. return total_assigned;
  1303. }
  1304. static int sg_assign_nm_standby (struct amf_sg *sg, int su_standby_assign)
  1305. {
  1306. struct amf_su *su;
  1307. struct amf_si *si;
  1308. int assigned = 0;
  1309. int assign_to_su = 0;
  1310. int total_assigned = 0;
  1311. int si_left;
  1312. int si_total;
  1313. int su_left_to_assign = su_standby_assign;
  1314. ENTER ("'%s'", sg->name.value);
  1315. if (su_standby_assign == 0) {
  1316. return 0;
  1317. }
  1318. si_total = sg_si_count_get (sg);
  1319. si_left = si_total;
  1320. assign_to_su = div_round (si_left, su_standby_assign);
  1321. if (assign_to_su > sg->saAmfSGMaxStandbySIsperSUs) {
  1322. assign_to_su = sg->saAmfSGMaxStandbySIsperSUs;
  1323. }
  1324. su = sg->su_head;
  1325. while (su != NULL && su_left_to_assign > 0) {
  1326. if (amf_su_get_saAmfSUReadinessState (su) !=
  1327. SA_AMF_READINESS_IN_SERVICE ||
  1328. amf_su_get_saAmfSUNumCurrActiveSIs (su) > 0 ||
  1329. amf_su_get_saAmfSUNumCurrStandbySIs (su) ==
  1330. assign_to_su) {
  1331. su = su->next;
  1332. continue; /* Not available for assignment */
  1333. }
  1334. si = sg->application->si_head;
  1335. assigned = 0;
  1336. assign_to_su = div_round (si_left, su_left_to_assign);
  1337. if (assign_to_su > sg->saAmfSGMaxStandbySIsperSUs) {
  1338. assign_to_su = sg->saAmfSGMaxStandbySIsperSUs;
  1339. }
  1340. while (si != NULL) {
  1341. if (name_match (&si->saAmfSIProtectedbySG, &sg->name) &&
  1342. assigned < assign_to_su &&
  1343. amf_si_get_saAmfSINumReqStandbyAssignments (si) == 0) {
  1344. assigned += 1;
  1345. total_assigned += 1;
  1346. amf_su_assign_si (su, si, SA_AMF_HA_STANDBY);
  1347. }
  1348. si = si->next;
  1349. }
  1350. su_left_to_assign -= 1;
  1351. si_left -= assigned;
  1352. dprintf (" su_left_to_assign =%d, si_left=%d\n",
  1353. su_left_to_assign, si_left);
  1354. su = su->next;
  1355. }
  1356. assert (total_assigned <= si_total);
  1357. if (total_assigned == 0) {
  1358. dprintf ("Info: No SIs assigned!");
  1359. }
  1360. return total_assigned;
  1361. }
  1362. static int su_inservice_count_get (struct amf_sg *sg)
  1363. {
  1364. struct amf_su *su;
  1365. int answer = 0;
  1366. for (su = sg->su_head; su != NULL; su = su->next) {
  1367. if (amf_su_get_saAmfSUReadinessState (su) ==
  1368. SA_AMF_READINESS_IN_SERVICE) {
  1369. answer += 1;
  1370. }
  1371. }
  1372. return(answer);
  1373. }
  1374. /**
  1375. * TODO: dependency_level not used, hard coded
  1376. * @param sg
  1377. * @param dependency_level
  1378. */
  1379. static int assign_si (struct amf_sg *sg, int dependency_level)
  1380. {
  1381. int active_sus_needed = 0;
  1382. int standby_sus_needed = 0;
  1383. int inservice_count;
  1384. int su_active_assign;
  1385. int su_standby_assign;
  1386. int su_spare_assign;
  1387. int assigned = 0;
  1388. ENTER ("'%s'", sg->name.value);
  1389. /**
  1390. * Phase 1: Calculate assignments and create all runtime objects in
  1391. * information model. Do not do the actual assignment, done in
  1392. * phase 2.
  1393. */
  1394. /**
  1395. * Calculate number of SUs to assign to active or standby state
  1396. */
  1397. inservice_count = su_inservice_count_get (sg);
  1398. if (sg->saAmfSGNumPrefActiveSUs > 0) {
  1399. active_sus_needed = div_round (
  1400. sg_si_count_get (sg),
  1401. sg->saAmfSGMaxActiveSIsperSUs);
  1402. } else {
  1403. log_printf (LOG_LEVEL_ERROR, "ERROR: saAmfSGNumPrefActiveSUs == 0 !!");
  1404. openais_exit_error (AIS_DONE_FATAL_ERR);
  1405. }
  1406. if (sg->saAmfSGNumPrefStandbySUs > 0) {
  1407. standby_sus_needed = div_round (
  1408. sg_si_count_get (sg),
  1409. sg->saAmfSGMaxStandbySIsperSUs);
  1410. } else {
  1411. log_printf (LOG_LEVEL_ERROR, "ERROR: saAmfSGNumPrefStandbySUs == 0 !!");
  1412. openais_exit_error (AIS_DONE_FATAL_ERR);
  1413. }
  1414. dprintf ("(inservice=%d) (active_sus_needed=%d) (standby_sus_needed=%d)"
  1415. "\n",
  1416. inservice_count, active_sus_needed, standby_sus_needed);
  1417. /* Determine number of active and standby service units
  1418. * to assign based upon reduction procedure
  1419. */
  1420. if ((inservice_count < active_sus_needed)) {
  1421. dprintf ("assignment VI - partial assignment with SIs drop outs\n");
  1422. su_active_assign = inservice_count;
  1423. su_standby_assign = 0;
  1424. su_spare_assign = 0;
  1425. } else
  1426. if ((inservice_count < active_sus_needed + standby_sus_needed)) {
  1427. dprintf ("assignment V - partial assignment with reduction of"
  1428. " standby units\n");
  1429. su_active_assign = active_sus_needed;
  1430. su_standby_assign = inservice_count - active_sus_needed;
  1431. su_spare_assign = 0;
  1432. } else
  1433. if ((inservice_count < sg->saAmfSGNumPrefActiveSUs + standby_sus_needed)) {
  1434. dprintf ("IV: full assignment with reduction of active service"
  1435. " units\n");
  1436. su_active_assign = inservice_count - standby_sus_needed;
  1437. su_standby_assign = standby_sus_needed;
  1438. su_spare_assign = 0;
  1439. } else
  1440. if ((inservice_count <
  1441. sg->saAmfSGNumPrefActiveSUs + sg->saAmfSGNumPrefStandbySUs)) {
  1442. dprintf ("III: full assignment with reduction of standby service"
  1443. " units\n");
  1444. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1445. su_standby_assign = inservice_count - sg->saAmfSGNumPrefActiveSUs;
  1446. su_spare_assign = 0;
  1447. } else
  1448. if ((inservice_count ==
  1449. sg->saAmfSGNumPrefActiveSUs + sg->saAmfSGNumPrefStandbySUs)) {
  1450. if (sg->saAmfSGNumPrefInserviceSUs > inservice_count) {
  1451. dprintf ("II: full assignment with spare reduction\n");
  1452. } else {
  1453. dprintf ("II: full assignment without spares\n");
  1454. }
  1455. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1456. su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
  1457. su_spare_assign = 0;
  1458. } else {
  1459. dprintf ("I: full assignment with spares\n");
  1460. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1461. su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
  1462. su_spare_assign = inservice_count -
  1463. sg->saAmfSGNumPrefActiveSUs - sg->saAmfSGNumPrefStandbySUs;
  1464. }
  1465. dprintf ("(inservice=%d) (assigning active=%d) (assigning standby=%d)"
  1466. " (assigning spares=%d)\n",
  1467. inservice_count, su_active_assign, su_standby_assign, su_spare_assign);
  1468. if (inservice_count > 0) {
  1469. assigned = sg_assign_nm_active (sg, su_active_assign);
  1470. assigned += sg_assign_nm_standby (sg, su_standby_assign);
  1471. sg->saAmfSGNumCurrAssignedSUs = inservice_count;
  1472. /**
  1473. * Phase 2: do the actual assignment to the component
  1474. * TODO: first do active, then standby
  1475. */
  1476. {
  1477. struct amf_si *si;
  1478. struct amf_si_assignment *si_assignment;
  1479. for (si = sg->application->si_head; si != NULL; si = si->next) {
  1480. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  1481. for (si_assignment = si->assigned_sis;
  1482. si_assignment != NULL;
  1483. si_assignment = si_assignment->next) {
  1484. if (si_assignment->requested_ha_state !=
  1485. si_assignment->saAmfSISUHAState) {
  1486. amf_si_ha_state_assume (
  1487. si_assignment, assign_si_assumed_cbfn);
  1488. }
  1489. }
  1490. }
  1491. }
  1492. }
  1493. }
  1494. LEAVE ("'%s'", sg->name.value);
  1495. return assigned;
  1496. }
  1497. static void remove_si_in_scope (amf_sg_t *sg, amf_si_t *si)
  1498. {
  1499. int i;
  1500. int j;
  1501. amf_si_t **sis = sg->recovery_scope.sis;
  1502. amf_si_t **new_sis = amf_calloc (1, sizeof (amf_si_t*));
  1503. for (i = 0,j = 0; sis[i] != NULL; i++) {
  1504. if (sis[i] == si) {
  1505. continue;
  1506. }
  1507. new_sis[j] = sis[i];
  1508. new_sis = amf_realloc (new_sis, j + sizeof (amf_si_t *));
  1509. j++;
  1510. }
  1511. sg->recovery_scope.sis = new_sis;
  1512. }
  1513. static void remove_sis_for_term_failed_su_from_scope (amf_sg_t *sg,
  1514. amf_su_t *su)
  1515. {
  1516. amf_comp_t *component;
  1517. /*
  1518. * foreach component with presense state termiantion failed in su
  1519. */
  1520. for (component = su->comp_head; component != NULL;
  1521. component = component->next) {
  1522. amf_csi_assignment_t *csi_assignment;
  1523. if (component->saAmfCompPresenceState !=
  1524. SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  1525. continue;
  1526. }
  1527. csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
  1528. while (csi_assignment != NULL) {
  1529. remove_si_in_scope (sg, csi_assignment->csi->si);
  1530. csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
  1531. }
  1532. }
  1533. }
  1534. int amf_sg_assign_si_req (struct amf_sg *sg, int dependency_level)
  1535. {
  1536. int posible_to_assign_si;
  1537. sg->recovery_scope.event_type = SG_ASSIGN_SI_EV;
  1538. sg->avail_state = SG_AC_AssigningOnRequest;
  1539. if ((posible_to_assign_si = assign_si (sg, dependency_level)) == 0) {
  1540. acsm_enter_idle (sg);
  1541. }
  1542. return posible_to_assign_si;
  1543. }
  1544. void amf_sg_failover_node_req (struct amf_sg *sg, struct amf_node *node)
  1545. {
  1546. ENTER("'%s, %s'",node->name.value, sg->name.value);
  1547. sg_event_t sg_event;
  1548. switch (sg->avail_state) {
  1549. case SG_AC_Idle:
  1550. set_scope_for_failover_node(sg, node);
  1551. if (has_any_su_in_scope_active_workload (sg)) {
  1552. acsm_enter_deactivating_dependent_workload (sg);
  1553. } else {
  1554. amf_su_t **sus = sg->recovery_scope.sus;
  1555. /*
  1556. * Select next state depending on if some
  1557. * SU in the scope needs to be terminated.
  1558. */
  1559. while (*sus != NULL) {
  1560. amf_su_t *su = *sus;
  1561. ENTER("SU %s pr_state='%d'",su->name.value,
  1562. su->saAmfSUPresenceState);
  1563. if (su_presense_state_is_ored (su,
  1564. SA_AMF_PRESENCE_UNINSTANTIATED,
  1565. SA_AMF_PRESENCE_TERMINATION_FAILED,
  1566. SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
  1567. sus++;
  1568. continue;
  1569. }
  1570. break;
  1571. }
  1572. if (*sus != NULL) {
  1573. acsm_enter_terminating_suspected (sg);
  1574. } else {
  1575. delete_si_assignments_in_scope (sg);
  1576. acsm_enter_idle (sg);
  1577. }
  1578. }
  1579. break;
  1580. case SG_AC_DeactivatingDependantWorkload:
  1581. case SG_AC_TerminatingSuspected:
  1582. case SG_AC_ActivatingStandby:
  1583. case SG_AC_AssigningStandbyToSpare:
  1584. case SG_AC_ReparingComponent:
  1585. case SG_AC_ReparingSu:
  1586. case SG_AC_AssigningOnRequest:
  1587. case SG_AC_InstantiatingServiceUnits:
  1588. case SG_AC_RemovingAssignment:
  1589. case SG_AC_AssigningActiveworkload:
  1590. case SG_AC_AssigningAutoAdjust:
  1591. case SG_AC_AssigningStandBy:
  1592. case SG_AC_WaitingAfterOperationFailed:
  1593. sg_set_event (SG_FAILOVER_NODE_EV, sg, 0, 0, node, &sg_event);
  1594. sg_defer_event (SG_FAILOVER_NODE_EV, &sg_event);
  1595. break;
  1596. default:
  1597. assert (0);
  1598. break;
  1599. }
  1600. }
  1601. void amf_sg_start (struct amf_sg *sg, struct amf_node *node)
  1602. {
  1603. sg_event_t sg_event;
  1604. sg->recovery_scope.event_type = SG_START_EV;
  1605. switch (sg->avail_state) {
  1606. case SG_AC_Idle: {
  1607. amf_su_t *su;
  1608. sg_avail_control_state_t old_avail_state = sg->avail_state;
  1609. int instantiated_sus = 0;
  1610. ENTER ("'%s'", sg->name.value);
  1611. sg->node_to_start = node;
  1612. sg->avail_state = SG_AC_InstantiatingServiceUnits;
  1613. for (su = sg->su_head;
  1614. (su != NULL) &&
  1615. (instantiated_sus < sg->saAmfSGNumPrefInserviceSUs);
  1616. su = su->next) {
  1617. if (node == NULL) {
  1618. /*
  1619. * Cluster start
  1620. */
  1621. amf_su_instantiate (su);
  1622. instantiated_sus++;
  1623. } else {
  1624. /*
  1625. * Node start, match if SU is hosted on the
  1626. * specified node
  1627. */
  1628. if (name_match (&node->name,
  1629. &su->saAmfSUHostedByNode)) {
  1630. amf_su_instantiate (su);
  1631. instantiated_sus++;
  1632. }
  1633. }
  1634. }
  1635. if (instantiated_sus == 0) {
  1636. sg->avail_state = old_avail_state;
  1637. }
  1638. break;
  1639. }
  1640. case SG_AC_InstantiatingServiceUnits:
  1641. sg_set_event (SG_START_EV, sg, 0, 0, node, &sg_event);
  1642. sg_defer_event (SG_START_EV, &sg_event);
  1643. break;
  1644. case SG_AC_DeactivatingDependantWorkload:
  1645. case SG_AC_TerminatingSuspected:
  1646. case SG_AC_ActivatingStandby:
  1647. case SG_AC_AssigningStandbyToSpare:
  1648. case SG_AC_ReparingComponent:
  1649. case SG_AC_ReparingSu:
  1650. case SG_AC_AssigningOnRequest:
  1651. case SG_AC_RemovingAssignment:
  1652. case SG_AC_AssigningActiveworkload:
  1653. case SG_AC_AssigningAutoAdjust:
  1654. case SG_AC_AssigningStandBy:
  1655. case SG_AC_WaitingAfterOperationFailed:
  1656. default:
  1657. assert (0);
  1658. break;
  1659. }
  1660. }
  1661. void amf_sg_su_state_changed (struct amf_sg *sg,
  1662. struct amf_su *su, SaAmfStateT type, int state)
  1663. {
  1664. ENTER ("'%s' SU '%s' state %s",
  1665. sg->name.value, su->name.value, amf_presence_state(state));
  1666. if (type == SA_AMF_PRESENCE_STATE) {
  1667. if (state == SA_AMF_PRESENCE_INSTANTIATED) {
  1668. if (sg->avail_state == SG_AC_InstantiatingServiceUnits) {
  1669. if (no_su_has_presence_state(sg, sg->node_to_start,
  1670. SA_AMF_PRESENCE_INSTANTIATING)) {
  1671. acsm_enter_idle (sg);
  1672. }
  1673. } else if (sg->avail_state == SG_AC_ReparingSu) {
  1674. if (all_su_in_scope_has_presence_state(su->sg,
  1675. SA_AMF_PRESENCE_INSTANTIATED)) {
  1676. su->sg->avail_state = SG_AC_AssigningStandBy;
  1677. if (assign_si (sg, 0) == 0) {
  1678. acsm_enter_idle (sg);
  1679. }
  1680. } else {
  1681. dprintf ("avail-state: %u", sg->avail_state);
  1682. assert (0);
  1683. }
  1684. } else {
  1685. dprintf ("avail-state: %u", sg->avail_state);
  1686. assert (0);
  1687. }
  1688. } else if (state == SA_AMF_PRESENCE_UNINSTANTIATED) {
  1689. if (sg->avail_state == SG_AC_TerminatingSuspected) {
  1690. if (all_su_in_scope_has_either_presence_state (sg,
  1691. SA_AMF_PRESENCE_UNINSTANTIATED,
  1692. SA_AMF_PRESENCE_TERMINATION_FAILED)) {
  1693. delete_si_assignments_in_scope (sg);
  1694. if (is_any_si_in_scope_assigned_stanby (sg)) {
  1695. remove_all_suspected_sus (sg);
  1696. acsm_enter_removing_standby_assignments (sg);
  1697. } else {
  1698. remove_all_suspected_sus (sg);
  1699. acsm_enter_assigning_standby_to_spare (sg);
  1700. }
  1701. }
  1702. } else {
  1703. assert (0);
  1704. }
  1705. } else if (state == SA_AMF_PRESENCE_TERMINATION_FAILED) {
  1706. if (all_su_in_scope_has_either_presence_state (sg,
  1707. SA_AMF_PRESENCE_UNINSTANTIATED,
  1708. SA_AMF_PRESENCE_TERMINATION_FAILED) &&
  1709. is_any_si_in_scope_assigned_stanby (sg)) {
  1710. remove_all_suspected_sus (sg);
  1711. acsm_enter_removing_standby_assignments (sg);
  1712. } else if (all_su_in_scope_has_either_presence_state (sg,
  1713. SA_AMF_PRESENCE_UNINSTANTIATED,
  1714. SA_AMF_PRESENCE_TERMINATION_FAILED) &&
  1715. !is_any_si_in_scope_assigned_stanby (sg)){
  1716. remove_all_suspected_sus (sg);
  1717. acsm_enter_assigning_standby_to_spare (sg);
  1718. } else {
  1719. remove_sis_for_term_failed_su_from_scope (sg, su);
  1720. }
  1721. } else if (state == SA_AMF_PRESENCE_INSTANTIATING) {
  1722. ; /* nop */
  1723. } else if (state == SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  1724. if (sg->avail_state == SG_AC_InstantiatingServiceUnits) {
  1725. if (no_su_has_presence_state(sg, sg->node_to_start,
  1726. SA_AMF_PRESENCE_INSTANTIATING)) {
  1727. acsm_enter_idle (sg);
  1728. }
  1729. }
  1730. } else {
  1731. assert (0);
  1732. }
  1733. } else {
  1734. assert (0);
  1735. }
  1736. }
  1737. void amf_sg_init (void)
  1738. {
  1739. log_init ("AMF");
  1740. }
  1741. void amf_sg_failover_su_req (struct amf_sg *sg, struct amf_su *su,
  1742. struct amf_node *node)
  1743. {
  1744. ENTER ("");
  1745. sg_event_t sg_event;
  1746. switch (sg->avail_state) {
  1747. case SG_AC_Idle:
  1748. set_scope_for_failover_su (sg, su);
  1749. if (has_any_su_in_scope_active_workload (sg)) {
  1750. acsm_enter_deactivating_dependent_workload (sg);
  1751. } else {
  1752. acsm_enter_terminating_suspected (sg);
  1753. }
  1754. break;
  1755. case SG_AC_DeactivatingDependantWorkload:
  1756. case SG_AC_TerminatingSuspected:
  1757. case SG_AC_ActivatingStandby:
  1758. case SG_AC_AssigningStandbyToSpare:
  1759. case SG_AC_ReparingComponent:
  1760. case SG_AC_ReparingSu:
  1761. case SG_AC_AssigningOnRequest:
  1762. case SG_AC_InstantiatingServiceUnits:
  1763. case SG_AC_RemovingAssignment:
  1764. case SG_AC_AssigningActiveworkload:
  1765. case SG_AC_AssigningAutoAdjust:
  1766. case SG_AC_AssigningStandBy:
  1767. case SG_AC_WaitingAfterOperationFailed:
  1768. sg_set_event (SG_FAILOVER_SU_EV, sg, su, 0, 0, &sg_event);
  1769. sg_defer_event (SG_FAILOVER_SU_EV, &sg_event);
  1770. break;
  1771. default:
  1772. assert (0);
  1773. break;
  1774. }
  1775. }
  1776. /**
  1777. * Constructor for SG objects. Adds SG to the list owned by
  1778. * the specified application. Always returns a valid SG
  1779. * object, out-of-memory problems are handled here. Default
  1780. * values are initialized.
  1781. * @param sg
  1782. * @param name
  1783. *
  1784. * @return struct amf_sg*
  1785. */
  1786. struct amf_sg *amf_sg_new (struct amf_application *app, char *name)
  1787. {
  1788. struct amf_sg *sg = amf_calloc (1, sizeof (struct amf_sg));
  1789. setSaNameT (&sg->name, name);
  1790. sg->saAmfSGAdminState = SA_AMF_ADMIN_UNLOCKED;
  1791. sg->saAmfSGNumPrefActiveSUs = 1;
  1792. sg->saAmfSGNumPrefStandbySUs = 1;
  1793. sg->saAmfSGNumPrefInserviceSUs = ~0;
  1794. sg->saAmfSGNumPrefAssignedSUs = ~0;
  1795. sg->saAmfSGCompRestartProb = -1;
  1796. sg->saAmfSGCompRestartMax = ~0;
  1797. sg->saAmfSGSuRestartProb = -1;
  1798. sg->saAmfSGSuRestartMax = ~0;
  1799. sg->saAmfSGAutoAdjustProb = -1;
  1800. sg->saAmfSGAutoRepair = SA_TRUE;
  1801. sg->application = app;
  1802. sg->next = app->sg_head;
  1803. app->sg_head = sg;
  1804. sg->deferred_events = NULL;
  1805. return sg;
  1806. }
  1807. void amf_sg_delete (struct amf_sg *sg)
  1808. {
  1809. struct amf_su *su;
  1810. for (su = sg->su_head; su != NULL;) {
  1811. struct amf_su *tmp = su;
  1812. su = su->next;
  1813. amf_su_delete (tmp);
  1814. }
  1815. free (sg);
  1816. }
  1817. void *amf_sg_serialize (struct amf_sg *sg, int *len)
  1818. {
  1819. char *buf = NULL;
  1820. int offset = 0, size = 0;
  1821. TRACE8 ("%s", sg->name.value);
  1822. buf = amf_serialize_SaNameT (buf, &size, &offset, &sg->name);
  1823. buf = amf_serialize_SaUint32T (buf, &size, &offset, sg->saAmfSGRedundancyModel);
  1824. buf = amf_serialize_SaUint32T (
  1825. buf, &size, &offset, sg->saAmfSGAutoAdjust);
  1826. buf = amf_serialize_SaUint32T (
  1827. buf, &size, &offset, sg->saAmfSGNumPrefActiveSUs);
  1828. buf = amf_serialize_SaUint32T (
  1829. buf, &size, &offset, sg->saAmfSGNumPrefStandbySUs);
  1830. buf = amf_serialize_SaUint32T (
  1831. buf, &size, &offset, sg->saAmfSGNumPrefInserviceSUs);
  1832. buf = amf_serialize_SaUint32T (
  1833. buf, &size, &offset, sg->saAmfSGNumPrefAssignedSUs);
  1834. buf = amf_serialize_SaUint32T (
  1835. buf, &size, &offset, sg->saAmfSGMaxActiveSIsperSUs);
  1836. buf = amf_serialize_SaUint32T (
  1837. buf, &size, &offset, sg->saAmfSGMaxStandbySIsperSUs);
  1838. buf = amf_serialize_SaUint32T (
  1839. buf, &size, &offset, sg->saAmfSGCompRestartProb);
  1840. buf = amf_serialize_SaUint32T (
  1841. buf, &size, &offset, sg->saAmfSGCompRestartMax);
  1842. buf = amf_serialize_SaUint32T (
  1843. buf, &size, &offset, sg->saAmfSGSuRestartProb);
  1844. buf = amf_serialize_SaUint32T (
  1845. buf, &size, &offset, sg->saAmfSGSuRestartMax);
  1846. buf = amf_serialize_SaUint32T (
  1847. buf, &size, &offset, sg->saAmfSGAutoAdjustProb);
  1848. buf = amf_serialize_SaUint32T (
  1849. buf, &size, &offset, sg->saAmfSGAutoRepair);
  1850. buf = amf_serialize_SaUint32T (
  1851. buf, &size, &offset, sg->saAmfSGAdminState);
  1852. buf = amf_serialize_SaUint32T (
  1853. buf, &size, &offset, sg->saAmfSGNumCurrAssignedSUs);
  1854. buf = amf_serialize_SaUint32T (
  1855. buf, &size, &offset, sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
  1856. buf = amf_serialize_SaUint32T (
  1857. buf, &size, &offset, sg->saAmfSGNumCurrInstantiatedSpareSUs);
  1858. buf = amf_serialize_SaStringT (
  1859. buf, &size, &offset, sg->clccli_path);
  1860. buf = amf_serialize_SaUint32T (
  1861. buf, &size, &offset, sg->avail_state);
  1862. *len = offset;
  1863. return buf;
  1864. }
  1865. struct amf_sg *amf_sg_deserialize (struct amf_application *app, char *buf)
  1866. {
  1867. char *tmp = buf;
  1868. struct amf_sg *sg = amf_sg_new (app, "");
  1869. tmp = amf_deserialize_SaNameT (tmp, &sg->name);
  1870. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGRedundancyModel);
  1871. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoAdjust);
  1872. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefActiveSUs);
  1873. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefStandbySUs);
  1874. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefInserviceSUs);
  1875. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefAssignedSUs);
  1876. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGMaxActiveSIsperSUs);
  1877. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGMaxStandbySIsperSUs);
  1878. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGCompRestartProb);
  1879. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGCompRestartMax);
  1880. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGSuRestartProb);
  1881. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGSuRestartMax);
  1882. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoAdjustProb);
  1883. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoRepair);
  1884. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAdminState);
  1885. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrAssignedSUs);
  1886. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
  1887. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrInstantiatedSpareSUs);
  1888. tmp = amf_deserialize_SaStringT (tmp, &sg->clccli_path);
  1889. tmp = amf_deserialize_SaUint32T (tmp, &sg->avail_state);
  1890. return sg;
  1891. }
  1892. struct amf_sg *amf_sg_find (struct amf_application *app, char *name)
  1893. {
  1894. struct amf_sg *sg;
  1895. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1896. if (sg->name.length == strlen(name) &&
  1897. strncmp (name, (char*)sg->name.value, sg->name.length) == 0) {
  1898. break;
  1899. }
  1900. }
  1901. return sg;
  1902. }