amfsg.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538
  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 void acsm_enter_removing_standby_assignments (amf_sg_t *sg);
  157. static void acsm_enter_assigning_standby_to_spare (amf_sg_t *sg);
  158. static const char *sg_event_type_text[] = {
  159. "Unknown",
  160. "Failover SU",
  161. "Failover node",
  162. "Failover comp",
  163. "Switchover node",
  164. "Start",
  165. "Autoadjust",
  166. "Assign SI"
  167. };
  168. typedef struct sg_event {
  169. amf_sg_event_type_t event_type;
  170. amf_sg_t *sg;
  171. amf_su_t *su;
  172. amf_comp_t *comp;
  173. amf_node_t *node;
  174. } sg_event_t;
  175. static int is_cluster_start(amf_node_t *node_to_start)
  176. {
  177. return node_to_start == NULL;
  178. }
  179. static void sg_set_event (amf_sg_event_type_t sg_event_type,
  180. amf_sg_t *sg, amf_su_t *su, amf_comp_t *comp, amf_node_t * node,
  181. sg_event_t *sg_event)
  182. {
  183. sg_event->event_type = sg_event_type;
  184. sg_event->node = node;
  185. sg_event->su = su;
  186. sg_event->comp = comp;
  187. sg_event->sg = sg;
  188. }
  189. static void sg_defer_event (amf_sg_event_type_t event_type,
  190. sg_event_t *sg_event)
  191. {
  192. ENTER("Defered event = %d", event_type);
  193. amf_fifo_put (event_type, &sg_event->sg->deferred_events,
  194. sizeof (sg_event_t),
  195. sg_event);
  196. }
  197. static void sg_recall_deferred_events (amf_sg_t *sg)
  198. {
  199. sg_event_t sg_event;
  200. ENTER ("%s", sg->name.value);
  201. if (amf_fifo_get (&sg->deferred_events, &sg_event)) {
  202. switch (sg_event.event_type) {
  203. case SG_FAILOVER_SU_EV:
  204. amf_sg_failover_su_req (sg_event.sg,
  205. sg_event.su, sg_event.node);
  206. break;
  207. case SG_FAILOVER_NODE_EV:
  208. amf_sg_failover_node_req (sg_event.sg,
  209. sg_event.node);
  210. break;
  211. case SG_FAILOVER_COMP_EV:
  212. case SG_SWITCH_OVER_NODE_EV:
  213. case SG_START_EV:
  214. case SG_AUTO_ADJUST_EV:
  215. default:
  216. dprintf("event_type = %d", sg_event.event_type);
  217. break;
  218. }
  219. }
  220. }
  221. static void timer_function_sg_recall_deferred_events (void *data)
  222. {
  223. amf_sg_t *sg = (amf_sg_t*)data;
  224. ENTER ("");
  225. sg_recall_deferred_events (sg);
  226. }
  227. static void acsm_enter_idle (amf_sg_t *sg)
  228. {
  229. SaNameT dn;
  230. ENTER ("sg: %s state: %d", sg->name.value, sg->avail_state);
  231. sg->avail_state = SG_AC_Idle;
  232. if (sg->recovery_scope.event_type != 0) {
  233. switch (sg->recovery_scope.event_type) {
  234. case SG_FAILOVER_SU_EV:
  235. assert (sg->recovery_scope.sus[0] != NULL);
  236. amf_su_dn_make (sg->recovery_scope.sus[0], &dn);
  237. log_printf (
  238. LOG_NOTICE,
  239. "'%s' %s recovery action finished",
  240. dn.value,
  241. sg_event_type_text[sg->recovery_scope.event_type]);
  242. break;
  243. case SG_FAILOVER_NODE_EV:
  244. amf_node_sg_failed_over (
  245. sg->recovery_scope.node, sg);
  246. log_printf (
  247. LOG_NOTICE,
  248. "'%s for %s' recovery action finished",
  249. sg_event_type_text[sg->recovery_scope.event_type],
  250. sg->name.value);
  251. break;
  252. case SG_START_EV:
  253. amf_application_sg_started (sg->application,
  254. sg, this_amf_node);
  255. break;
  256. case SG_ASSIGN_SI_EV:
  257. log_printf (LOG_NOTICE, "All SI assigned");
  258. break;
  259. default:
  260. log_printf (
  261. LOG_NOTICE,
  262. "'%s' recovery action finished",
  263. sg_event_type_text[sg->recovery_scope.event_type]);
  264. break;
  265. }
  266. }
  267. if (sg->recovery_scope.sus != NULL) {
  268. free ((void *)sg->recovery_scope.sus);
  269. }
  270. if (sg->recovery_scope.sis != NULL) {
  271. free ((void *)sg->recovery_scope.sis);
  272. }
  273. memset (&sg->recovery_scope, 0, sizeof (struct sg_recovery_scope));
  274. sg->node_to_start = NULL;
  275. amf_call_function_asynchronous (
  276. timer_function_sg_recall_deferred_events, sg);
  277. }
  278. static int su_instantiated_count (struct amf_sg *sg)
  279. {
  280. int cnt = 0;
  281. struct amf_su *su;
  282. for (su = sg->su_head; su != NULL; su = su->next) {
  283. if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED)
  284. cnt++;
  285. }
  286. return cnt;
  287. }
  288. static int has_any_su_in_scope_active_workload (struct amf_sg *sg)
  289. {
  290. struct amf_su **sus= sg->recovery_scope.sus;
  291. struct amf_si_assignment *si_assignment;
  292. while (*sus != NULL) {
  293. si_assignment = amf_su_get_next_si_assignment (*sus, NULL);
  294. while (si_assignment != NULL) {
  295. if (si_assignment->saAmfSISUHAState !=
  296. SA_AMF_HA_ACTIVE) {
  297. break;
  298. }
  299. si_assignment = amf_su_get_next_si_assignment (
  300. *sus, si_assignment);
  301. }
  302. if (si_assignment != NULL) {
  303. break;
  304. }
  305. sus++;
  306. }
  307. return(*sus == NULL);
  308. }
  309. static int is_any_si_in_scope_assigned_standby (struct amf_sg *sg)
  310. {
  311. struct amf_si **sis= sg->recovery_scope.sis;
  312. struct amf_si_assignment *si_assignment;
  313. /*
  314. * Check if there is any si in the scope which has no
  315. * active assignment and at least one standby assignment.
  316. */
  317. while (*sis != NULL) {
  318. si_assignment = (*sis)->assigned_sis;
  319. while (si_assignment != NULL) {
  320. if (si_assignment->saAmfSISUHAState ==
  321. SA_AMF_HA_ACTIVE) {
  322. break;
  323. }
  324. si_assignment = si_assignment->next;
  325. }
  326. if (si_assignment == NULL) {
  327. /* There is no ACTIVE assignment ..*/
  328. si_assignment = (*sis)->assigned_sis;
  329. while (si_assignment != NULL) {
  330. if (si_assignment->saAmfSISUHAState ==
  331. SA_AMF_HA_STANDBY) {
  332. break;
  333. }
  334. si_assignment = si_assignment->next;
  335. }
  336. if (si_assignment != NULL) {
  337. /* .. and one STANDBY assignment*/
  338. break;
  339. }
  340. }
  341. sis++;
  342. }
  343. return(*sis != NULL);
  344. }
  345. static void acsm_enter_terminating_suspected (struct amf_sg *sg)
  346. {
  347. struct amf_su **sus= sg->recovery_scope.sus;
  348. ENTER("%s",sg->name.value);
  349. sg->avail_state = SG_AC_TerminatingSuspected;
  350. /*
  351. * Terminate suspected SU(s)
  352. */
  353. while (*sus != 0) {
  354. amf_su_terminate (*sus);
  355. sus++;
  356. }
  357. }
  358. static inline int su_presense_state_is_ored (amf_su_t *su,
  359. SaAmfPresenceStateT state1,SaAmfPresenceStateT state2,
  360. SaAmfPresenceStateT state3)
  361. {
  362. return(su->saAmfSUPresenceState == state1 || su->saAmfSUPresenceState ==
  363. state2 || su->saAmfSUPresenceState == state3) ? 1 : 0;
  364. }
  365. static inline int su_presense_state_is_not (amf_su_t *su,
  366. SaAmfPresenceStateT state1,SaAmfPresenceStateT state2,
  367. SaAmfPresenceStateT state3)
  368. {
  369. return(su->saAmfSUPresenceState != state1 && su->saAmfSUPresenceState !=
  370. state2 && su->saAmfSUPresenceState != state3) ? 1 : 0;
  371. }
  372. /**
  373. * Callback function used by SI when there is no dependent SI to
  374. * deactivate.
  375. * @param sg
  376. */
  377. static void dependent_si_deactivated_cbfn2 (struct amf_sg *sg)
  378. {
  379. struct amf_su **sus = sg->recovery_scope.sus;
  380. ENTER("'%s'", sg->name.value);
  381. /*
  382. * Select next state depending on if some
  383. * SU in the scope is needs to be terminated.
  384. */
  385. while (*sus != NULL) {
  386. amf_su_t *su = *sus;
  387. ENTER("SU %s pr_state='%d'",su->name.value,
  388. su->saAmfSUPresenceState);
  389. if (su_presense_state_is_ored (su,
  390. SA_AMF_PRESENCE_UNINSTANTIATED,
  391. SA_AMF_PRESENCE_TERMINATION_FAILED,
  392. SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
  393. sus++;
  394. continue;
  395. }
  396. break;
  397. }
  398. if (*sus != NULL) {
  399. acsm_enter_terminating_suspected (sg);
  400. } else {
  401. delete_si_assignments_in_scope(sg);
  402. acsm_enter_removing_standby_assignments (sg);
  403. }
  404. }
  405. static void timer_function_dependent_si_deactivated2 (void *data)
  406. {
  407. amf_sg_t *sg = (amf_sg_t *)data;
  408. ENTER ("");
  409. dependent_si_deactivated_cbfn2 (sg);
  410. }
  411. static struct amf_si *si_get_dependent (struct amf_si *si)
  412. {
  413. struct amf_si *tmp_si = NULL;
  414. if (si->depends_on != NULL) {
  415. SaNameT res_arr[2];
  416. int is_match;
  417. if (si->depends_on->name.length < SA_MAX_NAME_LENGTH) {
  418. si->depends_on->name.value[si->depends_on->name.length] = '\0';
  419. }
  420. is_match = sa_amf_grep ((char*)si->depends_on->name.value,
  421. "safDepend=.*,safSi=(.*),safApp=.*",
  422. 2, res_arr);
  423. if (is_match) {
  424. tmp_si = amf_si_find (si->application, (char*)res_arr[1].value);
  425. } else {
  426. log_printf (LOG_LEVEL_ERROR, "distinguished name for "
  427. "amf_si_depedency failed\n");
  428. openais_exit_error (AIS_DONE_FATAL_ERR);
  429. }
  430. }
  431. return tmp_si;
  432. }
  433. static struct amf_si *amf_dependent_get_next (struct amf_si *si,
  434. struct amf_si *si_iter)
  435. {
  436. struct amf_si *tmp_si;
  437. struct amf_application *application;
  438. if (si_iter == NULL) {
  439. assert(amf_cluster != NULL);
  440. application = amf_cluster->application_head;
  441. assert(application != NULL);
  442. tmp_si = application->si_head;
  443. } else {
  444. tmp_si = si_iter->next;
  445. if (tmp_si == NULL) {
  446. application = si->application->next;
  447. if (application == NULL) {
  448. goto out;
  449. }
  450. }
  451. }
  452. for (; tmp_si != NULL; tmp_si = tmp_si->next) {
  453. struct amf_si *depends_on_si = si_get_dependent (tmp_si);
  454. while (depends_on_si != NULL) {
  455. if (depends_on_si == si) {
  456. goto out;
  457. }
  458. depends_on_si = depends_on_si->next;
  459. }
  460. }
  461. out:
  462. return tmp_si;
  463. }
  464. static void acsm_enter_deactivating_dependent_workload (amf_sg_t *sg)
  465. {
  466. struct amf_si **sis= sg->recovery_scope.sis;
  467. struct amf_si_assignment *si_assignment;
  468. int callback_pending = 0;
  469. sg->avail_state = SG_AC_DeactivatingDependantWorkload;
  470. ENTER("'%s'",sg->name.value);
  471. /*
  472. * For each SI in the recovery scope, find all active
  473. * assignments and request them to be deactivated.
  474. */
  475. while (*sis != NULL) {
  476. struct amf_si *dependent_si;
  477. struct amf_si *si = *sis;
  478. si_assignment = si->assigned_sis;
  479. dependent_si = amf_dependent_get_next (si, NULL);
  480. while (dependent_si != NULL) {
  481. si_assignment = dependent_si->assigned_sis;
  482. while (si_assignment != NULL) {
  483. if (si_assignment->saAmfSISUHAState ==
  484. SA_AMF_HA_ACTIVE) {
  485. si_assignment->requested_ha_state =
  486. SA_AMF_HA_QUIESCED;
  487. callback_pending = 1;
  488. amf_si_ha_state_assume (
  489. si_assignment,
  490. dependent_si_deactivated_cbfn);
  491. }
  492. si_assignment = si_assignment->next;
  493. }
  494. dependent_si = amf_dependent_get_next (si, dependent_si);
  495. }
  496. sis++;
  497. }
  498. if (callback_pending == 0) {
  499. static poll_timer_handle dependent_si_deactivated_handle;
  500. ENTER("");
  501. poll_timer_add (aisexec_poll_handle, 0, sg,
  502. timer_function_dependent_si_deactivated2,
  503. &dependent_si_deactivated_handle);
  504. }
  505. }
  506. /**
  507. * Enter function for state SG_AC_ActivatingStandby. It activates
  508. * one STANDBY assignment for each SI in the recovery scope.
  509. * @param sg
  510. */
  511. static void acsm_enter_activating_standby (struct amf_sg *sg)
  512. {
  513. struct amf_si **sis= sg->recovery_scope.sis;
  514. struct amf_si_assignment *si_assignment;
  515. int is_no_standby_activated = 1;
  516. ENTER("'%s'",sg->name.value);
  517. sg->avail_state = SG_AC_ActivatingStandby;
  518. /*
  519. * For each SI in the recovery scope, find one standby
  520. * SI assignment and activate it.
  521. */
  522. while (*sis != NULL) {
  523. si_assignment = (*sis)->assigned_sis;
  524. while (si_assignment != NULL) {
  525. if (si_assignment->saAmfSISUHAState ==
  526. SA_AMF_HA_STANDBY) {
  527. si_assignment->requested_ha_state =
  528. SA_AMF_HA_ACTIVE;
  529. amf_si_ha_state_assume (
  530. si_assignment, standby_su_activated_cbfn);
  531. is_no_standby_activated = 0;
  532. break;
  533. }
  534. si_assignment = si_assignment->next;
  535. }
  536. sis++;
  537. }
  538. if (is_no_standby_activated) {
  539. acsm_enter_assigning_standby_to_spare (sg);
  540. }
  541. }
  542. static void acsm_enter_repairing_su (struct amf_sg *sg)
  543. {
  544. struct amf_su **sus= sg->recovery_scope.sus;
  545. int is_any_su_instantiated = 0;
  546. const int PERFORMS_INSTANTIATING = 1;
  547. ENTER("'%s'",sg->name.value);
  548. sg->avail_state = SG_AC_ReparingSu;
  549. /*
  550. * Instantiate SUs in current recovery scope until the configured
  551. * preference is fulfiled.
  552. */
  553. while (*sus != NULL) {
  554. if (su_instantiated_count ((*sus)->sg) <
  555. (*sus)->sg->saAmfSGNumPrefInserviceSUs) {
  556. struct amf_node *node =
  557. amf_node_find(&((*sus)->saAmfSUHostedByNode));
  558. if (node == NULL) {
  559. log_printf (LOG_LEVEL_ERROR,
  560. "Su to recover not hosted on any node\n");
  561. openais_exit_error (AIS_DONE_FATAL_ERR);
  562. }
  563. if (node->saAmfNodeOperState == SA_AMF_OPERATIONAL_ENABLED) {
  564. /* node is synchronized */
  565. if (amf_su_instantiate ((*sus)) == PERFORMS_INSTANTIATING) {
  566. is_any_su_instantiated = 1;
  567. }
  568. }
  569. }
  570. sus++;
  571. }
  572. if (is_any_su_instantiated == 0) {
  573. acsm_enter_idle (sg);
  574. }
  575. }
  576. static inline void remove_all_suspected_sus (amf_sg_t *sg)
  577. {
  578. amf_su_t *su;
  579. ENTER("");
  580. for (su = sg->su_head; su != NULL; su =su->next) {
  581. amf_comp_t *component;
  582. for (component = su->comp_head; component != NULL;
  583. component = component->next) {
  584. amf_comp_error_suspected_clear (component);
  585. }
  586. }
  587. }
  588. static int is_all_si_assigned (amf_sg_t *sg)
  589. {
  590. struct amf_si_assignment *si_assignment;
  591. int si_assignment_cnt = 0;
  592. int confirmed_assignments = 0;
  593. amf_si_t *si;
  594. for (si = sg->application->si_head; si != NULL; si = si->next) {
  595. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  596. for (si_assignment = si->assigned_sis;
  597. si_assignment != NULL;
  598. si_assignment = si_assignment->next) {
  599. si_assignment_cnt++;
  600. if (si_assignment->requested_ha_state ==
  601. si_assignment->saAmfSISUHAState) {
  602. confirmed_assignments++;
  603. }
  604. }
  605. }
  606. }
  607. return (confirmed_assignments == si_assignment_cnt);
  608. }
  609. static void assign_si_assumed_cbfn (
  610. struct amf_si_assignment *si_assignment, int result)
  611. {
  612. struct amf_sg *sg = si_assignment->su->sg;
  613. int si_assignment_cnt = 0;
  614. int confirmed_assignments = 0;
  615. ENTER ("'%s', %d", si_assignment->si->name.value, result);
  616. switch (sg->avail_state) {
  617. case SG_AC_AssigningOnRequest:
  618. if (is_all_si_assigned (sg)) {
  619. acsm_enter_idle (sg);
  620. amf_application_sg_assigned (sg->application, sg);
  621. } else {
  622. dprintf ("%d, %d", si_assignment_cnt, confirmed_assignments);
  623. }
  624. break;
  625. case SG_AC_AssigningStandBy:
  626. {
  627. if (is_all_si_assigned(sg)) {
  628. acsm_enter_idle (sg);
  629. }
  630. break;
  631. }
  632. case SG_AC_AssigningStandbyToSpare:
  633. {
  634. if(is_all_si_assigned (sg)) {
  635. /*
  636. * All si_assignments has asumed
  637. * Prescense state SA_AMF_HA_STANDBY
  638. */
  639. switch (sg->recovery_scope.event_type) {
  640. case SG_FAILOVER_NODE_EV:
  641. acsm_enter_idle (sg);
  642. break;
  643. case SG_FAILOVER_SU_EV:
  644. if (sg->saAmfSGAutoRepair == SA_TRUE) {
  645. acsm_enter_repairing_su (sg);
  646. }
  647. break;
  648. default:
  649. assert (0);
  650. break;
  651. }
  652. } else {
  653. si_assignment->saAmfSISUHAState = SA_AMF_HA_STANDBY;
  654. }
  655. }
  656. break;
  657. default:
  658. dprintf ("%d, %d, %d", sg->avail_state, si_assignment_cnt,
  659. confirmed_assignments);
  660. amf_runtime_attributes_print (amf_cluster);
  661. assert (0);
  662. break;
  663. }
  664. }
  665. /**
  666. * Inquire if SI is assigned to SU
  667. * @param si
  668. * @param su
  669. *
  670. * @return int
  671. */
  672. static int is_si_assigned_to_su (amf_si_t *si, amf_su_t *su)
  673. {
  674. amf_si_assignment_t *si_assignment = 0;
  675. int si_assignment_assigned_to_su = 0;
  676. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  677. si_assignment = si_assignment->next) {
  678. if (si_assignment->su == su) {
  679. si_assignment_assigned_to_su = 1;
  680. break;
  681. }
  682. }
  683. return si_assignment_assigned_to_su;
  684. }
  685. /**
  686. * Inquire if SU is a spare.
  687. * @param sg
  688. * @param su
  689. *
  690. * @return int
  691. */
  692. static int is_spare_su (amf_sg_t *sg, amf_su_t *su)
  693. {
  694. amf_si_t *si;
  695. int spare_su = 1;
  696. for (si = sg->application->si_head; si != NULL; si = si->next) {
  697. if(name_match(&sg->name, &si->saAmfSIProtectedbySG)) {
  698. if (is_si_assigned_to_su (si, su)) {
  699. spare_su = 0;
  700. break;
  701. }
  702. }
  703. }
  704. return (spare_su && su->saAmfSUPresenceState ==
  705. SA_AMF_PRESENCE_INSTANTIATED);
  706. }
  707. /**
  708. * Inqure if it is any spare SUs covered by SG
  709. * @param sg
  710. *
  711. * @return int
  712. */
  713. static int is_spare_sus (amf_sg_t *sg)
  714. {
  715. amf_su_t *su = NULL;
  716. int spare_sus = 0;
  717. for (su = sg->su_head; su != NULL; su = su->next) {
  718. if (is_spare_su(sg, su)) {
  719. spare_sus = 1;
  720. break;
  721. }
  722. }
  723. return spare_sus;
  724. }
  725. /**
  726. * Provide standby assignments for the spare SUs in SG
  727. * @param sg
  728. */
  729. static void assume_standby_si_assignment_for_spare_sus (amf_sg_t *sg)
  730. {
  731. ENTER("");
  732. assign_si (sg, 0);
  733. }
  734. /**
  735. * Enter the AssigningStandbyToSpare state.
  736. * @param sg
  737. */
  738. static void acsm_enter_assigning_standby_to_spare (amf_sg_t *sg)
  739. {
  740. ENTER("%s", sg->name.value);
  741. sg->avail_state = SG_AC_AssigningStandbyToSpare;
  742. if (is_spare_sus (sg)) {
  743. assume_standby_si_assignment_for_spare_sus (sg);
  744. } else {
  745. switch (sg->recovery_scope.event_type) {
  746. case SG_FAILOVER_NODE_EV:
  747. acsm_enter_idle (sg);
  748. break;
  749. case SG_FAILOVER_SU_EV:
  750. acsm_enter_repairing_su (sg);
  751. break;
  752. default:
  753. dprintf("event_type %d",sg->recovery_scope.event_type);
  754. assert (0);
  755. break;
  756. }
  757. }
  758. }
  759. /**
  760. * Checks if the si pointed out is already in the scope.
  761. * @param sg
  762. * @param si
  763. */
  764. static int is_si_in_scope(struct amf_sg *sg, struct amf_si *si)
  765. {
  766. struct amf_si **tmp_sis= sg->recovery_scope.sis;
  767. while (*tmp_sis != NULL) {
  768. if (*tmp_sis == si) {
  769. break;
  770. }
  771. tmp_sis++;
  772. }
  773. return(*tmp_sis == si);
  774. }
  775. /**
  776. * Adds the si pointed out to the scope.
  777. * @param sg
  778. * @param si
  779. */
  780. static void add_si_to_scope ( struct amf_sg *sg, struct amf_si *si)
  781. {
  782. int number_of_si = 2; /* It shall be at least two */
  783. struct amf_si **tmp_sis= sg->recovery_scope.sis;
  784. ENTER ("'%s'", si->name.value);
  785. while (*tmp_sis != NULL) {
  786. number_of_si++;
  787. tmp_sis++;
  788. }
  789. sg->recovery_scope.sis = (struct amf_si **)
  790. realloc((void *)sg->recovery_scope.sis,
  791. sizeof (struct amf_si *)*number_of_si);
  792. assert (sg->recovery_scope.sis != NULL);
  793. tmp_sis= sg->recovery_scope.sis;
  794. while (*tmp_sis != NULL) {
  795. tmp_sis++;
  796. }
  797. *tmp_sis = si;
  798. *(++tmp_sis) = NULL;
  799. }
  800. /**
  801. * Adds the ssu pointed out to the scope.
  802. * @param sg
  803. * @param su
  804. */
  805. static void add_su_to_scope (struct amf_sg *sg, struct amf_su *su)
  806. {
  807. int number_of_su = 2; /* It shall be at least two */
  808. struct amf_su **tmp_sus= sg->recovery_scope.sus;
  809. ENTER ("'%s'", su->name.value);
  810. while (*tmp_sus != NULL) {
  811. number_of_su++;
  812. tmp_sus++;
  813. }
  814. sg->recovery_scope.sus = (struct amf_su **)
  815. realloc((void *)sg->recovery_scope.sus,
  816. sizeof (struct amf_su *)*number_of_su);
  817. assert (sg->recovery_scope.sus != NULL);
  818. tmp_sus= sg->recovery_scope.sus;
  819. while (*tmp_sus != NULL) {
  820. tmp_sus++;
  821. }
  822. *tmp_sus = su;
  823. *(++tmp_sus) = NULL;
  824. }
  825. /**
  826. * Set recovery scope for failover SU.
  827. * @param sg
  828. * @param su
  829. */
  830. static void set_scope_for_failover_su (struct amf_sg *sg, struct amf_su *su)
  831. {
  832. struct amf_si_assignment *si_assignment;
  833. struct amf_si **sis;
  834. struct amf_su **sus;
  835. SaNameT dn;
  836. sg->recovery_scope.event_type = SG_FAILOVER_SU_EV;
  837. sg->recovery_scope.node = NULL;
  838. sg->recovery_scope.comp = NULL;
  839. sg->recovery_scope.sus = (struct amf_su **)
  840. calloc (2, sizeof (struct amf_su *));
  841. sg->recovery_scope.sis = (struct amf_si **)
  842. calloc (1, sizeof (struct amf_si *));
  843. assert ((sg->recovery_scope.sus != NULL) &&
  844. (sg->recovery_scope.sis != NULL));
  845. sg->recovery_scope.sus[0] = su;
  846. amf_su_dn_make (sg->recovery_scope.sus[0], &dn);
  847. log_printf (
  848. LOG_NOTICE, "'%s' for %s recovery action started",
  849. sg_event_type_text[sg->recovery_scope.event_type],
  850. dn.value);
  851. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  852. while (si_assignment != NULL) {
  853. if (is_si_in_scope(sg, si_assignment->si) == 0) {
  854. add_si_to_scope(sg,si_assignment->si );
  855. }
  856. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  857. }
  858. sus = sg->recovery_scope.sus;
  859. dprintf("The following sus are within the scope:\n");
  860. while (*sus != NULL) {
  861. dprintf("%s\n", (*sus)->name.value);
  862. sus++;
  863. }
  864. sis= sg->recovery_scope.sis;
  865. dprintf("The following sis are within the scope:\n");
  866. while (*sis != NULL) {
  867. dprintf("%s\n", (*sis)->name.value);
  868. sis++;
  869. }
  870. }
  871. static void set_scope_for_failover_node (struct amf_sg *sg, struct amf_node *node)
  872. {
  873. struct amf_si_assignment *si_assignment;
  874. struct amf_si **sis;
  875. struct amf_su **sus;
  876. struct amf_su *su;
  877. ENTER ("'%s'", node->name.value);
  878. sg->recovery_scope.event_type = SG_FAILOVER_NODE_EV;
  879. sg->recovery_scope.node = node;
  880. sg->recovery_scope.comp = NULL;
  881. sg->recovery_scope.sus = (struct amf_su **)
  882. calloc (1, sizeof (struct amf_su *));
  883. sg->recovery_scope.sis = (struct amf_si **)
  884. calloc (1, sizeof (struct amf_si *));
  885. log_printf (
  886. LOG_NOTICE, "'%s' for node %s recovery action started",
  887. sg_event_type_text[sg->recovery_scope.event_type],
  888. node->name.value);
  889. assert ((sg->recovery_scope.sus != NULL) &&
  890. (sg->recovery_scope.sis != NULL));
  891. for (su = sg->su_head; su != NULL; su = su->next) {
  892. if (name_match (&node->name, &su->saAmfSUHostedByNode)) {
  893. add_su_to_scope (sg, su);
  894. }
  895. }
  896. sus = sg->recovery_scope.sus;
  897. while (*sus != 0) {
  898. su = *sus;
  899. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  900. while (si_assignment != NULL) {
  901. if (is_si_in_scope(sg, si_assignment->si) == 0) {
  902. add_si_to_scope(sg, si_assignment->si );
  903. }
  904. si_assignment = amf_su_get_next_si_assignment (
  905. su, si_assignment);
  906. }
  907. sus++;
  908. }
  909. sus = sg->recovery_scope.sus;
  910. dprintf("The following sus are within the scope:\n");
  911. while (*sus != NULL) {
  912. dprintf("%s\n", (*sus)->name.value);
  913. sus++;
  914. }
  915. sis = sg->recovery_scope.sis;
  916. dprintf("The following sis are within the scope:\n");
  917. while (*sis != NULL) {
  918. dprintf("%s\n", (*sis)->name.value);
  919. sis++;
  920. }
  921. }
  922. static void delete_si_assignment (amf_si_assignment_t *si_assignment)
  923. {
  924. amf_csi_t *csi;
  925. amf_si_assignment_t *si_assignment_tmp;
  926. amf_si_assignment_t **prev = &si_assignment->si->assigned_sis;
  927. for (csi = si_assignment->si->csi_head; csi != NULL; csi = csi->next) {
  928. amf_csi_delete_assignments (csi, si_assignment->su);
  929. }
  930. for (si_assignment_tmp = si_assignment->si->assigned_sis;
  931. si_assignment_tmp != NULL;
  932. si_assignment_tmp = si_assignment_tmp->next) {
  933. if (si_assignment_tmp == si_assignment) {
  934. amf_si_assignment_t *to_be_removed = si_assignment_tmp;
  935. *prev = si_assignment_tmp->next;
  936. dprintf ("SI assignment %s unlinked",
  937. to_be_removed->name.value);
  938. free (to_be_removed);
  939. } else {
  940. prev = &si_assignment_tmp->next;
  941. }
  942. }
  943. }
  944. /**
  945. * Delete all SI assignments and all CSI assignments
  946. * by requesting all contained components.
  947. * @param su
  948. */
  949. static void delete_si_assignments (struct amf_su *su)
  950. {
  951. struct amf_csi *csi;
  952. struct amf_si *si;
  953. struct amf_si_assignment *si_assignment;
  954. struct amf_si_assignment **prev;
  955. ENTER ("'%s'", su->name.value);
  956. for (si = su->sg->application->si_head; si != NULL; si = si->next) {
  957. prev = &si->assigned_sis;
  958. if (!name_match (&si->saAmfSIProtectedbySG, &su->sg->name)) {
  959. continue;
  960. }
  961. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  962. amf_csi_delete_assignments (csi, su);
  963. }
  964. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  965. si_assignment = si_assignment->next) {
  966. if (si_assignment->su == su) {
  967. struct amf_si_assignment *tmp = si_assignment;
  968. *prev = si_assignment->next;
  969. dprintf ("SI assignment %s unlinked", tmp->name.value);
  970. free (tmp);
  971. } else {
  972. prev = &si_assignment->next;
  973. }
  974. }
  975. }
  976. }
  977. /**
  978. * Delete all SI assignments and all CSI assignments in current
  979. * recovery scope.
  980. * @param sg
  981. */
  982. static void delete_si_assignments_in_scope (struct amf_sg *sg)
  983. {
  984. struct amf_su **sus= sg->recovery_scope.sus;
  985. while (*sus != NULL) {
  986. delete_si_assignments (*sus);
  987. sus++;
  988. }
  989. }
  990. /**
  991. * Given an SI, find and return the SU assigned as standby
  992. * @param si
  993. *
  994. * @return amf_su_t*
  995. */
  996. static amf_su_t *find_standby_su (amf_si_t *si)
  997. {
  998. amf_si_assignment_t *si_assignment;
  999. amf_su_t *standby_su = NULL;
  1000. si_assignment = si->assigned_sis;
  1001. while (si_assignment != NULL) {
  1002. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  1003. standby_su = si_assignment->su;
  1004. break;
  1005. }
  1006. si_assignment = si_assignment->next;
  1007. }
  1008. return standby_su;
  1009. }
  1010. static int no_si_assignment_is_requested_to_be_removed (amf_sg_t *sg)
  1011. {
  1012. amf_si_t *si;
  1013. int no_to_be_removed = 1;
  1014. for (si = sg->application->si_head; si != NULL; si = si->next) {
  1015. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  1016. amf_si_assignment_t *si_assignment = 0;
  1017. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  1018. si_assignment = si_assignment->next) {
  1019. if (si_assignment->requested_ha_state ==
  1020. USR_AMF_HA_STATE_REMOVED) {
  1021. no_to_be_removed = 0;
  1022. goto out;
  1023. }
  1024. }
  1025. }
  1026. }
  1027. out:
  1028. return no_to_be_removed;
  1029. }
  1030. static void removed_si_assignment_callback_fn (void *si_assignment_in)
  1031. {
  1032. amf_si_assignment_t *si_assignment = si_assignment_in;
  1033. ENTER("");
  1034. delete_si_assignment (si_assignment);
  1035. /*
  1036. * if all si assignments are remove then change state
  1037. */
  1038. if (no_si_assignment_is_requested_to_be_removed (si_assignment->su->sg)) {
  1039. acsm_enter_activating_standby (si_assignment->su->sg);
  1040. }
  1041. }
  1042. /**
  1043. *
  1044. * @param sg
  1045. *
  1046. * @return int, number of removed SI assignments
  1047. */
  1048. static int remove_standby_si_assignments (amf_sg_t *sg)
  1049. {
  1050. struct amf_si **sis = sg->recovery_scope.sis;
  1051. struct amf_si_assignment *si_assignment;
  1052. amf_su_t *standby_su;
  1053. int removed = 0;
  1054. ENTER("'%s'", sg->name.value);
  1055. /*
  1056. * For each SI in the recovery scope, find a standby
  1057. * SU, then remove all 'standby SI assignment' not in
  1058. * the recovery scope.
  1059. */
  1060. while (*sis != NULL) {
  1061. standby_su = find_standby_su (*sis);
  1062. if (standby_su != NULL) {
  1063. si_assignment = amf_su_get_next_si_assignment (standby_su, NULL);
  1064. while (si_assignment != NULL) {
  1065. amf_si_t **sia;
  1066. int in_recovery_scope;
  1067. for (sia = sg->recovery_scope.sis, in_recovery_scope = 0;
  1068. *sia != NULL; sia++) {
  1069. if (name_match (&si_assignment->si->name, &(*sia)->name)) {
  1070. in_recovery_scope = 1;
  1071. }
  1072. }
  1073. /*
  1074. * The si_assignment found with standby hastate is not in the
  1075. * recovery scope. The found si_assignment will then be
  1076. * requested to be removed once.
  1077. */
  1078. if (!in_recovery_scope &&
  1079. si_assignment->requested_ha_state !=
  1080. USR_AMF_HA_STATE_REMOVED) {
  1081. amf_si_assignment_remove (si_assignment,
  1082. removed_si_assignment_callback_fn);
  1083. removed++;
  1084. }
  1085. si_assignment = amf_su_get_next_si_assignment (standby_su,
  1086. si_assignment);
  1087. }
  1088. }
  1089. sis++;
  1090. }
  1091. return removed;
  1092. }
  1093. /**
  1094. * Entry function for state 'removing standby assignments'
  1095. * @param sg
  1096. */
  1097. static void acsm_enter_removing_standby_assignments (amf_sg_t *sg)
  1098. {
  1099. ENTER("SG: %s", sg->name.value);
  1100. sg->avail_state = SG_AC_RemovingStandbyAssignments;
  1101. if (sg->saAmfSGRedundancyModel == SA_AMF_NPM_REDUNDANCY_MODEL) {
  1102. if (!remove_standby_si_assignments (sg)) {
  1103. acsm_enter_activating_standby (sg);
  1104. }
  1105. }
  1106. }
  1107. /**
  1108. * Callback function used by SI when an SI has been deactivated.
  1109. * @param si_assignment
  1110. * @param result
  1111. */
  1112. static void dependent_si_deactivated_cbfn (
  1113. struct amf_si_assignment *si_assignment, int result)
  1114. {
  1115. struct amf_sg *sg = si_assignment->su->sg;
  1116. struct amf_su **sus = sg->recovery_scope.sus;
  1117. struct amf_su *su;
  1118. ENTER ("'%s', %d", si_assignment->si->name.value, result);
  1119. /*
  1120. * If all SI assignments for all SUs in the SG are not pending,
  1121. * goto next state (TerminatingSuspected).
  1122. */
  1123. for (su = sg->su_head ; su != NULL; su = su->next) {
  1124. struct amf_si_assignment *si_assignment;
  1125. si_assignment = amf_su_get_next_si_assignment(su, NULL);
  1126. while (si_assignment != NULL) {
  1127. if (si_assignment->saAmfSISUHAState !=
  1128. si_assignment->requested_ha_state) {
  1129. goto still_wating;
  1130. }
  1131. si_assignment = amf_su_get_next_si_assignment(su,
  1132. si_assignment);
  1133. }
  1134. }
  1135. still_wating:
  1136. if (su == NULL) {
  1137. sus = si_assignment->su->sg->recovery_scope.sus;
  1138. /*
  1139. * Select next state depending on if some
  1140. * SU in the scope is needs to be terminated.
  1141. */
  1142. while (*sus != NULL) {
  1143. if (su_presense_state_is_not (*sus,
  1144. SA_AMF_PRESENCE_UNINSTANTIATED,
  1145. SA_AMF_PRESENCE_TERMINATION_FAILED,
  1146. SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
  1147. break;
  1148. }
  1149. sus++;
  1150. }
  1151. if (*sus != NULL) {
  1152. acsm_enter_terminating_suspected (sg);
  1153. } else {
  1154. acsm_enter_removing_standby_assignments (sg);
  1155. }
  1156. }
  1157. LEAVE("");
  1158. }
  1159. static void standby_su_activated_cbfn (
  1160. struct amf_si_assignment *si_assignment, int result)
  1161. {
  1162. struct amf_su **sus = si_assignment->su->sg->recovery_scope.sus;
  1163. struct amf_si **sis = si_assignment->su->sg->recovery_scope.sis;
  1164. ENTER ("'%s', %d", si_assignment->si->name.value, result);
  1165. /*
  1166. * If all SI assignments for all SIs in the scope are activated, goto next
  1167. * state.
  1168. */
  1169. while (*sis != NULL) {
  1170. if ((*sis)->assigned_sis != NULL &&
  1171. (*sis)->assigned_sis->saAmfSISUHAState != SA_AMF_HA_ACTIVE) {
  1172. break;
  1173. }
  1174. sis++;
  1175. }
  1176. if (*sis == NULL) {
  1177. acsm_enter_assigning_standby_to_spare ((*sus)->sg);
  1178. }
  1179. }
  1180. static inline int div_round (int a, int b)
  1181. {
  1182. int res;
  1183. assert (b != 0);
  1184. res = a / b;
  1185. if ((a % b) != 0)
  1186. res++;
  1187. return res;
  1188. }
  1189. static int no_su_has_presence_state (
  1190. struct amf_sg *sg, struct amf_node *node_to_start,
  1191. SaAmfPresenceStateT state)
  1192. {
  1193. struct amf_su *su;
  1194. int no_su_has_presence_state = 1;
  1195. for (su = sg->su_head; su != NULL; su = su->next) {
  1196. if (su->saAmfSUPresenceState == state) {
  1197. if (node_to_start == NULL) {
  1198. no_su_has_presence_state = 0;
  1199. break;
  1200. } else {
  1201. if (name_match(&node_to_start->name,
  1202. &su->saAmfSUHostedByNode)) {
  1203. no_su_has_presence_state = 0;
  1204. break;
  1205. }
  1206. }
  1207. }
  1208. }
  1209. return no_su_has_presence_state;
  1210. }
  1211. #if COMPILE_OUT
  1212. static int all_su_in_scope_has_presence_state (
  1213. struct amf_sg *sg, SaAmfPresenceStateT state)
  1214. {
  1215. struct amf_su **sus= sg->recovery_scope.sus;
  1216. while (*sus != NULL) {
  1217. if ((*sus)->saAmfSUPresenceState != state) {
  1218. break;
  1219. }
  1220. sus++;
  1221. }
  1222. return(*sus == NULL);
  1223. }
  1224. #endif
  1225. static int all_su_in_scope_has_either_two_presence_state (
  1226. amf_sg_t *sg,
  1227. SaAmfPresenceStateT state1,
  1228. SaAmfPresenceStateT state2)
  1229. {
  1230. struct amf_su **sus = sg->recovery_scope.sus;
  1231. while (*sus != NULL) {
  1232. if (!((*sus)->saAmfSUPresenceState == state1 ||
  1233. (*sus)->saAmfSUPresenceState == state2)) {
  1234. break;
  1235. }
  1236. sus++;
  1237. }
  1238. return (*sus == NULL);
  1239. }
  1240. static int all_su_in_scope_has_either_of_three_presence_state (amf_sg_t *sg,
  1241. SaAmfPresenceStateT state1, SaAmfPresenceStateT state2,
  1242. SaAmfPresenceStateT state3)
  1243. {
  1244. struct amf_su **sus = sg->recovery_scope.sus;
  1245. while (*sus != NULL) {
  1246. if (!((*sus)->saAmfSUPresenceState == state1 ||
  1247. (*sus)->saAmfSUPresenceState == state2 ||
  1248. (*sus)->saAmfSUPresenceState == state3)) {
  1249. break;
  1250. }
  1251. sus++;
  1252. }
  1253. return (*sus == NULL);
  1254. }
  1255. /**
  1256. * Get number of SIs protected by the specified SG.
  1257. * @param sg
  1258. *
  1259. * @return int
  1260. */
  1261. static int sg_si_count_get (struct amf_sg *sg)
  1262. {
  1263. struct amf_si *si;
  1264. int cnt = 0;
  1265. for (si = sg->application->si_head; si != NULL; si = si->next) {
  1266. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  1267. cnt += 1;
  1268. }
  1269. }
  1270. return(cnt);
  1271. }
  1272. static int amf_si_get_saAmfSINumReqActiveAssignments(struct amf_si *si)
  1273. {
  1274. struct amf_si_assignment *si_assignment = si->assigned_sis;
  1275. int number_of_req_active_assignments = 0;
  1276. for (; si_assignment != NULL; si_assignment = si_assignment->next) {
  1277. if (si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
  1278. number_of_req_active_assignments++;
  1279. }
  1280. }
  1281. return number_of_req_active_assignments;
  1282. }
  1283. static int amf_si_get_saAmfSINumReqStandbyAssignments(struct amf_si *si)
  1284. {
  1285. struct amf_si_assignment *si_assignment = si->assigned_sis;
  1286. int number_of_req_active_assignments = 0;
  1287. for (; si_assignment != NULL; si_assignment = si_assignment->next) {
  1288. if (si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
  1289. number_of_req_active_assignments++;
  1290. }
  1291. }
  1292. return number_of_req_active_assignments;
  1293. }
  1294. static int sg_assign_nm_active (struct amf_sg *sg, int su_active_assign)
  1295. {
  1296. struct amf_su *su;
  1297. struct amf_si *si;
  1298. int assigned = 0;
  1299. int assign_to_su = 0;
  1300. int total_assigned = 0;
  1301. int si_left;
  1302. int si_total;
  1303. int su_left_to_assign = su_active_assign;
  1304. ENTER("SG: %s", sg->name.value);
  1305. si_total = sg_si_count_get (sg);
  1306. si_left = si_total;
  1307. assign_to_su = div_round (si_left, su_active_assign);
  1308. if (assign_to_su > sg->saAmfSGMaxActiveSIsperSUs) {
  1309. assign_to_su = sg->saAmfSGMaxActiveSIsperSUs;
  1310. }
  1311. su = sg->su_head;
  1312. while (su != NULL && su_left_to_assign > 0) {
  1313. if (amf_su_get_saAmfSUReadinessState (su) !=
  1314. SA_AMF_READINESS_IN_SERVICE ||
  1315. amf_su_get_saAmfSUNumCurrActiveSIs (su) == assign_to_su ||
  1316. amf_su_get_saAmfSUNumCurrStandbySIs (su) > 0) {
  1317. su = su->next;
  1318. continue; /* Not in service */
  1319. }
  1320. si = sg->application->si_head;
  1321. assigned = 0;
  1322. assign_to_su = div_round (si_left, su_left_to_assign);
  1323. if (assign_to_su > sg->saAmfSGMaxActiveSIsperSUs) {
  1324. assign_to_su = sg->saAmfSGMaxActiveSIsperSUs;
  1325. }
  1326. while (si != NULL) {
  1327. if (name_match (&si->saAmfSIProtectedbySG, &sg->name) &&
  1328. assigned < assign_to_su &&
  1329. amf_si_get_saAmfSINumReqActiveAssignments(si) == 0) {
  1330. assigned += 1;
  1331. total_assigned += 1;
  1332. amf_su_assign_si (su, si, SA_AMF_HA_ACTIVE);
  1333. }
  1334. si = si->next;
  1335. }
  1336. su = su->next;
  1337. su_left_to_assign -= 1;
  1338. si_left -= assigned;
  1339. dprintf (" su_left_to_assign =%d, si_left=%d\n",
  1340. su_left_to_assign, si_left);
  1341. }
  1342. assert (total_assigned <= si_total);
  1343. if (total_assigned == 0) {
  1344. dprintf ("Info: No SIs assigned");
  1345. }
  1346. return total_assigned;
  1347. }
  1348. static int sg_assign_nm_standby (struct amf_sg *sg, int su_standby_assign)
  1349. {
  1350. struct amf_su *su;
  1351. struct amf_si *si;
  1352. int assigned = 0;
  1353. int assign_to_su = 0;
  1354. int total_assigned = 0;
  1355. int si_left;
  1356. int si_total;
  1357. int su_left_to_assign = su_standby_assign;
  1358. ENTER ("'%s'", sg->name.value);
  1359. if (su_standby_assign == 0) {
  1360. return 0;
  1361. }
  1362. si_total = sg_si_count_get (sg);
  1363. si_left = si_total;
  1364. assign_to_su = div_round (si_left, su_standby_assign);
  1365. if (assign_to_su > sg->saAmfSGMaxStandbySIsperSUs) {
  1366. assign_to_su = sg->saAmfSGMaxStandbySIsperSUs;
  1367. }
  1368. su = sg->su_head;
  1369. while (su != NULL && su_left_to_assign > 0) {
  1370. if (amf_su_get_saAmfSUReadinessState (su) !=
  1371. SA_AMF_READINESS_IN_SERVICE ||
  1372. amf_su_get_saAmfSUNumCurrActiveSIs (su) > 0 ||
  1373. amf_su_get_saAmfSUNumCurrStandbySIs (su) ==
  1374. assign_to_su) {
  1375. su = su->next;
  1376. continue; /* Not available for assignment */
  1377. }
  1378. si = sg->application->si_head;
  1379. assigned = 0;
  1380. assign_to_su = div_round (si_left, su_left_to_assign);
  1381. if (assign_to_su > sg->saAmfSGMaxStandbySIsperSUs) {
  1382. assign_to_su = sg->saAmfSGMaxStandbySIsperSUs;
  1383. }
  1384. while (si != NULL) {
  1385. if (name_match (&si->saAmfSIProtectedbySG, &sg->name) &&
  1386. assigned < assign_to_su &&
  1387. amf_si_get_saAmfSINumReqStandbyAssignments (si) == 0) {
  1388. assigned += 1;
  1389. total_assigned += 1;
  1390. amf_su_assign_si (su, si, SA_AMF_HA_STANDBY);
  1391. }
  1392. si = si->next;
  1393. }
  1394. su_left_to_assign -= 1;
  1395. si_left -= assigned;
  1396. dprintf (" su_left_to_assign =%d, si_left=%d\n",
  1397. su_left_to_assign, si_left);
  1398. su = su->next;
  1399. }
  1400. assert (total_assigned <= si_total);
  1401. if (total_assigned == 0) {
  1402. dprintf ("Info: No SIs assigned!");
  1403. }
  1404. return total_assigned;
  1405. }
  1406. static int su_inservice_count_get (struct amf_sg *sg)
  1407. {
  1408. struct amf_su *su;
  1409. int answer = 0;
  1410. for (su = sg->su_head; su != NULL; su = su->next) {
  1411. if (amf_su_get_saAmfSUReadinessState (su) ==
  1412. SA_AMF_READINESS_IN_SERVICE) {
  1413. answer += 1;
  1414. }
  1415. }
  1416. return(answer);
  1417. }
  1418. static int su_active_out_of_service_count_get (amf_sg_t *sg)
  1419. {
  1420. int active_out_of_service_count = 0;
  1421. amf_su_t *su;
  1422. for (su = sg->su_head; su != NULL; su = su->next) {
  1423. amf_si_assignment_t *si_assignment;
  1424. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1425. while (si_assignment != NULL) {
  1426. if ((si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) &&
  1427. (amf_su_get_saAmfSUReadinessState (su) ==
  1428. SA_AMF_READINESS_OUT_OF_SERVICE)) {
  1429. active_out_of_service_count += 1;
  1430. }
  1431. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1432. }
  1433. }
  1434. return active_out_of_service_count;
  1435. }
  1436. static int su_standby_out_of_service_count_get (amf_sg_t *sg)
  1437. {
  1438. int active_out_of_service_count = 0;
  1439. amf_su_t *su;
  1440. for (su = sg->su_head; su != NULL; su = su->next) {
  1441. amf_si_assignment_t *si_assignment;
  1442. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1443. while (si_assignment != NULL) {
  1444. if ((si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) &&
  1445. (amf_su_get_saAmfSUReadinessState (su) ==
  1446. SA_AMF_READINESS_OUT_OF_SERVICE)) {
  1447. active_out_of_service_count += 1;
  1448. }
  1449. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1450. }
  1451. }
  1452. return active_out_of_service_count;
  1453. }
  1454. /**
  1455. * TODO: dependency_level not used, hard coded
  1456. * @param sg
  1457. * @param dependency_level
  1458. */
  1459. static int assign_si (struct amf_sg *sg, int dependency_level)
  1460. {
  1461. int active_sus_needed = 0;
  1462. int standby_sus_needed = 0;
  1463. int inservice_count;
  1464. int su_active_assign;
  1465. int su_standby_assign;
  1466. int su_spare_assign;
  1467. int assigned = 0;
  1468. int active_out_of_service = 0;
  1469. int standby_out_of_service = 0;
  1470. ENTER ("'%s'", sg->name.value);
  1471. /**
  1472. * Phase 1: Calculate assignments and create all runtime objects in
  1473. * information model. Do not do the actual assignment, done in
  1474. * phase 2.
  1475. */
  1476. /**
  1477. * Calculate number of SUs to assign to active or standby state
  1478. */
  1479. inservice_count = su_inservice_count_get (sg);
  1480. active_out_of_service = su_active_out_of_service_count_get(sg);
  1481. standby_out_of_service = su_standby_out_of_service_count_get(sg);
  1482. if (sg->saAmfSGNumPrefActiveSUs > 0) {
  1483. active_sus_needed = div_round (
  1484. sg_si_count_get (sg),
  1485. sg->saAmfSGMaxActiveSIsperSUs);
  1486. } else {
  1487. log_printf (LOG_LEVEL_ERROR, "ERROR: saAmfSGNumPrefActiveSUs == 0 !!");
  1488. openais_exit_error (AIS_DONE_FATAL_ERR);
  1489. }
  1490. if (sg->saAmfSGNumPrefStandbySUs > 0) {
  1491. standby_sus_needed = div_round (
  1492. sg_si_count_get (sg),
  1493. sg->saAmfSGMaxStandbySIsperSUs);
  1494. } else {
  1495. log_printf (LOG_LEVEL_ERROR, "ERROR: saAmfSGNumPrefStandbySUs == 0 !!");
  1496. openais_exit_error (AIS_DONE_FATAL_ERR);
  1497. }
  1498. dprintf ("(inservice=%d) (active_sus_needed=%d) (standby_sus_needed=%d)"
  1499. "\n",
  1500. inservice_count, active_sus_needed, standby_sus_needed);
  1501. /* Determine number of active and standby service units
  1502. * to assign based upon reduction procedure
  1503. */
  1504. if ((inservice_count < active_sus_needed - active_out_of_service)) {
  1505. dprintf ("assignment VI - partial assignment with SIs drop outs\n");
  1506. su_active_assign = inservice_count;
  1507. su_standby_assign = 0;
  1508. su_spare_assign = 0;
  1509. } else
  1510. if ((inservice_count < active_sus_needed - active_out_of_service +
  1511. standby_sus_needed)) {
  1512. dprintf ("assignment V - partial assignment with reduction of"
  1513. " standby units\n");
  1514. su_active_assign = active_sus_needed;
  1515. su_standby_assign = inservice_count - active_sus_needed - active_out_of_service;
  1516. su_spare_assign = 0;
  1517. } else
  1518. if ((inservice_count < sg->saAmfSGNumPrefActiveSUs + standby_sus_needed)) {
  1519. dprintf ("IV: full assignment with reduction of active service"
  1520. " units\n");
  1521. su_active_assign = inservice_count - standby_sus_needed;
  1522. su_standby_assign = standby_sus_needed;
  1523. su_spare_assign = 0;
  1524. } else
  1525. if ((inservice_count <
  1526. sg->saAmfSGNumPrefActiveSUs + sg->saAmfSGNumPrefStandbySUs)) {
  1527. dprintf ("III: full assignment with reduction of standby service"
  1528. " units\n");
  1529. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1530. su_standby_assign = inservice_count - sg->saAmfSGNumPrefActiveSUs;
  1531. su_spare_assign = 0;
  1532. } else
  1533. if ((inservice_count ==
  1534. sg->saAmfSGNumPrefActiveSUs + sg->saAmfSGNumPrefStandbySUs)) {
  1535. if (sg->saAmfSGNumPrefInserviceSUs > inservice_count) {
  1536. dprintf ("II: full assignment with spare reduction\n");
  1537. } else {
  1538. dprintf ("II: full assignment without spares\n");
  1539. }
  1540. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1541. su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
  1542. su_spare_assign = 0;
  1543. } else {
  1544. dprintf ("I: full assignment with spares\n");
  1545. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1546. su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
  1547. su_spare_assign = inservice_count -
  1548. sg->saAmfSGNumPrefActiveSUs - sg->saAmfSGNumPrefStandbySUs;
  1549. }
  1550. dprintf ("(inservice=%d) (assigning active=%d) (assigning standby=%d)"
  1551. " (assigning spares=%d)\n",
  1552. inservice_count, su_active_assign, su_standby_assign, su_spare_assign);
  1553. if (inservice_count > 0) {
  1554. assigned = sg_assign_nm_active (sg, su_active_assign);
  1555. assigned += sg_assign_nm_standby (sg, su_standby_assign);
  1556. sg->saAmfSGNumCurrAssignedSUs = inservice_count;
  1557. /**
  1558. * Phase 2: do the actual assignment to the component
  1559. * TODO: first do active, then standby
  1560. */
  1561. {
  1562. struct amf_si *si;
  1563. struct amf_si_assignment *si_assignment;
  1564. for (si = sg->application->si_head; si != NULL; si = si->next) {
  1565. if (name_match (&si->saAmfSIProtectedbySG, &sg->name)) {
  1566. for (si_assignment = si->assigned_sis;
  1567. si_assignment != NULL;
  1568. si_assignment = si_assignment->next) {
  1569. if (si_assignment->requested_ha_state !=
  1570. si_assignment->saAmfSISUHAState) {
  1571. amf_si_ha_state_assume (
  1572. si_assignment, assign_si_assumed_cbfn);
  1573. }
  1574. }
  1575. }
  1576. }
  1577. }
  1578. }
  1579. LEAVE ("'%s'", sg->name.value);
  1580. return assigned;
  1581. }
  1582. #ifdef COMPILE_OUT
  1583. static void remove_si_in_scope (amf_sg_t *sg, amf_si_t *si)
  1584. {
  1585. int i;
  1586. int j;
  1587. amf_si_t **sis = sg->recovery_scope.sis;
  1588. amf_si_t **new_sis = amf_calloc (1, sizeof (amf_si_t*));
  1589. for (i = 0,j = 0; sis[i] != NULL; i++) {
  1590. if (sis[i] == si) {
  1591. continue;
  1592. }
  1593. new_sis[j] = sis[i];
  1594. new_sis = amf_realloc (new_sis, j + sizeof (amf_si_t *));
  1595. j++;
  1596. }
  1597. sg->recovery_scope.sis = new_sis;
  1598. }
  1599. #endif
  1600. #ifdef COMPILE_OUT
  1601. static void remove_sis_for_term_failed_su_from_scope (amf_sg_t *sg,
  1602. amf_su_t *su)
  1603. {
  1604. amf_comp_t *component;
  1605. /*
  1606. * foreach component with presense state termiantion failed in su
  1607. */
  1608. for (component = su->comp_head; component != NULL;
  1609. component = component->next) {
  1610. amf_csi_assignment_t *csi_assignment;
  1611. if (component->saAmfCompPresenceState !=
  1612. SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  1613. continue;
  1614. }
  1615. csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
  1616. while (csi_assignment != NULL) {
  1617. remove_si_in_scope (sg, csi_assignment->csi->si);
  1618. csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
  1619. }
  1620. }
  1621. }
  1622. #endif
  1623. /**
  1624. * sg_su_state_changed_in_instantiated
  1625. * @param sg
  1626. * @param su
  1627. */
  1628. static void sg_su_state_changed_to_instantiated (struct amf_sg *sg, struct amf_su *su)
  1629. {
  1630. ENTER("%s %s",sg->name.value, su->name.value);
  1631. switch (sg->avail_state) {
  1632. case SG_AC_InstantiatingServiceUnits:
  1633. if (no_su_has_presence_state(sg, sg->node_to_start,
  1634. SA_AMF_PRESENCE_INSTANTIATING)) {
  1635. acsm_enter_idle (sg);
  1636. }
  1637. break;
  1638. case SG_AC_ReparingSu:
  1639. if (no_su_has_presence_state(sg, sg->node_to_start,
  1640. SA_AMF_PRESENCE_INSTANTIATING)) {
  1641. if (all_su_in_scope_has_either_of_three_presence_state(
  1642. su->sg,
  1643. SA_AMF_PRESENCE_INSTANTIATED,
  1644. SA_AMF_PRESENCE_INSTANTIATION_FAILED,
  1645. SA_AMF_PRESENCE_UNINSTANTIATED)) {
  1646. su->sg->avail_state = SG_AC_AssigningStandBy;
  1647. if (assign_si (sg, 0) == 0) {
  1648. acsm_enter_idle (sg);
  1649. }
  1650. } else {
  1651. dprintf ("avail-state: %u", sg->avail_state);
  1652. assert (0);
  1653. }
  1654. }
  1655. break;
  1656. default:
  1657. dprintf ("avail-state: %u", sg->avail_state);
  1658. assert (0);
  1659. break;
  1660. }
  1661. }
  1662. /**
  1663. * amf_sg_su_state_changed_in_uninstantiated
  1664. * @param sg
  1665. * @param su
  1666. */
  1667. static void amf_sg_su_state_changed_to_uninstantiated (amf_sg_t *sg,
  1668. amf_su_t *su)
  1669. {
  1670. ENTER("%s %s",sg->name.value, su->name.value);
  1671. switch (sg->avail_state) {
  1672. case SG_AC_TerminatingSuspected:
  1673. if (no_su_has_presence_state(sg, sg->node_to_start,
  1674. SA_AMF_PRESENCE_TERMINATING)) {
  1675. if (all_su_in_scope_has_either_two_presence_state (sg,
  1676. SA_AMF_PRESENCE_UNINSTANTIATED,
  1677. SA_AMF_PRESENCE_TERMINATION_FAILED)) {
  1678. delete_si_assignments_in_scope (sg);
  1679. if (is_any_si_in_scope_assigned_standby (sg)) {
  1680. remove_all_suspected_sus (sg);
  1681. acsm_enter_removing_standby_assignments (sg);
  1682. } else { /*is_no_si_in_scope_assigned_standby*/
  1683. remove_all_suspected_sus (sg);
  1684. acsm_enter_assigning_standby_to_spare (sg);
  1685. }
  1686. }
  1687. }
  1688. break;
  1689. case SG_AC_ReparingSu:
  1690. if (no_su_has_presence_state(sg, sg->node_to_start,
  1691. SA_AMF_PRESENCE_TERMINATING)) {
  1692. if (all_su_in_scope_has_either_of_three_presence_state(
  1693. su->sg,
  1694. SA_AMF_PRESENCE_INSTANTIATED,
  1695. SA_AMF_PRESENCE_INSTANTIATION_FAILED,
  1696. SA_AMF_PRESENCE_UNINSTANTIATED)) {
  1697. su->sg->avail_state = SG_AC_AssigningStandBy;
  1698. if (assign_si (sg, 0) == 0) {
  1699. acsm_enter_idle (sg);
  1700. }
  1701. }
  1702. }
  1703. break;
  1704. default:
  1705. log_printf (LOG_ERR, "sg avail_state = %d", sg->avail_state);
  1706. assert (0);
  1707. break;
  1708. }
  1709. }
  1710. static int npm_and_comp_in_active_ha_state (
  1711. amf_sg_t *sg, amf_su_t *su)
  1712. {
  1713. amf_comp_t *component;
  1714. amf_csi_assignment_t *csi_assignment;
  1715. int comp_is_in_active_ha_state = 0;
  1716. if(sg->saAmfSGRedundancyModel == SA_AMF_NPM_REDUNDANCY_MODEL) {
  1717. for (component = su->comp_head; component != NULL;
  1718. component = component->next) {
  1719. csi_assignment = amf_comp_get_next_csi_assignment(component, NULL);
  1720. while (csi_assignment != NULL) {
  1721. if (csi_assignment->saAmfCSICompHAState == SA_AMF_HA_ACTIVE) {
  1722. comp_is_in_active_ha_state = 1;
  1723. goto out;
  1724. }
  1725. csi_assignment = amf_comp_get_next_csi_assignment(component,
  1726. csi_assignment);
  1727. }
  1728. }
  1729. }
  1730. out:
  1731. return comp_is_in_active_ha_state;
  1732. }
  1733. /**
  1734. * amf_sg_su_state_changed_in_termination_failed
  1735. * @param sg
  1736. * @param su
  1737. */
  1738. static void amf_sg_su_state_changed_to_termination_failed (amf_sg_t *sg,
  1739. amf_su_t *su)
  1740. {
  1741. ENTER("%s %s",sg->name.value, su->name.value);
  1742. if (no_su_has_presence_state(sg, sg->node_to_start,
  1743. SA_AMF_PRESENCE_INSTANTIATING)) {
  1744. if (npm_and_comp_in_active_ha_state (sg, su)) {
  1745. acsm_enter_idle (sg);
  1746. goto out;
  1747. }
  1748. if (all_su_in_scope_has_either_two_presence_state (sg,
  1749. SA_AMF_PRESENCE_UNINSTANTIATED,
  1750. SA_AMF_PRESENCE_TERMINATION_FAILED)) {
  1751. delete_si_assignments_in_scope (sg);
  1752. if (is_any_si_in_scope_assigned_standby (sg)) {
  1753. remove_all_suspected_sus (sg);
  1754. acsm_enter_removing_standby_assignments (sg);
  1755. } else { /*is_no_si_in_scope_assigned_standby*/
  1756. remove_all_suspected_sus (sg);
  1757. acsm_enter_assigning_standby_to_spare (sg);
  1758. }
  1759. }
  1760. }
  1761. out:
  1762. return;
  1763. }
  1764. /**
  1765. * amf_sg_su_state_changed_in_instantiation_failed
  1766. * @param sg
  1767. * @param su
  1768. */
  1769. static void amf_sg_su_state_changed_to_instantiation_failed (amf_sg_t *sg,
  1770. amf_su_t *su)
  1771. {
  1772. ENTER("%s %s",sg->name.value, su->name.value);
  1773. switch (sg->avail_state) {
  1774. case SG_AC_InstantiatingServiceUnits:
  1775. if (no_su_has_presence_state(sg, sg->node_to_start,
  1776. SA_AMF_PRESENCE_INSTANTIATING)) {
  1777. acsm_enter_idle (sg);
  1778. }
  1779. break;
  1780. case SG_AC_ReparingSu:
  1781. if (no_su_has_presence_state(sg, sg->node_to_start,
  1782. SA_AMF_PRESENCE_INSTANTIATING)) {
  1783. if (all_su_in_scope_has_either_of_three_presence_state(
  1784. su->sg,
  1785. SA_AMF_PRESENCE_INSTANTIATED,
  1786. SA_AMF_PRESENCE_INSTANTIATION_FAILED,
  1787. SA_AMF_PRESENCE_UNINSTANTIATED)) {
  1788. su->sg->avail_state = SG_AC_AssigningStandBy;
  1789. if (assign_si (sg, 0) == 0) {
  1790. acsm_enter_idle (sg);
  1791. }
  1792. }
  1793. }
  1794. break;
  1795. default:
  1796. /* TODO: Insert the assert (0) until solving defers in SU */
  1797. dprintf("sg->avail_state = %d", sg->avail_state);
  1798. break;
  1799. }
  1800. }
  1801. int amf_sg_assign_si_req (struct amf_sg *sg, int dependency_level)
  1802. {
  1803. int posible_to_assign_si;
  1804. sg->recovery_scope.event_type = SG_ASSIGN_SI_EV;
  1805. sg->avail_state = SG_AC_AssigningOnRequest;
  1806. if ((posible_to_assign_si = assign_si (sg, dependency_level)) == 0) {
  1807. acsm_enter_idle (sg);
  1808. }
  1809. return posible_to_assign_si;
  1810. }
  1811. void amf_sg_failover_node_req (struct amf_sg *sg, struct amf_node *node)
  1812. {
  1813. ENTER("'%s, %s'",node->name.value, sg->name.value);
  1814. sg_event_t sg_event;
  1815. switch (sg->avail_state) {
  1816. case SG_AC_Idle:
  1817. set_scope_for_failover_node(sg, node);
  1818. if (has_any_su_in_scope_active_workload (sg)) {
  1819. acsm_enter_deactivating_dependent_workload (sg);
  1820. } else {
  1821. amf_su_t **sus = sg->recovery_scope.sus;
  1822. /*
  1823. * Select next state depending on if some
  1824. * SU in the scope needs to be terminated.
  1825. */
  1826. while (*sus != NULL) {
  1827. amf_su_t *su = *sus;
  1828. ENTER("SU %s pr_state='%d'",su->name.value,
  1829. su->saAmfSUPresenceState);
  1830. if (su_presense_state_is_ored (su,
  1831. SA_AMF_PRESENCE_UNINSTANTIATED,
  1832. SA_AMF_PRESENCE_TERMINATION_FAILED,
  1833. SA_AMF_PRESENCE_INSTANTIATION_FAILED)) {
  1834. sus++;
  1835. continue;
  1836. }
  1837. break;
  1838. }
  1839. if (*sus != NULL) {
  1840. acsm_enter_terminating_suspected (sg);
  1841. } else {
  1842. delete_si_assignments_in_scope (sg);
  1843. acsm_enter_idle (sg);
  1844. }
  1845. }
  1846. break;
  1847. case SG_AC_DeactivatingDependantWorkload:
  1848. case SG_AC_TerminatingSuspected:
  1849. case SG_AC_ActivatingStandby:
  1850. case SG_AC_AssigningStandbyToSpare:
  1851. case SG_AC_ReparingComponent:
  1852. case SG_AC_ReparingSu:
  1853. case SG_AC_AssigningOnRequest:
  1854. case SG_AC_InstantiatingServiceUnits:
  1855. case SG_AC_RemovingAssignment:
  1856. case SG_AC_AssigningActiveworkload:
  1857. case SG_AC_AssigningAutoAdjust:
  1858. case SG_AC_AssigningStandBy:
  1859. case SG_AC_WaitingAfterOperationFailed:
  1860. case SG_AC_RemovingStandbyAssignments:
  1861. sg_set_event (SG_FAILOVER_NODE_EV, sg, 0, 0, node, &sg_event);
  1862. sg_defer_event (SG_FAILOVER_NODE_EV, &sg_event);
  1863. break;
  1864. default:
  1865. assert (0);
  1866. break;
  1867. }
  1868. }
  1869. int amf_sg_start (struct amf_sg *sg, struct amf_node *node)
  1870. {
  1871. sg->recovery_scope.event_type = SG_START_EV;
  1872. ENTER ("'%s'", sg->name.value);
  1873. int instantiated_sus = 0;
  1874. switch (sg->avail_state) {
  1875. case SG_AC_InstantiatingServiceUnits:
  1876. case SG_AC_Idle: {
  1877. amf_su_t *su;
  1878. sg_avail_control_state_t old_avail_state = sg->avail_state;
  1879. ENTER ("'%s'", sg->name.value);
  1880. sg->node_to_start = node;
  1881. sg->avail_state = SG_AC_InstantiatingServiceUnits;
  1882. for (su = sg->su_head;
  1883. (su != NULL) &&
  1884. (instantiated_sus < sg->saAmfSGNumPrefInserviceSUs);
  1885. su = su->next) {
  1886. if (is_cluster_start (node)) {
  1887. amf_su_instantiate (su);
  1888. instantiated_sus++;
  1889. } else { /*is_not_cluster_start*/
  1890. /*
  1891. * Node start, match if SU is hosted on the
  1892. * specified node
  1893. */
  1894. if (name_match (&node->name,
  1895. &su->saAmfSUHostedByNode)) {
  1896. amf_su_instantiate (su);
  1897. instantiated_sus++;
  1898. }
  1899. }
  1900. }
  1901. if (instantiated_sus == 0) {
  1902. sg->avail_state = old_avail_state;
  1903. }
  1904. break;
  1905. }
  1906. case SG_AC_DeactivatingDependantWorkload:
  1907. case SG_AC_TerminatingSuspected:
  1908. case SG_AC_ActivatingStandby:
  1909. case SG_AC_AssigningStandbyToSpare:
  1910. case SG_AC_ReparingComponent:
  1911. case SG_AC_ReparingSu:
  1912. case SG_AC_AssigningOnRequest:
  1913. case SG_AC_RemovingAssignment:
  1914. case SG_AC_AssigningActiveworkload:
  1915. case SG_AC_AssigningAutoAdjust:
  1916. case SG_AC_AssigningStandBy:
  1917. case SG_AC_WaitingAfterOperationFailed:
  1918. case SG_AC_RemovingStandbyAssignments:
  1919. default:
  1920. assert (0);
  1921. break;
  1922. }
  1923. return instantiated_sus;
  1924. }
  1925. #ifdef COMPILE_OUT
  1926. void amf_sg_su_state_changed_2 (struct amf_sg *sg,
  1927. struct amf_su *su, SaAmfStateT type, int state)
  1928. {
  1929. ENTER ("'%s' SU '%s' state %s",
  1930. sg->name.value, su->name.value, amf_presence_state(state));
  1931. if (type == SA_AMF_PRESENCE_STATE) {
  1932. if (state == SA_AMF_PRESENCE_INSTANTIATED) {
  1933. if (sg->avail_state == SG_AC_InstantiatingServiceUnits) {
  1934. if (no_su_has_presence_state(sg, sg->node_to_start,
  1935. SA_AMF_PRESENCE_INSTANTIATING)) {
  1936. acsm_enter_idle (sg);
  1937. }
  1938. } else if (sg->avail_state == SG_AC_ReparingSu) {
  1939. if (all_su_in_scope_has_either_of_three_presence_state(
  1940. su->sg,
  1941. SA_AMF_PRESENCE_INSTANTIATED,
  1942. SA_AMF_PRESENCE_INSTANTIATION_FAILED,
  1943. SA_AMF_PRESENCE_UNINSTANTIATED)) {
  1944. su->sg->avail_state = SG_AC_AssigningStandBy;
  1945. if (assign_si (sg, 0) == 0) {
  1946. acsm_enter_idle (sg);
  1947. }
  1948. } else {
  1949. dprintf ("avail-state: %u", sg->avail_state);
  1950. assert (0);
  1951. }
  1952. } else {
  1953. dprintf ("avail-state: %u", sg->avail_state);
  1954. assert (0);
  1955. }
  1956. } else if (state == SA_AMF_PRESENCE_UNINSTANTIATED) {
  1957. if (sg->avail_state == SG_AC_TerminatingSuspected) {
  1958. if (all_su_in_scope_has_either_two_presence_state (sg,
  1959. SA_AMF_PRESENCE_UNINSTANTIATED,
  1960. SA_AMF_PRESENCE_TERMINATION_FAILED)) {
  1961. delete_si_assignments_in_scope (sg);
  1962. if (is_any_si_in_scope_assigned_standby (sg)) {
  1963. remove_all_suspected_sus (sg);
  1964. acsm_enter_removing_standby_assignments (sg);
  1965. } else { /*is_no_si_in_scope_assigned_standby*/
  1966. remove_all_suspected_sus (sg);
  1967. acsm_enter_assigning_standby_to_spare (sg);
  1968. }
  1969. }
  1970. } else if (sg->avail_state == SG_AC_ReparingSu) {
  1971. if (all_su_in_scope_has_either_of_three_presence_state(
  1972. su->sg,
  1973. SA_AMF_PRESENCE_INSTANTIATED,
  1974. SA_AMF_PRESENCE_INSTANTIATION_FAILED,
  1975. SA_AMF_PRESENCE_UNINSTANTIATED)) {
  1976. su->sg->avail_state = SG_AC_AssigningStandBy;
  1977. if (assign_si (sg, 0) == 0) {
  1978. acsm_enter_idle (sg);
  1979. }
  1980. } else {
  1981. dprintf("%d",sg->avail_state);
  1982. assert (0);
  1983. }
  1984. }
  1985. } else if (state == SA_AMF_PRESENCE_TERMINATION_FAILED) {
  1986. if (all_su_in_scope_has_either_two_presence_state (sg,
  1987. SA_AMF_PRESENCE_UNINSTANTIATED,
  1988. SA_AMF_PRESENCE_TERMINATION_FAILED) &&
  1989. is_any_si_in_scope_assigned_standby (sg)) {
  1990. remove_all_suspected_sus (sg);
  1991. acsm_enter_removing_standby_assignments (sg);
  1992. } else if (all_su_in_scope_has_either_two_presence_state (sg,
  1993. SA_AMF_PRESENCE_UNINSTANTIATED,
  1994. SA_AMF_PRESENCE_TERMINATION_FAILED) &&
  1995. !is_any_si_in_scope_assigned_standby (sg)) {
  1996. remove_all_suspected_sus (sg);
  1997. acsm_enter_assigning_standby_to_spare (sg);
  1998. } else {
  1999. remove_sis_for_term_failed_su_from_scope (sg, su);
  2000. }
  2001. } else if (state == SA_AMF_PRESENCE_INSTANTIATING) {
  2002. ; /* nop */
  2003. } else if (state == SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  2004. if (sg->avail_state == SG_AC_InstantiatingServiceUnits) {
  2005. if (no_su_has_presence_state(sg, sg->node_to_start,
  2006. SA_AMF_PRESENCE_INSTANTIATING)) {
  2007. acsm_enter_idle (sg);
  2008. }
  2009. } else if (sg->avail_state == SG_AC_ReparingSu) {
  2010. if (all_su_in_scope_has_either_of_three_presence_state(
  2011. su->sg,
  2012. SA_AMF_PRESENCE_INSTANTIATED,
  2013. SA_AMF_PRESENCE_INSTANTIATION_FAILED,
  2014. SA_AMF_PRESENCE_UNINSTANTIATED)) {
  2015. su->sg->avail_state = SG_AC_AssigningStandBy;
  2016. if (assign_si (sg, 0) == 0) {
  2017. acsm_enter_idle (sg);
  2018. }
  2019. }
  2020. } else {
  2021. /* TODO: Insert the assert (0) until solving defers in SU */
  2022. dprintf("sg->avail_state = %d, su instantiation state = %d",
  2023. sg->avail_state, state);
  2024. }
  2025. } else {
  2026. dprintf("sg->avail_state = %d, su instantiation state = %d",
  2027. sg->avail_state, state);
  2028. assert (0);
  2029. }
  2030. }
  2031. }
  2032. #endif
  2033. void amf_sg_su_state_changed (struct amf_sg *sg, struct amf_su *su,
  2034. SaAmfStateT type, int state)
  2035. {
  2036. ENTER ("'%s' SU '%s' state %s",
  2037. sg->name.value, su->name.value, amf_presence_state(state));
  2038. if (type == SA_AMF_PRESENCE_STATE) {
  2039. switch (state) {
  2040. case SA_AMF_PRESENCE_INSTANTIATED:
  2041. sg_su_state_changed_to_instantiated(sg, su);
  2042. break;
  2043. case SA_AMF_PRESENCE_UNINSTANTIATED:
  2044. amf_sg_su_state_changed_to_uninstantiated(sg, su);
  2045. break;
  2046. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  2047. amf_sg_su_state_changed_to_termination_failed(sg, su);
  2048. break;
  2049. case SA_AMF_PRESENCE_INSTANTIATING:
  2050. ; /* nop */
  2051. break;
  2052. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  2053. amf_sg_su_state_changed_to_instantiation_failed(sg, su);
  2054. break;
  2055. default :
  2056. dprintf("sg->avail_state = %d, su instantiation state = %d",
  2057. sg->avail_state, state);
  2058. assert (0);
  2059. break;
  2060. }
  2061. }
  2062. }
  2063. void amf_sg_init (void)
  2064. {
  2065. log_init ("AMF");
  2066. }
  2067. void amf_sg_failover_su_req (struct amf_sg *sg, struct amf_su *su,
  2068. struct amf_node *node)
  2069. {
  2070. ENTER ("%s", su->name.value);
  2071. sg_event_t sg_event;
  2072. switch (sg->avail_state) {
  2073. case SG_AC_Idle:
  2074. su->su_failover_cnt += 1;
  2075. set_scope_for_failover_su (sg, su);
  2076. if (has_any_su_in_scope_active_workload (sg)) {
  2077. acsm_enter_deactivating_dependent_workload (sg);
  2078. } else {
  2079. acsm_enter_terminating_suspected (sg);
  2080. }
  2081. break;
  2082. case SG_AC_DeactivatingDependantWorkload:
  2083. case SG_AC_TerminatingSuspected:
  2084. case SG_AC_ActivatingStandby:
  2085. case SG_AC_AssigningStandbyToSpare:
  2086. case SG_AC_ReparingComponent:
  2087. case SG_AC_ReparingSu:
  2088. case SG_AC_AssigningOnRequest:
  2089. case SG_AC_InstantiatingServiceUnits:
  2090. case SG_AC_RemovingAssignment:
  2091. case SG_AC_AssigningActiveworkload:
  2092. case SG_AC_AssigningAutoAdjust:
  2093. case SG_AC_AssigningStandBy:
  2094. case SG_AC_WaitingAfterOperationFailed:
  2095. case SG_AC_RemovingStandbyAssignments:
  2096. sg_set_event (SG_FAILOVER_SU_EV, sg, su, 0, 0, &sg_event);
  2097. sg_defer_event (SG_FAILOVER_SU_EV, &sg_event);
  2098. break;
  2099. default:
  2100. assert (0);
  2101. break;
  2102. }
  2103. }
  2104. /**
  2105. * Constructor for SG objects. Adds SG to the list owned by
  2106. * the specified application. Always returns a valid SG
  2107. * object, out-of-memory problems are handled here. Default
  2108. * values are initialized.
  2109. * @param sg
  2110. * @param name
  2111. *
  2112. * @return struct amf_sg*
  2113. */
  2114. struct amf_sg *amf_sg_new (struct amf_application *app, char *name)
  2115. {
  2116. struct amf_sg *sg = amf_calloc (1, sizeof (struct amf_sg));
  2117. setSaNameT (&sg->name, name);
  2118. sg->saAmfSGAdminState = SA_AMF_ADMIN_UNLOCKED;
  2119. sg->saAmfSGNumPrefActiveSUs = 1;
  2120. sg->saAmfSGNumPrefStandbySUs = 1;
  2121. sg->saAmfSGNumPrefInserviceSUs = ~0;
  2122. sg->saAmfSGNumPrefAssignedSUs = ~0;
  2123. sg->saAmfSGCompRestartProb = -1;
  2124. sg->saAmfSGCompRestartMax = ~0;
  2125. sg->saAmfSGSuRestartProb = -1;
  2126. sg->saAmfSGSuRestartMax = ~0;
  2127. sg->saAmfSGAutoAdjustProb = -1;
  2128. sg->saAmfSGAutoRepair = SA_TRUE;
  2129. sg->application = app;
  2130. sg->next = app->sg_head;
  2131. app->sg_head = sg;
  2132. sg->deferred_events = NULL;
  2133. return sg;
  2134. }
  2135. void amf_sg_delete (struct amf_sg *sg)
  2136. {
  2137. struct amf_su *su;
  2138. for (su = sg->su_head; su != NULL;) {
  2139. struct amf_su *tmp = su;
  2140. su = su->next;
  2141. amf_su_delete (tmp);
  2142. }
  2143. free (sg);
  2144. }
  2145. void *amf_sg_serialize (struct amf_sg *sg, int *len)
  2146. {
  2147. char *buf = NULL;
  2148. int offset = 0, size = 0;
  2149. TRACE8 ("%s", sg->name.value);
  2150. buf = amf_serialize_SaNameT (buf, &size, &offset, &sg->name);
  2151. buf = amf_serialize_SaUint32T (buf, &size, &offset, sg->saAmfSGRedundancyModel);
  2152. buf = amf_serialize_SaUint32T (
  2153. buf, &size, &offset, sg->saAmfSGAutoAdjust);
  2154. buf = amf_serialize_SaUint32T (
  2155. buf, &size, &offset, sg->saAmfSGNumPrefActiveSUs);
  2156. buf = amf_serialize_SaUint32T (
  2157. buf, &size, &offset, sg->saAmfSGNumPrefStandbySUs);
  2158. buf = amf_serialize_SaUint32T (
  2159. buf, &size, &offset, sg->saAmfSGNumPrefInserviceSUs);
  2160. buf = amf_serialize_SaUint32T (
  2161. buf, &size, &offset, sg->saAmfSGNumPrefAssignedSUs);
  2162. buf = amf_serialize_SaUint32T (
  2163. buf, &size, &offset, sg->saAmfSGMaxActiveSIsperSUs);
  2164. buf = amf_serialize_SaUint32T (
  2165. buf, &size, &offset, sg->saAmfSGMaxStandbySIsperSUs);
  2166. buf = amf_serialize_SaUint32T (
  2167. buf, &size, &offset, sg->saAmfSGCompRestartProb);
  2168. buf = amf_serialize_SaUint32T (
  2169. buf, &size, &offset, sg->saAmfSGCompRestartMax);
  2170. buf = amf_serialize_SaUint32T (
  2171. buf, &size, &offset, sg->saAmfSGSuRestartProb);
  2172. buf = amf_serialize_SaUint32T (
  2173. buf, &size, &offset, sg->saAmfSGSuRestartMax);
  2174. buf = amf_serialize_SaUint32T (
  2175. buf, &size, &offset, sg->saAmfSGAutoAdjustProb);
  2176. buf = amf_serialize_SaUint32T (
  2177. buf, &size, &offset, sg->saAmfSGAutoRepair);
  2178. buf = amf_serialize_SaUint32T (
  2179. buf, &size, &offset, sg->saAmfSGAdminState);
  2180. buf = amf_serialize_SaUint32T (
  2181. buf, &size, &offset, sg->saAmfSGNumCurrAssignedSUs);
  2182. buf = amf_serialize_SaUint32T (
  2183. buf, &size, &offset, sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
  2184. buf = amf_serialize_SaUint32T (
  2185. buf, &size, &offset, sg->saAmfSGNumCurrInstantiatedSpareSUs);
  2186. buf = amf_serialize_SaStringT (
  2187. buf, &size, &offset, sg->clccli_path);
  2188. buf = amf_serialize_SaUint32T (
  2189. buf, &size, &offset, sg->avail_state);
  2190. buf = amf_serialize_SaUint32T (
  2191. buf, &size, &offset, sg->recovery_scope.event_type);
  2192. *len = offset;
  2193. return buf;
  2194. }
  2195. struct amf_sg *amf_sg_deserialize (struct amf_application *app, char *buf)
  2196. {
  2197. char *tmp = buf;
  2198. struct amf_sg *sg = amf_sg_new (app, "");
  2199. tmp = amf_deserialize_SaNameT (tmp, &sg->name);
  2200. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGRedundancyModel);
  2201. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoAdjust);
  2202. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefActiveSUs);
  2203. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefStandbySUs);
  2204. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefInserviceSUs);
  2205. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumPrefAssignedSUs);
  2206. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGMaxActiveSIsperSUs);
  2207. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGMaxStandbySIsperSUs);
  2208. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGCompRestartProb);
  2209. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGCompRestartMax);
  2210. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGSuRestartProb);
  2211. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGSuRestartMax);
  2212. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoAdjustProb);
  2213. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAutoRepair);
  2214. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGAdminState);
  2215. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrAssignedSUs);
  2216. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
  2217. tmp = amf_deserialize_SaUint32T (tmp, &sg->saAmfSGNumCurrInstantiatedSpareSUs);
  2218. tmp = amf_deserialize_SaStringT (tmp, &sg->clccli_path);
  2219. tmp = amf_deserialize_SaUint32T (tmp, &sg->avail_state);
  2220. tmp = amf_deserialize_SaUint32T (tmp, &sg->recovery_scope.event_type);
  2221. return sg;
  2222. }
  2223. struct amf_sg *amf_sg_find (struct amf_application *app, char *name)
  2224. {
  2225. struct amf_sg *sg;
  2226. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  2227. if (sg->name.length == strlen(name) &&
  2228. strncmp (name, (char*)sg->name.value, sg->name.length) == 0) {
  2229. break;
  2230. }
  2231. }
  2232. return sg;
  2233. }