amfnode.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. /** @file amfnode.c
  2. *
  3. * Copyright (c) 2006 Ericsson AB.
  4. * Author: Hans Feldt, Anders Eriksson, Lars Holm
  5. * - Constructors/destructors
  6. * - Serializers/deserializers
  7. *
  8. * All rights reserved.
  9. *
  10. *
  11. * This software licensed under BSD license, the text of which follows:
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright notice,
  17. * this list of conditions and the following disclaimer.
  18. * - Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  22. * contributors may be used to endorse or promote products derived from this
  23. * software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  35. * THE POSSIBILITY OF SUCH DAMAGE.
  36. *
  37. * AMF Node Class Implementation
  38. *
  39. * This file contains functions for handling AMF nodes. It can be
  40. * viewed as the implementation of the AMF Node class (called NODE)
  41. * as described in SAI-Overview-B.02.01. The SA Forum specification
  42. * SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
  43. * and is referred to as 'the spec' below.
  44. *
  45. * The functions in this file are responsible for:
  46. * - controlling the instantiation of the SUs hosted on current node and
  47. * controlling the assigning of workload to them when a node joins the
  48. * cluster (cluster start is controlled by the Cluster Class)
  49. * - controlling node level recovery and repair functions
  50. * - implementing error escallation level 2 and 3 (paragraph 3.12.2.2 and
  51. * 3.12.2.3 in the spec)
  52. * - handling run time attributes of the AMF NODE; cached
  53. * attributes are stored as variables and sent to the IMM service (future)
  54. * upon the changes described in the specification
  55. *
  56. * The node class contains the following state machines:
  57. * - administrative state machine (ADSM)
  58. * - operational state machine (OPSM)
  59. * - availability control state machine (ACSM)
  60. *
  61. * The administrative state machine will be implemented in the future.
  62. *
  63. * The operational state machine is primarily used to report status of the
  64. * node.
  65. *
  66. * The availability control state machine is used for control purposes.
  67. * ACSM contains three states of which two are composite.
  68. * Being a composite state means that the state contains substates.
  69. * ACSM states are:
  70. * - REPAIR_NEEDED
  71. * - ESCALLATION_LEVEL (LEVEL_0, LEVEL_2 and LEVEL_3)
  72. * - MANAGING_HOSTED_SERVICE_UNITS (
  73. * . FAILING_FAST (REBOOTING_NODE and ACTIVATING_STANDBY_NODE)
  74. * . FAILING_GRACEFULLY (SWITCHING_OVER, FAILING_OVER and REBOOTING_NODE)
  75. * . LEAVING_SPONTANEOUSLY (FAILING_OVER and
  76. * WAITING_FOR_NODE_TO_JOIN)
  77. * . JOINING (STARTING_SERVICE_UNITS and ASSIGNING_STANDBY_WORKLOAD)
  78. *
  79. * REPAIR_NEEDED indicates the node needs a manual repair and this state will be
  80. * maintained until the administrative command REPAIRED is entered (implemented
  81. * in the future)
  82. *
  83. * ESCALLATION_LEVEL is a kind of idle state where no actions are performed
  84. * and used only to remember the escallation level. Substate LEVEL_0 indicates
  85. * no escallation. LEVEL_2 indicates that so many component restarts have been
  86. * executed recently that a new component restart request will escalate
  87. * to service unit restart action. Node will request a service unit restart
  88. * from SU.
  89. * LEVEL_3 will be entered if either there are too many service unit restarts
  90. * been made or a component failover recovery action is requested. On level 3
  91. * the recovery action performed is service unit failover (paragraph 3.12.1.3).
  92. *
  93. * FAILING_FAST state executes a node re-boot and waits for the node to join
  94. * the cluster again.
  95. *
  96. * FAILING_GRACEFULLY state requests all SGs which have SUs hosted on current
  97. * node to switch or failover according to the procedures described in
  98. * paragraphs 3.12.1.3 before re-boot is executed. Then the confirmation is
  99. * awaited from all concerned SGs and finally a node re-boot is executed as
  100. * the repair action (see paragraph 2.12.1.4).
  101. *
  102. * LEAVING_SPONTANEOUSLY state handles the spontaneous leave of a node.
  103. *
  104. * JOINING state handles the start of a node in all cases except cluster start,
  105. * which is handled by the CLUSTER class.
  106. *
  107. * 1. Node Availability Control State Machine
  108. * ==========================================
  109. *
  110. * 1.1 State Transition Table
  111. *
  112. * State: Event: Action: New state:
  113. * ============================================================================
  114. * ESCALATION_LEVEL_0 node_sync_ready A6 JOINING_STARTING_APPLS
  115. * ESCALATION_LEVEL_0 node_leave A9,A8 LEAVING_SP_FAILING_OVER
  116. * JOINING_STARTING_APPLS appl_started [C4] A7 JOINING_ASSIGNING_WL
  117. * JOINING_ASSIGNING_WL appl_assigned [C5] ESCALATION_LEVEL_0
  118. * LEAVING_SP_FAILING_OVER sg_failed_over [C1] LEAVING_SP_WAIT_FOR_JOIN
  119. * LEAVING_SP_WAIT_FOR_JOIN node_sync_ready A6 JOINING_STARTING_APPLS
  120. *
  121. * 1.2 State Description
  122. * =====================
  123. * ESCALATION_LEVEL_0 - Node is synchronized and idle.
  124. * JOINING_STARTING_APPLS - JOINING_STARTING_APPLICATIONS
  125. * Node has ordered all applications to start its SUs
  126. * hosted on current node and is now waiting for them
  127. * to acknowledge that they have started.
  128. *
  129. * JOINING_ASSIGNING_WL - JOINING_ASSIGNING_WORKLOAD
  130. * Node has ordered all applications to assign workload
  131. * to all its SUs which currently have no workload and
  132. * is now waiting for the applications to acknowledge.
  133. *
  134. * LEAVING_SP_FAILING_OVER - LEAVING_SPONTANEOUSLY_FAILING_OVER
  135. * Node has received an event telling that this node
  136. * has left the cluster and has ordered all service
  137. * groups to failover those of its SUs that were
  138. * hosted on current node.
  139. *
  140. * LEAVING_SP_WAIT_FOR_JOIN - LEAVING_SPONTANEOUSLY_WAITING_FOR_NODE_TO_JOIN
  141. * Node is waiting for current node to join again.
  142. *
  143. * 1.3 Actions
  144. * ===========
  145. * A1 -
  146. * A2 -
  147. * A3 -
  148. * A4 -
  149. * A5 -
  150. * A6 - [foreach application in cluster]start application
  151. * A7 - [foreach application in cluster]assign workload to application
  152. * A8 - [foreach application in cluster]
  153. * [foreach SG in application ]failover node
  154. * A9 - [foreach application in cluster]
  155. * [foreach SG in application ]
  156. * [foreach SU in SG where the SU is hosted on current node]
  157. * [foreach comp in such an SU]indicate that the node has left the cluster
  158. *
  159. * 1.4 Guards
  160. * ==========
  161. * C1 - All SG availability control state machines (ACSM) == IDLE
  162. * C2 -
  163. * C3 -
  164. * C4 - No applications are in ACSM state == STARTING_SGS
  165. * C5 - All applications have ACSM state == WORKLOAD_ASSIGNED
  166. */
  167. #include <stdlib.h>
  168. #include <assert.h>
  169. #include "amf.h"
  170. #include "util.h"
  171. #include "print.h"
  172. #include "main.h"
  173. /******************************************************************************
  174. * Internal (static) utility functions
  175. *****************************************************************************/
  176. static void amf_node_acsm_enter_leaving_spontaneously(struct amf_node *node)
  177. {
  178. ENTER("'%s'", node->name.value);
  179. node->saAmfNodeOperState = SA_AMF_OPERATIONAL_DISABLED;
  180. node->nodeid = 0;
  181. }
  182. static void amf_node_acsm_enter_failing_over (struct amf_node *node)
  183. {
  184. struct amf_application *app;
  185. struct amf_sg *sg;
  186. struct amf_su *su;
  187. struct amf_comp *component = NULL;
  188. ENTER("'%s'", node->name.value);
  189. node->acsm_state = NODE_ACSM_LEAVING_SPONTANEOUSLY_FAILING_OVER;
  190. /*
  191. * Indicate to each component object in the model that current
  192. * node has left the cluster
  193. */
  194. for (app = amf_cluster->application_head; app != NULL; app = app->next) {
  195. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  196. for (su = sg->su_head; su != NULL; su = su->next) {
  197. if (name_match(&node->name, &su->saAmfSUHostedByNode)) {
  198. for (component = su->comp_head; component != NULL;
  199. component = component->next) {
  200. amf_comp_node_left(component);
  201. }
  202. }
  203. }
  204. }
  205. }
  206. /*
  207. * Let all service groups with service units hosted on current node failover
  208. * its workload
  209. */
  210. for (app = amf_cluster->application_head; app != NULL; app =
  211. app->next) {
  212. for (sg = app->sg_head; sg != NULL; sg =
  213. sg->next) {
  214. amf_sg_failover_node_req(sg, node);
  215. }
  216. }
  217. }
  218. #ifdef COMPILE_OUT
  219. static int all_applications_on_node_started (struct amf_node *node,
  220. struct amf_cluster *cluster)
  221. {
  222. int all_started = 1;
  223. struct amf_application *app;
  224. struct amf_sg *sg;
  225. struct amf_su *su;
  226. for (app = cluster->application_head; app != NULL; app = app->next) {
  227. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  228. for (su = sg->su_head; su != NULL; su = su->next) {
  229. /*
  230. * TODO: Replace the if-statement below with the if-statementin
  231. * this comment when the real problem is fixed !
  232. */
  233. if (su->saAmfSUPresenceState !=
  234. SA_AMF_PRESENCE_INSTANTIATED &&
  235. name_match(&su->saAmfSUHostedByNode,&node->name)) {
  236. all_started = 0; goto done;
  237. }
  238. if (su->saAmfSUPresenceState != SA_AMF_PRESENCE_INSTANTIATED ) {
  239. all_started = 0;
  240. goto done;
  241. }
  242. }
  243. }
  244. }
  245. done:
  246. return all_started;
  247. }
  248. #endif
  249. /******************************************************************************
  250. * Event methods
  251. *****************************************************************************/
  252. /**
  253. * This event indicates that a node has unexpectedly left the cluster. Node
  254. * leave event is obtained from amf_confchg_fn.
  255. *
  256. * @param node
  257. */
  258. void amf_node_leave (struct amf_node *node)
  259. {
  260. assert (node != NULL);
  261. ENTER("'%s', CLM node '%s'", node->name.value,
  262. node->saAmfNodeClmNode.value);
  263. switch (node->acsm_state) {
  264. case NODE_ACSM_ESCALLATION_LEVEL_0:
  265. case NODE_ACSM_ESCALLATION_LEVEL_2:
  266. case NODE_ACSM_ESCALLATION_LEVEL_3:
  267. amf_node_acsm_enter_leaving_spontaneously(node);
  268. amf_node_acsm_enter_failing_over (node);
  269. break;
  270. case NODE_ACSM_REPAIR_NEEDED:
  271. break;
  272. default:
  273. log_printf (LOG_LEVEL_ERROR, "amf_node_leave()called in state = %d"
  274. " (should have been defered)", node->acsm_state);
  275. openais_exit_error (AIS_DONE_FATAL_ERR);
  276. break;
  277. }
  278. }
  279. /**
  280. *
  281. * @param node
  282. */
  283. void amf_node_failover (struct amf_node *node)
  284. {
  285. }
  286. /**
  287. *
  288. * @param node
  289. */
  290. void amf_node_switchover (struct amf_node *node)
  291. {
  292. }
  293. /**
  294. *
  295. * @param node
  296. */
  297. void amf_node_failfast (struct amf_node *node)
  298. {
  299. }
  300. /**
  301. *
  302. * @param node
  303. * @param comp
  304. */
  305. void amf_node_comp_restart_req (
  306. struct amf_node *node, struct amf_comp *comp)
  307. {
  308. }
  309. /**
  310. *
  311. * @param node
  312. * @param comp
  313. */
  314. void amf_node_comp_failover_req (
  315. struct amf_node *node, struct amf_comp *comp)
  316. {
  317. }
  318. /**
  319. * This event indicates that current node has joined and its cluster model has
  320. * been synchronized with the other nodes cluster models.
  321. *
  322. * @param node
  323. */
  324. void amf_node_sync_ready (struct amf_node *node)
  325. {
  326. struct amf_application *app;
  327. assert (node != NULL);
  328. log_printf(LOG_NOTICE, "Node=%s: sync ready, starting hosted SUs.",
  329. node->name.value);
  330. node->saAmfNodeOperState = SA_AMF_OPERATIONAL_ENABLED;
  331. switch (node->acsm_state) {
  332. case NODE_ACSM_ESCALLATION_LEVEL_0:
  333. case NODE_ACSM_ESCALLATION_LEVEL_2:
  334. case NODE_ACSM_ESCALLATION_LEVEL_3:
  335. case NODE_ACSM_LEAVING_SPONTANEOUSLY_WAITING_FOR_NODE_TO_JOIN:
  336. node->acsm_state = NODE_ACSM_JOINING_STARTING_APPLICATIONS;
  337. for (app = amf_cluster->application_head; app != NULL; app = app->next) {
  338. amf_application_start (app, node);
  339. }
  340. break;
  341. case NODE_ACSM_REPAIR_NEEDED:
  342. break;
  343. default:
  344. log_printf (LOG_LEVEL_ERROR, "amf_node_sync_ready()called in state"
  345. " = %d (should have been defered)", node->acsm_state);
  346. openais_exit_error (AIS_DONE_FATAL_ERR);
  347. break;
  348. }
  349. }
  350. /******************************************************************************
  351. * Event response methods
  352. *****************************************************************************/
  353. /**
  354. * This event indicates that an application has started. Started in this context
  355. * means that none of its contained service units is in an -ING state with other
  356. * words successfully instantiated, instantiation has failed or instantiation
  357. * was not possible (due to the node on which the SU was to be hosted is not
  358. * operational).
  359. *
  360. * @param node
  361. * @param application which has been started
  362. */
  363. void amf_node_application_started (struct amf_node *node,
  364. struct amf_application *app)
  365. {
  366. assert (node != NULL && app != NULL );
  367. ENTER ("Node=%s: application '%s' started", node->name.value,
  368. app->name.value);
  369. switch (node->acsm_state) {
  370. case NODE_ACSM_JOINING_STARTING_APPLICATIONS:
  371. if (amf_cluster_applications_started_with_no_starting_sgs(
  372. app->cluster)) {
  373. log_printf(LOG_NOTICE,
  374. "Node=%s: all applications started, assigning workload.",
  375. node->name.value);
  376. node->acsm_state = NODE_ACSM_JOINING_ASSIGNING_WORKLOAD;
  377. for (app = app->cluster->application_head; app != NULL;
  378. app = app->next) {
  379. amf_application_assign_workload (app, node);
  380. }
  381. }
  382. break;
  383. default:
  384. log_printf (LOG_LEVEL_ERROR, "amf_node_application_started()"
  385. "called in state = %d (unexpected !!)", node->acsm_state);
  386. openais_exit_error (AIS_DONE_FATAL_ERR);
  387. break;
  388. }
  389. }
  390. /**
  391. * This event indicates that an application has been assigned workload.
  392. *
  393. * @param node
  394. * @param application which has been assigned workload
  395. */
  396. void amf_node_application_workload_assigned (struct amf_node *node,
  397. struct amf_application *app)
  398. {
  399. assert (node != NULL && app != NULL );
  400. ENTER ("Node=%s: application '%s' started", node->name.value,
  401. app->name.value);
  402. switch (node->acsm_state) {
  403. case NODE_ACSM_JOINING_ASSIGNING_WORKLOAD:
  404. if (amf_cluster_applications_assigned (amf_cluster)) {
  405. log_printf(LOG_NOTICE, "Node=%s: all workload assigned",
  406. node->name.value);
  407. /*
  408. * TODO: new state should be set via history
  409. */
  410. node->acsm_state = NODE_ACSM_ESCALLATION_LEVEL_0;
  411. }
  412. break;
  413. default:
  414. log_printf (LOG_LEVEL_ERROR, "amf_node_application_workload_assigned()"
  415. "called in state = %d (unexpected !!)", node->acsm_state);
  416. openais_exit_error (AIS_DONE_FATAL_ERR);
  417. break;
  418. }
  419. }
  420. /**
  421. * This event indicates that an SG has failed over its workload after a node
  422. * failure.
  423. *
  424. * @param node
  425. * @param sg_in SG which is now ready with its failover
  426. */
  427. void amf_node_sg_failed_over (struct amf_node *node, struct amf_sg *sg_in)
  428. {
  429. struct amf_sg *sg;
  430. struct amf_application *app;
  431. int all_sg_has_failed_over = 1;
  432. assert (node != NULL && app != NULL);
  433. ENTER ("Node=%s: SG '%s' started", node->name.value,
  434. sg_in->name.value);
  435. switch (node->acsm_state) {
  436. case NODE_ACSM_LEAVING_SPONTANEOUSLY_FAILING_OVER:
  437. for (app = amf_cluster->application_head; app != NULL;
  438. app = app->next) {
  439. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  440. if (sg->avail_state != SG_AC_Idle) {
  441. all_sg_has_failed_over = 0;
  442. goto end;
  443. }
  444. }
  445. }
  446. break;
  447. default:
  448. log_printf (LOG_LEVEL_ERROR, "amf_node_sg_failed_over()"
  449. "called in state = %d (unexpected !!)", node->acsm_state);
  450. openais_exit_error (AIS_DONE_FATAL_ERR);
  451. break;
  452. }
  453. end:
  454. if (all_sg_has_failed_over) {
  455. node->acsm_state = NODE_ACSM_LEAVING_SPONTANEOUSLY_WAITING_FOR_NODE_TO_JOIN;
  456. }
  457. }
  458. /******************************************************************************
  459. * General methods
  460. *****************************************************************************/
  461. void amf_node_init (void)
  462. {
  463. log_init ("AMF");
  464. }
  465. /**
  466. * Node constructor
  467. * @param loc
  468. * @param cluster
  469. * @param node
  470. */
  471. struct amf_node *amf_node_new (struct amf_cluster *cluster, char *name) {
  472. struct amf_node *node = amf_calloc (1, sizeof (struct amf_node));
  473. setSaNameT (&node->name, name);
  474. node->saAmfNodeAdminState = SA_AMF_ADMIN_UNLOCKED;
  475. node->saAmfNodeOperState = SA_AMF_OPERATIONAL_ENABLED;
  476. node->saAmfNodeAutoRepair = SA_TRUE;
  477. node->saAmfNodeSuFailOverProb = -1;
  478. node->saAmfNodeSuFailoverMax = ~0;
  479. node->cluster = cluster;
  480. node->next = cluster->node_head;
  481. cluster->node_head = node;
  482. node->acsm_state = NODE_ACSM_ESCALLATION_LEVEL_0;
  483. return node;
  484. }
  485. void *amf_node_serialize (struct amf_node *node, int *len)
  486. {
  487. char *buf = NULL;
  488. int offset = 0, size = 0;
  489. TRACE8 ("%s", node->name.value);
  490. buf = amf_serialize_SaNameT (buf, &size, &offset, &node->name);
  491. buf = amf_serialize_SaNameT (buf, &size, &offset, &node->saAmfNodeClmNode);
  492. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  493. node->saAmfNodeSuFailOverProb);
  494. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  495. node->saAmfNodeSuFailoverMax);
  496. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  497. node->saAmfNodeAutoRepair);
  498. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  499. node->saAmfNodeRebootOnInstantiationFailure);
  500. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  501. node->saAmfNodeRebootOnTerminationFailure);
  502. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  503. node->saAmfNodeAdminState);
  504. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  505. node->saAmfNodeOperState);
  506. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  507. node->nodeid);
  508. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  509. node->acsm_state);
  510. *len = offset;
  511. return buf;
  512. }
  513. struct amf_node *amf_node_deserialize (struct amf_cluster *cluster, char *buf) {
  514. char *tmp = buf;
  515. struct amf_node *node = amf_node_new (cluster, "");
  516. tmp = amf_deserialize_SaNameT (tmp, &node->name);
  517. tmp = amf_deserialize_SaNameT (tmp, &node->saAmfNodeClmNode);
  518. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeSuFailOverProb);
  519. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeSuFailoverMax);
  520. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeAutoRepair);
  521. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeRebootOnInstantiationFailure);
  522. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeRebootOnTerminationFailure);
  523. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeAdminState);
  524. tmp = amf_deserialize_SaUint32T (tmp, &node->saAmfNodeOperState);
  525. tmp = amf_deserialize_SaUint32T (tmp, &node->nodeid);
  526. tmp = amf_deserialize_SaUint32T (tmp, &node->acsm_state);
  527. return node;
  528. }
  529. struct amf_node *amf_node_find (SaNameT *name) {
  530. struct amf_node *node;
  531. assert (name != NULL && amf_cluster != NULL);
  532. for (node = amf_cluster->node_head; node != NULL; node = node->next) {
  533. if (name_match (&node->name, name)) {
  534. return node;
  535. }
  536. }
  537. dprintf ("node %s not found in configuration!", name->value);
  538. return NULL;
  539. }
  540. struct amf_node *amf_node_find_by_nodeid (unsigned int nodeid) {
  541. struct amf_node *node;
  542. assert (amf_cluster != NULL);
  543. for (node = amf_cluster->node_head; node != NULL; node = node->next) {
  544. if (node->nodeid == nodeid) {
  545. return node;
  546. }
  547. }
  548. dprintf ("node %u not found in configuration!", nodeid);
  549. return NULL;
  550. }
  551. struct amf_node *amf_node_find_by_hostname (const char *hostname) {
  552. struct amf_node *node;
  553. assert (hostname != NULL && amf_cluster != NULL);
  554. for (node = amf_cluster->node_head; node != NULL; node = node->next) {
  555. if (strcmp ((char*)node->saAmfNodeClmNode.value, hostname) == 0) {
  556. return node;
  557. }
  558. }
  559. dprintf ("node %s not found in configuration!", hostname);
  560. return NULL;
  561. }