amf.c 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016
  1. /*
  2. * Copyright (c) 2002-2006 MontaVista Software, Inc.
  3. * Author: Steven Dake (sdake@mvista.com)
  4. *
  5. * Copyright (c) 2006 Ericsson AB.
  6. * Author: Hans Feldt
  7. * Description: - Introduced AMF B.02 information model
  8. * - Use DN in API and multicast messages
  9. * - (Re-)Introduction of event based multicast messages
  10. *
  11. * All rights reserved.
  12. *
  13. *
  14. * This software licensed under BSD license, the text of which follows:
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions are met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * - Redistributions in binary form must reproduce the above copyright notice,
  22. * this list of conditions and the following disclaimer in the documentation
  23. * and/or other materials provided with the distribution.
  24. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  25. * contributors may be used to endorse or promote products derived from this
  26. * software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  34. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  35. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  36. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  37. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  38. * THE POSSIBILITY OF SUCH DAMAGE.
  39. */
  40. #include <sys/types.h>
  41. #include <sys/uio.h>
  42. #include <sys/socket.h>
  43. #include <sys/un.h>
  44. #include <sys/types.h>
  45. #include <sys/wait.h>
  46. #include <netinet/in.h>
  47. #include <arpa/inet.h>
  48. #include <unistd.h>
  49. #include <fcntl.h>
  50. #include <stdlib.h>
  51. #include <stdio.h>
  52. #include <errno.h>
  53. #include <signal.h>
  54. #include <string.h>
  55. #include <pthread.h>
  56. #include <assert.h>
  57. #include "../include/saAis.h"
  58. #include "../include/saAmf.h"
  59. #include "../include/ipc_gen.h"
  60. #include "../include/ipc_amf.h"
  61. #include "../include/list.h"
  62. #include "../lcr/lcr_comp.h"
  63. #include "totempg.h"
  64. #include "mempool.h"
  65. #include "util.h"
  66. #include "amfconfig.h"
  67. #include "main.h"
  68. #include "timer.h"
  69. #include "service.h"
  70. #include "objdb.h"
  71. #include "print.h"
  72. #define LOG_LEVEL_FROM_LIB LOG_LEVEL_DEBUG
  73. #define LOG_LEVEL_FROM_GMI LOG_LEVEL_DEBUG
  74. #define LOG_LEVEL_ENTER_FUNC LOG_LEVEL_DEBUG
  75. enum amf_message_req_types {
  76. MESSAGE_REQ_EXEC_AMF_COMPONENT_REGISTER = 0,
  77. MESSAGE_REQ_EXEC_AMF_COMPONENT_ERROR_REPORT = 1,
  78. MESSAGE_REQ_EXEC_AMF_CLC_CLEANUP_COMPLETED = 2,
  79. MESSAGE_REQ_EXEC_AMF_HEALTHCHECK_TMO = 3,
  80. MESSAGE_REQ_EXEC_AMF_RESPONSE = 4
  81. };
  82. #ifndef HOST_NAME_MAX
  83. # define HOST_NAME_MAX 255
  84. #endif
  85. struct invocation {
  86. void *data;
  87. int interface;
  88. int active;
  89. };
  90. static struct invocation *invocation_entries = 0;
  91. static int invocation_entries_size = 0;
  92. static int waiting = 0;
  93. enum amf_response_interfaces {
  94. AMF_RESPONSE_HEALTHCHECKCALLBACK = 1,
  95. AMF_RESPONSE_CSISETCALLBACK = 2,
  96. AMF_RESPONSE_CSIREMOVECALLBACK = 3,
  97. AMF_RESPONSE_COMPONENTTERMINATECALLBACK = 4
  98. };
  99. struct component_terminate_callback_data {
  100. struct amf_comp *comp;
  101. };
  102. static void amf_confchg_fn (
  103. enum totem_configuration_type configuration_type,
  104. unsigned int *member_list, int member_list_entries,
  105. unsigned int *left_list, int left_list_entries,
  106. unsigned int *joined_list, int joined_list_entries,
  107. struct memb_ring_id *ring_id);
  108. static int amf_lib_exit_fn (void *conn);
  109. static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb);
  110. static int amf_lib_init_fn (void *conn);
  111. static void message_handler_req_lib_amf_componentregister (void *conn, void *msg);
  112. static void message_handler_req_lib_amf_componentunregister (void *conn, void *msg);
  113. static void message_handler_req_lib_amf_pmstart (void *conn, void *msg);
  114. static void message_handler_req_lib_amf_pmstop (void *conn, void *msg);
  115. static void message_handler_req_lib_amf_healthcheckstart (void *conn, void *msg);
  116. static void message_handler_req_lib_amf_healthcheckconfirm (void *conn, void *msg);
  117. static void message_handler_req_lib_amf_healthcheckstop (void *conn, void *msg);
  118. static void message_handler_req_lib_amf_hastateget (void *conn, void *message);
  119. static void message_handler_req_lib_amf_csiquiescingcomplete (void *conn, void *msg);
  120. static void message_handler_req_lib_amf_protectiongrouptrack (void *conn, void *msg);
  121. static void message_handler_req_lib_amf_protectiongrouptrackstop (void *conn, void *msg);
  122. static void message_handler_req_lib_amf_componenterrorreport (void *conn, void *msg);
  123. static void message_handler_req_lib_amf_componenterrorclear (void *conn, void *msg);
  124. static void message_handler_req_lib_amf_response (void *conn, void *msg);
  125. static void message_handler_req_exec_amf_comp_register (
  126. void *message,
  127. unsigned int nodeid);
  128. static void message_handler_req_exec_amf_comp_error_report (
  129. void *message,
  130. unsigned int nodeid);
  131. static void message_handler_req_exec_amf_clc_cleanup_completed (
  132. void *message,
  133. unsigned int nodeid);
  134. static void message_handler_req_exec_amf_healthcheck_tmo (
  135. void *message,
  136. unsigned int nodeid);
  137. static void message_handler_req_exec_amf_response (
  138. void *message,
  139. unsigned int nodeid);
  140. static void comp_presence_state_set (
  141. struct amf_comp *comp,
  142. SaAmfPresenceStateT presence_state);
  143. static void comp_operational_state_set (
  144. struct amf_comp *comp,
  145. SaAmfOperationalStateT operational_state);
  146. static void su_operational_state_set (
  147. struct amf_su *unit,
  148. SaAmfOperationalStateT operational_state);
  149. static void su_presence_state_set (
  150. struct amf_su *su,
  151. SaAmfPresenceStateT presence_state);
  152. static void sg_assign_si (struct amf_sg *group);
  153. static int clc_instantiate (struct amf_comp *comp);
  154. #if 0
  155. static int clc_terminate (struct amf_comp *comp);
  156. #endif
  157. static int clc_cli_instantiate (struct amf_comp *comp);
  158. static int clc_instantiate_callback (struct amf_comp *comp);
  159. static int clc_csi_set_callback (struct amf_comp *comp);
  160. static int clc_cli_terminate (struct amf_comp *comp);
  161. static int clc_terminate_callback (struct amf_comp *comp);
  162. static int clc_csi_remove_callback (struct amf_comp *comp);
  163. static int clc_cli_cleanup (struct amf_comp *comp);
  164. static int clc_cli_cleanup_local (struct amf_comp *comp);
  165. static void healthcheck_activate (struct amf_healthcheck *healthcheck_active);
  166. static void healthcheck_deactivate (struct amf_healthcheck *healthcheck_active);
  167. //static void comp_healthcheck_activate (struct amf_comp *comp);
  168. static void comp_healthcheck_deactivate (struct amf_comp *comp);
  169. static void escalation_policy_restart (struct amf_comp *comp);
  170. static void amf_runtime_attributes_print (void);
  171. static void clc_su_instantiate (struct amf_su *unit);
  172. static void cluster_start_applications (void *data);
  173. static char *presence_state_text[] = {
  174. "UNKNOWN",
  175. "UNINSTANTIATED",
  176. "INSTANTIATING",
  177. "INSTANTIATED",
  178. "TERMINATING",
  179. "RESTARTING",
  180. "INSTANTION_FAILED",
  181. "TERMINIATION-FAILED"
  182. };
  183. static char *oper_state_text[] = {
  184. "UNKNOWN",
  185. "ENABLED",
  186. "DISABLED"
  187. };
  188. static char *admin_state_text[] = {
  189. "UNKNOWN",
  190. "UNLOCKED",
  191. "LOCKED",
  192. "LOCKED-INSTANTIATION",
  193. "SHUTTING-DOWN"
  194. };
  195. static char *readiness_state_text[] = {
  196. "UNKNOWN",
  197. "OUT-OF-SERVICE",
  198. "IN-SERVICE",
  199. };
  200. static char *ha_state_text[] = {
  201. "UNKNOWN",
  202. "ACTIVE",
  203. "STANDBY",
  204. "QUIESCED",
  205. "QUIESCING",
  206. };
  207. static char *assignment_state_text[] = {
  208. "UNKNOWN",
  209. "UNASSIGNED",
  210. "FULLY-ASSIGNED",
  211. "PARTIALLY-ASSIGNED"
  212. };
  213. struct libamf_ci_trackentry {
  214. int active;
  215. SaUint8T trackFlags;
  216. SaAmfProtectionGroupNotificationT *notificationBufferAddress;
  217. SaNameT csiName;
  218. };
  219. struct amf_comp;
  220. struct amf_pd {
  221. struct amf_comp *comp;
  222. struct list_head list;
  223. /*
  224. struct libamf_ci_trackentry *tracks;
  225. int trackEntries;
  226. int trackActive;
  227. */
  228. };
  229. struct clc_interface {
  230. int (*instantiate) (struct amf_comp *comp);
  231. int (*terminate) (struct amf_comp *comp);
  232. int (*cleanup) (struct amf_comp *comp);
  233. };
  234. /*
  235. * Life cycle functions
  236. */
  237. static struct clc_interface clc_interface_sa_aware = {
  238. clc_cli_instantiate,
  239. clc_terminate_callback,
  240. clc_cli_cleanup
  241. };
  242. static struct clc_interface clc_interface_proxied_pre = {
  243. clc_instantiate_callback,
  244. clc_terminate_callback,
  245. clc_cli_cleanup
  246. };
  247. static struct clc_interface clc_interface_proxied_non_pre = {
  248. clc_csi_set_callback,
  249. clc_csi_remove_callback,
  250. clc_cli_cleanup_local
  251. };
  252. static struct clc_interface clc_interface_non_proxied_non_saware = {
  253. clc_cli_instantiate,
  254. clc_cli_terminate,
  255. clc_cli_cleanup_local
  256. };
  257. static struct clc_interface *clc_interfaces[4] = {
  258. &clc_interface_sa_aware,
  259. &clc_interface_proxied_pre,
  260. &clc_interface_proxied_non_pre,
  261. &clc_interface_non_proxied_non_saware
  262. };
  263. /*
  264. * Service Handler Definition
  265. */
  266. static struct openais_lib_handler amf_lib_service[] =
  267. {
  268. { /* 0 */
  269. .lib_handler_fn = message_handler_req_lib_amf_componentregister,
  270. .response_size = sizeof (struct res_lib_amf_componentregister),
  271. .response_id = MESSAGE_RES_AMF_COMPONENTREGISTER,
  272. .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
  273. },
  274. { /* 1 */
  275. .lib_handler_fn = message_handler_req_lib_amf_componentunregister,
  276. .response_size = sizeof (struct res_lib_amf_componentunregister),
  277. .response_id = MESSAGE_RES_AMF_COMPONENTUNREGISTER,
  278. .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
  279. },
  280. { /* 2 */
  281. .lib_handler_fn = message_handler_req_lib_amf_pmstart,
  282. .response_size = sizeof (struct res_lib_amf_pmstart),
  283. .response_id = MESSAGE_RES_AMF_PMSTART,
  284. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  285. },
  286. { /* 3 */
  287. .lib_handler_fn = message_handler_req_lib_amf_pmstop,
  288. .response_size = sizeof (struct res_lib_amf_pmstop),
  289. .response_id = MESSAGE_RES_AMF_PMSTOP,
  290. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  291. },
  292. { /* 4 */
  293. .lib_handler_fn = message_handler_req_lib_amf_healthcheckstart,
  294. .response_size = sizeof (struct res_lib_amf_healthcheckstart),
  295. .response_id = MESSAGE_RES_AMF_HEALTHCHECKSTART,
  296. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  297. },
  298. { /* 5 */
  299. .lib_handler_fn = message_handler_req_lib_amf_healthcheckconfirm,
  300. .response_size = sizeof (struct res_lib_amf_healthcheckconfirm),
  301. .response_id = MESSAGE_RES_AMF_HEALTHCHECKCONFIRM,
  302. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  303. },
  304. { /* 6 */
  305. .lib_handler_fn = message_handler_req_lib_amf_healthcheckstop,
  306. .response_size = sizeof (struct res_lib_amf_healthcheckstop),
  307. .response_id = MESSAGE_RES_AMF_HEALTHCHECKSTOP,
  308. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  309. },
  310. { /* 7 */
  311. .lib_handler_fn = message_handler_req_lib_amf_hastateget,
  312. .response_size = sizeof (struct res_lib_amf_hastateget),
  313. .response_id = MESSAGE_RES_AMF_HASTATEGET,
  314. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  315. },
  316. { /* 8 */
  317. .lib_handler_fn = message_handler_req_lib_amf_csiquiescingcomplete,
  318. .response_size = sizeof (struct res_lib_amf_csiquiescingcomplete),
  319. .response_id = MESSAGE_RES_AMF_CSIQUIESCINGCOMPLETE,
  320. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  321. },
  322. { /* 9 */
  323. .lib_handler_fn = message_handler_req_lib_amf_protectiongrouptrack,
  324. .response_size = sizeof (struct res_lib_amf_protectiongrouptrack),
  325. .response_id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACK,
  326. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  327. },
  328. { /* 10 */
  329. .lib_handler_fn = message_handler_req_lib_amf_protectiongrouptrackstop,
  330. .response_size = sizeof (struct res_lib_amf_protectiongrouptrackstop),
  331. .response_id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACKSTOP,
  332. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  333. },
  334. { /* 11 */
  335. .lib_handler_fn = message_handler_req_lib_amf_componenterrorreport,
  336. .response_size = sizeof (struct res_lib_amf_componenterrorreport),
  337. .response_id = MESSAGE_RES_AMF_COMPONENTERRORREPORT,
  338. .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
  339. },
  340. { /* 12 */
  341. .lib_handler_fn = message_handler_req_lib_amf_componenterrorclear,
  342. .response_size = sizeof (struct res_lib_amf_componenterrorclear),
  343. .response_id = MESSAGE_RES_AMF_COMPONENTERRORCLEAR,
  344. .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED
  345. },
  346. { /* 13 */
  347. .lib_handler_fn = message_handler_req_lib_amf_response,
  348. .response_size = sizeof (struct res_lib_amf_response),
  349. .response_id = MESSAGE_RES_AMF_RESPONSE, // TODO
  350. .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
  351. },
  352. };
  353. static struct openais_exec_handler amf_exec_service[] = {
  354. {
  355. .exec_handler_fn = message_handler_req_exec_amf_comp_register,
  356. },
  357. {
  358. .exec_handler_fn = message_handler_req_exec_amf_comp_error_report,
  359. },
  360. {
  361. .exec_handler_fn = message_handler_req_exec_amf_clc_cleanup_completed,
  362. },
  363. {
  364. .exec_handler_fn = message_handler_req_exec_amf_healthcheck_tmo,
  365. },
  366. {
  367. .exec_handler_fn = message_handler_req_exec_amf_response,
  368. }
  369. };
  370. /*
  371. * Exports the interface for the service
  372. */
  373. static struct openais_service_handler amf_service_handler = {
  374. .name = (unsigned char *)"openais availability management framework B.01.01",
  375. .id = AMF_SERVICE,
  376. .private_data_size = sizeof (struct amf_pd),
  377. .lib_init_fn = amf_lib_init_fn,
  378. .lib_exit_fn = amf_lib_exit_fn,
  379. .lib_service = amf_lib_service,
  380. .lib_service_count = sizeof (amf_lib_service) / sizeof (struct openais_lib_handler),
  381. .exec_init_fn = amf_exec_init_fn,
  382. .exec_service = amf_exec_service,
  383. .exec_service_count = sizeof (amf_exec_service) / sizeof (struct openais_exec_handler),
  384. .confchg_fn = amf_confchg_fn,
  385. .exec_dump_fn = amf_runtime_attributes_print
  386. };
  387. static struct amf_node *this_amf_node;
  388. static struct amf_cluster amf_cluster;
  389. static struct openais_service_handler *amf_get_handler_ver0 (void);
  390. static struct openais_service_handler_iface_ver0 amf_service_handler_iface = {
  391. .openais_get_service_handler_ver0 = amf_get_handler_ver0
  392. };
  393. static struct lcr_iface openais_amf_ver0[1] = {
  394. {
  395. .name = "openais_amf",
  396. .version = 0,
  397. .versions_replace = 0,
  398. .versions_replace_count = 0,
  399. .dependencies = 0,
  400. .dependency_count = 0,
  401. .constructor = NULL,
  402. .destructor = NULL,
  403. .interfaces = NULL
  404. }
  405. };
  406. static struct lcr_comp amf_comp_ver0 = {
  407. .iface_count = 1,
  408. .ifaces = openais_amf_ver0
  409. };
  410. static struct openais_service_handler *amf_get_handler_ver0 (void)
  411. {
  412. return (&amf_service_handler);
  413. }
  414. __attribute__ ((constructor)) static void register_this_component (void) {
  415. lcr_interfaces_set (&openais_amf_ver0[0], &amf_service_handler_iface);
  416. lcr_component_register (&amf_comp_ver0);
  417. }
  418. enum clc_command_run_operation_type {
  419. CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE = 1,
  420. CLC_COMMAND_RUN_OPERATION_TYPE_TERMINATE = 2,
  421. CLC_COMMAND_RUN_OPERATION_TYPE_CLEANUP = 3
  422. };
  423. struct clc_command_run_data {
  424. struct amf_comp *comp;
  425. enum clc_command_run_operation_type type;
  426. void (*completion_callback) (void *context);
  427. };
  428. struct req_exec_amf_comp_register {
  429. struct req_header header;
  430. SaNameT compName;
  431. SaNameT proxyCompName;
  432. };
  433. struct req_exec_amf_comp_error_report {
  434. struct req_header header;
  435. SaNameT reportingComponent;
  436. SaNameT erroneousComponent;
  437. SaTimeT errorDetectionTime;
  438. SaAmfRecommendedRecoveryT recommendedRecovery;
  439. SaNtfIdentifierT ntfIdentifier;
  440. };
  441. struct req_exec_amf_clc_cleanup_completed {
  442. struct req_header header;
  443. SaNameT compName;
  444. };
  445. struct req_exec_amf_healthcheck_tmo {
  446. struct req_header header;
  447. SaNameT compName;
  448. };
  449. struct req_exec_amf_response {
  450. struct req_header header;
  451. SaNameT compName;
  452. SaNameT csiName;
  453. unsigned int interface;
  454. SaAisErrorT error;
  455. };
  456. static char *comp_dn_make (struct amf_comp *comp, SaNameT *name)
  457. {
  458. int i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  459. "safComp=%s,safSu=%s,safSg=%s,safApp=%s",
  460. comp->name.value, comp->su->name.value,
  461. comp->su->sg->name.value, comp->su->sg->application->name.value);
  462. assert (i <= SA_MAX_NAME_LENGTH);
  463. name->length = i;
  464. return (char *)name->value;
  465. }
  466. static char *csi_dn_make (struct amf_csi *csi, SaNameT *name)
  467. {
  468. int i = snprintf((char*) name->value, SA_MAX_NAME_LENGTH,
  469. "safCsi=%s,safSi=%s,safApp=%s",
  470. csi->name.value, csi->si->name.value,
  471. csi->si->application->name.value);
  472. assert (i <= SA_MAX_NAME_LENGTH);
  473. name->length = i;
  474. return (char *)name->value;
  475. }
  476. static int invocation_create (
  477. int interface,
  478. void *data)
  479. {
  480. struct invocation *invocation_addr = 0;
  481. struct invocation *invocation_temp;
  482. int i;
  483. int loc = 0;
  484. for (i = 0; i < invocation_entries_size; i++) {
  485. if (invocation_entries[i].active == 0) {
  486. invocation_addr = &invocation_entries[i];
  487. loc = i;
  488. break;
  489. }
  490. }
  491. if (invocation_addr == 0) {
  492. invocation_temp = (struct invocation *)realloc (invocation_entries,
  493. (invocation_entries_size + 1) * sizeof (struct invocation));
  494. if (invocation_temp == 0) {
  495. return (-1);
  496. }
  497. invocation_entries = invocation_temp;
  498. invocation_addr = &invocation_entries[invocation_entries_size];
  499. loc = invocation_entries_size;
  500. invocation_entries_size += 1;
  501. }
  502. invocation_addr->interface = interface;
  503. invocation_addr->data = data;
  504. invocation_addr->active = 1;
  505. return (loc);
  506. }
  507. static int invocation_get_and_destroy (int invocation, int *interface,
  508. void **data)
  509. {
  510. if (invocation > invocation_entries_size) {
  511. return (-1);
  512. }
  513. if (invocation_entries[invocation].active == 0) {
  514. return (-1);
  515. }
  516. *interface = invocation_entries[invocation].interface;
  517. *data = invocation_entries[invocation].data;
  518. memset (&invocation_entries[invocation], 0, sizeof (struct invocation));
  519. return (0);
  520. }
  521. static void invocation_destroy_by_data (void *data)
  522. {
  523. int i;
  524. for (i = 0; i < invocation_entries_size; i++) {
  525. if (invocation_entries[i].data == data) {
  526. memset (&invocation_entries[i], 0,
  527. sizeof (struct invocation));
  528. break;
  529. }
  530. }
  531. }
  532. static void *clc_command_run (void *context)
  533. {
  534. struct clc_command_run_data *clc_command_run_data =
  535. (struct clc_command_run_data *)context;
  536. pid_t pid;
  537. int res;
  538. char *argv[10];
  539. char *envp[10];
  540. int status;
  541. char path[PATH_MAX];
  542. char *cmd = 0;
  543. char *comp_argv = 0;
  544. char comp_name[SA_MAX_NAME_LENGTH];
  545. int i;
  546. ENTER_VOID();
  547. pid = fork();
  548. if (pid == -1) {
  549. dprintf ("Couldn't fork process %s\n", strerror (errno));
  550. return (0);
  551. }
  552. if (pid) {
  553. waiting = 1;
  554. dprintf ("waiting for pid %d to finish\n", pid);
  555. waitpid (pid, &status, 0);
  556. dprintf ("process (%d) finished with %d\n", pid, status);
  557. if (clc_command_run_data->completion_callback) {
  558. clc_command_run_data->completion_callback (context);
  559. }
  560. pthread_exit(0);
  561. }
  562. switch (clc_command_run_data->type) {
  563. case CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE:
  564. cmd = clc_command_run_data->comp->saAmfCompInstantiateCmd;
  565. comp_argv = clc_command_run_data->comp->saAmfCompInstantiateCmdArgv;
  566. break;
  567. case CLC_COMMAND_RUN_OPERATION_TYPE_TERMINATE:
  568. cmd = clc_command_run_data->comp->saAmfCompTerminateCmd;
  569. comp_argv = clc_command_run_data->comp->saAmfCompTerminateCmdArgv;
  570. break;
  571. case CLC_COMMAND_RUN_OPERATION_TYPE_CLEANUP:
  572. cmd = clc_command_run_data->comp->saAmfCompCleanupCmd;
  573. comp_argv = clc_command_run_data->comp->saAmfCompCleanupCmdArgv;
  574. break;
  575. default:
  576. assert (0 != 1);
  577. break;
  578. }
  579. /* If command is not an absolute path, search for paths in parent objects */
  580. if (cmd[0] != '/') {
  581. if (strlen (clc_command_run_data->comp->clccli_path)) {
  582. sprintf (path, "%s/%s",
  583. clc_command_run_data->comp->clccli_path, cmd);
  584. } else if (strlen (clc_command_run_data->comp->su->clccli_path)) {
  585. sprintf (path, "%s/%s",
  586. clc_command_run_data->comp->su->clccli_path, cmd);
  587. } else if (strlen (clc_command_run_data->comp->su->sg->clccli_path)) {
  588. sprintf (path, "%s/%s",
  589. clc_command_run_data->comp->su->sg->clccli_path, cmd);
  590. } else if (strlen (clc_command_run_data->comp->su->sg->application->clccli_path)) {
  591. sprintf (path, "%s/%s",
  592. clc_command_run_data->comp->su->sg->application->clccli_path, cmd);
  593. }
  594. cmd = path;
  595. }
  596. argv[0] = cmd;
  597. {
  598. /* make a proper argv array */
  599. i = 1;
  600. char *ptrptr;
  601. char *arg = strtok_r(comp_argv, " ", &ptrptr);
  602. while (arg) {
  603. argv[i] = arg;
  604. arg = strtok_r(NULL, " ", & ptrptr);
  605. i++;
  606. }
  607. }
  608. argv[i] = NULL;
  609. envp[0] = comp_name;
  610. i = snprintf(comp_name, SA_MAX_NAME_LENGTH,
  611. "SA_AMF_COMPONENT_NAME=safComp=%s,safSu=%s,safSg=%s,safApp=%s",
  612. clc_command_run_data->comp->name.value,
  613. clc_command_run_data->comp->su->name.value,
  614. clc_command_run_data->comp->su->sg->name.value,
  615. clc_command_run_data->comp->su->sg->application->name.value);
  616. assert (i <= SA_MAX_NAME_LENGTH);
  617. for (i = 1; clc_command_run_data->comp->saAmfCompCmdEnv &&
  618. clc_command_run_data->comp->saAmfCompCmdEnv[i - 1]; i++) {
  619. envp[i] = clc_command_run_data->comp->saAmfCompCmdEnv[i - 1];
  620. }
  621. envp[i] = NULL;
  622. dprintf ("running command '%s' with environment:\n", cmd);
  623. for (i = 0; envp[i] != NULL; i++) {
  624. dprintf (" %s\n", envp[i]);
  625. }
  626. dprintf (" and argv:\n", cmd);
  627. for (i = 0; argv[i] != NULL; i++) {
  628. dprintf (" %s\n", argv[i]);
  629. }
  630. res = execve (cmd, argv, envp);
  631. if (res == -1) {
  632. log_printf (LOG_LEVEL_ERROR, "Couldn't exec program %s (%s)\n",
  633. cmd, strerror (errno));
  634. }
  635. assert (res != -1);
  636. return (0);
  637. }
  638. /*
  639. * Instantiate possible operations
  640. */
  641. static int clc_cli_instantiate (struct amf_comp *comp)
  642. {
  643. int res;
  644. pthread_t thread;
  645. pthread_attr_t thread_attr; /* thread attribute */
  646. struct clc_command_run_data *clc_command_run_data;
  647. ENTER("comp '%s'\n", getSaNameT (&comp->name));
  648. clc_command_run_data = malloc (sizeof (struct clc_command_run_data));
  649. if (clc_command_run_data == NULL) {
  650. openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
  651. }
  652. clc_command_run_data->comp = comp;
  653. clc_command_run_data->type = CLC_COMMAND_RUN_OPERATION_TYPE_INSTANTIATE;
  654. clc_command_run_data->completion_callback = NULL;
  655. pthread_attr_init (&thread_attr);
  656. pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
  657. res = pthread_create (&thread, &thread_attr, clc_command_run, (void *)clc_command_run_data);
  658. if (res != 0) {
  659. log_printf (LOG_LEVEL_ERROR, "pthread_create failed: %d", res);
  660. }
  661. // TODO error code from pthread_create
  662. return (res);
  663. }
  664. static int clc_instantiate_callback (struct amf_comp *comp)
  665. {
  666. ENTER("comp %s\n", getSaNameT (&comp->name));
  667. return (0);
  668. }
  669. static int clc_csi_set_callback (struct amf_comp *comp)
  670. {
  671. ENTER("comp %s\n", getSaNameT (&comp->name));
  672. return (0);
  673. }
  674. /*
  675. * Terminate possible operations
  676. */
  677. static int clc_cli_terminate (struct amf_comp *comp)
  678. {
  679. ENTER("comp %s\n", getSaNameT (&comp->name));
  680. return (0);
  681. }
  682. static int clc_terminate_callback (struct amf_comp *comp)
  683. {
  684. struct res_lib_amf_componentterminatecallback res_lib_amf_componentterminatecallback;
  685. struct component_terminate_callback_data *component_terminate_callback_data;
  686. ENTER("comp %s\n", getSaNameT (&comp->name));
  687. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_INSTANTIATED) {
  688. dprintf ("component terminated but not instantiated %s - %d\n",
  689. getSaNameT (&comp->name), comp->saAmfCompPresenceState);
  690. assert (0);
  691. return (0);
  692. }
  693. dprintf ("component name terminating %s\n", getSaNameT (&comp->name));
  694. dprintf ("component presence state %d\n", comp->saAmfCompPresenceState);
  695. res_lib_amf_componentterminatecallback.header.id = MESSAGE_RES_AMF_COMPONENTTERMINATECALLBACK;
  696. res_lib_amf_componentterminatecallback.header.size = sizeof (struct res_lib_amf_componentterminatecallback);
  697. res_lib_amf_componentterminatecallback.header.error = SA_AIS_OK;
  698. memcpy (&res_lib_amf_componentterminatecallback.compName,
  699. &comp->name, sizeof (SaNameT));
  700. component_terminate_callback_data =
  701. malloc (sizeof (struct component_terminate_callback_data));
  702. if (component_terminate_callback_data == NULL) {
  703. openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
  704. }
  705. component_terminate_callback_data->comp = comp;
  706. res_lib_amf_componentterminatecallback.invocation =
  707. invocation_create (
  708. AMF_RESPONSE_COMPONENTTERMINATECALLBACK,
  709. component_terminate_callback_data);
  710. dprintf ("Creating invocation %llu",
  711. (unsigned long long)res_lib_amf_componentterminatecallback.invocation);
  712. openais_conn_send_response (
  713. openais_conn_partner_get (comp->conn),
  714. &res_lib_amf_componentterminatecallback,
  715. sizeof (struct res_lib_amf_componentterminatecallback));
  716. return (0);
  717. }
  718. static int clc_csi_remove_callback (struct amf_comp *comp)
  719. {
  720. dprintf ("clc_tcsi_remove_callback\n");
  721. return (0);
  722. }
  723. /*
  724. * Clean up completed
  725. */
  726. static void clc_cleanup_completion_callback (void *context) {
  727. struct clc_command_run_data *clc_command_run_data =
  728. (struct clc_command_run_data *)context;
  729. struct req_exec_amf_clc_cleanup_completed req;
  730. struct iovec iovec;
  731. TRACE2("CLC cleanup done for '%s'", clc_command_run_data->comp->name.value);
  732. req.header.size = sizeof (struct req_exec_amf_clc_cleanup_completed);
  733. req.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  734. MESSAGE_REQ_EXEC_AMF_CLC_CLEANUP_COMPLETED);
  735. comp_dn_make (clc_command_run_data->comp, &req.compName);
  736. iovec.iov_base = (char *)&req;
  737. iovec.iov_len = sizeof (req);
  738. assert (totempg_groups_mcast_joined (openais_group_handle,
  739. &iovec, 1, TOTEMPG_AGREED) == 0);
  740. }
  741. /*
  742. * Cleanup possible operations
  743. */
  744. static int clc_cli_cleanup (struct amf_comp *comp)
  745. {
  746. int res;
  747. pthread_t thread;
  748. pthread_attr_t thread_attr; /* thread attribute */
  749. struct clc_command_run_data *clc_command_run_data;
  750. dprintf ("clc_cli_cleanup\n");
  751. clc_command_run_data = malloc (sizeof (struct clc_command_run_data));
  752. if (clc_command_run_data == NULL) {
  753. openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
  754. }
  755. clc_command_run_data->comp = comp;
  756. clc_command_run_data->type = CLC_COMMAND_RUN_OPERATION_TYPE_CLEANUP;
  757. clc_command_run_data->completion_callback = clc_cleanup_completion_callback;
  758. pthread_attr_init (&thread_attr);
  759. pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
  760. res = pthread_create (&thread, &thread_attr, clc_command_run, (void *)clc_command_run_data);
  761. if (res != 0) {
  762. log_printf (LOG_LEVEL_ERROR, "pthread_create failed: %d", res);
  763. }
  764. // TODO error code from pthread_create
  765. return (res);
  766. }
  767. static int clc_cli_cleanup_local (struct amf_comp *comp)
  768. {
  769. dprintf ("clc_cli_cleanup_local\n");
  770. return (0);
  771. }
  772. static int clc_instantiate (struct amf_comp *comp)
  773. {
  774. int res = 0;
  775. dprintf ("clc instantiate for comp '%s'\n", getSaNameT (&comp->name));
  776. if (comp->saAmfCompPresenceState != SA_AMF_PRESENCE_RESTARTING) {
  777. comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATING);
  778. }
  779. if (comp->su->is_local) {
  780. res = clc_interfaces[comp->comptype]->instantiate (comp);
  781. }
  782. return res;
  783. }
  784. #if 0
  785. static int clc_terminate (struct amf_comp *comp)
  786. {
  787. int res;
  788. dprintf ("clc terminate for comp %s\n", getSaNameT (&comp->name));
  789. assert (0);
  790. operational_state_comp_set (comp, SA_AMF_OPERATIONAL_DISABLED);
  791. comp_presence_state_set (comp, SA_AMF_PRESENCE_TERMINATING);
  792. res = clc_interfaces[comp->comptype]->terminate (comp);
  793. return (0);
  794. }
  795. #endif
  796. static int presence_state_all_comps_in_su_are_set (struct amf_su *su, SaAmfPresenceStateT state)
  797. {
  798. int all_set = 1;
  799. struct amf_comp *comp;
  800. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  801. if (comp->saAmfCompPresenceState != state) {
  802. all_set = 0;
  803. }
  804. }
  805. return all_set;
  806. }
  807. static int clc_cleanup (struct amf_comp *comp)
  808. {
  809. int res = 0;
  810. dprintf ("clc cleanup for comp %s\n", getSaNameT (&comp->name));
  811. comp_healthcheck_deactivate (comp);
  812. comp_presence_state_set (comp, SA_AMF_PRESENCE_RESTARTING);
  813. /* when all components in su are restarting, the SU becomes restarting */
  814. if (presence_state_all_comps_in_su_are_set(comp->su, SA_AMF_PRESENCE_RESTARTING)) {
  815. su_presence_state_set (comp->su, SA_AMF_PRESENCE_RESTARTING);
  816. }
  817. if (comp->su->is_local) {
  818. res = clc_interfaces[comp->comptype]->cleanup (comp);
  819. }
  820. return res;
  821. }
  822. /* IMPL */
  823. static void amf_runtime_attributes_print (void)
  824. {
  825. struct amf_node *node;
  826. struct amf_application *app;
  827. struct amf_sg *sg;
  828. struct amf_su *su;
  829. struct amf_comp *comp;
  830. struct amf_si *si;
  831. struct amf_csi *csi;
  832. struct amf_si_assignment *si_assignment;
  833. struct amf_csi_assignment *csi_assignment;
  834. dprintf("AMF runtime attributes:");
  835. dprintf("===================================================");
  836. dprintf("safCluster=%s", getSaNameT(&amf_cluster.name));
  837. dprintf(" admin state: %s\n", admin_state_text[amf_cluster.saAmfClusterAdminState]);
  838. for (node = amf_cluster.node_head; node != NULL; node = node->next) {
  839. dprintf(" safNode=%s\n", getSaNameT (&node->name));
  840. dprintf(" admin state: %s\n", admin_state_text[node->saAmfNodeAdminState]);
  841. dprintf(" oper state: %s\n", oper_state_text[node->saAmfNodeOperState]);
  842. }
  843. for (app = amf_cluster.application_head; app != NULL; app = app->next) {
  844. dprintf(" safApp=%s\n", getSaNameT(&app->name));
  845. dprintf(" admin state: %s\n", admin_state_text[app->saAmfApplicationAdminState]);
  846. dprintf(" num_sg: %d\n", app->saAmfApplicationCurrNumSG);
  847. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  848. dprintf(" safSG=%s\n", getSaNameT(&sg->name));
  849. dprintf(" admin state: %s\n", admin_state_text[sg->saAmfSGAdminState]);
  850. dprintf(" assigned SUs %d\n", sg->saAmfSGNumCurrAssignedSUs);
  851. dprintf(" non inst. spare SUs %d\n", sg->saAmfSGNumCurrNonInstantiatedSpareSUs);
  852. dprintf(" inst. spare SUs %d\n", sg->saAmfSGNumCurrInstantiatedSpareSUs);
  853. for (su = sg->su_head; su != NULL; su = su->next) {
  854. dprintf(" safSU=%s\n", getSaNameT(&su->name));
  855. dprintf(" oper state: %s\n", oper_state_text[su->saAmfSUOperState]);
  856. dprintf(" admin state: %s\n", admin_state_text[su->saAmfSUAdminState]);
  857. dprintf(" readiness state: %s\n", readiness_state_text[su->saAmfSUReadinessState]);
  858. dprintf(" presence state: %s\n", presence_state_text[su->saAmfSUPresenceState]);
  859. dprintf(" hosted by node %s\n", su->saAmfSUHostedByNode.value);
  860. dprintf(" num active SIs %d\n", su->saAmfSUNumCurrActiveSIs);
  861. dprintf(" num standby SIs %d\n", su->saAmfSUNumCurrStandbySIs);
  862. dprintf(" restart count %d\n", su->saAmfSURestartCount);
  863. dprintf(" escalation level %d\n", su->escalation_level);
  864. dprintf(" SU failover cnt %d\n", su->su_failover_cnt);
  865. dprintf(" assigned SIs:");
  866. for (si_assignment = su->assigned_sis; si_assignment != NULL;
  867. si_assignment = si_assignment->next) {
  868. dprintf(" safSi=%s\n", si_assignment->si->name.value);
  869. dprintf(" HA state: %s\n",
  870. ha_state_text[si_assignment->saAmfSISUHAState]);
  871. }
  872. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  873. dprintf(" safComp=%s\n", getSaNameT(&comp->name));
  874. dprintf(" oper state: %s\n",
  875. oper_state_text[comp->saAmfCompOperState]);
  876. dprintf(" readiness state: %s\n",
  877. readiness_state_text[comp->saAmfCompReadinessState]);
  878. dprintf(" presence state: %s\n",
  879. presence_state_text[comp->saAmfCompPresenceState]);
  880. dprintf(" num active CSIs %d\n",
  881. comp->saAmfCompNumCurrActiveCsi);
  882. dprintf(" num standby CSIs %d\n",
  883. comp->saAmfCompNumCurrStandbyCsi);
  884. dprintf(" restart count %d\n", comp->saAmfCompRestartCount);
  885. dprintf(" assigned CSIs:");
  886. for (csi_assignment = comp->assigned_csis; csi_assignment != NULL;
  887. csi_assignment = csi_assignment->comp_next) {
  888. dprintf(" safCSI=%s\n", csi_assignment->csi->name.value);
  889. dprintf(" HA state: %s\n",
  890. ha_state_text[csi_assignment->saAmfCSICompHASate]);
  891. }
  892. }
  893. }
  894. }
  895. for (si = app->si_head; si != NULL; si = si->next) {
  896. dprintf(" safSi=%s\n", getSaNameT(&si->name));
  897. dprintf(" admin state: %s\n", admin_state_text[si->saAmfSIAdminState]);
  898. dprintf(" assignm. state: %s\n", assignment_state_text[si->saAmfSIAssignmentState]);
  899. dprintf(" active assignments: %d\n", si->saAmfSINumCurrActiveAssignments);
  900. dprintf(" standby assignments: %d\n", si->saAmfSINumCurrStandbyAssignments);
  901. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  902. dprintf(" safCsi=%s\n", getSaNameT(&csi->name));
  903. }
  904. }
  905. }
  906. dprintf("===================================================");
  907. }
  908. /* to be removed... */
  909. static int amf_enabled (struct objdb_iface_ver0 *objdb)
  910. {
  911. unsigned int object_service_handle;
  912. char *value;
  913. int enabled = 0;
  914. objdb->object_find_reset (OBJECT_PARENT_HANDLE);
  915. if (objdb->object_find (
  916. OBJECT_PARENT_HANDLE,
  917. "amf",
  918. strlen ("amf"),
  919. &object_service_handle) == 0) {
  920. value = NULL;
  921. if ( !objdb->object_key_get (object_service_handle,
  922. "mode",
  923. strlen ("mode"),
  924. (void *)&value,
  925. NULL) && value) {
  926. if (strcmp (value, "enabled") == 0) {
  927. enabled = 1;
  928. } else
  929. if (strcmp (value, "disabled") == 0) {
  930. enabled = 0;
  931. }
  932. }
  933. }
  934. return enabled;
  935. }
  936. static int amf_exec_init_fn (struct objdb_iface_ver0 *objdb)
  937. {
  938. int res;
  939. char *error_string;
  940. char hostname[HOST_NAME_MAX + 1];
  941. struct amf_node *node;
  942. log_init ("AMF");
  943. if (!amf_enabled (objdb)) {
  944. return 0;
  945. }
  946. res = amf_config_read (&amf_cluster, &error_string);
  947. if (res == -1) {
  948. log_printf (LOG_LEVEL_ERROR, error_string);
  949. return res;
  950. }
  951. if (gethostname (hostname, sizeof(hostname)) == -1) {
  952. log_printf (LOG_LEVEL_ERROR, "gethostname failed: %d", errno);
  953. return -1;
  954. }
  955. /* look for this node */
  956. for (node = amf_cluster.node_head; node != NULL; node = node->next) {
  957. if (strcmp(hostname, getSaNameT (&node->name)) == 0) {
  958. this_amf_node = node;
  959. }
  960. }
  961. if (this_amf_node != NULL) {
  962. this_amf_node->saAmfNodeOperState = SA_AMF_OPERATIONAL_ENABLED;
  963. /* wait a while before starting applications as the AMF spec. says. */
  964. openais_timer_add(
  965. amf_cluster.saAmfClusterStartupTimeout,
  966. NULL,
  967. cluster_start_applications,
  968. &amf_cluster.timeout_handle);
  969. } else {
  970. log_printf (LOG_LEVEL_INFO, "This CLM node (%s) is not configured as an AMF node, disabling...", hostname);
  971. }
  972. return (0);
  973. }
  974. static void amf_confchg_fn (
  975. enum totem_configuration_type configuration_type,
  976. unsigned int *member_list, int member_list_entries,
  977. unsigned int *left_list, int left_list_entries,
  978. unsigned int *joined_list, int joined_list_entries,
  979. struct memb_ring_id *ring_id)
  980. {
  981. #ifdef COMPILE_OUT
  982. int i;
  983. log_printf (LOG_LEVEL_FROM_GMI, "Executive: amf_confchg_fn : type = %d,mnum = %d,jnum = %d,lnum = %d\n", configuration_type,member_list_entries,joined_list_entries,left_list_entries);
  984. recovery = 1;
  985. /*
  986. * If node join, component register
  987. */
  988. if ( joined_list_entries > 0 ) {
  989. enumerate_components (amf_confchg_njoin, NULL);
  990. }
  991. /*
  992. * If node leave, component unregister
  993. */
  994. for (i = 0; i<left_list_entries ; i++) {
  995. enumerate_components (amf_confchg_nleave, (void *)&(left_list[i]));
  996. }
  997. #ifdef TODO
  998. if (configuration_type == TOTEMPG_CONFIGURATION_REGULAR) {
  999. totempg_recovery_plug_unplug (amf_recovery_plug_handle);
  1000. recovery = 0;
  1001. }
  1002. #endif
  1003. #endif
  1004. }
  1005. static int amf_lib_exit_fn (void *conn)
  1006. {
  1007. struct amf_comp *comp;
  1008. struct amf_pd *amf_pd = (struct amf_pd *)openais_conn_private_data_get (conn);
  1009. assert (amf_pd != NULL);
  1010. comp = amf_pd->comp;
  1011. assert (comp != NULL);
  1012. comp->conn = NULL;
  1013. dprintf ("Lib exit from comp %s\n", getSaNameT (&comp->name));
  1014. return (0);
  1015. }
  1016. static int amf_lib_init_fn (void *conn)
  1017. {
  1018. struct amf_pd *amf_pd = (struct amf_pd *)openais_conn_private_data_get (conn);
  1019. list_init (&amf_pd->list);
  1020. return (0);
  1021. }
  1022. static DECLARE_LIST_INIT (library_notification_send_listhead);
  1023. // TODO static totempg_recovery_plug_handle amf_recovery_plug_handle;
  1024. #ifdef COMPILE_OUT
  1025. static void protectiongroup_notifications_send (
  1026. struct amf_comp *changedComponent,
  1027. SaAmfProtectionGroupChangesT changeToComponent)
  1028. {
  1029. int i;
  1030. struct conn_info *conn_info;
  1031. struct list_head *list;
  1032. log_printf (LOG_LEVEL_ENTER_FUNC, "protectiongroup_notifications_send: sending PGs to API.\n");
  1033. /*
  1034. * Iterate all tracked connections
  1035. */
  1036. for (list = library_notification_send_listhead.next;
  1037. list != &library_notification_send_listhead;
  1038. list = list->next) {
  1039. conn_info = list_entry (list, struct conn_info, conn_list);
  1040. for (i = 0; i < conn_info->ais_ci.u.libamf_ci.trackEntries; i++) {
  1041. if (conn_info->ais_ci.u.libamf_ci.tracks[i].active) {
  1042. if (conn_info->ais_ci.u.libamf_ci.tracks[i].csiName.length
  1043. != changedComponent->amf_pg->name.length) {
  1044. continue;
  1045. }
  1046. if (memcmp (conn_info->ais_ci.u.libamf_ci.tracks[i].csiName.value,
  1047. changedComponent->amf_pg->name.value,
  1048. conn_info->ais_ci.u.libamf_ci.tracks[i].csiName.length)) {
  1049. continue;
  1050. }
  1051. #ifdef COMPILE_OUT
  1052. protectiongroup_notification_send (conn_info,
  1053. conn_info->ais_ci.u.libamf_ci.tracks[i].notificationBufferAddress,
  1054. changedComponent->saAmfProtectionGroup,
  1055. changedComponent,
  1056. changeToComponent,
  1057. conn_info->ais_ci.u.libamf_ci.tracks[i].trackFlags);
  1058. #endif
  1059. } /* if track flags active */
  1060. } /* for all track entries */
  1061. } /* for all connection entries */
  1062. }
  1063. #endif
  1064. #ifdef COMPILE_OUT
  1065. static int make_protectiongroup_notification_allcomponent (
  1066. struct amf_comp *changedComponent,
  1067. SaAmfProtectionGroupChangesT changeToComponent,
  1068. SaAmfProtectionGroupNotificationT **notification )
  1069. {
  1070. SaAmfProtectionGroupNotificationT *protectionGroupNotification = 0;
  1071. int notifyEntries = 0;
  1072. struct amf_comp *component;
  1073. struct list_head *AmfGroupList;
  1074. struct list_head *AmfUnitList;
  1075. struct list_head *AmfComponentList;
  1076. struct saAmfGroup *saAmfGroup;
  1077. struct saAmfUnit *AmfUnit;
  1078. for (AmfGroupList = saAmfGroupHead.next; AmfGroupList != &saAmfGroupHead; AmfGroupList = AmfGroupList->next) {
  1079. saAmfGroup = list_entry (AmfGroupList, struct saAmfGroup, saAmfGroupList);
  1080. /*
  1081. * Search all units
  1082. */
  1083. for (AmfUnitList = saAmfGroup->saAmfUnitHead.next;
  1084. AmfUnitList != &saAmfGroup->saAmfUnitHead;
  1085. AmfUnitList = AmfUnitList->next) {
  1086. AmfUnit = list_entry (AmfUnitList, struct saAmfUnit, saAmfUnitList);
  1087. /*
  1088. * Search all components
  1089. */
  1090. for (AmfComponentList = AmfUnit->amf_compHead.next;
  1091. AmfComponentList != &AmfUnit->amf_compHead;
  1092. AmfComponentList = AmfComponentList->next) {
  1093. component = list_entry (AmfComponentList, struct amf_comp, amf_compList);
  1094. protectionGroupNotification =
  1095. (SaAmfProtectionGroupNotificationT *)mempool_realloc (protectionGroupNotification,
  1096. sizeof (SaAmfProtectionGroupNotificationT) * (notifyEntries + 1));
  1097. memset (&protectionGroupNotification[notifyEntries],
  1098. 0,sizeof (SaAmfProtectionGroupNotificationT));
  1099. memcpy (&protectionGroupNotification[notifyEntries].member.compName,
  1100. &component->name, sizeof (SaNameT));
  1101. // memcpy (&protectionGroupNotification[notifyEntries].member.readinessState,
  1102. // &component->currentReadinessState, sizeof (SaAmfReadinessStateT));
  1103. memcpy (&protectionGroupNotification[notifyEntries].member.haState,
  1104. &component->currentHAState, sizeof (SaAmfHAStateT));
  1105. if (component == changedComponent) {
  1106. protectionGroupNotification[notifyEntries].change = changeToComponent;
  1107. } else {
  1108. protectionGroupNotification[notifyEntries].change
  1109. = SA_AMF_PROTECTION_GROUP_NO_CHANGE;
  1110. }
  1111. notifyEntries += 1;
  1112. }
  1113. }
  1114. }
  1115. if (notifyEntries) {
  1116. *notification = protectionGroupNotification;
  1117. }
  1118. return (notifyEntries);
  1119. }
  1120. #endif
  1121. #ifdef COMPILE_OUT
  1122. static int make_protectiongroup_notification (
  1123. struct saAmfProtectionGroup *amfProtectionGroup,
  1124. struct amf_comp *changedComponent,
  1125. SaAmfProtectionGroupChangesT changeToComponent,
  1126. SaAmfProtectionGroupNotificationT **notification )
  1127. {
  1128. struct res_lib_amf_protectiongrouptrackcallback res_lib_amf_protectiongrouptrackcallback;
  1129. int notifyEntries = 0;
  1130. struct amf_comp *component;
  1131. struct list_head *componentList;
  1132. SaAmfProtectionGroupNotificationT *protectionGroupNotification = 0;
  1133. memset (&res_lib_amf_protectiongrouptrackcallback,0,sizeof(res_lib_amf_protectiongrouptrackcallback));
  1134. for (componentList = amfProtectionGroup->saAmfMembersHead.next;
  1135. componentList != &amfProtectionGroup->saAmfMembersHead;
  1136. componentList = componentList->next) {
  1137. component = list_entry (componentList, struct amf_comp, saAmfProtectionGroupList);
  1138. protectionGroupNotification =
  1139. (SaAmfProtectionGroupNotificationT *)mempool_realloc (protectionGroupNotification,
  1140. sizeof (SaAmfProtectionGroupNotificationT) * (notifyEntries + 1));
  1141. memset (&protectionGroupNotification[notifyEntries],0,sizeof (SaAmfProtectionGroupNotificationT));
  1142. memcpy (&protectionGroupNotification[notifyEntries].member.compName,
  1143. &component->name, sizeof (SaNameT));
  1144. // memcpy (&protectionGroupNotification[notifyEntries].member.readinessState,
  1145. // &component->currentReadinessState, sizeof (SaAmfReadinessStateT));
  1146. memcpy (&protectionGroupNotification[notifyEntries].member.haState,
  1147. &component->currentHAState, sizeof (SaAmfHAStateT));
  1148. if (component == changedComponent) {
  1149. protectionGroupNotification[notifyEntries].change = changeToComponent;
  1150. } else {
  1151. protectionGroupNotification[notifyEntries].change = SA_AMF_PROTECTION_GROUP_NO_CHANGE;
  1152. }
  1153. notifyEntries += 1;
  1154. } /* for */
  1155. if (notifyEntries) {
  1156. *notification = protectionGroupNotification;
  1157. }
  1158. return (notifyEntries);
  1159. return (0);
  1160. }
  1161. #endif
  1162. #ifdef COMPILE_OUT
  1163. static void protectiongroup_notification_send (struct conn_info *conn_info,
  1164. SaAmfProtectionGroupNotificationT *notificationBufferAddress,
  1165. struct saAmfProtectionGroup *amfProtectionGroup,
  1166. struct amf_comp *changedComponent,
  1167. SaAmfProtectionGroupChangesT changeToComponent,
  1168. SaUint8T trackFlags)
  1169. {
  1170. //struct res_lib_amf_protectiongrouptrackcallback res_lib_amf_protectiongrouptrackcallback;
  1171. SaAmfProtectionGroupNotificationT *protectionGroupNotification = 0;
  1172. int notifyEntries;
  1173. /*
  1174. * Step through all components and generate protection group list for csi
  1175. */
  1176. memset (&res_lib_amf_protectiongrouptrackcallback, 0, sizeof(res_lib_amf_protectiongrouptrackcallback));
  1177. if ( trackFlags == SA_TRACK_CHANGES ) {
  1178. notifyEntries = make_protectiongroup_notification_allcomponent (changedComponent,
  1179. changeToComponent, &protectionGroupNotification);
  1180. }else if (trackFlags == SA_TRACK_CHANGES_ONLY) {
  1181. notifyEntries = make_protectiongroup_notification (amfProtectionGroup,
  1182. changedComponent, changeToComponent, &protectionGroupNotification );
  1183. }else{
  1184. notifyEntries = 0;
  1185. }
  1186. /*
  1187. * Send track callback
  1188. */
  1189. if (notifyEntries) {
  1190. res_lib_amf_protectiongrouptrackcallback.header.size =
  1191. sizeof (struct res_lib_amf_protectiongrouptrackcallback) +
  1192. (notifyEntries * sizeof (SaAmfProtectionGroupNotificationT));
  1193. // res_lib_amf_protectiongrouptrackcallback.header.id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACKCALLBACK;
  1194. res_lib_amf_protectiongrouptrackcallback.header.error = SA_AIS_OK;
  1195. res_lib_amf_protectiongrouptrackcallback.numberOfItems = notifyEntries;
  1196. res_lib_amf_protectiongrouptrackcallback.numberOfMembers = notifyEntries;
  1197. memcpy (&res_lib_amf_protectiongrouptrackcallback.csiName,
  1198. &amfProtectionGroup->name, sizeof (SaNameT));
  1199. res_lib_amf_protectiongrouptrackcallback.notificationBufferAddress = notificationBufferAddress;
  1200. openais_conn_send_response (conno, &res_lib_amf_protectiongrouptrackcallback,
  1201. sizeof (struct res_lib_amf_protectiongrouptrackcallback));
  1202. openais_conn_send_response (conno, protectionGroupNotification,
  1203. sizeof (SaAmfProtectionGroupNotificationT) * notifyEntries);
  1204. mempool_free (protectionGroupNotification);
  1205. }
  1206. }
  1207. #endif
  1208. #define INVOCATION_DONT_COMPARE 0xFFFFFFFFULL
  1209. #if 0
  1210. static struct healthcheck_active *find_healthcheck_active (
  1211. struct amf_comp *comp,
  1212. SaAmfHealthcheckKeyT *key,
  1213. SaAmfHealthcheckInvocationT invocation)
  1214. {
  1215. struct list_head *list;
  1216. struct healthcheck_active *ret_healthcheck_active = 0;
  1217. struct healthcheck_active *healthcheck_active;
  1218. for (list = comp->healthcheck_head.next;
  1219. list != &comp->healthcheck_head;
  1220. list = list->next) {
  1221. healthcheck_active = list_entry (list,
  1222. struct healthcheck_active, list);
  1223. if ((memcmp (key, &healthcheck_active->key,
  1224. sizeof (SaAmfHealthcheckKeyT)) == 0) &&
  1225. (invocation == INVOCATION_DONT_COMPARE ||
  1226. healthcheck_active->invocationType == invocation)) {
  1227. ret_healthcheck_active = healthcheck_active;
  1228. break;
  1229. }
  1230. }
  1231. return (ret_healthcheck_active);
  1232. }
  1233. static void comp_healthcheck_activate (struct amf_comp *comp)
  1234. {
  1235. struct amf_healthcheck *healthcheck;
  1236. if (!comp->is_local)
  1237. return;
  1238. for (healthcheck = comp->healthcheck_head;
  1239. healthcheck != NULL;
  1240. healthcheck = healthcheck->next) {
  1241. if (healthcheck->active == 0) {
  1242. healthcheck_activate (healthcheck);
  1243. }
  1244. }
  1245. }
  1246. #endif
  1247. static void comp_healthcheck_deactivate (
  1248. struct amf_comp *comp)
  1249. {
  1250. struct amf_healthcheck *healthcheck;
  1251. if (!comp->su->is_local)
  1252. return;
  1253. ENTER ("'%s'\n", getSaNameT (&comp->name));
  1254. for (healthcheck = comp->healthcheck_head;
  1255. healthcheck != NULL;
  1256. healthcheck = healthcheck->next) {
  1257. if (healthcheck->active) {
  1258. healthcheck_deactivate (healthcheck);
  1259. }
  1260. }
  1261. }
  1262. static void comp_presence_state_set (struct amf_comp *comp,
  1263. SaAmfPresenceStateT presence_state)
  1264. {
  1265. comp->saAmfCompPresenceState = presence_state;
  1266. TRACE1 ("Setting comp '%s' presence state: %s\n",
  1267. comp->name.value, presence_state_text[comp->saAmfCompPresenceState]);
  1268. /*
  1269. * If all comp presence states are INSTANTIATED, then SU should be instantated
  1270. */
  1271. if ((presence_state == SA_AMF_PRESENCE_INSTANTIATED) &&
  1272. presence_state_all_comps_in_su_are_set (comp->su, SA_AMF_PRESENCE_INSTANTIATED)) {
  1273. su_presence_state_set (comp->su, SA_AMF_PRESENCE_INSTANTIATED);
  1274. }
  1275. }
  1276. static void comp_readiness_state_set (struct amf_comp *comp)
  1277. {
  1278. /*
  1279. * Set component readiness state appropriately
  1280. * if unit in service and component is enabled, it is in service
  1281. * otherwise it is out of service page 50 B.02.01
  1282. */
  1283. if (comp->su->saAmfSUReadinessState == SA_AMF_READINESS_IN_SERVICE &&
  1284. comp->saAmfCompOperState == SA_AMF_OPERATIONAL_ENABLED) {
  1285. comp->saAmfCompReadinessState = SA_AMF_READINESS_IN_SERVICE;
  1286. } else if (comp->su->saAmfSUReadinessState == SA_AMF_READINESS_STOPPING &&
  1287. comp->saAmfCompOperState == SA_AMF_OPERATIONAL_ENABLED) {
  1288. comp->saAmfCompReadinessState = SA_AMF_READINESS_STOPPING;
  1289. } else {
  1290. comp->saAmfCompReadinessState = SA_AMF_READINESS_OUT_OF_SERVICE;
  1291. }
  1292. TRACE1 ("Setting comp '%s' readiness state: %s\n",
  1293. comp->name.value, readiness_state_text[comp->saAmfCompReadinessState]);
  1294. }
  1295. static void comp_operational_state_set (struct amf_comp *comp,
  1296. SaAmfOperationalStateT oper_state)
  1297. {
  1298. struct amf_comp *comp_compare;
  1299. int all_set;
  1300. comp->saAmfCompOperState = oper_state;
  1301. TRACE1 ("Setting comp '%s' operational state: %s\n",
  1302. comp->name.value, oper_state_text[comp->saAmfCompOperState]);
  1303. /*
  1304. * If all operational states are ENABLED, then SU should be ENABLED
  1305. */
  1306. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  1307. all_set = 1;
  1308. for (comp_compare = comp->su->comp_head; comp_compare != NULL; comp_compare = comp->next) {
  1309. if (comp_compare->saAmfCompOperState != SA_AMF_OPERATIONAL_ENABLED) {
  1310. all_set = 0;
  1311. break;
  1312. }
  1313. }
  1314. if (all_set) {
  1315. su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_ENABLED);
  1316. } else {
  1317. su_operational_state_set (comp->su, SA_AMF_OPERATIONAL_DISABLED);
  1318. }
  1319. }
  1320. }
  1321. static void comp_csi_set_callback (
  1322. struct amf_comp *comp,
  1323. struct amf_csi_assignment *csi_assignment)
  1324. {
  1325. struct res_lib_amf_csisetcallback* res_lib_amf_csisetcallback;
  1326. void* p;
  1327. struct amf_csi_attribute *attribute;
  1328. size_t char_length_of_csi_attrs=0;
  1329. size_t num_of_csi_attrs=0;
  1330. int i;
  1331. struct amf_csi *csi = csi_assignment->csi;
  1332. int ha_state = csi_assignment->saAmfCSICompHASate;
  1333. if (!comp->su->is_local)
  1334. return;
  1335. dprintf("\t Assigning CSI '%s' state %s to comp '%s'\n",
  1336. getSaNameT (&csi->name), ha_state_text[ha_state], comp->name.value);
  1337. for (attribute = csi->attributes_head;
  1338. attribute != NULL;
  1339. attribute = attribute->next) {
  1340. for (i = 0; attribute->value[i] != NULL; i++) {
  1341. num_of_csi_attrs++;
  1342. char_length_of_csi_attrs += strlen(attribute->name);
  1343. char_length_of_csi_attrs += strlen(attribute->value[i]);
  1344. char_length_of_csi_attrs += 2;
  1345. }
  1346. }
  1347. p = malloc(sizeof(struct res_lib_amf_csisetcallback)+
  1348. char_length_of_csi_attrs);
  1349. if (p == NULL) {
  1350. openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
  1351. }
  1352. res_lib_amf_csisetcallback = (struct res_lib_amf_csisetcallback*)p;
  1353. /* Address of the buffer containing the Csi name value pair */
  1354. char* csi_attribute_buf = res_lib_amf_csisetcallback->csi_attr_buf;
  1355. /* Byteoffset start at the zero byte */
  1356. unsigned int byte_offset = 0;
  1357. for (attribute = csi->attributes_head;
  1358. attribute != NULL;
  1359. attribute = attribute->next) {
  1360. for (i = 0; attribute->value[i] != NULL; i++) {
  1361. strcpy(&csi_attribute_buf[byte_offset], (char*)attribute->name);
  1362. byte_offset += strlen(attribute->name) + 1;
  1363. strcpy(&csi_attribute_buf[byte_offset], (char*)attribute->value[i]);
  1364. byte_offset += strlen(attribute->value[i]) + 1;
  1365. }
  1366. }
  1367. res_lib_amf_csisetcallback->number = num_of_csi_attrs;
  1368. res_lib_amf_csisetcallback->csiFlags = SA_AMF_CSI_ADD_ONE;
  1369. switch (ha_state) {
  1370. case SA_AMF_HA_ACTIVE: {
  1371. res_lib_amf_csisetcallback->csiStateDescriptor.activeDescriptor.activeCompName.length = 0;
  1372. res_lib_amf_csisetcallback->csiStateDescriptor.activeDescriptor.transitionDescriptor =
  1373. SA_AMF_CSI_NEW_ASSIGN;
  1374. break;
  1375. }
  1376. case SA_AMF_HA_STANDBY: {
  1377. res_lib_amf_csisetcallback->csiStateDescriptor.standbyDescriptor.activeCompName.length = 0;
  1378. res_lib_amf_csisetcallback->csiStateDescriptor.standbyDescriptor.standbyRank = 1;
  1379. break;
  1380. }
  1381. case SA_AMF_HA_QUIESCED: {
  1382. /*TODO*/
  1383. break;
  1384. }
  1385. case SA_AMF_HA_QUIESCING: {
  1386. /*TODO*/
  1387. break;
  1388. }
  1389. default: {
  1390. assert(SA_AMF_HA_ACTIVE||SA_AMF_HA_STANDBY||SA_AMF_HA_QUIESCING||SA_AMF_HA_QUIESCED);
  1391. break;
  1392. }
  1393. }
  1394. res_lib_amf_csisetcallback->header.id = MESSAGE_RES_AMF_CSISETCALLBACK;
  1395. res_lib_amf_csisetcallback->header.size =
  1396. sizeof (struct res_lib_amf_csisetcallback)+
  1397. char_length_of_csi_attrs;
  1398. res_lib_amf_csisetcallback->header.error = SA_AIS_OK;
  1399. comp_dn_make (comp, &res_lib_amf_csisetcallback->compName);
  1400. csi_dn_make (csi, &res_lib_amf_csisetcallback->csiName);
  1401. res_lib_amf_csisetcallback->haState = ha_state;
  1402. res_lib_amf_csisetcallback->invocation =
  1403. invocation_create (AMF_RESPONSE_CSISETCALLBACK, csi_assignment);
  1404. openais_conn_send_response (openais_conn_partner_get (comp->conn),
  1405. res_lib_amf_csisetcallback,
  1406. res_lib_amf_csisetcallback->header.size);
  1407. free(p);
  1408. }
  1409. #if 0
  1410. static void pg_create (struct amf_si *si, struct amf_pg **pg_out)
  1411. {
  1412. struct amf_pg *pg;
  1413. // struct amf_pg_comp *pg_comp;
  1414. pg = malloc (sizeof (struct amf_pg));
  1415. assert (pg);
  1416. list_init (&pg->pg_comp_head);
  1417. list_init (&pg->pg_list);
  1418. list_add (&pg->pg_list, &si->pg_head);
  1419. *pg_out = pg;
  1420. }
  1421. #endif
  1422. #if 0
  1423. static void csi_comp_remove_callback (struct amf_comp *comp, struct amf_csi *csi)
  1424. {
  1425. struct res_lib_amf_csiremovecallback res_lib_amf_csiremovecallback;
  1426. struct csi_remove_callback_data *csi_remove_callback_data;
  1427. dprintf ("\t%s\n",
  1428. getSaNameT (&comp->name));
  1429. res_lib_amf_csiremovecallback.header.id = MESSAGE_RES_AMF_CSIREMOVECALLBACK;
  1430. res_lib_amf_csiremovecallback.header.size = sizeof (struct res_lib_amf_csiremovecallback);
  1431. res_lib_amf_csiremovecallback.header.error = SA_AIS_OK;
  1432. csi_remove_callback_data = malloc (sizeof (struct csi_remove_callback_data));
  1433. assert (csi_remove_callback_data); // TODO failure here of malloc
  1434. csi_remove_callback_data->csi = csi;
  1435. res_lib_amf_csiremovecallback.invocation =
  1436. invocation_create (
  1437. AMF_RESPONSE_CSIREMOVECALLBACK,
  1438. csi_remove_callback_data);
  1439. memcpy (&res_lib_amf_csiremovecallback.compName,
  1440. &comp->name, sizeof (SaNameT));
  1441. memcpy (&res_lib_amf_csiremovecallback.csiName,
  1442. &csi->name, sizeof (SaNameT));
  1443. res_lib_amf_csiremovecallback.csiFlags = 0;
  1444. openais_conn_send_response (
  1445. openais_conn_partner_get (comp->conn),
  1446. &res_lib_amf_csiremovecallback,
  1447. sizeof (struct res_lib_amf_csiremovecallback));
  1448. }
  1449. #endif
  1450. static void cluster_assign_workload (void *data)
  1451. {
  1452. struct amf_application *app;
  1453. struct amf_sg *sg;
  1454. dprintf("2nd Cluster start timer expired, assigning SIs\n");
  1455. for (app = amf_cluster.application_head; app != NULL; app = app->next) {
  1456. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1457. sg_assign_si (sg);
  1458. }
  1459. }
  1460. }
  1461. static void cluster_start_applications (void *data)
  1462. {
  1463. struct amf_application *app;
  1464. struct amf_sg *sg;
  1465. struct amf_su *su;
  1466. dprintf("1st Cluster start timer expired, instantiating SUs");
  1467. for (app = amf_cluster.application_head; app != NULL; app = app->next) {
  1468. for (sg = app->sg_head; sg != NULL; sg = sg->next) {
  1469. for (su = sg->su_head; su != NULL; su = su->next) {
  1470. /* Only start SUs configured to this node */
  1471. if (name_match (&this_amf_node->name,
  1472. &su->saAmfSUHostedByNode )) {
  1473. su->is_local = 1;
  1474. clc_su_instantiate (su);
  1475. }
  1476. }
  1477. }
  1478. }
  1479. /* wait a while before assigning SIs as the AMF spec. says. */
  1480. openais_timer_add(
  1481. amf_cluster.saAmfClusterStartupTimeout,
  1482. NULL,
  1483. cluster_assign_workload,
  1484. &amf_cluster.timeout_handle);
  1485. }
  1486. #if 0
  1487. static void comp_terminate (struct amf_comp *comp)
  1488. {
  1489. clc_terminate (comp);
  1490. }
  1491. static void unit_terminate (struct amf_su *unit)
  1492. {
  1493. struct amf_comp *comp;
  1494. for (comp = unit->comp_head; comp != NULL; comp = comp->next) {
  1495. clc_terminate (comp);
  1496. }
  1497. }
  1498. #endif
  1499. static void comp_cleanup (struct amf_comp *comp)
  1500. {
  1501. clc_cleanup (comp);
  1502. }
  1503. static void su_cleanup (struct amf_su *unit)
  1504. {
  1505. struct amf_comp *comp;
  1506. for (comp = unit->comp_head; comp != NULL; comp = comp->next) {
  1507. clc_cleanup (comp);
  1508. }
  1509. }
  1510. static void comp_restart (struct amf_comp *comp)
  1511. {
  1512. comp_presence_state_set (comp, SA_AMF_PRESENCE_RESTARTING);
  1513. }
  1514. static void comp_reassign_csis (struct amf_comp *comp)
  1515. {
  1516. struct amf_csi_assignment *csi_assignment = comp->assigned_csis;
  1517. ENTER ("'%s'", comp->name.value);
  1518. for (; csi_assignment; csi_assignment = csi_assignment->comp_next) {
  1519. comp_csi_set_callback (comp, csi_assignment);
  1520. }
  1521. }
  1522. #if 0
  1523. static void unit_restart (struct amf_su *unit)
  1524. {
  1525. struct amf_comp *comp;
  1526. for (comp = unit->comp_head; comp != NULL; comp = comp->next) {
  1527. comp_presence_state_set (comp, SA_AMF_PRESENCE_RESTARTING);
  1528. }
  1529. }
  1530. #endif
  1531. static void clc_su_instantiate (struct amf_su *unit)
  1532. {
  1533. struct amf_comp *comp;
  1534. for (comp = unit->comp_head; comp != NULL; comp = comp->next) {
  1535. clc_instantiate (comp);
  1536. }
  1537. }
  1538. static void comp_assign_csi (struct amf_comp *comp, struct amf_csi *csi,
  1539. SaAmfHAStateT ha_state)
  1540. {
  1541. struct amf_csi_assignment *csi_assignment;
  1542. dprintf (" Assigning CSI '%s' to comp '%s' with hastate %s\n",
  1543. getSaNameT (&csi->name), getSaNameT (&comp->name),
  1544. ha_state_text[ha_state]);
  1545. csi_assignment = malloc (sizeof (struct amf_csi_assignment));
  1546. if (csi_assignment == NULL) {
  1547. openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
  1548. }
  1549. csi_assignment->comp_next = comp->assigned_csis;
  1550. comp->assigned_csis = csi_assignment;
  1551. setSaNameT (&csi_assignment->name, (char*)comp->name.value);
  1552. csi_assignment->saAmfCSICompHASate = ha_state;
  1553. csi_assignment->csi = csi;
  1554. csi_assignment->comp = comp;
  1555. csi_assignment->saAmfCSICompHASate = ha_state;
  1556. if (ha_state == SA_AMF_HA_ACTIVE)
  1557. comp->saAmfCompNumCurrActiveCsi++;
  1558. else if (ha_state == SA_AMF_HA_STANDBY)
  1559. comp->saAmfCompNumCurrStandbyCsi++;
  1560. else
  1561. assert (0);
  1562. comp_csi_set_callback (comp, csi_assignment);
  1563. }
  1564. static void su_assign_si (struct amf_su *su, struct amf_si *si,
  1565. SaAmfHAStateT ha_state)
  1566. {
  1567. struct amf_si_assignment *si_assignment;
  1568. dprintf ("Assigning SI '%s' to SU '%s' with hastate %s\n",
  1569. getSaNameT (&si->name), getSaNameT (&su->name),
  1570. ha_state_text[ha_state]);
  1571. si_assignment = malloc (sizeof (struct amf_si_assignment));
  1572. if (si_assignment == NULL) {
  1573. openais_exit_error (AIS_DONE_OUT_OF_MEMORY);
  1574. }
  1575. setSaNameT (&si_assignment->name, (char*)su->name.value);
  1576. si_assignment->saAmfSISUHAState = ha_state;
  1577. si_assignment->next = su->assigned_sis;
  1578. su->assigned_sis = si_assignment;
  1579. si_assignment->si = si;
  1580. if (ha_state == SA_AMF_HA_ACTIVE) {
  1581. si->saAmfSINumCurrActiveAssignments++;
  1582. su->saAmfSUNumCurrActiveSIs++;
  1583. } else if (ha_state == SA_AMF_HA_STANDBY) {
  1584. su->saAmfSUNumCurrStandbySIs++;
  1585. si->saAmfSINumCurrStandbyAssignments++;
  1586. } else
  1587. assert(0);
  1588. if ((si->saAmfSINumCurrActiveAssignments == si->saAmfSIPrefActiveAssignments) &&
  1589. (si->saAmfSINumCurrStandbyAssignments == si->saAmfSIPrefStandbyAssignments)) {
  1590. si->saAmfSIAssignmentState = SA_AMF_ASSIGNMENT_FULLY_ASSIGNED;
  1591. } else if ((si->saAmfSINumCurrActiveAssignments < si->saAmfSIPrefActiveAssignments) ||
  1592. (si->saAmfSINumCurrStandbyAssignments < si->saAmfSIPrefStandbyAssignments)) {
  1593. si->saAmfSIAssignmentState = SA_AMF_ASSIGNMENT_PARTIALLY_ASSIGNED;
  1594. }
  1595. {
  1596. struct amf_csi *csi;
  1597. struct amf_comp *comp;
  1598. SaNameT *cs_type;
  1599. int i;
  1600. /*
  1601. ** for each component in SU, find a CSI in the SI with the same type
  1602. */
  1603. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1604. int no_of_cs_types = 0;
  1605. for (i = 0; comp->saAmfCompCsTypes[i]; i++) {
  1606. cs_type = comp->saAmfCompCsTypes[i];
  1607. no_of_cs_types++;
  1608. int no_of_assignments = 0;
  1609. for (csi = si->csi_head; csi != NULL; csi = csi->next) {
  1610. if (!memcmp(csi->saAmfCSTypeName.value, cs_type->value, cs_type->length)) {
  1611. comp_assign_csi (comp, csi, ha_state);
  1612. no_of_assignments++;
  1613. }
  1614. }
  1615. if (no_of_assignments == 0) {
  1616. log_printf (LOG_WARNING, "\t No CSIs of type %s configured?!!\n",
  1617. getSaNameT (cs_type));
  1618. }
  1619. }
  1620. if (no_of_cs_types == 0) {
  1621. log_printf (LOG_LEVEL_ERROR, "\t No CS types configured for comp %s ?!!\n",
  1622. getSaNameT (&comp->name));
  1623. }
  1624. }
  1625. }
  1626. }
  1627. static int su_inservice_count_get (struct amf_sg *sg)
  1628. {
  1629. struct amf_su *unit;
  1630. int answer = 0;
  1631. for (unit = sg->su_head; unit != NULL; unit = unit->next) {
  1632. if (unit->saAmfSUReadinessState == SA_AMF_READINESS_IN_SERVICE) {
  1633. answer += 1;
  1634. }
  1635. }
  1636. return (answer);
  1637. }
  1638. #if 0
  1639. static int comp_inservice_count (struct amf_su *unit)
  1640. {
  1641. struct amf_comp *comp;
  1642. int answer = 0;
  1643. for (comp = unit->comp_head; comp != NULL; comp = comp->next) {
  1644. if (comp->saAmfCompReadinessState == SA_AMF_READINESS_IN_SERVICE) {
  1645. answer += 1;
  1646. }
  1647. }
  1648. return (answer);
  1649. }
  1650. #endif
  1651. static int application_si_count_get (struct amf_application *app)
  1652. {
  1653. struct amf_si *si;
  1654. int answer = 0;
  1655. for (si = app->si_head; si != NULL; si = si->next) {
  1656. answer += 1;
  1657. }
  1658. return (answer);
  1659. }
  1660. static inline int div_round (int a, int b)
  1661. {
  1662. int res;
  1663. res = a / b;
  1664. if ((a % b) != 0)
  1665. res++;
  1666. return res;
  1667. }
  1668. static void sg_assign_nm_active (struct amf_sg *sg, int su_units_assign)
  1669. {
  1670. struct amf_su *unit;
  1671. struct amf_si *si;
  1672. int assigned = 0;
  1673. int assign_per_su = 0;
  1674. int total_assigned = 0;
  1675. assign_per_su = application_si_count_get (sg->application);
  1676. assign_per_su = div_round (assign_per_su, su_units_assign);
  1677. if (assign_per_su > sg->saAmfSGMaxActiveSIsperSUs) {
  1678. assign_per_su = sg->saAmfSGMaxActiveSIsperSUs;
  1679. }
  1680. si = sg->application->si_head;
  1681. unit = sg->su_head;
  1682. while (unit != NULL) {
  1683. if (unit->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE ||
  1684. unit->saAmfSUNumCurrActiveSIs == sg->saAmfSGMaxActiveSIsperSUs ||
  1685. unit->saAmfSUNumCurrStandbySIs > 0) {
  1686. unit = unit->next;
  1687. continue; /* Not in service */
  1688. }
  1689. assigned = 0;
  1690. while (si != NULL &&
  1691. assigned < assign_per_su &&
  1692. total_assigned < application_si_count_get (sg->application)) {
  1693. assigned += 1;
  1694. total_assigned += 1;
  1695. su_assign_si (unit, si, SA_AMF_HA_ACTIVE);
  1696. si = si->next;
  1697. }
  1698. unit = unit->next;
  1699. }
  1700. if (total_assigned == 0) {
  1701. dprintf ("Error: No SIs assigned!");
  1702. }
  1703. }
  1704. static void sg_assign_nm_standby (struct amf_sg *sg, int units_assign_standby)
  1705. {
  1706. struct amf_su *unit;
  1707. struct amf_si *si;
  1708. int assigned = 0;
  1709. int assign_per_su = 0;
  1710. int total_assigned = 0;
  1711. if (units_assign_standby == 0) {
  1712. return;
  1713. }
  1714. assign_per_su = application_si_count_get (sg->application);
  1715. assign_per_su = div_round (assign_per_su, units_assign_standby);
  1716. if (assign_per_su > sg->saAmfSGMaxStandbySIsperSUs) {
  1717. assign_per_su = sg->saAmfSGMaxStandbySIsperSUs;
  1718. }
  1719. si = sg->application->si_head;
  1720. unit = sg->su_head;
  1721. while (unit != NULL) {
  1722. if (unit->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE ||
  1723. unit->saAmfSUNumCurrActiveSIs > 0 ||
  1724. unit->saAmfSUNumCurrStandbySIs == sg->saAmfSGMaxStandbySIsperSUs) {
  1725. unit = unit->next;
  1726. continue; /* Not available for assignment */
  1727. }
  1728. assigned = 0;
  1729. while (si != NULL && assigned < assign_per_su) {
  1730. assigned += 1;
  1731. total_assigned += 1;
  1732. su_assign_si (unit, si, SA_AMF_HA_STANDBY);
  1733. si = si->next;
  1734. }
  1735. unit = unit->next;
  1736. }
  1737. if (total_assigned == 0) {
  1738. dprintf ("Error: No SIs assigned!");
  1739. }
  1740. }
  1741. #if 0
  1742. static void assign_nm_spare (struct amf_sg *sg)
  1743. {
  1744. struct amf_su *unit;
  1745. for (unit = sg->su_head; unit != NULL; unit = unit->next) {
  1746. if (unit->saAmfSUReadinessState == SA_AMF_READINESS_IN_SERVICE &&
  1747. (unit->requested_ha_state != SA_AMF_HA_ACTIVE &&
  1748. unit->requested_ha_state != SA_AMF_HA_STANDBY)) {
  1749. dprintf ("Assigning to SU %s with SPARE\n",
  1750. getSaNameT (&unit->name));
  1751. }
  1752. }
  1753. }
  1754. #endif
  1755. static void sg_assign_si (struct amf_sg *sg)
  1756. {
  1757. int active_sus_needed;
  1758. int standby_sus_needed;
  1759. int inservice_count;
  1760. int units_for_standby;
  1761. int units_for_active;
  1762. int ii_spare;
  1763. int su_active_assign;
  1764. int su_standby_assign;
  1765. int su_spare_assign;
  1766. ENTER ("'%s'", sg->name.value);
  1767. /*
  1768. * Number of SUs to assign to active or standby state
  1769. */
  1770. inservice_count = (float)su_inservice_count_get (sg);
  1771. active_sus_needed = div_round (application_si_count_get (sg->application),
  1772. sg->saAmfSGMaxActiveSIsperSUs);
  1773. standby_sus_needed = div_round (application_si_count_get (sg->application),
  1774. sg->saAmfSGMaxStandbySIsperSUs);
  1775. units_for_active = inservice_count - sg->saAmfSGNumPrefStandbySUs;
  1776. if (units_for_active < 0) {
  1777. units_for_active = 0;
  1778. }
  1779. units_for_standby = inservice_count - sg->saAmfSGNumPrefActiveSUs;
  1780. if (units_for_standby < 0) {
  1781. units_for_standby = 0;
  1782. }
  1783. ii_spare = inservice_count - sg->saAmfSGNumPrefActiveSUs - sg->saAmfSGNumPrefStandbySUs;
  1784. if (ii_spare < 0) {
  1785. ii_spare = 0;
  1786. }
  1787. /*
  1788. * Determine number of active and standby service units
  1789. * to assign based upon reduction procedure
  1790. */
  1791. if ((inservice_count - active_sus_needed) < 0) {
  1792. dprintf ("assignment VI - partial assignment with SIs drop outs\n");
  1793. su_active_assign = active_sus_needed;
  1794. su_standby_assign = 0;
  1795. su_spare_assign = 0;
  1796. } else
  1797. if ((inservice_count - active_sus_needed - standby_sus_needed) < 0) {
  1798. dprintf ("assignment V - partial assignment with reduction of standby units\n");
  1799. su_active_assign = active_sus_needed;
  1800. if (standby_sus_needed > units_for_standby) {
  1801. su_standby_assign = units_for_standby;
  1802. } else {
  1803. su_standby_assign = standby_sus_needed;
  1804. }
  1805. su_spare_assign = 0;
  1806. } else
  1807. if ((sg->saAmfSGMaxStandbySIsperSUs * units_for_standby) <= application_si_count_get (sg->application)) {
  1808. dprintf ("IV: full assignment with reduction of active service units\n");
  1809. su_active_assign = inservice_count - standby_sus_needed;
  1810. su_standby_assign = standby_sus_needed;
  1811. su_spare_assign = 0;
  1812. } else
  1813. if ((sg->saAmfSGMaxActiveSIsperSUs * units_for_active) <= application_si_count_get (sg->application)) {
  1814. dprintf ("III: full assignment with reduction of standby service units\n");
  1815. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1816. su_standby_assign = units_for_standby;
  1817. su_spare_assign = 0;
  1818. } else
  1819. if (ii_spare == 0) {
  1820. dprintf ("II: full assignment with spare reduction\n");
  1821. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1822. su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
  1823. su_spare_assign = 0;
  1824. } else {
  1825. dprintf ("I: full assignment with spares\n");
  1826. su_active_assign = sg->saAmfSGNumPrefActiveSUs;
  1827. su_standby_assign = sg->saAmfSGNumPrefStandbySUs;
  1828. su_spare_assign = ii_spare;
  1829. }
  1830. dprintf ("(inservice=%d) (assigning active=%d) (assigning standby=%d) (assigning spares=%d)\n",
  1831. inservice_count, su_active_assign, su_standby_assign, su_spare_assign);
  1832. sg_assign_nm_active (sg, su_active_assign);
  1833. sg_assign_nm_standby (sg, su_standby_assign);
  1834. LEAVE ("'%s'", sg->name.value);
  1835. }
  1836. static int sg_all_su_in_service(struct amf_sg *sg)
  1837. {
  1838. struct amf_su *su;
  1839. struct amf_comp *comp;
  1840. int ready = 1;
  1841. for (su = sg->su_head; su != NULL; su = su->next) {
  1842. for (comp = su->comp_head; comp != NULL; comp = comp->next) {
  1843. if (su->saAmfSUReadinessState != SA_AMF_READINESS_IN_SERVICE) {
  1844. ready = 0;
  1845. }
  1846. }
  1847. }
  1848. return ready;
  1849. }
  1850. static void su_readiness_state_set (struct amf_su *su,
  1851. SaAmfReadinessStateT readiness_state)
  1852. {
  1853. su->saAmfSUReadinessState = readiness_state;
  1854. TRACE1 ("Setting SU '%s' readiness state: %s\n",
  1855. &su->name.value, readiness_state_text[readiness_state]);
  1856. }
  1857. static void su_presence_state_set (struct amf_su *su,
  1858. SaAmfPresenceStateT presence_state)
  1859. {
  1860. su->saAmfSUPresenceState = presence_state;
  1861. TRACE1 ("Setting SU '%s' presence state: %s\n",
  1862. su->name.value, presence_state_text[presence_state]);
  1863. }
  1864. static void escalation_policy_restart (struct amf_comp *comp)
  1865. {
  1866. dprintf ("escalation_policy_restart %d\n", comp->su->escalation_level);
  1867. dprintf ("escalation policy restart uninsint %p\n", comp);
  1868. // comp_presence_state_set (comp, SA_AMF_PRESENCE_UNINSTANTIATED);
  1869. // comp_operational_state_set (comp, SA_AMF_OPERATIONAL_DISABLED);
  1870. switch (comp->su->escalation_level) {
  1871. case ESCALATION_LEVEL_NO_ESCALATION:
  1872. comp_restart (comp);
  1873. break;
  1874. case ESCALATION_LEVEL_ONE:
  1875. comp_restart (comp);
  1876. break;
  1877. case ESCALATION_LEVEL_TWO:
  1878. break;
  1879. case ESCALATION_LEVEL_THREE:
  1880. break;
  1881. }
  1882. }
  1883. static void escalation_policy_cleanup (struct amf_comp *comp)
  1884. {
  1885. // escalation_timer_start (comp);
  1886. switch (comp->su->escalation_level) {
  1887. case ESCALATION_LEVEL_NO_ESCALATION:
  1888. comp->saAmfCompRestartCount += 1;
  1889. if (comp->saAmfCompRestartCount >= comp->su->sg->saAmfSGCompRestartMax) {
  1890. comp->su->escalation_level = ESCALATION_LEVEL_ONE;
  1891. escalation_policy_cleanup (comp);
  1892. comp->saAmfCompRestartCount = 0;
  1893. return;
  1894. }
  1895. dprintf ("Escalation level 0 - restart component\n");
  1896. dprintf ("Cleaning up and restarting component.\n");
  1897. comp_cleanup (comp);
  1898. break;
  1899. case ESCALATION_LEVEL_ONE:
  1900. comp->su->saAmfSURestartCount += 1;
  1901. if (comp->su->saAmfSURestartCount >= comp->su->sg->saAmfSGSuRestartMax) {
  1902. comp->su->escalation_level = ESCALATION_LEVEL_TWO;
  1903. escalation_policy_cleanup (comp);
  1904. comp->saAmfCompRestartCount = 0;
  1905. comp->su->saAmfSURestartCount = 0;
  1906. return;
  1907. }
  1908. dprintf ("Escalation level 1 - restart unit\n");
  1909. dprintf ("Cleaning up and restarting unit.\n");
  1910. su_cleanup (comp->su);
  1911. break;
  1912. case ESCALATION_LEVEL_TWO:
  1913. dprintf ("Escalation level TWO\n");
  1914. su_cleanup (comp->su);
  1915. // unit_terminate_failover (comp);
  1916. break;
  1917. case ESCALATION_LEVEL_THREE:
  1918. //TODO
  1919. break;
  1920. }
  1921. }
  1922. static void timer_function_healthcheck_timeout (
  1923. void *data)
  1924. {
  1925. struct req_exec_amf_healthcheck_tmo req_exec;
  1926. struct iovec iovec;
  1927. struct amf_healthcheck *healthcheck = (struct amf_healthcheck *)data;
  1928. TRACE2 ("timeout occured on healthcheck for component %s.\n",
  1929. getSaNameT (&healthcheck->comp->name));
  1930. req_exec.header.size = sizeof (struct req_exec_amf_healthcheck_tmo);
  1931. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  1932. MESSAGE_REQ_EXEC_AMF_HEALTHCHECK_TMO);
  1933. comp_dn_make (healthcheck->comp, &req_exec.compName);
  1934. iovec.iov_base = (char *)&req_exec;
  1935. iovec.iov_len = sizeof (req_exec);
  1936. assert (totempg_groups_mcast_joined (openais_group_handle,
  1937. &iovec, 1, TOTEMPG_AGREED) == 0);
  1938. }
  1939. static void healthcheck_activate (struct amf_healthcheck *healthcheck_active)
  1940. {
  1941. struct res_lib_amf_healthcheckcallback res_lib_amf_healthcheckcallback;
  1942. healthcheck_active->active = 1;
  1943. // TODO memset (&res_lib_amf_healthcheckcallback, 0, sizeof(res_lib_amf_healthcheckcallback));
  1944. res_lib_amf_healthcheckcallback.header.id = MESSAGE_RES_AMF_HEALTHCHECKCALLBACK;
  1945. res_lib_amf_healthcheckcallback.header.size = sizeof (struct res_lib_amf_healthcheckcallback);
  1946. res_lib_amf_healthcheckcallback.header.error = SA_AIS_OK;
  1947. res_lib_amf_healthcheckcallback.invocation =
  1948. invocation_create (
  1949. AMF_RESPONSE_HEALTHCHECKCALLBACK,
  1950. (void *)healthcheck_active);
  1951. comp_dn_make (healthcheck_active->comp, &res_lib_amf_healthcheckcallback.compName);
  1952. memcpy (&res_lib_amf_healthcheckcallback.key,
  1953. &healthcheck_active->safHealthcheckKey,
  1954. sizeof (SaAmfHealthcheckKeyT));
  1955. TRACE8 ("sending healthcheck to component %s",
  1956. res_lib_amf_healthcheckcallback.compName.value);
  1957. openais_conn_send_response (
  1958. openais_conn_partner_get (healthcheck_active->comp->conn),
  1959. &res_lib_amf_healthcheckcallback,
  1960. sizeof (struct res_lib_amf_healthcheckcallback));
  1961. openais_timer_delete (healthcheck_active->timer_handle_duration);
  1962. openais_timer_add (
  1963. healthcheck_active->saAmfHealthcheckMaxDuration,
  1964. (void *)healthcheck_active,
  1965. timer_function_healthcheck_timeout,
  1966. &healthcheck_active->timer_handle_duration);
  1967. }
  1968. static void healthcheck_deactivate (struct amf_healthcheck *healthcheck_active)
  1969. {
  1970. dprintf ("deactivating healthcheck for component %s\n",
  1971. getSaNameT (&healthcheck_active->comp->name));
  1972. openais_timer_delete (healthcheck_active->timer_handle_period);
  1973. openais_timer_delete (healthcheck_active->timer_handle_duration);
  1974. invocation_destroy_by_data ((void *)healthcheck_active);
  1975. healthcheck_active->active = 0;
  1976. }
  1977. static void timer_function_healthcheck_next_fn (void *data)
  1978. {
  1979. healthcheck_activate (data);
  1980. }
  1981. static void su_operational_state_set (
  1982. struct amf_su *unit,
  1983. SaAmfOperationalStateT oper_state)
  1984. {
  1985. struct amf_comp* comp;
  1986. if (oper_state == unit->saAmfSUOperState) {
  1987. log_printf (LOG_INFO,
  1988. "Not assigning service unit new operational state - same state\n");
  1989. return;
  1990. }
  1991. unit->saAmfSUOperState = oper_state;
  1992. TRACE1 ("Setting SU '%s' operational state: %s\n",
  1993. unit->name.value, oper_state_text[oper_state]);
  1994. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  1995. su_readiness_state_set (unit, SA_AMF_READINESS_IN_SERVICE);
  1996. for (comp = unit->comp_head; comp; comp = comp->next) {
  1997. comp_readiness_state_set (comp);
  1998. }
  1999. if (sg_all_su_in_service(unit->sg)) {
  2000. TRACE1 ("All SUs in SG '%s' in service, assigning SIs\n", unit->sg->name.value);
  2001. sg_assign_si (unit->sg);
  2002. if (amf_cluster.timeout_handle) {
  2003. openais_timer_delete (amf_cluster.timeout_handle);
  2004. }
  2005. }
  2006. } else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
  2007. su_readiness_state_set (unit, SA_AMF_READINESS_OUT_OF_SERVICE);
  2008. }
  2009. }
  2010. /*
  2011. * Executive Message Implementation
  2012. */
  2013. static void message_handler_req_exec_amf_comp_register (
  2014. void *message, unsigned int nodeid)
  2015. {
  2016. struct res_lib_amf_componentregister res_lib;
  2017. struct req_exec_amf_comp_register *req_exec = message;
  2018. struct amf_comp *comp;
  2019. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2020. if (comp == NULL) {
  2021. log_printf (LOG_ERR, "Component '%s' not found", &req_exec->compName.value);
  2022. return;
  2023. }
  2024. TRACE2("Exec comp register '%s'", &req_exec->compName.value);
  2025. if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_RESTARTING) {
  2026. comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED);
  2027. comp_readiness_state_set (comp);
  2028. if (comp->saAmfCompReadinessState == SA_AMF_READINESS_IN_SERVICE) {
  2029. comp_reassign_csis (comp);
  2030. }
  2031. } else if ((comp->saAmfCompPresenceState == SA_AMF_PRESENCE_INSTANTIATING) ||
  2032. (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED)){
  2033. comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED);
  2034. comp_operational_state_set (comp, SA_AMF_OPERATIONAL_ENABLED);
  2035. }
  2036. else {
  2037. assert (0);
  2038. }
  2039. if (comp->su->is_local) {
  2040. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTREGISTER;
  2041. res_lib.header.size = sizeof (struct res_lib_amf_componentregister);
  2042. res_lib.header.error = SA_AIS_OK;
  2043. openais_conn_send_response (comp->conn, &res_lib, sizeof (res_lib));
  2044. }
  2045. }
  2046. static void message_handler_req_exec_amf_comp_error_report (
  2047. void *message, unsigned int nodeid)
  2048. {
  2049. struct res_lib_amf_componenterrorreport res_lib;
  2050. struct req_exec_amf_comp_error_report *req_exec = message;
  2051. struct amf_comp *comp;
  2052. comp = amf_find_comp (&amf_cluster, &req_exec->erroneousComponent);
  2053. if (comp == NULL) {
  2054. log_printf (LOG_ERR, "Component '%s' not found", &req_exec->erroneousComponent);
  2055. return;
  2056. }
  2057. TRACE2("Exec comp error report '%s'", &req_exec->reportingComponent.value);
  2058. if (comp->su->is_local) {
  2059. res_lib.header.size = sizeof (struct res_lib_amf_componenterrorreport);
  2060. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTERRORREPORT;
  2061. res_lib.header.error = SA_AIS_OK;
  2062. openais_conn_send_response (comp->conn, &res_lib, sizeof (res_lib));
  2063. }
  2064. escalation_policy_cleanup (comp);
  2065. }
  2066. static void message_handler_req_exec_amf_clc_cleanup_completed (
  2067. void *message, unsigned int nodeid)
  2068. {
  2069. struct req_exec_amf_clc_cleanup_completed *req_exec = message;
  2070. struct amf_comp *comp;
  2071. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2072. if (comp == NULL) {
  2073. log_printf (LOG_ERR, "'%s' not found", &req_exec->compName.value);
  2074. return;
  2075. }
  2076. TRACE2("Exec CLC cleanup completed for '%s'", &req_exec->compName.value);
  2077. clc_instantiate (comp);
  2078. }
  2079. static void message_handler_req_exec_amf_healthcheck_tmo (
  2080. void *message, unsigned int nodeid)
  2081. {
  2082. struct req_exec_amf_healthcheck_tmo *req_exec = message;
  2083. struct amf_comp *comp;
  2084. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2085. if (comp == NULL) {
  2086. log_printf (LOG_ERR, "'%s' not found", &req_exec->compName.value);
  2087. return;
  2088. }
  2089. TRACE2("Exec healthcheck tmo for '%s'", &comp->name.value);
  2090. escalation_policy_cleanup (comp);
  2091. }
  2092. static void message_handler_req_exec_amf_response (
  2093. void *message, unsigned int nodeid)
  2094. {
  2095. struct req_exec_amf_response *req_exec = message;
  2096. struct amf_comp *comp;
  2097. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2098. assert (comp != NULL);
  2099. switch (req_exec->interface) {
  2100. case AMF_RESPONSE_CSISETCALLBACK:
  2101. dprintf ("Exec csi set callback response from '%s', error: %d",
  2102. &req_exec->compName.value, req_exec->error);
  2103. break;
  2104. case AMF_RESPONSE_CSIREMOVECALLBACK:
  2105. dprintf ("Exec csi remove callback response from '%s', error: %d",
  2106. &req_exec->compName.value, req_exec->error);
  2107. break;
  2108. case AMF_RESPONSE_COMPONENTTERMINATECALLBACK:
  2109. dprintf ("Exec component terminate callback response from '%s', error: %s",
  2110. &req_exec->compName.value, req_exec->error);
  2111. break;
  2112. default:
  2113. assert (0);
  2114. break;
  2115. }
  2116. }
  2117. /*
  2118. * Library Interface Implementation
  2119. */
  2120. static void message_handler_req_lib_amf_componentregister (
  2121. void *conn,
  2122. void *msg)
  2123. {
  2124. struct req_lib_amf_componentregister *req_lib = msg;
  2125. struct amf_comp *comp;
  2126. comp = amf_find_comp (&amf_cluster, &req_lib->compName);
  2127. if (comp) {
  2128. struct req_exec_amf_comp_register req_exec;
  2129. struct iovec iovec;
  2130. struct amf_pd *amf_pd = openais_conn_private_data_get (conn);
  2131. TRACE2("Lib comp register '%s'", &req_lib->compName.value);
  2132. comp->conn = conn;
  2133. amf_pd->comp = comp;
  2134. req_exec.header.size = sizeof (struct req_exec_amf_comp_register);
  2135. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  2136. MESSAGE_REQ_EXEC_AMF_COMPONENT_REGISTER);
  2137. memcpy (&req_exec.compName, &req_lib->compName, sizeof (SaNameT));
  2138. memcpy (&req_exec.proxyCompName,
  2139. &req_lib->proxyCompName, sizeof (SaNameT));
  2140. iovec.iov_base = (char *)&req_exec;
  2141. iovec.iov_len = sizeof (req_exec);
  2142. assert (totempg_groups_mcast_joined (openais_group_handle,
  2143. &iovec, 1, TOTEMPG_AGREED) == 0);
  2144. } else {
  2145. struct res_lib_amf_componentregister res_lib;
  2146. log_printf (LOG_ERR, "Lib comp register: comp '%s' not found", &req_lib->compName.value);
  2147. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTREGISTER;
  2148. res_lib.header.size = sizeof (struct res_lib_amf_componentregister);
  2149. res_lib.header.error = SA_AIS_ERR_INVALID_PARAM;
  2150. openais_conn_send_response (
  2151. conn, &res_lib, sizeof (struct res_lib_amf_componentregister));
  2152. }
  2153. }
  2154. static void message_handler_req_lib_amf_componentunregister (
  2155. void *conn,
  2156. void *msg)
  2157. {
  2158. #ifdef COMPILE_OUT
  2159. struct req_lib_amf_componentunregister *req_lib_amf_componentunregister = (struct req_lib_amf_componentunregister *)message;
  2160. struct req_exec_amf_componentunregister req_exec_amf_componentunregister;
  2161. struct iovec iovec;
  2162. struct amf_comp *component;
  2163. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_componentunregister()\n");
  2164. req_exec_amf_componentunregister.header.size = sizeof (struct req_exec_amf_componentunregister);
  2165. req_exec_amf_componentunregister.header.id =
  2166. SERVICE_ID_MAKE (AMF_SERVICE, MESSAGE_REQ_EXEC_AMF_COMPONENTUNREGISTER);
  2167. message_source_set (&req_exec_amf_componentunregister.source, conn_info);
  2168. memcpy (&req_exec_amf_componentunregister.req_lib_amf_componentunregister,
  2169. req_lib_amf_componentunregister,
  2170. sizeof (struct req_lib_amf_componentunregister));
  2171. component = amf_find_comp (&amf_cluster, &req_lib_amf_componentunregister->compName);
  2172. if (component && component->registered && component->local) {
  2173. // component->probableCause = SA_AMF_NOT_RESPONDING;
  2174. }
  2175. iovec.iov_base = (char *)&req_exec_amf_componentunregister;
  2176. iovec.iov_len = sizeof (req_exec_amf_componentunregister);
  2177. assert (totempg_groups_mcast_joined (openais_group_handle,
  2178. &iovec, 1, TOTEMPG_AGREED) == 0);
  2179. #endif
  2180. }
  2181. static void message_handler_req_lib_amf_pmstart (
  2182. void *conn,
  2183. void *msg)
  2184. {
  2185. }
  2186. static void message_handler_req_lib_amf_pmstop (
  2187. void *conn,
  2188. void *msg)
  2189. {
  2190. }
  2191. static void message_handler_req_lib_amf_healthcheckstart (
  2192. void *conn, void *msg)
  2193. {
  2194. struct req_lib_amf_healthcheckstart *req_lib = msg;
  2195. struct res_lib_amf_healthcheckstart res_lib;
  2196. struct amf_healthcheck *healthcheck;
  2197. struct amf_comp *comp;
  2198. SaAisErrorT error = SA_AIS_OK;
  2199. comp = amf_find_comp (&amf_cluster, &req_lib->compName);
  2200. if (comp == 0) {
  2201. log_printf (LOG_ERR, "Healthcheckstart: Component '%s' not found",
  2202. req_lib->compName.value);
  2203. error = SA_AIS_ERR_NOT_EXIST;
  2204. goto error_exit;
  2205. }
  2206. healthcheck = amf_find_healthcheck (comp, &req_lib->healthcheckKey);
  2207. if (healthcheck == 0) {
  2208. log_printf (LOG_ERR, "Healthcheckstart: Healthcheck '%s' not found",
  2209. req_lib->healthcheckKey.key);
  2210. error = SA_AIS_ERR_NOT_EXIST;
  2211. goto error_exit;
  2212. }
  2213. dprintf ("Healthcheckstart: '%s', key '%s'",
  2214. req_lib->compName.value, req_lib->healthcheckKey.key);
  2215. /*
  2216. * Determine if this healthcheck is already active
  2217. */
  2218. if (healthcheck->active) {
  2219. error = SA_AIS_ERR_EXIST;
  2220. goto error_exit;
  2221. }
  2222. /*
  2223. * Initialise
  2224. */
  2225. healthcheck->invocationType = req_lib->invocationType;
  2226. healthcheck->timer_handle_duration = 0;
  2227. healthcheck->timer_handle_period = 0;
  2228. healthcheck->active = 0;
  2229. if (comp->conn == NULL) {
  2230. comp->conn = conn;
  2231. }
  2232. healthcheck_activate (healthcheck);
  2233. error_exit:
  2234. res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKSTART;
  2235. res_lib.header.size = sizeof (res_lib);
  2236. res_lib.header.error = error;
  2237. openais_conn_send_response (conn, &res_lib,
  2238. sizeof (struct res_lib_amf_healthcheckstart));
  2239. }
  2240. static void message_handler_req_lib_amf_healthcheckconfirm (
  2241. void *conn,
  2242. void *msg)
  2243. {
  2244. }
  2245. static void message_handler_req_lib_amf_healthcheckstop (
  2246. void *conn,
  2247. void *msg)
  2248. {
  2249. struct req_lib_amf_healthcheckstop *req_lib = msg;
  2250. struct res_lib_amf_healthcheckstop res_lib;
  2251. struct amf_healthcheck *healthcheck;
  2252. struct amf_comp *comp;
  2253. SaAisErrorT error = SA_AIS_OK;
  2254. dprintf ("healthcheck stop\n");
  2255. comp = amf_find_comp (&amf_cluster, &req_lib->compName);
  2256. if (comp == 0) {
  2257. log_printf (LOG_ERR, "Healthcheckstop: Component '%s' not found",
  2258. req_lib->compName.value);
  2259. error = SA_AIS_ERR_NOT_EXIST;
  2260. goto error_exit;
  2261. }
  2262. healthcheck = amf_find_healthcheck (comp, &req_lib->healthcheckKey);
  2263. if (healthcheck == 0) {
  2264. log_printf (LOG_ERR, "Healthcheckstop: Healthcheck '%s' not found",
  2265. req_lib->healthcheckKey.key);
  2266. error = SA_AIS_ERR_NOT_EXIST;
  2267. goto error_exit;
  2268. }
  2269. healthcheck_deactivate (healthcheck);
  2270. error_exit:
  2271. res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKSTOP;
  2272. res_lib.header.size = sizeof (res_lib);
  2273. res_lib.header.error = error;
  2274. openais_conn_send_response (conn, &res_lib, sizeof (res_lib));
  2275. }
  2276. static void message_handler_req_lib_amf_hastateget (
  2277. void *conn,
  2278. void *msg)
  2279. {
  2280. #ifdef COMPILE_OUT
  2281. struct req_lib_amf_hastateget *req_lib_amf_hastateget = (struct req_lib_amf_hastateget *)msg;
  2282. struct res_lib_amf_hastateget res_lib_amf_hastateget;
  2283. struct amf_comp *component;
  2284. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_hastateget()\n");
  2285. res_lib_amf_hastateget.header.id = MESSAGE_RES_AMF_HASTATEGET;
  2286. res_lib_amf_hastateget.header.size = sizeof (struct res_lib_amf_hastateget);
  2287. res_lib_amf_hastateget.header.error = SA_ERR_NOT_EXIST;
  2288. #ifdef COMPILE_OUT
  2289. component = component_in_protectiongroup_find (&req_lib_amf_hastateget->csiName, &req_lib_amf_hastateget->compName);
  2290. #endif
  2291. if (component) {
  2292. memcpy (&res_lib_amf_hastateget.haState,
  2293. &component->currentHAState, sizeof (SaAmfHAStateT));
  2294. res_lib_amf_hastateget.header.error = SA_AIS_OK;
  2295. }
  2296. openais_conn_send_response (conn, &res_lib_amf_hastateget, sizeof (struct res_lib_amf_hastateget));
  2297. #endif
  2298. }
  2299. static void message_handler_req_lib_amf_protectiongrouptrack (
  2300. void *conn,
  2301. void *msg)
  2302. {
  2303. #ifdef COMPILE_OUT
  2304. struct req_lib_amf_protectiongrouptrack *req_lib_amf_protectiongrouptrack = (struct req_lib_amf_protectiongrouptrack *)message;
  2305. struct res_lib_amf_protectiongrouptrack res_lib_amf_protectiongrouptrack;
  2306. struct libamf_ci_trackentry *track = 0;
  2307. int i;
  2308. struct saAmfProtectionGroup *amfProtectionGroup;
  2309. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_protectiongrouptrack()\n");
  2310. amfProtectionGroup = protectiongroup_find (&req_lib_amf_protectiongrouptrack->csiName);
  2311. if (amfProtectionGroup) {
  2312. log_printf (LOG_LEVEL_DEBUG, "protectiongrouptrack: Got valid track start on CSI: %s.\n", getSaNameT (&req_lib_amf_protectiongrouptrack->csiName));
  2313. for (i = 0; i < conn_info->ais_ci.u.libamf_ci.trackEntries; i++) {
  2314. if (conn_info->ais_ci.u.libamf_ci.tracks[i].active == 0) {
  2315. track = &conn_info->ais_ci.u.libamf_ci.tracks[i];
  2316. break;
  2317. }
  2318. }
  2319. if (track == 0) {
  2320. grow_amf_track_table (conn_info, 1);
  2321. track = &conn_info->ais_ci.u.libamf_ci.tracks[i];
  2322. }
  2323. track->active = 1;
  2324. track->trackFlags = req_lib_amf_protectiongrouptrack->trackFlags;
  2325. track->notificationBufferAddress = req_lib_amf_protectiongrouptrack->notificationBufferAddress;
  2326. memcpy (&track->csiName,
  2327. &req_lib_amf_protectiongrouptrack->csiName, sizeof (SaNameT));
  2328. conn_info->ais_ci.u.libamf_ci.trackActive += 1;
  2329. list_add (&conn_info->conn_list, &library_notification_send_listhead);
  2330. /*
  2331. * If SA_TRACK_CURRENT is specified, write out all current connections
  2332. */
  2333. } else {
  2334. log_printf (LOG_LEVEL_DEBUG, "invalid track start, csi not registered with system.\n");
  2335. }
  2336. res_lib_amf_protectiongrouptrack.header.id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACK;
  2337. res_lib_amf_protectiongrouptrack.header.size = sizeof (struct res_lib_amf_protectiongrouptrack);
  2338. res_lib_amf_protectiongrouptrack.header.error = SA_ERR_NOT_EXIST;
  2339. if (amfProtectionGroup) {
  2340. res_lib_amf_protectiongrouptrack.header.error = SA_AIS_OK;
  2341. }
  2342. openais_conn_send_response (conn, &res_lib_amf_protectiongrouptrack,
  2343. sizeof (struct res_lib_amf_protectiongrouptrack));
  2344. if (amfProtectionGroup &&
  2345. req_lib_amf_protectiongrouptrack->trackFlags & SA_TRACK_CURRENT) {
  2346. protectiongroup_notification_send (conn_info,
  2347. track->notificationBufferAddress,
  2348. amfProtectionGroup,
  2349. 0,
  2350. 0,
  2351. SA_TRACK_CHANGES_ONLY);
  2352. track->trackFlags &= ~SA_TRACK_CURRENT;
  2353. }
  2354. #endif
  2355. }
  2356. static void message_handler_req_lib_amf_csiquiescingcomplete (
  2357. void *conn,
  2358. void *msg)
  2359. {
  2360. }
  2361. static void message_handler_req_lib_amf_protectiongrouptrackstop (
  2362. void *conn,
  2363. void *msg)
  2364. {
  2365. #ifdef COMPILE_OUT
  2366. struct req_lib_amf_protectiongrouptrackstop *req_lib_amf_protectiongrouptrackstop = (struct req_lib_amf_protectiongrouptrackstop *)message;
  2367. struct res_lib_amf_protectiongrouptrackstop res_lib_amf_protectiongrouptrackstop;
  2368. struct libamf_ci_trackentry *track = 0;
  2369. int i;
  2370. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_protectiongrouptrackstop()\n");
  2371. for (i = 0; i < conn_info->ais_ci.u.libamf_ci.trackEntries; i++) {
  2372. if (name_match (&req_lib_amf_protectiongrouptrackstop->csiName,
  2373. &conn_info->ais_ci.u.libamf_ci.tracks[i].csiName)) {
  2374. track = &conn_info->ais_ci.u.libamf_ci.tracks[i];
  2375. }
  2376. }
  2377. if (track) {
  2378. log_printf (LOG_LEVEL_DEBUG, "protectiongrouptrackstop: Trackstop on CSI: %s\n", getSaNameT (&req_lib_amf_protectiongrouptrackstop->csiName));
  2379. memset (track, 0, sizeof (struct libamf_ci_trackentry));
  2380. conn_info->ais_ci.u.libamf_ci.trackActive -= 1;
  2381. if (conn_info->ais_ci.u.libamf_ci.trackActive == 0) {
  2382. list_del (&conn_info->conn_list);
  2383. }
  2384. }
  2385. res_lib_amf_protectiongrouptrackstop.header.id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACKSTOP;
  2386. res_lib_amf_protectiongrouptrackstop.header.size = sizeof (struct res_lib_amf_protectiongrouptrackstop);
  2387. res_lib_amf_protectiongrouptrackstop.header.error = SA_ERR_NOT_EXIST;
  2388. if (track) {
  2389. res_lib_amf_protectiongrouptrackstop.header.error = SA_AIS_OK;
  2390. }
  2391. openais_conn_send_response (conn, &res_lib_amf_protectiongrouptrackstop,
  2392. sizeof (struct res_lib_amf_protectiongrouptrackstop));
  2393. #endif
  2394. }
  2395. static void message_handler_req_lib_amf_componenterrorreport (
  2396. void *conn,
  2397. void *msg)
  2398. {
  2399. struct req_lib_amf_componenterrorreport *req_lib = msg;
  2400. struct amf_comp *comp;
  2401. comp = amf_find_comp (&amf_cluster, &req_lib->erroneousComponent);
  2402. if (comp != NULL) {
  2403. struct req_exec_amf_comp_error_report req_exec;
  2404. struct iovec iovec;
  2405. TRACE2("Lib comp error report for '%s'", &comp->name.value);
  2406. req_exec.header.size = sizeof (struct req_exec_amf_comp_error_report);
  2407. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  2408. MESSAGE_REQ_EXEC_AMF_COMPONENT_ERROR_REPORT);
  2409. memcpy (&req_exec.reportingComponent, &req_lib->reportingComponent,
  2410. sizeof (SaNameT));
  2411. memcpy (&req_exec.erroneousComponent, &req_lib->erroneousComponent,
  2412. sizeof (SaNameT));
  2413. memcpy (&req_exec.errorDetectionTime, &req_lib->errorDetectionTime,
  2414. sizeof (SaTimeT));
  2415. memcpy (&req_exec.recommendedRecovery, &req_lib->recommendedRecovery,
  2416. sizeof (SaAmfRecommendedRecoveryT));
  2417. memcpy (&req_exec.ntfIdentifier, &req_lib->ntfIdentifier,
  2418. sizeof (SaNtfIdentifierT));
  2419. iovec.iov_base = (char *)&req_exec;
  2420. iovec.iov_len = sizeof (req_exec);
  2421. assert (totempg_groups_mcast_joined (openais_group_handle,
  2422. &iovec, 1, TOTEMPG_AGREED) == 0);
  2423. } else {
  2424. struct res_lib_amf_componenterrorreport res_lib;
  2425. log_printf (LOG_ERR, "Component %s not found",
  2426. &req_lib->erroneousComponent.value);
  2427. res_lib.header.size = sizeof (struct res_lib_amf_componenterrorreport);
  2428. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTERRORREPORT;
  2429. res_lib.header.error = SA_AIS_ERR_NOT_EXIST;
  2430. openais_conn_send_response (conn, &res_lib,
  2431. sizeof (struct res_lib_amf_componenterrorreport));
  2432. }
  2433. }
  2434. static void message_handler_req_lib_amf_componenterrorclear (
  2435. void *conn,
  2436. void *msg)
  2437. {
  2438. #ifdef COMPILLE_OUT
  2439. struct req_lib_amf_componenterrorclear *req_lib_amf_componenterrorclear = (struct req_lib_amf_componenterrorclear *)message;
  2440. struct req_exec_amf_componenterrorclear req_exec_amf_componenterrorclear;
  2441. struct iovec iovec;
  2442. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_componenterrorclear()\n");
  2443. req_exec_amf_componenterrorclear.header.size = sizeof (struct req_exec_amf_componenterrorclear);
  2444. req_exec_amf_componenterrorclear.header.id =
  2445. SERVICE_ID_MAKE (AMF_SERVICE, MESSAGE_REQ_EXEC_AMF_COMPONENTERRORCLEAR);
  2446. message_source_set (&req_exec_amf_componenterrorclear.source, conn_info);
  2447. memcpy (&req_exec_amf_componenterrorclear.req_lib_amf_componenterrorclear,
  2448. req_lib_amf_componenterrorclear,
  2449. sizeof (struct req_lib_amf_componenterrorclear));
  2450. iovec.iov_base = (char *)&req_exec_amf_componenterrorclear;
  2451. iovec.iov_len = sizeof (req_exec_amf_componenterrorclear);
  2452. assert (totempg_groups_mcast_joined (openais_group_handle,
  2453. &iovec, 1, TOTEMPG_AGREED) == 0);
  2454. #endif
  2455. }
  2456. #if 0
  2457. static void pg_comp_create (
  2458. struct amf_pg *pg,
  2459. struct amf_csi *csi,
  2460. struct amf_comp *comp)
  2461. {
  2462. struct amf_pg_comp *pg_comp;
  2463. dprintf ("creating component for pg\n");
  2464. pg_comp = malloc (sizeof (struct amf_pg_comp));
  2465. assert (pg_comp);
  2466. pg_comp->comp = comp;
  2467. pg_comp->csi = csi;
  2468. list_init (&pg_comp->list);
  2469. list_add_tail (&pg_comp->list, &pg->pg_comp_head);
  2470. }
  2471. #endif
  2472. static void message_handler_req_lib_amf_response (void *conn, void *msg)
  2473. {
  2474. struct res_lib_amf_response res_lib;
  2475. struct req_lib_amf_response *req_lib = msg;
  2476. struct req_exec_amf_response req_exec;
  2477. struct iovec iovec;
  2478. struct amf_pd *pd = openais_conn_private_data_get (conn);
  2479. int res;
  2480. int interface;
  2481. void *data;
  2482. int error = SA_AIS_OK;
  2483. res = invocation_get_and_destroy (req_lib->invocation, &interface, &data);
  2484. if (res == -1) {
  2485. log_printf (LOG_ERR, "Lib response: invocation not found\n");
  2486. error = SA_AIS_ERR_INVALID_PARAM;
  2487. goto end;
  2488. }
  2489. switch (interface) {
  2490. case AMF_RESPONSE_HEALTHCHECKCALLBACK: {
  2491. struct amf_healthcheck *healthcheck = data;
  2492. SaNameT name;
  2493. TRACE3 ("Lib healthcheck response from '%s'",
  2494. comp_dn_make (healthcheck->comp, &name));
  2495. openais_timer_delete (healthcheck->timer_handle_duration);
  2496. healthcheck->timer_handle_duration = 0;
  2497. openais_timer_add (
  2498. healthcheck->saAmfHealthcheckPeriod,
  2499. (void *)healthcheck,
  2500. timer_function_healthcheck_next_fn,
  2501. &healthcheck->timer_handle_period);
  2502. break;
  2503. }
  2504. case AMF_RESPONSE_CSISETCALLBACK: {
  2505. struct amf_csi_assignment *csi_assignment = data;
  2506. dprintf ("Lib csi '%s' set callback response from '%s', error: %d",
  2507. csi_assignment->csi->name.value, csi_assignment->comp->name.value, req_lib->error);
  2508. memcpy (&req_exec.csiName, &csi_assignment->name, sizeof (SaNameT));
  2509. break;
  2510. }
  2511. case AMF_RESPONSE_CSIREMOVECALLBACK: {
  2512. struct amf_csi_assignment *csi_assignment = data;
  2513. dprintf ("Lib csi '%s' remove callback response from '%s', error: %d",
  2514. csi_assignment->csi->name.value, csi_assignment->comp->name.value, req_lib->error);
  2515. memcpy (&req_exec.csiName, &csi_assignment->name, sizeof (SaNameT));
  2516. break;
  2517. }
  2518. case AMF_RESPONSE_COMPONENTTERMINATECALLBACK: {
  2519. struct component_terminate_callback_data *component_terminate_callback_data;
  2520. component_terminate_callback_data = data;
  2521. dprintf ("Lib component terminate callback response, error: %d", req_lib->error);
  2522. comp_healthcheck_deactivate (component_terminate_callback_data->comp);
  2523. escalation_policy_restart (component_terminate_callback_data->comp);
  2524. break;
  2525. }
  2526. default:
  2527. assert (0);
  2528. break;
  2529. }
  2530. /* Keep healthcheck responses node local */
  2531. if (interface != AMF_RESPONSE_HEALTHCHECKCALLBACK) {
  2532. assert (pd && pd->comp);
  2533. req_exec.header.size = sizeof (struct req_exec_amf_response);
  2534. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  2535. MESSAGE_REQ_EXEC_AMF_RESPONSE);
  2536. comp_dn_make (pd->comp, &req_exec.compName);
  2537. req_exec.interface = interface;
  2538. req_exec.error = req_lib->error;
  2539. iovec.iov_base = (char *)&req_exec;
  2540. iovec.iov_len = sizeof (req_exec);
  2541. assert (totempg_groups_mcast_joined (openais_group_handle,
  2542. &iovec, 1, TOTEMPG_AGREED) == 0);
  2543. }
  2544. end:
  2545. res_lib.header.id = MESSAGE_RES_AMF_RESPONSE;
  2546. res_lib.header.size = sizeof (struct res_lib_amf_response);
  2547. res_lib.header.error = error;
  2548. openais_conn_send_response (conn, &res_lib, sizeof (res_lib));
  2549. }