amfsu.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  1. /** @file exec/amfsu.c
  2. *
  3. * Copyright (c) 2002-2006 MontaVista Software, Inc.
  4. * Author: Steven Dake (sdake@mvista.com)
  5. *
  6. * Copyright (c) 2006 Ericsson AB.
  7. * Author: Hans Feldt, Anders Eriksson, Lars Holm
  8. * - Introduced AMF B.02 information model
  9. * - Use DN in API and multicast messages
  10. * - (Re-)Introduction of event based multicast messages
  11. * - Refactoring of code into several AMF files
  12. * - Component/SU restart, SU failover
  13. * - Constructors/destructors
  14. * - Serializers/deserializers
  15. *
  16. * All rights reserved.
  17. *
  18. *
  19. * This software licensed under BSD license, the text of which follows:
  20. *
  21. * Redistribution and use in source and binary forms, with or without
  22. * modification, are permitted provided that the following conditions are met:
  23. *
  24. * - Redistributions of source code must retain the above copyright notice,
  25. * this list of conditions and the following disclaimer.
  26. * - Redistributions in binary form must reproduce the above copyright notice,
  27. * this list of conditions and the following disclaimer in the documentation
  28. * and/or other materials provided with the distribution.
  29. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  30. * contributors may be used to endorse or promote products derived from this
  31. * software without specific prior written permission.
  32. *
  33. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  34. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  36. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  37. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  38. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  39. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  40. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  41. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  42. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  43. * THE POSSIBILITY OF SUCH DAMAGE.
  44. *
  45. * AMF Service Unit Class Implementation
  46. *
  47. * This file contains functions for handling AMF-service units(SUs). It can be
  48. * viewed as the implementation of the AMF Service Unit class (called SU)
  49. * as described in SAI-Overview-B.02.01. The SA Forum specification
  50. * SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
  51. * and is referred to as 'the spec' below.
  52. *
  53. * The functions in this file are responsible for:
  54. * - instantiating and terminating service units on request
  55. * (considering the dependencies between components described in paragraph
  56. * 3.9.2)
  57. * - creating and deleting CSI-assignment objects between its components and
  58. * CSI-objects upon request
  59. * - receiving error reports from its components and forwarding them to
  60. * appropriate handler (SU or SG or node or cluster)
  61. * - implementing restart of itself and its components (paragraph 3.12.1.2)
  62. * - implementing error escallation level 1 (paragraph 3.12.2.2 in the spec)
  63. * - handling all run time attributes of the AMF SU; all cached
  64. * attributes are stored as variables and sent to the IMM service
  65. * upon the changes described in the specification.
  66. *
  67. * SU contains the following state machines:
  68. * - presence state machine (PRSM)
  69. * - administrative state machine (ADSM) (NOT IN THIS RELEASE)
  70. * - operational state machine (OPSM)
  71. * - readiness state machine (RESM)
  72. * - ha state per service instance (SI)
  73. * - restart control state machine (RCSM)
  74. *
  75. * The presence state machine orders intantiation of its components on request.
  76. * It fully respects the dependency rules between components at instantiation
  77. * such that it orders instantiation simultaneously only of components on the
  78. * same instantiation level. The presence state machine is implemented with
  79. * the states described in the spec and the state transitions are trigged by
  80. * reported state transitions from its contained components according to
  81. * paragraph 3.3.1.1.
  82. *
  83. * The operational state machine is not responsible for any control function.
  84. * It assumes the DISABLED state if an incoming operational state change report
  85. * from a component indicates the component has assumed the DISABLED state.
  86. * Operational state changes are reported to IMM.
  87. *
  88. * The readiness state machine is not used for any control but is updated and
  89. * reported to IMM when it is changed.
  90. *
  91. * The restart control state machine (RCSM) is used to implement level 1 of
  92. * the error escallation polycy described in chapter 3.12.2 of the spec. It
  93. * also implements component restart and service unit restart as described in
  94. * paragraph 3.12.1.2 and 3.12.1.3.
  95. * RCSM contains three composite states.
  96. * Being a composite state means that the state contains substates.
  97. * RCSM composite states are:
  98. * - ESCALLATION_LEVEL (LEVEL_0, LEVEL_1 and LEVEL_2)
  99. * - RESTARTING_COMPONENT (DEACTIVATING, RESTARTING, SETTING and ACTIVATING)
  100. * - RESTARTING_SERVICE_UNIT (DEACTIVATING, TERMINATING, INSTANTIATING,
  101. * and ACTIVATING)
  102. *
  103. * ESCALLATION_LEVEL is a kind of idle state where no actions are performed
  104. * and used only to remember the escallation level. Substate LEVEL_0 indicates
  105. * no escallation. LEVEL_1 indicates that a component restart has been
  106. * executed recently and the escallation timer is still running. At this level
  107. * component restart requests will transition to RESTARTING_COMPONENT but
  108. * if there are too many restart requests before the probation timer expires
  109. * then a transition will be made to LEVEL_2 and the restart request will
  110. * be forwarded to the node instance hosting this component.
  111. * State RESTARTING_SERVICE_UNIT will only be assumed if the node explicitly
  112. * requests the SU to execute a restart of itself (after having evaluated its
  113. * part of the error escallation policy).
  114. *
  115. */
  116. /*
  117. *
  118. */
  119. #include <stdlib.h>
  120. #include <assert.h>
  121. #include <string.h>
  122. #include <errno.h>
  123. #include "amf.h"
  124. #include "util.h"
  125. #include "print.h"
  126. #include "main.h"
  127. static int terminate_all_components_in_level (struct amf_su *su,
  128. SaUint32T current_instantiation_level);
  129. static int are_all_comps_in_level_uninst_or_term_failed (struct amf_su *su);
  130. static int are_all_comps_in_level_instantiated (struct amf_su *su);
  131. static int instantiate_all_components_in_level (struct amf_su *su,
  132. SaUint32T current_instantiation_level);
  133. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su);
  134. typedef struct su_event {
  135. amf_su_event_type_t event_type;
  136. amf_su_t *su;
  137. amf_comp_t *comp;
  138. SaAmfRecommendedRecoveryT recommended_recovery;
  139. } su_event_t;
  140. /**
  141. *
  142. * @param su
  143. * @param comp
  144. * @param su_event
  145. * @param event_type
  146. */
  147. static void su_event_set(struct amf_su *su, struct amf_comp *comp,
  148. SaAmfRecommendedRecoveryT recommended_recovery,
  149. su_event_t *su_event, amf_su_event_type_t event_type)
  150. {
  151. su_event->event_type = event_type;
  152. su_event->comp = comp;
  153. su_event->su = su;
  154. su_event->recommended_recovery = recommended_recovery;
  155. }
  156. static void su_defer_event (amf_su_t *su, amf_comp_t *comp,
  157. SaAmfRecommendedRecoveryT recommended_recovery,
  158. amf_su_event_type_t su_event_type)
  159. {
  160. su_event_t event;
  161. su_event_set(su, comp, recommended_recovery,&event, su_event_type);
  162. ENTER("event_type = %d", event.event_type);
  163. amf_fifo_put (event.event_type, &event.su->deferred_events,
  164. sizeof (su_event_t), &event);
  165. }
  166. static void su_recall_deferred_events (amf_su_t *su)
  167. {
  168. su_event_t su_event;
  169. ENTER ("%s", su->name.value);
  170. if (amf_fifo_get (&su->deferred_events, &su_event)) {
  171. switch (su_event.event_type) {
  172. case SU_COMP_ERROR_SUSPECTED_EV:
  173. amf_su_comp_error_suspected (su_event.su,su_event.comp,
  174. su_event.recommended_recovery);
  175. break;
  176. default:
  177. dprintf("event_type = %d", su_event.event_type);
  178. break;
  179. }
  180. }
  181. }
  182. static int has_component_restarted_max_times (amf_comp_t *comp, amf_su_t *su)
  183. {
  184. return comp->saAmfCompRestartCount >= su->sg->saAmfSGCompRestartMax;
  185. }
  186. #ifdef COMPILE_OUT
  187. static int has_su_restarted_max_times (amf_su_t *su)
  188. {
  189. return su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax;
  190. }
  191. #endif
  192. /**
  193. * This function only logs since the readiness state is runtime
  194. * calculated.
  195. * @param su
  196. * @param amf_readiness_state
  197. */
  198. static void su_readiness_state_set (struct amf_su *su,
  199. SaAmfReadinessStateT readiness_state)
  200. {
  201. log_printf (LOG_NOTICE, "Setting SU '%s' readiness state: %s\n",
  202. su->name.value, amf_readiness_state (readiness_state));
  203. }
  204. static void clear_ha_state (
  205. struct amf_su *su, struct amf_si_assignment *si_assignment)
  206. {
  207. ENTER ("");
  208. si_assignment->saAmfSISUHAState = 0;
  209. }
  210. static void su_presence_state_set (struct amf_su *su,
  211. SaAmfPresenceStateT presence_state)
  212. {
  213. /*
  214. * Set all SI's confirmed HA state to unknown if uninstantiated
  215. */
  216. if (su->saAmfSUPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) {
  217. amf_su_foreach_si_assignment (su, clear_ha_state);
  218. }
  219. su->saAmfSUPresenceState = presence_state;
  220. log_printf (LOG_NOTICE, "Setting SU '%s' presence state: %s\n",
  221. su->name.value, amf_presence_state (presence_state));
  222. if (su->restart_control_state != SU_RC_RESTART_SU_SETTING &&
  223. su->restart_control_state != SU_RC_RESTART_COMP_RESTARTING) {
  224. amf_sg_su_state_changed (su->sg, su, SA_AMF_PRESENCE_STATE,
  225. presence_state);
  226. }
  227. }
  228. void amf_su_operational_state_set (struct amf_su *su,
  229. SaAmfOperationalStateT oper_state)
  230. {
  231. struct amf_comp* comp;
  232. su->saAmfSUOperState = oper_state;
  233. log_printf (LOG_NOTICE, "Setting SU '%s' operational state: %s\n",
  234. su->name.value, amf_op_state (oper_state));
  235. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  236. su_readiness_state_set (su, SA_AMF_READINESS_IN_SERVICE);
  237. for (comp = su->comp_head; comp; comp = comp->next) {
  238. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_IN_SERVICE);
  239. }
  240. } else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
  241. su_readiness_state_set (su, SA_AMF_READINESS_OUT_OF_SERVICE);
  242. for (comp = su->comp_head; comp; comp = comp->next) {
  243. amf_comp_readiness_state_set (comp, SA_AMF_READINESS_OUT_OF_SERVICE);
  244. }
  245. }
  246. }
  247. static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
  248. struct amf_si_assignment *si_assignment, SaAmfHAStateT ha_state)
  249. {
  250. struct amf_csi_assignment *csi_assignment;
  251. dprintf (" Creating CSI '%s' to comp '%s' with hastate %s\n",
  252. getSaNameT (&csi->name), getSaNameT (&comp->name),
  253. amf_ha_state (ha_state));
  254. csi_assignment = amf_malloc (sizeof (struct amf_csi_assignment));
  255. csi_assignment->next = csi->assigned_csis;
  256. csi->assigned_csis = csi_assignment;
  257. amf_comp_dn_make (comp, &csi_assignment->name);
  258. csi_assignment->comp = comp;
  259. csi_assignment->csi = csi;
  260. csi_assignment->saAmfCSICompHAState = 0; /* undefined confirmed HA state */
  261. csi_assignment->requested_ha_state = ha_state;
  262. csi_assignment->si_assignment = si_assignment;
  263. }
  264. static void comp_restart (struct amf_comp *comp)
  265. {
  266. SaNameT dn;
  267. ENTER ("'%s'", comp->name.value);
  268. amf_comp_dn_make (comp, &dn);
  269. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  270. "action: Component restart", dn.value);
  271. comp->su->restart_control_state = SU_RC_RESTART_COMP_DEACTIVATING;
  272. comp->su->restart_control_state = SU_RC_RESTART_COMP_RESTARTING;
  273. comp->su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  274. amf_comp_restart (comp);
  275. }
  276. static void si_ha_state_assumed_cbfn (
  277. struct amf_si_assignment *si_assignment, int result)
  278. {
  279. struct amf_si_assignment *tmp_si_assignment;
  280. struct amf_comp *comp;
  281. struct amf_csi_assignment *csi_assignment;
  282. int all_confirmed = 1;
  283. ENTER ("");
  284. tmp_si_assignment = amf_su_get_next_si_assignment(si_assignment->su, NULL);
  285. while (tmp_si_assignment != NULL) {
  286. for (comp = tmp_si_assignment->su->comp_head; comp != NULL;
  287. comp = comp->next) {
  288. csi_assignment = amf_comp_get_next_csi_assignment(comp, NULL);
  289. while (csi_assignment != NULL) {
  290. if (csi_assignment->requested_ha_state !=
  291. csi_assignment->saAmfCSICompHAState) {
  292. all_confirmed = 0;
  293. }
  294. csi_assignment = amf_comp_get_next_csi_assignment(
  295. comp, csi_assignment);
  296. }
  297. }
  298. tmp_si_assignment = amf_su_get_next_si_assignment(
  299. si_assignment->su, tmp_si_assignment);
  300. }
  301. if (all_confirmed) {
  302. switch (si_assignment->su->restart_control_state) {
  303. case SU_RC_RESTART_COMP_SETTING:
  304. log_printf (LOG_NOTICE, "Component restart recovery finished");
  305. break;
  306. case SU_RC_RESTART_SU_SETTING:
  307. log_printf (LOG_NOTICE, "SU restart recovery finished");
  308. break;
  309. default:
  310. assert (0);
  311. break;
  312. }
  313. si_assignment->su->restart_control_state =
  314. si_assignment->su->escalation_level_history_state;
  315. su_recall_deferred_events (si_assignment->su);
  316. }
  317. }
  318. static void reassign_sis(struct amf_su *su)
  319. {
  320. struct amf_si_assignment *si_assignment;
  321. ENTER ("");
  322. si_assignment = amf_su_get_next_si_assignment(su, NULL);
  323. while (si_assignment != NULL) {
  324. si_assignment->saAmfSISUHAState = 0; /* unknown */
  325. amf_si_ha_state_assume (si_assignment, si_ha_state_assumed_cbfn);
  326. si_assignment = amf_su_get_next_si_assignment(su, si_assignment);
  327. }
  328. }
  329. static int is_any_component_instantiating (amf_su_t *su)
  330. {
  331. amf_comp_t *component;
  332. int any_component_instantiating = 0;
  333. for (component = su->comp_head; component != NULL;
  334. component = component->next) {
  335. if (component->saAmfCompPresenceState ==
  336. SA_AMF_PRESENCE_INSTANTIATING) {
  337. any_component_instantiating = 1;
  338. break;
  339. }
  340. }
  341. return any_component_instantiating;
  342. }
  343. static int is_any_component_terminating (amf_su_t *su)
  344. {
  345. amf_comp_t *component;
  346. int any_component_terminating = 0;
  347. for (component = su->comp_head; component != NULL;
  348. component = component->next) {
  349. if (component->saAmfCompPresenceState ==
  350. SA_AMF_PRESENCE_TERMINATING) {
  351. any_component_terminating = 1;
  352. break;
  353. }
  354. }
  355. return any_component_terminating;
  356. }
  357. static int is_any_component_restarting (amf_su_t *su)
  358. {
  359. amf_comp_t *component;
  360. int any_component_terminating = 0;
  361. for (component = su->comp_head; component != NULL;
  362. component = component->next) {
  363. if (component->saAmfCompPresenceState ==
  364. SA_AMF_PRESENCE_RESTARTING) {
  365. any_component_terminating = 1;
  366. break;
  367. }
  368. }
  369. return any_component_terminating;
  370. }
  371. static int is_any_comp_instantiation_failed (amf_su_t *su)
  372. {
  373. amf_comp_t *comp_;
  374. int comp_instantiation_failed = 0;
  375. for (comp_ = su->comp_head; comp_ != NULL; comp_ = comp_->next) {
  376. if (comp_->saAmfCompPresenceState ==
  377. SA_AMF_PRESENCE_INSTANTIATION_FAILED) {
  378. comp_instantiation_failed = 1;
  379. break;
  380. }
  381. }
  382. return comp_instantiation_failed;
  383. }
  384. static SaAmfPresenceStateT get_worst_comps_presence_state_in_su (amf_su_t *su)
  385. {
  386. amf_comp_t *component;
  387. SaAmfPresenceStateT worst_presence_state = 0;
  388. for (component = su->comp_head; component != NULL;
  389. component = component->next) {
  390. if (component->saAmfCompPresenceState > worst_presence_state) {
  391. worst_presence_state = component->saAmfCompPresenceState;
  392. }
  393. }
  394. return worst_presence_state;
  395. }
  396. static void su_comp_presence_state_changed (struct amf_su *su,
  397. struct amf_comp *comp, int state)
  398. {
  399. ENTER ("'%s', '%s' %d %d", su->name.value, comp->name.value, state,
  400. su->restart_control_state);
  401. switch (state) {
  402. case SA_AMF_PRESENCE_INSTANTIATED:
  403. switch (su->restart_control_state) {
  404. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  405. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  406. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  407. if (!is_any_component_instantiating (su)) {
  408. if (are_all_comps_in_level_instantiated (su)) {
  409. if (instantiate_all_components_in_level (su,
  410. ++comp->su->current_comp_instantiation_level)) {
  411. /* All levels of instantiation is done */
  412. su_presence_state_set (comp->su,
  413. SA_AMF_PRESENCE_INSTANTIATED);
  414. }
  415. } else {
  416. if (is_any_comp_instantiation_failed (su)) {
  417. su_presence_state_set (comp->su,
  418. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  419. } else {
  420. assert (0);
  421. }
  422. }
  423. }
  424. break;
  425. case SU_RC_RESTART_COMP_RESTARTING:
  426. su->restart_control_state = SU_RC_RESTART_COMP_SETTING;
  427. reassign_sis (comp->su);
  428. break;
  429. case SU_RC_RESTART_SU_INSTANTIATING:
  430. if (!is_any_component_restarting(su)) {
  431. if (amf_su_are_all_comps_in_su (
  432. comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
  433. su->restart_control_state = SU_RC_RESTART_SU_SETTING;
  434. su_presence_state_set (comp->su,
  435. SA_AMF_PRESENCE_INSTANTIATED);
  436. reassign_sis (comp->su);
  437. } else {
  438. if (is_any_comp_instantiation_failed (su)) {
  439. su_presence_state_set (comp->su,
  440. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  441. } else {
  442. assert (0);
  443. }
  444. }
  445. }
  446. break;
  447. default:
  448. dprintf ("state %d", su->restart_control_state);
  449. assert (0);
  450. break;
  451. }
  452. break;
  453. case SA_AMF_PRESENCE_UNINSTANTIATED:
  454. if (!is_any_component_terminating (su)) {
  455. if (are_all_comps_in_level_uninst_or_term_failed (su)) {
  456. if (terminate_all_components_in_level (su,
  457. --su->current_comp_instantiation_level)) {
  458. su_presence_state_set (su,
  459. get_worst_comps_presence_state_in_su (su));
  460. }
  461. }
  462. }
  463. break;
  464. case SA_AMF_PRESENCE_INSTANTIATING:
  465. su_presence_state_set (comp->su,SA_AMF_PRESENCE_INSTANTIATING);
  466. break;
  467. case SA_AMF_PRESENCE_RESTARTING:
  468. break;
  469. case SA_AMF_PRESENCE_TERMINATING:
  470. break;
  471. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  472. switch (su->restart_control_state) {
  473. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  474. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  475. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  476. if (!is_any_component_instantiating (su)) {
  477. su_presence_state_set (comp->su,
  478. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  479. }
  480. break;
  481. case SU_RC_RESTART_COMP_RESTARTING:
  482. su->restart_control_state =
  483. su->escalation_level_history_state;
  484. su_presence_state_set (comp->su,
  485. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  486. break;
  487. case SU_RC_RESTART_SU_INSTANTIATING:
  488. if (!is_any_component_instantiating (su)) {
  489. su->restart_control_state =
  490. su->escalation_level_history_state;
  491. su_presence_state_set (comp->su,
  492. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  493. }
  494. break;
  495. default:
  496. assert (0);
  497. break;
  498. }
  499. #ifdef COMPILE_OUT
  500. su_presence_state_set (comp->su,
  501. SA_AMF_PRESENCE_INSTANTIATION_FAILED);
  502. #endif
  503. break;
  504. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  505. switch (su->restart_control_state) {
  506. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  507. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  508. case SU_RC_IDLE_ESCALATION_LEVEL_2:
  509. if (!is_any_component_terminating (su)) {
  510. if (are_all_comps_in_level_uninst_or_term_failed (su)) {
  511. if (terminate_all_components_in_level (su,
  512. --su->current_comp_instantiation_level)) {
  513. su_presence_state_set (su,
  514. get_worst_comps_presence_state_in_su (su));
  515. }
  516. }
  517. }
  518. break;
  519. case SU_RC_RESTART_COMP_RESTARTING:
  520. su->restart_control_state =
  521. su->escalation_level_history_state;
  522. su_presence_state_set (comp->su,
  523. SA_AMF_PRESENCE_TERMINATION_FAILED);
  524. break;
  525. case SU_RC_RESTART_SU_INSTANTIATING:
  526. /*
  527. * TODO Reconsider SU restart control concerning
  528. * TERMINATING and INSANITATION
  529. */
  530. case SU_RC_RESTART_SU_TERMINATING:
  531. if (!is_any_component_terminating (su)) {
  532. su->restart_control_state =
  533. su->escalation_level_history_state;
  534. su_presence_state_set (comp->su,
  535. SA_AMF_PRESENCE_TERMINATION_FAILED);
  536. }
  537. break;
  538. default:
  539. assert (0);
  540. break;
  541. }
  542. break;
  543. default:
  544. assert (0);
  545. break;
  546. }
  547. }
  548. static void su_comp_op_state_changed (
  549. struct amf_su *su, struct amf_comp *comp, int state)
  550. {
  551. ENTER ("'%s', '%s' %d", su->name.value, comp->name.value, state);
  552. switch (state) {
  553. case SA_AMF_OPERATIONAL_ENABLED:
  554. {
  555. struct amf_comp *comp_compare;
  556. int all_set = 1;
  557. for (comp_compare = comp->su->comp_head;
  558. comp_compare != NULL; comp_compare = comp_compare->next) {
  559. if (comp_compare->saAmfCompOperState !=
  560. SA_AMF_OPERATIONAL_ENABLED) {
  561. all_set = 0;
  562. break;
  563. }
  564. }
  565. if (all_set) {
  566. amf_su_operational_state_set (comp->su,
  567. SA_AMF_OPERATIONAL_ENABLED);
  568. } else {
  569. amf_su_operational_state_set (comp->su,
  570. SA_AMF_OPERATIONAL_DISABLED);
  571. }
  572. break;
  573. }
  574. case SA_AMF_OPERATIONAL_DISABLED:
  575. amf_su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_DISABLED);
  576. break;
  577. default:
  578. assert (0);
  579. break;
  580. }
  581. return;
  582. }
  583. /**
  584. *
  585. * @param su
  586. * @param comp
  587. */
  588. static int instantiate_all_components_in_level (struct amf_su *su,
  589. SaUint32T current_instantiation_level)
  590. {
  591. amf_comp_t *comp;
  592. SaUint32T all_components_instantiated = 1;
  593. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  594. if (su->current_comp_instantiation_level ==
  595. comp->saAmfCompInstantiationLevel) {
  596. all_components_instantiated = 0;
  597. amf_comp_instantiate (comp);
  598. }
  599. }
  600. return all_components_instantiated;
  601. }
  602. static int are_all_comps_in_level_instantiated (struct amf_su *su)
  603. {
  604. SaUint32T level = su->current_comp_instantiation_level;
  605. amf_comp_t *comp;
  606. int all = 1;
  607. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  608. if (level == comp->saAmfCompInstantiationLevel) {
  609. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
  610. all = 0;
  611. break;
  612. }
  613. }
  614. }
  615. return all;
  616. }
  617. static int are_all_comps_in_level_uninst_or_term_failed(
  618. struct amf_su *su)
  619. {
  620. SaUint32T level = su->current_comp_instantiation_level;
  621. amf_comp_t *comp;
  622. int all = 1;
  623. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  624. if (level == comp->saAmfCompInstantiationLevel) {
  625. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_UNINSTANTIATED &&
  626. comp->saAmfCompPresenceState != SA_AMF_PRESENCE_TERMINATION_FAILED) {
  627. all = 0;
  628. break;
  629. }
  630. }
  631. }
  632. return all;
  633. }
  634. int amf_su_are_all_comps_in_su (struct amf_su *su,
  635. SaAmfPresenceStateT state)
  636. {
  637. int all_comps_in_su_are_set = 1;
  638. amf_comp_t *component;
  639. for (component = su->comp_head; component != NULL;
  640. component = component->next) {
  641. if (component->saAmfCompPresenceState != state) {
  642. all_comps_in_su_are_set = 0;
  643. }
  644. }
  645. return all_comps_in_su_are_set;
  646. }
  647. void amf_su_restart (struct amf_su *su)
  648. {
  649. struct amf_comp *comp;
  650. SaNameT dn;
  651. ENTER ("'%s'", su->name.value);
  652. amf_su_dn_make (su, &dn);
  653. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  654. "action: SU restart", dn.value);
  655. su->restart_control_state = SU_RC_RESTART_SU_DEACTIVATING;
  656. su->restart_control_state = SU_RC_RESTART_SU_INSTANTIATING;
  657. su->escalation_level_history_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  658. su->saAmfSURestartCount += 1;
  659. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  660. amf_comp_restart (comp);
  661. }
  662. }
  663. int amf_su_instantiate (struct amf_su *su)
  664. {
  665. ENTER ("'%s %d'", su->name.value, su->saAmfSUPresenceState);
  666. int performs_instantiating = 1;
  667. switch (su->saAmfSUPresenceState) {
  668. case SA_AMF_PRESENCE_UNINSTANTIATED:
  669. instantiate_all_components_in_level(su,
  670. su_lowest_comp_instantiation_level_set (su));
  671. break;
  672. case SA_AMF_PRESENCE_RESTARTING:
  673. case SA_AMF_PRESENCE_INSTANTIATING:
  674. break;
  675. case SA_AMF_PRESENCE_INSTANTIATED:
  676. case SA_AMF_PRESENCE_TERMINATING:
  677. case SA_AMF_PRESENCE_INSTANTIATION_FAILED:
  678. case SA_AMF_PRESENCE_TERMINATION_FAILED:
  679. performs_instantiating = 0;
  680. break;
  681. default:
  682. assert (0);
  683. break;
  684. }
  685. return performs_instantiating;
  686. }
  687. amf_si_assignment_t *amf_su_assign_si (struct amf_su *su, struct amf_si *si,
  688. SaAmfHAStateT ha_state)
  689. {
  690. struct amf_si_assignment *si_assignment;
  691. dprintf ("Creating SI '%s' to SU '%s' with hastate %s\n",
  692. getSaNameT (&si->name), getSaNameT (&su->name),
  693. amf_ha_state (ha_state));
  694. si_assignment = amf_malloc (sizeof (struct amf_si_assignment));
  695. amf_su_dn_make (su, &si_assignment->name);
  696. si_assignment->saAmfSISUHAState = 0; /* undefined confirmed HA state */
  697. si_assignment->requested_ha_state = ha_state;
  698. si_assignment->next = si->assigned_sis;
  699. si->assigned_sis = si_assignment;
  700. si_assignment->si = si;
  701. si_assignment->su = su;
  702. {
  703. struct amf_csi *csi;
  704. struct amf_comp *comp;
  705. SaNameT *cs_type;
  706. int i;
  707. /*
  708. ** for each component in SU, find a CSI in the SI with the same type
  709. */
  710. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  711. int no_of_cs_types = 0;
  712. for (i = 0; comp->saAmfCompCsTypes[i]; i++) {
  713. cs_type = comp->saAmfCompCsTypes[i];
  714. no_of_cs_types++;
  715. int no_of_assignments = 0;
  716. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  717. if (!memcmp(csi->saAmfCSTypeName.value, cs_type->value,
  718. cs_type->length)) {
  719. comp_assign_csi (comp, csi, si_assignment, ha_state);
  720. no_of_assignments++;
  721. }
  722. }
  723. if (no_of_assignments == 0) {
  724. log_printf (
  725. LOG_WARNING, "\t No CSIs of type %s configured?!!\n",
  726. getSaNameT (cs_type));
  727. }
  728. }
  729. if (no_of_cs_types == 0) {
  730. log_printf (LOG_LEVEL_ERROR,
  731. "\t No CS types configured for comp %s ?!!\n",
  732. getSaNameT (&comp->name));
  733. }
  734. }
  735. }
  736. return si_assignment;
  737. }
  738. /**
  739. * Used by a component to report a state change event
  740. * @param su
  741. * @param comp
  742. * @param type type of state
  743. * @param state new state
  744. */
  745. void amf_su_comp_state_changed (
  746. struct amf_su *su, struct amf_comp *comp, SaAmfStateT type, int state)
  747. {
  748. switch (type) {
  749. case SA_AMF_PRESENCE_STATE:
  750. su_comp_presence_state_changed (su, comp, state);
  751. break;
  752. case SA_AMF_OP_STATE:
  753. su_comp_op_state_changed (su, comp, state);
  754. break;
  755. default:
  756. assert (0);
  757. break;
  758. }
  759. }
  760. /**
  761. * Determine if the SU is hosted on the local node.
  762. * @param su
  763. *
  764. * @return int
  765. */
  766. int amf_su_is_local (struct amf_su *su)
  767. {
  768. if (name_match (&this_amf_node->name, &su->saAmfSUHostedByNode)) {
  769. return 1;
  770. } else {
  771. return 0;
  772. }
  773. }
  774. static void su_rc_enter_idle_escalation_level_1 (amf_comp_t *component,
  775. SaAmfRecommendedRecoveryT recommended_recovery)
  776. {
  777. ENTER("");
  778. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_1;
  779. if (has_component_restarted_max_times (component, component->su)) {
  780. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  781. amf_su_comp_error_suspected (component->su, component, recommended_recovery);
  782. } else {
  783. comp_restart (component);
  784. }
  785. }
  786. static void su_rc_enter_idle_escalation_level_2 (amf_comp_t *component,
  787. SaAmfRecommendedRecoveryT recommended_recovery)
  788. {
  789. ENTER("");
  790. component->su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_2;
  791. amf_node_t *node = amf_node_find (&component->su->saAmfSUHostedByNode);
  792. amf_node_comp_restart_req (node, component);
  793. }
  794. /**
  795. * Called by a component to report a suspected error on a component
  796. * @param su
  797. * @param comp
  798. * @param recommended_recovery
  799. */
  800. void amf_su_comp_error_suspected (
  801. struct amf_su *su,
  802. struct amf_comp *comp,
  803. SaAmfRecommendedRecoveryT recommended_recovery)
  804. {
  805. ENTER ("Comp '%s', SU '%s' %d", comp->name.value, su->name.value,
  806. su->restart_control_state);
  807. switch (su->restart_control_state) {
  808. case SU_RC_IDLE_ESCALATION_LEVEL_0:
  809. su_rc_enter_idle_escalation_level_1 (comp,
  810. recommended_recovery);
  811. break;
  812. case SU_RC_IDLE_ESCALATION_LEVEL_1:
  813. if (has_component_restarted_max_times (comp, su)) {
  814. su_rc_enter_idle_escalation_level_2 (comp,
  815. recommended_recovery);
  816. } else {
  817. comp_restart (comp);
  818. }
  819. break;
  820. case SU_RC_IDLE_ESCALATION_LEVEL_2: {
  821. amf_node_t *node = amf_node_find (&comp->su->saAmfSUHostedByNode);
  822. amf_node_comp_restart_req (node, comp);
  823. #ifdef COMPILE_OUT
  824. if (su->saAmfSURestartCount >= su->sg->saAmfSGSuRestartMax) {
  825. /*
  826. * TODO: delegate to node
  827. */
  828. SaNameT dn;
  829. amf_comp_operational_state_set (comp,
  830. SA_AMF_OPERATIONAL_DISABLED);
  831. amf_su_operational_state_set (su,
  832. SA_AMF_OPERATIONAL_DISABLED);
  833. amf_comp_dn_make (comp, &dn);
  834. log_printf (LOG_NOTICE, "Error detected for '%s', recovery "
  835. "action:\n\t\tSU failover", dn.value);
  836. amf_sg_failover_su_req (comp->su->sg, comp->su, this_amf_node);
  837. return;
  838. } else {
  839. su_restart (comp->su);
  840. }
  841. #endif
  842. break;
  843. }
  844. case SU_RC_RESTART_SU_SETTING:
  845. case SU_RC_RESTART_COMP_RESTARTING:
  846. case SU_RC_RESTART_COMP_SETTING:
  847. /* TODO: Complete the implementation of SU defer event */
  848. su_defer_event (su, comp, recommended_recovery,
  849. SU_COMP_ERROR_SUSPECTED_EV);
  850. break;
  851. default:
  852. dprintf ("restart_control_state = %d",su->restart_control_state);
  853. break;
  854. }
  855. }
  856. void amf_su_init (void)
  857. {
  858. log_init ("AMF");
  859. }
  860. static int get_instantiation_max_level (amf_su_t *su)
  861. {
  862. amf_comp_t *comp;
  863. int instantiation_level = 0;
  864. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  865. if (comp->saAmfCompInstantiationLevel > instantiation_level) {
  866. instantiation_level = comp->saAmfCompInstantiationLevel;
  867. }
  868. }
  869. return instantiation_level;
  870. }
  871. /**
  872. *
  873. * @param su
  874. * @param comp
  875. */
  876. static int terminate_all_components_in_level (struct amf_su *su,
  877. SaUint32T current_instantiation_level)
  878. {
  879. amf_comp_t *comp;
  880. int all_components_in_level = 1;
  881. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  882. /*
  883. * Terminate all components in instantiation level in SU
  884. * abruptly.
  885. */
  886. if (comp->saAmfCompInstantiationLevel == current_instantiation_level) {
  887. amf_comp_error_suspected_set (comp);
  888. amf_comp_terminate (comp);
  889. all_components_in_level = 0;
  890. }
  891. }
  892. return all_components_in_level;
  893. }
  894. /**
  895. * su_current_instantiation_level_init
  896. * @param su
  897. */
  898. static SaUint32T su_lowest_comp_instantiation_level_set (struct amf_su *su)
  899. {
  900. amf_comp_t *component = su->comp_head;
  901. int comp_instantiation_level = component->saAmfCompInstantiationLevel;
  902. for (; component != NULL; component = component->next) {
  903. TRACE1("component->saAmfCompInstantiationLevel=%d",
  904. component->saAmfCompInstantiationLevel);
  905. if (component->saAmfCompInstantiationLevel <
  906. comp_instantiation_level) {
  907. comp_instantiation_level =
  908. component->saAmfCompInstantiationLevel;
  909. }
  910. }
  911. su->current_comp_instantiation_level = comp_instantiation_level;
  912. return comp_instantiation_level;
  913. }
  914. void amf_su_terminate (struct amf_su *su)
  915. {
  916. ENTER ("'%s'", su->name.value);
  917. su->current_comp_instantiation_level = get_instantiation_max_level (su);
  918. terminate_all_components_in_level (su, su->current_comp_instantiation_level);
  919. }
  920. char *amf_su_dn_make (struct amf_su *su, SaNameT *name)
  921. {
  922. int i;
  923. assert (su != NULL);
  924. i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  925. "safSu=%s,safSg=%s,safApp=%s",
  926. su->name.value, su->sg->name.value, su->sg->application->name.value);
  927. assert (i <= SA_MAX_NAME_LENGTH);
  928. name->length = i;
  929. return (char *)name->value;
  930. }
  931. struct amf_si_assignment *amf_su_get_next_si_assignment (
  932. struct amf_su *su, const struct amf_si_assignment *si_assignment)
  933. {
  934. struct amf_si *si;
  935. struct amf_si_assignment *tmp_si_assignment;
  936. SaNameT dn;
  937. amf_su_dn_make (su, &dn);
  938. if (si_assignment == NULL) {
  939. assert (su->sg);
  940. assert (su->sg->application);
  941. assert (su->sg->application->si_head);
  942. si = su->sg->application->si_head;
  943. tmp_si_assignment = si->assigned_sis;
  944. } else {
  945. tmp_si_assignment = si_assignment->next;
  946. if (tmp_si_assignment == NULL) {
  947. si = si_assignment->si->next;
  948. if (si == NULL) {
  949. return NULL;
  950. } else {
  951. tmp_si_assignment = si->assigned_sis;
  952. }
  953. } else {
  954. si = tmp_si_assignment->si;
  955. }
  956. }
  957. for (; si != NULL; si = si->next) {
  958. if (tmp_si_assignment == NULL && si != NULL) {
  959. tmp_si_assignment = si->assigned_sis;
  960. }
  961. for (; tmp_si_assignment != NULL;
  962. tmp_si_assignment = tmp_si_assignment->next) {
  963. if (name_match (&tmp_si_assignment->name, &dn)) {
  964. return tmp_si_assignment;
  965. }
  966. }
  967. }
  968. return NULL;
  969. }
  970. void amf_su_foreach_si_assignment (
  971. struct amf_su *su,
  972. void (*foreach_fn)(struct amf_su *su,
  973. struct amf_si_assignment *si_assignment))
  974. {
  975. struct amf_si_assignment *si_assignment;
  976. assert (foreach_fn != NULL);
  977. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  978. while (si_assignment != NULL) {
  979. foreach_fn (su, si_assignment);
  980. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  981. }
  982. }
  983. int amf_su_get_saAmfSUNumCurrActiveSIs(struct amf_su *su)
  984. {
  985. int cnt = 0;
  986. struct amf_si_assignment *si_assignment;
  987. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  988. while (si_assignment != NULL) {
  989. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  990. si_assignment->requested_ha_state == SA_AMF_HA_ACTIVE) {
  991. cnt++;
  992. } else {
  993. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
  994. cnt++;
  995. }
  996. }
  997. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  998. }
  999. return cnt;
  1000. }
  1001. int amf_su_get_saAmfSUNumCurrStandbySIs(struct amf_su *su)
  1002. {
  1003. int cnt = 0;
  1004. struct amf_si_assignment *si_assignment;
  1005. si_assignment = amf_su_get_next_si_assignment (su, NULL);
  1006. while (si_assignment != NULL) {
  1007. if (su->sg->avail_state == SG_AC_AssigningOnRequest &&
  1008. si_assignment->requested_ha_state == SA_AMF_HA_STANDBY) {
  1009. cnt++;
  1010. } else {
  1011. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  1012. cnt++;
  1013. }
  1014. }
  1015. si_assignment = amf_su_get_next_si_assignment (su, si_assignment);
  1016. }
  1017. return cnt;
  1018. }
  1019. SaAmfReadinessStateT amf_su_get_saAmfSUReadinessState (struct amf_su *su)
  1020. {
  1021. if ((su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) &&
  1022. ((su->saAmfSUPresenceState == SA_AMF_PRESENCE_INSTANTIATED) ||
  1023. (su->saAmfSUPresenceState == SA_AMF_PRESENCE_RESTARTING))) {
  1024. return SA_AMF_READINESS_IN_SERVICE;
  1025. } else if (su->saAmfSUOperState == SA_AMF_OPERATIONAL_ENABLED) {
  1026. return SA_AMF_READINESS_STOPPING;
  1027. } else {
  1028. return SA_AMF_READINESS_OUT_OF_SERVICE;
  1029. }
  1030. }
  1031. /**
  1032. * Constructor for SU objects. Adds SU last in the ordered
  1033. * list owned by the specified SG. Always returns a
  1034. * valid SU object, out-of-memory problems are handled here.
  1035. * Default values are initialized.
  1036. * @param sg
  1037. * @param name
  1038. *
  1039. * @return struct amf_su*
  1040. */
  1041. struct amf_su *amf_su_new (struct amf_sg *sg, char *name)
  1042. {
  1043. struct amf_su *tail = sg->su_head;
  1044. struct amf_su *su = amf_calloc (1, sizeof (struct amf_su));
  1045. while (tail != NULL) {
  1046. if (tail->next == NULL) {
  1047. break;
  1048. }
  1049. tail = tail->next;
  1050. }
  1051. if (tail == NULL) {
  1052. sg->su_head = su;
  1053. } else {
  1054. tail->next = su;
  1055. }
  1056. su->sg = sg;
  1057. /* setup default values from spec. */
  1058. su->saAmfSURank = 0;
  1059. su->saAmfSUIsExternal = 0;
  1060. su->saAmfSUFailover = 1;
  1061. su->saAmfSUAdminState = SA_AMF_ADMIN_UNLOCKED;
  1062. su->saAmfSUOperState = SA_AMF_OPERATIONAL_DISABLED;
  1063. su->saAmfSUPresenceState = SA_AMF_PRESENCE_UNINSTANTIATED;
  1064. su->restart_control_state = SU_RC_IDLE_ESCALATION_LEVEL_0;
  1065. su->current_comp_instantiation_level = 0;
  1066. setSaNameT (&su->name, name);
  1067. return su;
  1068. }
  1069. void amf_su_delete (struct amf_su *su)
  1070. {
  1071. struct amf_comp *comp;
  1072. for (comp = su->comp_head; comp != NULL;) {
  1073. struct amf_comp *tmp = comp;
  1074. comp = comp->next;
  1075. amf_comp_delete (tmp);
  1076. }
  1077. free (su);
  1078. }
  1079. void *amf_su_serialize (struct amf_su *su, int *len)
  1080. {
  1081. char *buf = NULL;
  1082. int offset = 0, size = 0;
  1083. TRACE8 ("%s", su->name.value);
  1084. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->name);
  1085. buf = amf_serialize_SaUint32T (buf, &size, &offset, su->saAmfSURank);
  1086. buf = amf_serialize_SaUint32T (
  1087. buf, &size, &offset, su->saAmfSUNumComponents);
  1088. buf = amf_serialize_SaUint32T (
  1089. buf, &size, &offset, su->saAmfSUIsExternal);
  1090. buf = amf_serialize_SaUint32T (
  1091. buf, &size, &offset, su->saAmfSUFailover);
  1092. buf = amf_serialize_SaUint32T (
  1093. buf, &size, &offset, su->saAmfSUPreInstantiable);
  1094. buf = amf_serialize_SaUint32T (
  1095. buf, &size, &offset, su->saAmfSUOperState);
  1096. buf = amf_serialize_SaUint32T (
  1097. buf, &size, &offset, su->saAmfSUAdminState);
  1098. buf = amf_serialize_SaUint32T (
  1099. buf, &size, &offset, su->saAmfSUPresenceState);
  1100. buf = amf_serialize_SaNameT (buf, &size, &offset, &su->saAmfSUHostedByNode);
  1101. buf = amf_serialize_SaUint32T (
  1102. buf, &size, &offset, su->saAmfSURestartCount);
  1103. buf = amf_serialize_SaUint32T (
  1104. buf, &size, &offset, su->restart_control_state);
  1105. buf = amf_serialize_SaUint32T (
  1106. buf, &size, &offset, su->escalation_level_history_state);
  1107. buf = amf_serialize_SaStringT (
  1108. buf, &size, &offset, su->clccli_path);
  1109. buf = amf_serialize_SaUint32T (
  1110. buf, &size, &offset, su->su_failover_cnt);
  1111. buf = amf_serialize_SaUint32T (
  1112. buf, &size, &offset, su->current_comp_instantiation_level);
  1113. *len = offset;
  1114. return buf;
  1115. }
  1116. struct amf_su *amf_su_deserialize (struct amf_sg *sg, char *buf)
  1117. {
  1118. char *tmp = buf;
  1119. struct amf_su *su = amf_su_new (sg, "");
  1120. tmp = amf_deserialize_SaNameT (tmp, &su->name);
  1121. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURank);
  1122. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUNumComponents);
  1123. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUIsExternal);
  1124. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUFailover);
  1125. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPreInstantiable);
  1126. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUOperState);
  1127. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUAdminState);
  1128. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSUPresenceState);
  1129. tmp = amf_deserialize_SaNameT (tmp, &su->saAmfSUHostedByNode);
  1130. tmp = amf_deserialize_SaUint32T (tmp, &su->saAmfSURestartCount);
  1131. tmp = amf_deserialize_SaUint32T (tmp, &su->restart_control_state);
  1132. tmp = amf_deserialize_SaUint32T (tmp, &su->escalation_level_history_state);
  1133. tmp = amf_deserialize_SaStringT (tmp, &su->clccli_path);
  1134. tmp = amf_deserialize_SaUint32T (tmp, &su->su_failover_cnt);
  1135. tmp = amf_deserialize_SaUint32T (tmp, &su->current_comp_instantiation_level);
  1136. return su;
  1137. }
  1138. struct amf_su *amf_su_find (struct amf_cluster *cluster, SaNameT *name)
  1139. {
  1140. struct amf_application *app;
  1141. struct amf_sg *sg;
  1142. struct amf_su *su = NULL;
  1143. char *app_name;
  1144. char *sg_name;
  1145. char *su_name;
  1146. char *ptrptr;
  1147. char *buf;
  1148. assert (cluster != NULL && name != NULL);
  1149. /* malloc new buffer since strtok_r writes to its first argument */
  1150. buf = amf_malloc (name->length + 1);
  1151. memcpy (buf, name->value, name->length + 1);
  1152. su_name = strtok_r(buf, ",", &ptrptr);
  1153. sg_name = strtok_r(NULL, ",", &ptrptr);
  1154. app_name = strtok_r(NULL, ",", &ptrptr);
  1155. if (su_name == NULL || sg_name == NULL || app_name == NULL) {
  1156. goto end;
  1157. }
  1158. su_name += 6;
  1159. sg_name += 6;
  1160. app_name += 7;
  1161. app = amf_application_find (cluster, app_name);
  1162. if (app == NULL) {
  1163. goto end;
  1164. }
  1165. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1166. if (strncmp (sg_name, (char*)sg->name.value,
  1167. sg->name.length) == 0) {
  1168. for (su = sg->su_head; su != NULL; su = su->next) {
  1169. if (su->name.length == strlen(su_name) &&
  1170. strncmp (su_name, (char*)su->name.value,
  1171. su->name.length) == 0) {
  1172. goto end;
  1173. }
  1174. }
  1175. }
  1176. }
  1177. end:
  1178. free (buf);
  1179. return su;
  1180. }