amfsi.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. /** @file amfsi.c
  2. *
  3. * Copyright (c) 2006 Ericsson AB.
  4. * Author: Hans Feldt, Anders Eriksson, Lars Holm
  5. * - Refactoring of code into several AMF files
  6. * - Component/SU restart, SU failover
  7. * - Constructors/destructors
  8. * - Serializers/deserializers
  9. *
  10. * All rights reserved.
  11. *
  12. *
  13. * This software licensed under BSD license, the text of which follows:
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions are met:
  17. *
  18. * - Redistributions of source code must retain the above copyright notice,
  19. * this list of conditions and the following disclaimer.
  20. * - Redistributions in binary form must reproduce the above copyright notice,
  21. * this list of conditions and the following disclaimer in the documentation
  22. * and/or other materials provided with the distribution.
  23. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  24. * contributors may be used to endorse or promote products derived from this
  25. * software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  37. * THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * AMF Workload related classes Implementation
  40. *
  41. * This file contains functions for handling :
  42. * - AMF service instances(SI)
  43. * - AMF SI Dependency
  44. * - AMF SI Ranked SU
  45. * - AMF SI Assignment
  46. * - AMF component service instances (CSI)
  47. * - AMF CSI Assignment
  48. * - AMF CSI Type
  49. * - AMF CSI Attribute
  50. * The file can be viewed as the implementation of the classes listed above
  51. * as described in SAI-Overview-B.02.01. The SA Forum specification
  52. * SAI-AIS-AMF-B.02.01 has been used as specification of the behaviour
  53. * and is referred to as 'the spec' below.
  54. *
  55. * The functions in this file are responsible for:
  56. * - calculating and storing an SI_dependency_level integer per SI
  57. * - calculating and storing a csi_dependency_level integer per CSI
  58. * - on request change HA state of an SI or CSI in such a way that the
  59. * requirements regarding SI -> SI dependencies (paragraphs 3.9.1.1 and
  60. * 3.9.1.2) and CSI -> CSI dependencies (paragraph 3.9.1.3) are fully
  61. * respected
  62. *
  63. * The si_dependency_level is an attribute calculated at init (in the future
  64. * also at reconfiguration) which indicates dependencies between SIs as
  65. * an integer. The si_dependency level indicates to which extent an SI depends
  66. * on other SIs such that an SI that depends on no other SI is on
  67. * si_dependecy_level == 1, an SI that depends only on an SI on
  68. * si_dependency_level == 1 is on si_dependency-level == 2.
  69. * An SI that depends on several SIs gets a si_dependency_level that is one
  70. * unit higher than the SI with the highest si_dependency_level it depends on.
  71. *
  72. * The csi_dependency_level attribute works the same way.
  73. *
  74. * According to paragraph 3.9.1 of the spec, a change to or from the ACTIVE
  75. * HA state is not always allowed without first deactivate dependent SI and CSI
  76. * assignments. Dependencies between CSIs are absolute while an SI that depends
  77. * on another SI may tolerate that the SI on which it depends is inactive for a
  78. * configurable time (the tolerance time). The consequence of this is that a
  79. * request to change the SI state may require a sequence of requests to
  80. * components to assume a new HA state for a CSI-assignment and to guarantee
  81. * the dependency rules, the active response from the component has to be
  82. * awaited before next HA state can be set.
  83. *
  84. * This file implements an SI state machine that fully implements these rules.
  85. * This state machine is called SI Dependency Control State Machine (dcsm)
  86. * and has the following states:
  87. * - DEACTIVATED (there is no SI-assignment with active HA state)
  88. * - ACTIVATING (a request to set the ACTIVE HA state has been received and
  89. * setting ACTIVE HA states to the appropriate components are
  90. * in progress)
  91. * - ACTIVATED (there is at least one SI-assignment with the ACTIVE HA-state)
  92. * - DEACTIVATING (a request to de-activate an SI or only a specific CSI
  93. * within an SI has been received and setting the QUISCED
  94. * HA states to the appropriate components are in progress)
  95. * - DEPENDENCY_DEACTIVATING (the SI-SI dependency tolerance timer has expired
  96. * and setting the QUISCED HA states to the
  97. * appropriate components are in progress)
  98. * - DEPENDENCY_DEACTIVATED (as state DEACTIVATED but will automatically
  99. * transition to state ACTIVATING when the
  100. * dependency problem is solved, i.e. the SI on
  101. * which it depends has re-assumed the ACTIVE HA
  102. * state)
  103. * - SETTING (a request to change the HA state when neither the existing
  104. * nor the requested state is ACTIVE)
  105. *
  106. * This file also implements:
  107. * - SI: Assignment state (for report purposes)
  108. * - SI Assignment: HA state
  109. * - CSI Assignment: HA state
  110. *
  111. */
  112. #include <assert.h>
  113. #include <stdio.h>
  114. #include "amf.h"
  115. #include "print.h"
  116. #include "util.h"
  117. #include "aispoll.h"
  118. #include "main.h"
  119. /**
  120. * Check if any CSI assignment belonging to SU has the requested
  121. * state.
  122. * @param su
  123. * @param hastate
  124. *
  125. * @return int
  126. */
  127. static int any_csi_has_hastate_in_su (struct amf_su *su, SaAmfHAStateT hastate)
  128. {
  129. struct amf_comp *component;
  130. struct amf_csi_assignment *csi_assignment;
  131. int exist = 0;
  132. for (component = su->comp_head; component != NULL;
  133. component = component->next) {
  134. csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
  135. while (csi_assignment != NULL) {
  136. if (csi_assignment->saAmfCSICompHAState == hastate) {
  137. exist = 1;
  138. goto done;
  139. }
  140. csi_assignment =
  141. amf_comp_get_next_csi_assignment (component, csi_assignment);
  142. }
  143. }
  144. done:
  145. return exist;
  146. }
  147. /**
  148. * Check if all CSI assignments belonging to a
  149. * an SI assignemnt has the requested state.
  150. * @param su
  151. * @param hastate
  152. *
  153. * @return int
  154. */
  155. static int all_csi_has_hastate_for_si (
  156. struct amf_si_assignment *si_assignment, SaAmfHAStateT hastate)
  157. {
  158. struct amf_comp *component;
  159. struct amf_csi_assignment *tmp_csi_assignment;
  160. int all = 1;
  161. for (component = si_assignment->su->comp_head; component != NULL;
  162. component = component->next) {
  163. tmp_csi_assignment = amf_comp_get_next_csi_assignment (component, NULL);
  164. while (tmp_csi_assignment != NULL) {
  165. if ((tmp_csi_assignment->si_assignment == si_assignment) &&
  166. (tmp_csi_assignment->saAmfCSICompHAState != hastate)) {
  167. all = 0;
  168. goto done;
  169. }
  170. tmp_csi_assignment =
  171. amf_comp_get_next_csi_assignment (component, tmp_csi_assignment);
  172. }
  173. }
  174. done:
  175. return all;
  176. }
  177. /**
  178. * Implements table 6 in 3.3.2.4
  179. * TODO: active & standby is not correct calculated acc. to
  180. * table. This knowledge is e.g. used in assign_si_assumed_cbfn
  181. * (sg.c)
  182. * @param csi_assignment
  183. */
  184. static void set_si_ha_state (struct amf_csi_assignment *csi_assignment)
  185. {
  186. SaAmfHAStateT old_ha_state =
  187. csi_assignment->si_assignment->saAmfSISUHAState;
  188. SaAmfAssignmentStateT old_assigment_state =
  189. amf_si_get_saAmfSIAssignmentState (csi_assignment->csi->si);
  190. if (all_csi_has_hastate_for_si (
  191. csi_assignment->si_assignment, SA_AMF_HA_ACTIVE)) {
  192. csi_assignment->si_assignment->saAmfSISUHAState = SA_AMF_HA_ACTIVE;
  193. }
  194. if (all_csi_has_hastate_for_si (
  195. csi_assignment->si_assignment, SA_AMF_HA_STANDBY)) {
  196. csi_assignment->si_assignment->saAmfSISUHAState = SA_AMF_HA_STANDBY;
  197. }
  198. if (any_csi_has_hastate_in_su (
  199. csi_assignment->comp->su, SA_AMF_HA_QUIESCING)) {
  200. csi_assignment->si_assignment->saAmfSISUHAState = SA_AMF_HA_QUIESCING;
  201. }
  202. if (any_csi_has_hastate_in_su (
  203. csi_assignment->comp->su, SA_AMF_HA_QUIESCED)) {
  204. csi_assignment->si_assignment->saAmfSISUHAState = SA_AMF_HA_QUIESCED;
  205. }
  206. /* log changes to HA state */
  207. if (old_ha_state != csi_assignment->si_assignment->saAmfSISUHAState) {
  208. log_printf (LOG_NOTICE, "SU HA state changed to '%s' for:\n"
  209. "\t\tSI '%s', SU '%s'",
  210. amf_ha_state (csi_assignment->si_assignment->saAmfSISUHAState),
  211. csi_assignment->si_assignment->si->name.value,
  212. csi_assignment->si_assignment->name.value);
  213. }
  214. /* log changes to assignment state */
  215. if (old_assigment_state !=
  216. amf_si_get_saAmfSIAssignmentState (csi_assignment->csi->si)) {
  217. log_printf (LOG_NOTICE, "SI Assignment state changed to '%s' for:\n"
  218. "\t\tSI '%s', SU '%s'",
  219. amf_assignment_state (
  220. amf_si_get_saAmfSIAssignmentState (csi_assignment->csi->si)),
  221. csi_assignment->si_assignment->si->name.value,
  222. csi_assignment->si_assignment->name.value);
  223. }
  224. }
  225. char *amf_csi_dn_make (struct amf_csi *csi, SaNameT *name)
  226. {
  227. int i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  228. "safCsi=%s,safSi=%s,safApp=%s",
  229. csi->name.value, csi->si->name.value,
  230. csi->si->application->name.value);
  231. assert (i <= SA_MAX_NAME_LENGTH);
  232. name->length = i;
  233. return(char *)name->value;
  234. }
  235. void amf_si_init (void)
  236. {
  237. log_init ("AMF");
  238. }
  239. void amf_si_comp_set_ha_state_done (
  240. struct amf_si *si, struct amf_csi_assignment *csi_assignment)
  241. {
  242. ENTER ("'%s', '%s'", si->name.value, csi_assignment->csi->name.value);
  243. set_si_ha_state (csi_assignment);
  244. assert (csi_assignment->si_assignment->assumed_callback_fn != NULL);
  245. /*
  246. * Report to caller when the requested SI assignment state is
  247. * confirmed.
  248. */
  249. if (csi_assignment->si_assignment->requested_ha_state ==
  250. csi_assignment->si_assignment->saAmfSISUHAState) {
  251. csi_assignment->si_assignment->assumed_callback_fn (
  252. csi_assignment->si_assignment, 0);
  253. csi_assignment->si_assignment->assumed_callback_fn = NULL;
  254. }
  255. }
  256. void amf_si_activate (
  257. struct amf_si *si,
  258. void (*activated_callback_fn)(struct amf_si *si, int result))
  259. {
  260. struct amf_csi *csi;
  261. ENTER ("'%s'", si->name.value);
  262. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  263. struct amf_csi_assignment *csi_assignment;
  264. for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;
  265. csi_assignment = csi_assignment->next) {
  266. csi_assignment->si_assignment->requested_ha_state =
  267. SA_AMF_HA_ACTIVE;
  268. /*
  269. * TODO: only active assignments should be set when dependency
  270. * levels are used.
  271. */
  272. csi_assignment->requested_ha_state = SA_AMF_HA_ACTIVE;
  273. amf_comp_hastate_set (csi_assignment->comp, csi_assignment);
  274. }
  275. }
  276. }
  277. void amf_si_comp_set_ha_state_failed (
  278. struct amf_si *si, struct amf_csi_assignment *csi_assignment)
  279. {
  280. ENTER ("");
  281. assert (0);
  282. }
  283. static void timer_function_ha_state_assumed (void *_si_assignment)
  284. {
  285. struct amf_si_assignment *si_assignment = _si_assignment;
  286. ENTER ("");
  287. si_assignment->saAmfSISUHAState = si_assignment->requested_ha_state;
  288. si_assignment->assumed_callback_fn (si_assignment, 0);
  289. }
  290. void amf_si_ha_state_assume (
  291. struct amf_si_assignment *si_assignment,
  292. void (*assumed_ha_state_callback_fn)(struct amf_si_assignment *si_assignment,
  293. int result))
  294. {
  295. struct amf_csi_assignment *csi_assignment;
  296. struct amf_csi *csi;
  297. int csi_assignment_cnt = 0;
  298. int hastate_set_done_cnt = 0;
  299. ENTER ("SI '%s' SU '%s' state %s", si_assignment->si->name.value,
  300. si_assignment->su->name.value,
  301. amf_ha_state (si_assignment->requested_ha_state));
  302. si_assignment->assumed_callback_fn = assumed_ha_state_callback_fn;
  303. for (csi = si_assignment->si->csi_head; csi != NULL; csi = csi->next) {
  304. for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;
  305. csi_assignment = csi_assignment->next) {
  306. /*
  307. * If the CSI assignment and the SI assignment belongs to the
  308. * same SU, we have a match and can request the component to
  309. * change HA state.
  310. */
  311. if (name_match (&csi_assignment->comp->su->name,
  312. &si_assignment->su->name) &&
  313. (csi_assignment->saAmfCSICompHAState !=
  314. si_assignment->requested_ha_state)) {
  315. csi_assignment_cnt++;
  316. csi_assignment->requested_ha_state =
  317. si_assignment->requested_ha_state;
  318. amf_comp_hastate_set (csi_assignment->comp, csi_assignment);
  319. if (csi_assignment->saAmfCSICompHAState ==
  320. csi_assignment->requested_ha_state) {
  321. hastate_set_done_cnt++;
  322. }
  323. }
  324. }
  325. }
  326. /*
  327. * If the SU has only one component which is the faulty one, we
  328. * will not get an asynchronous response from the component.
  329. * This response (amf_si_comp_set_ha_state_done) is used to do
  330. * the next state transition. The asynchronous response is
  331. * simulated using a timeout instead.
  332. */
  333. if (csi_assignment_cnt == hastate_set_done_cnt) {
  334. poll_timer_handle handle;
  335. poll_timer_add (aisexec_poll_handle, 0, si_assignment,
  336. timer_function_ha_state_assumed, &handle);
  337. }
  338. }
  339. /**
  340. * Get number of active assignments for the specified SI
  341. * @param si
  342. *
  343. * @return int
  344. */
  345. int amf_si_get_saAmfSINumCurrActiveAssignments (struct amf_si *si)
  346. {
  347. int cnt = 0;
  348. struct amf_si_assignment *si_assignment;
  349. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  350. si_assignment = si_assignment->next) {
  351. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
  352. cnt++;
  353. }
  354. }
  355. return cnt;
  356. }
  357. int amf_si_su_get_saAmfSINumCurrActiveAssignments (struct amf_si *si,
  358. struct amf_su *su)
  359. {
  360. int cnt = 0;
  361. struct amf_si_assignment *si_assignment;
  362. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  363. si_assignment = si_assignment->next) {
  364. if (si_assignment->su == su &&
  365. si_assignment->saAmfSISUHAState == SA_AMF_HA_ACTIVE) {
  366. cnt++;
  367. }
  368. }
  369. return cnt;
  370. }
  371. int amf_si_get_saAmfSINumCurrStandbyAssignments (struct amf_si *si)
  372. {
  373. int cnt = 0;
  374. struct amf_si_assignment *si_assignment;
  375. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  376. si_assignment = si_assignment->next) {
  377. if (si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  378. cnt++;
  379. }
  380. }
  381. return cnt;
  382. }
  383. int amf_si_su_get_saAmfSINumCurrStandbyAssignments (struct amf_si *si,
  384. struct amf_su *su)
  385. {
  386. int cnt = 0;
  387. struct amf_si_assignment *si_assignment;
  388. for (si_assignment = si->assigned_sis; si_assignment != NULL;
  389. si_assignment = si_assignment->next) {
  390. if (si_assignment->su == su &&
  391. si_assignment->saAmfSISUHAState == SA_AMF_HA_STANDBY) {
  392. cnt++;
  393. }
  394. }
  395. return cnt;
  396. }
  397. SaAmfAssignmentStateT amf_si_get_saAmfSIAssignmentState (struct amf_si *si)
  398. {
  399. if ((amf_si_get_saAmfSINumCurrActiveAssignments (si) ==
  400. si->saAmfSIPrefActiveAssignments) &&
  401. (amf_si_get_saAmfSINumCurrStandbyAssignments (si) ==
  402. si->saAmfSIPrefStandbyAssignments)) {
  403. return SA_AMF_ASSIGNMENT_FULLY_ASSIGNED;
  404. } else if (amf_si_get_saAmfSINumCurrActiveAssignments (si) == 0) {
  405. return SA_AMF_ASSIGNMENT_UNASSIGNED;
  406. } else {
  407. return SA_AMF_ASSIGNMENT_PARTIALLY_ASSIGNED;
  408. }
  409. }
  410. void amf_csi_delete_assignments (struct amf_csi *csi, struct amf_su *su)
  411. {
  412. struct amf_csi_assignment *csi_assignment;
  413. ENTER ("'%s'", su->name.value);
  414. struct amf_csi_assignment **prev = &csi->assigned_csis;
  415. for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;
  416. csi_assignment = csi_assignment->next) {
  417. if (csi_assignment->comp->su == su) {
  418. struct amf_csi_assignment *tmp = csi_assignment;
  419. *prev = csi_assignment->next;
  420. dprintf ("CSI assignment %s unlinked", tmp->name.value);
  421. free (tmp);
  422. } else {
  423. prev = &csi_assignment->next;
  424. }
  425. }
  426. }
  427. /**
  428. * Constructor for SI objects. Adds SI last in the ordered
  429. * list owned by the specified application. Always returns a
  430. * valid SI object, out-of-memory problems are handled here.
  431. * Default values are initialized.
  432. * @param app
  433. *
  434. * @return struct amf_si*
  435. */
  436. struct amf_si *amf_si_new (struct amf_application *app, char *name)
  437. {
  438. struct amf_si *tail = app->si_head;
  439. struct amf_si *si = amf_calloc (1, sizeof (struct amf_si));
  440. while (tail != NULL) {
  441. if (tail->next == NULL) {
  442. break;
  443. }
  444. tail = tail->next;
  445. }
  446. if (tail == NULL) {
  447. app->si_head = si;
  448. } else {
  449. tail->next = si;
  450. }
  451. si->application = app;
  452. /* setup default values from spec. */
  453. si->saAmfSIAdminState = SA_AMF_ADMIN_UNLOCKED;
  454. si->saAmfSIRank = 0;
  455. si->saAmfSIPrefActiveAssignments = 1;
  456. si->saAmfSIPrefStandbyAssignments = 1;
  457. si->assigned_sis = NULL;
  458. si->csi_head = NULL;
  459. setSaNameT (&si->name, name);
  460. return si;
  461. }
  462. void amf_si_delete (struct amf_si *si)
  463. {
  464. struct amf_si_assignment *si_assignment;
  465. struct amf_csi *csi;
  466. for (csi = si->csi_head; csi != NULL;) {
  467. struct amf_csi *tmp = csi;
  468. csi = csi->next;
  469. amf_csi_delete (tmp);
  470. }
  471. for (si_assignment = si->assigned_sis; si_assignment != NULL;) {
  472. struct amf_si_assignment *tmp = si_assignment;
  473. si_assignment = si_assignment->next;
  474. free (tmp);
  475. }
  476. free (si);
  477. }
  478. void *amf_si_serialize (struct amf_si *si, int *len)
  479. {
  480. char *buf = NULL;
  481. int offset = 0, size = 0;
  482. TRACE8 ("%s", si->name.value);
  483. buf = amf_serialize_SaNameT (buf, &size, &offset, &si->name);
  484. buf = amf_serialize_SaNameT (buf, &size, &offset,
  485. &si->saAmfSIProtectedbySG);
  486. buf = amf_serialize_SaUint32T (buf, &size, &offset, si->saAmfSIRank);
  487. buf = amf_serialize_SaUint32T (buf, &size, &offset, si->saAmfSINumCSIs);
  488. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  489. si->saAmfSIPrefActiveAssignments);
  490. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  491. si->saAmfSIPrefStandbyAssignments);
  492. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  493. si->saAmfSIAdminState);
  494. *len = offset;
  495. return buf;
  496. }
  497. struct amf_si *amf_si_deserialize (struct amf_application *app, char *buf)
  498. {
  499. char *tmp = buf;
  500. struct amf_si *si = amf_si_new (app, "");
  501. tmp = amf_deserialize_SaNameT (tmp, &si->name);
  502. tmp = amf_deserialize_SaNameT (tmp, &si->saAmfSIProtectedbySG);
  503. tmp = amf_deserialize_SaUint32T (tmp, &si->saAmfSIRank);
  504. tmp = amf_deserialize_SaUint32T (tmp, &si->saAmfSINumCSIs);
  505. tmp = amf_deserialize_SaUint32T (tmp, &si->saAmfSIPrefActiveAssignments);
  506. tmp = amf_deserialize_SaUint32T (tmp, &si->saAmfSIPrefStandbyAssignments);
  507. tmp = amf_deserialize_SaUint32T (tmp, &si->saAmfSIAdminState);
  508. return si;
  509. }
  510. /*****************************************************************************
  511. * SI Assignment class implementation *
  512. ****************************************************************************/
  513. struct amf_si_assignment *amf_si_assignment_new (struct amf_si *si)
  514. {
  515. struct amf_si_assignment *si_assignment =
  516. amf_calloc (1, sizeof (struct amf_si_assignment));
  517. si_assignment->si = si;
  518. si_assignment->next = si->assigned_sis;
  519. si->assigned_sis = si_assignment;
  520. return si_assignment;
  521. }
  522. void *amf_si_assignment_serialize (
  523. amf_si_assignment_t *si_assignment, int *len)
  524. {
  525. char *buf = NULL;
  526. int offset = 0, size = 0;
  527. TRACE8 ("%s", si_assignment->name.value);
  528. buf = amf_serialize_SaNameT (buf, &size, &offset, &si_assignment->name);
  529. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  530. si_assignment->saAmfSISUHAState);
  531. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  532. si_assignment->requested_ha_state);
  533. *len = offset;
  534. return buf;
  535. }
  536. struct amf_si_assignment *amf_si_assignment_deserialize (
  537. struct amf_si *si, char *buf)
  538. {
  539. char *tmp = buf;
  540. struct amf_si_assignment *si_assignment = amf_si_assignment_new (si);
  541. tmp = amf_deserialize_SaNameT (tmp, &si_assignment->name);
  542. tmp = amf_deserialize_SaUint32T (tmp, &si_assignment->saAmfSISUHAState);
  543. tmp = amf_deserialize_SaUint32T (tmp, &si_assignment->requested_ha_state);
  544. si_assignment->su = amf_su_find (si->application->cluster,
  545. &si_assignment->name);
  546. return si_assignment;
  547. }
  548. struct amf_si *amf_si_find (struct amf_application *app, char *name)
  549. {
  550. struct amf_si *si;
  551. for (si = app->si_head; si != NULL; si = si->next) {
  552. if (si->name.length == strlen(name) &&
  553. strncmp (name, (char*)si->name.value, si->name.length) == 0) {
  554. break;
  555. }
  556. }
  557. if (si == NULL) {
  558. dprintf ("SI %s not found!", name);
  559. }
  560. return si;
  561. }
  562. /*****************************************************************************
  563. * CSI class implementation *
  564. ****************************************************************************/
  565. struct amf_csi *amf_csi_new (struct amf_si *si)
  566. {
  567. struct amf_csi *csi = amf_calloc (1, sizeof (struct amf_csi));
  568. csi->si = si;
  569. csi->next = si->csi_head;
  570. si->csi_head = csi;
  571. return csi;
  572. }
  573. void amf_csi_delete (struct amf_csi *csi)
  574. {
  575. struct amf_csi_assignment *csi_assignment;
  576. for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;) {
  577. struct amf_csi_assignment *tmp = csi_assignment;
  578. csi_assignment = csi_assignment->next;
  579. free (tmp);
  580. }
  581. free (csi);
  582. }
  583. void *amf_csi_serialize (struct amf_csi *csi, int *len)
  584. {
  585. char *buf = NULL;
  586. int offset = 0, size = 0;
  587. TRACE8 ("%s", csi->name.value);
  588. buf = amf_serialize_SaNameT (buf, &size, &offset, &csi->name);
  589. buf = amf_serialize_SaNameT (buf, &size, &offset, &csi->saAmfCSTypeName);
  590. *len = offset;
  591. return buf;
  592. }
  593. struct amf_csi *amf_csi_deserialize (struct amf_si *si, char *buf)
  594. {
  595. char *tmp = buf;
  596. struct amf_csi *csi = amf_csi_new (si);
  597. tmp = amf_deserialize_SaNameT (tmp, &csi->name);
  598. tmp = amf_deserialize_SaNameT (tmp, &csi->saAmfCSTypeName);
  599. return csi;
  600. }
  601. struct amf_csi *amf_csi_find (struct amf_si *si, char *name)
  602. {
  603. struct amf_csi *csi;
  604. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  605. if (csi->name.length == strlen(name) &&
  606. strncmp (name, (char*)csi->name.value, csi->name.length) == 0) {
  607. break;
  608. }
  609. }
  610. if (csi == NULL) {
  611. dprintf ("CSI %s not found!", name);
  612. }
  613. return csi;
  614. }
  615. /*****************************************************************************
  616. * CSI Assignment class implementation *
  617. ****************************************************************************/
  618. struct amf_csi_assignment *amf_csi_assignment_new (struct amf_csi *csi)
  619. {
  620. struct amf_csi_assignment *csi_assignment =
  621. amf_calloc (1, sizeof (struct amf_csi_assignment));
  622. csi_assignment->csi = csi;
  623. csi_assignment->next = csi->assigned_csis;
  624. csi->assigned_csis = csi_assignment;
  625. return csi_assignment;
  626. }
  627. void *amf_csi_assignment_serialize (
  628. struct amf_csi_assignment *csi_assignment, int *len)
  629. {
  630. char *buf = NULL;
  631. int offset = 0, size = 0;
  632. TRACE8 ("%s", csi_assignment->name.value);
  633. buf = amf_serialize_SaNameT (buf, &size, &offset, &csi_assignment->name);
  634. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  635. csi_assignment->saAmfCSICompHAState);
  636. buf = amf_serialize_SaUint32T (buf, &size, &offset,
  637. csi_assignment->requested_ha_state);
  638. *len = offset;
  639. return buf;
  640. }
  641. struct amf_si_assignment *si_assignment_find (
  642. struct amf_csi_assignment *csi_assignment)
  643. {
  644. struct amf_comp *component;
  645. struct amf_si_assignment *si_assignment = NULL;
  646. component = amf_comp_find(csi_assignment->csi->si->application->cluster,
  647. &csi_assignment->name);
  648. for (si_assignment = csi_assignment->csi->si->assigned_sis;
  649. si_assignment != NULL; si_assignment = si_assignment->next) {
  650. SaNameT su_name;
  651. amf_su_dn_make (component->su,&su_name);
  652. if (name_match(&su_name, &si_assignment->name)) {
  653. break;
  654. }
  655. }
  656. return si_assignment;
  657. }
  658. struct amf_csi_assignment *amf_csi_assignment_deserialize (
  659. struct amf_csi *csi, char *buf)
  660. {
  661. char *tmp = buf;
  662. struct amf_csi_assignment *csi_assignment = amf_csi_assignment_new (csi);
  663. tmp = amf_deserialize_SaNameT (tmp, &csi_assignment->name);
  664. tmp = amf_deserialize_SaUint32T (tmp,
  665. &csi_assignment->saAmfCSICompHAState);
  666. tmp = amf_deserialize_SaUint32T (tmp, &csi_assignment->requested_ha_state);
  667. csi_assignment->comp = amf_comp_find (csi->si->application->cluster,
  668. &csi_assignment->name);
  669. assert (csi_assignment->comp != NULL);
  670. csi_assignment->si_assignment = si_assignment_find(csi_assignment);
  671. return csi_assignment;
  672. }
  673. char *amf_csi_assignment_dn_make (
  674. struct amf_csi_assignment *csi_assignment, SaNameT *name)
  675. {
  676. SaNameT comp_name;
  677. struct amf_csi *csi = csi_assignment->csi;
  678. int i;
  679. amf_comp_dn_make (csi_assignment->comp, &comp_name);
  680. i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  681. "safCSIComp=%s,safCsi=%s,safSi=%s,safApp=%s",
  682. comp_name.value,
  683. csi->name.value, csi->si->name.value,
  684. csi->si->application->name.value);
  685. assert (i <= SA_MAX_NAME_LENGTH);
  686. name->length = i;
  687. return(char *)name->value;
  688. }
  689. struct amf_csi_assignment *amf_csi_assignment_find (
  690. struct amf_cluster *cluster, SaNameT *name)
  691. {
  692. struct amf_application *app;
  693. struct amf_si *si;
  694. struct amf_csi *csi;
  695. struct amf_csi_assignment *csi_assignment = NULL;
  696. char *app_name;
  697. char *si_name;
  698. char *csi_name;
  699. char *csi_assignment_name;
  700. char *buf;
  701. /* malloc new buffer since we need to write to the buffer */
  702. buf = amf_malloc (name->length + 1);
  703. memcpy (buf, name->value, name->length + 1);
  704. csi_assignment_name = strstr (buf, "safCSIComp=");
  705. csi_name = strstr (buf, "safCsi=");
  706. si_name = strstr (buf, "safSi=");
  707. app_name = strstr (buf, "safApp=");
  708. app_name++;
  709. app_name = strstr (app_name, "safApp=");
  710. if (csi_assignment_name == NULL || csi_name == NULL || si_name == NULL ||
  711. app_name == NULL) {
  712. goto end;
  713. }
  714. *(csi_name - 1) = '\0';
  715. *(si_name - 1) = '\0';
  716. *(app_name - 1) = '\0';
  717. /* jump to value */
  718. csi_assignment_name += 11;
  719. csi_name += 7;
  720. si_name += 6;
  721. app_name += 7;
  722. app = amf_application_find (cluster, app_name);
  723. if (app == NULL) {
  724. goto end;
  725. }
  726. si = amf_si_find (app, si_name);
  727. if (si == NULL) {
  728. goto end;
  729. }
  730. csi = amf_csi_find (si, csi_name);
  731. if (csi == NULL) {
  732. goto end;
  733. }
  734. for (csi_assignment = csi->assigned_csis; csi_assignment != NULL;
  735. csi_assignment = csi_assignment->next) {
  736. if (csi_assignment->name.length == strlen(csi_assignment_name) &&
  737. strncmp (csi_assignment_name,
  738. (char*)csi_assignment->name.value,
  739. csi_assignment->name.length) == 0) {
  740. goto end;
  741. }
  742. }
  743. end:
  744. assert(csi_assignment);
  745. free (buf);
  746. return csi_assignment;
  747. }
  748. struct amf_csi_attribute *amf_csi_attribute_new (struct amf_csi *csi)
  749. {
  750. struct amf_csi_attribute *csi_attribute =
  751. amf_calloc (1, sizeof (struct amf_csi_assignment));
  752. csi_attribute->next = csi->attributes_head;
  753. csi->attributes_head = csi_attribute;
  754. return csi_attribute;
  755. }
  756. void *amf_csi_attribute_serialize (
  757. struct amf_csi_attribute *csi_attribute, int *len)
  758. {
  759. char *buf = NULL;
  760. int i, offset = 0, size = 0;
  761. TRACE8 ("%s", csi_attribute->name);
  762. buf = amf_serialize_SaStringT (buf, &size, &offset, csi_attribute->name);
  763. /* count value and write to buf */
  764. for (i = 0; csi_attribute->value &&
  765. csi_attribute->value[i] != NULL; i++);
  766. buf = amf_serialize_SaUint32T (buf, &size, &offset, i);
  767. for (i = 0; csi_attribute->value &&
  768. csi_attribute->value[i] != NULL; i++) {
  769. buf = amf_serialize_SaStringT (
  770. buf, &size, &offset, csi_attribute->value[i]);
  771. }
  772. *len = offset;
  773. return buf;
  774. }
  775. struct amf_csi_attribute *amf_csi_attribute_deserialize (
  776. struct amf_csi *csi, char *buf)
  777. {
  778. char *tmp = buf;
  779. struct amf_csi_attribute *csi_attribute;
  780. int i;
  781. SaUint32T cnt;
  782. csi_attribute = amf_csi_attribute_new (csi);
  783. tmp = amf_deserialize_SaStringT (tmp, &csi_attribute->name);
  784. tmp = amf_deserialize_SaUint32T (tmp, &cnt);
  785. csi_attribute->value = amf_malloc ((cnt + 1) * sizeof (SaStringT*));
  786. for (i = 0; i < cnt; i++) {
  787. tmp = amf_deserialize_SaStringT (tmp, &csi_attribute->value[i]);
  788. }
  789. csi_attribute->value[i] = NULL;
  790. return csi_attribute;
  791. }