amf.c 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020
  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 "aispoll.h"
  65. #include "mempool.h"
  66. #include "util.h"
  67. #include "amfconfig.h"
  68. #include "main.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 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 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. poll_timer_add(aisexec_poll_handle,
  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. poll_timer_add(aisexec_poll_handle,
  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. poll_timer_delete (aisexec_poll_handle,
  1962. healthcheck_active->timer_handle_duration);
  1963. poll_timer_add (aisexec_poll_handle,
  1964. healthcheck_active->saAmfHealthcheckMaxDuration,
  1965. (void *)healthcheck_active,
  1966. timer_function_healthcheck_timeout,
  1967. &healthcheck_active->timer_handle_duration);
  1968. }
  1969. static void healthcheck_deactivate (struct amf_healthcheck *healthcheck_active)
  1970. {
  1971. dprintf ("deactivating healthcheck for component %s\n",
  1972. getSaNameT (&healthcheck_active->comp->name));
  1973. poll_timer_delete (aisexec_poll_handle,
  1974. healthcheck_active->timer_handle_period);
  1975. poll_timer_delete (aisexec_poll_handle,
  1976. healthcheck_active->timer_handle_duration);
  1977. invocation_destroy_by_data ((void *)healthcheck_active);
  1978. healthcheck_active->active = 0;
  1979. }
  1980. static void timer_function_healthcheck_next_fn (void *data)
  1981. {
  1982. healthcheck_activate (data);
  1983. }
  1984. static void su_operational_state_set (
  1985. struct amf_su *unit,
  1986. SaAmfOperationalStateT oper_state)
  1987. {
  1988. struct amf_comp* comp;
  1989. if (oper_state == unit->saAmfSUOperState) {
  1990. log_printf (LOG_INFO,
  1991. "Not assigning service unit new operational state - same state\n");
  1992. return;
  1993. }
  1994. unit->saAmfSUOperState = oper_state;
  1995. TRACE1 ("Setting SU '%s' operational state: %s\n",
  1996. unit->name.value, oper_state_text[oper_state]);
  1997. if (oper_state == SA_AMF_OPERATIONAL_ENABLED) {
  1998. su_readiness_state_set (unit, SA_AMF_READINESS_IN_SERVICE);
  1999. for (comp = unit->comp_head; comp; comp = comp->next) {
  2000. comp_readiness_state_set (comp);
  2001. }
  2002. if (sg_all_su_in_service(unit->sg)) {
  2003. TRACE1 ("All SUs in SG '%s' in service, assigning SIs\n", unit->sg->name.value);
  2004. sg_assign_si (unit->sg);
  2005. if (amf_cluster.timeout_handle) {
  2006. poll_timer_delete (aisexec_poll_handle, amf_cluster.timeout_handle);
  2007. }
  2008. }
  2009. } else if (oper_state == SA_AMF_OPERATIONAL_DISABLED) {
  2010. su_readiness_state_set (unit, SA_AMF_READINESS_OUT_OF_SERVICE);
  2011. }
  2012. }
  2013. /*
  2014. * Executive Message Implementation
  2015. */
  2016. static void message_handler_req_exec_amf_comp_register (
  2017. void *message, unsigned int nodeid)
  2018. {
  2019. struct res_lib_amf_componentregister res_lib;
  2020. struct req_exec_amf_comp_register *req_exec = message;
  2021. struct amf_comp *comp;
  2022. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2023. if (comp == NULL) {
  2024. log_printf (LOG_ERR, "Component '%s' not found", &req_exec->compName.value);
  2025. return;
  2026. }
  2027. TRACE2("Exec comp register '%s'", &req_exec->compName.value);
  2028. if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_RESTARTING) {
  2029. comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED);
  2030. comp_readiness_state_set (comp);
  2031. if (comp->saAmfCompReadinessState == SA_AMF_READINESS_IN_SERVICE) {
  2032. comp_reassign_csis (comp);
  2033. }
  2034. } else if ((comp->saAmfCompPresenceState == SA_AMF_PRESENCE_INSTANTIATING) ||
  2035. (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED)){
  2036. comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED);
  2037. comp_operational_state_set (comp, SA_AMF_OPERATIONAL_ENABLED);
  2038. }
  2039. else {
  2040. assert (0);
  2041. }
  2042. if (comp->su->is_local) {
  2043. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTREGISTER;
  2044. res_lib.header.size = sizeof (struct res_lib_amf_componentregister);
  2045. res_lib.header.error = SA_AIS_OK;
  2046. openais_conn_send_response (comp->conn, &res_lib, sizeof (res_lib));
  2047. }
  2048. }
  2049. static void message_handler_req_exec_amf_comp_error_report (
  2050. void *message, unsigned int nodeid)
  2051. {
  2052. struct res_lib_amf_componenterrorreport res_lib;
  2053. struct req_exec_amf_comp_error_report *req_exec = message;
  2054. struct amf_comp *comp;
  2055. comp = amf_find_comp (&amf_cluster, &req_exec->erroneousComponent);
  2056. if (comp == NULL) {
  2057. log_printf (LOG_ERR, "Component '%s' not found", &req_exec->erroneousComponent);
  2058. return;
  2059. }
  2060. TRACE2("Exec comp error report '%s'", &req_exec->reportingComponent.value);
  2061. if (comp->su->is_local) {
  2062. res_lib.header.size = sizeof (struct res_lib_amf_componenterrorreport);
  2063. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTERRORREPORT;
  2064. res_lib.header.error = SA_AIS_OK;
  2065. openais_conn_send_response (comp->conn, &res_lib, sizeof (res_lib));
  2066. }
  2067. escalation_policy_cleanup (comp);
  2068. }
  2069. static void message_handler_req_exec_amf_clc_cleanup_completed (
  2070. void *message, unsigned int nodeid)
  2071. {
  2072. struct req_exec_amf_clc_cleanup_completed *req_exec = message;
  2073. struct amf_comp *comp;
  2074. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2075. if (comp == NULL) {
  2076. log_printf (LOG_ERR, "'%s' not found", &req_exec->compName.value);
  2077. return;
  2078. }
  2079. TRACE2("Exec CLC cleanup completed for '%s'", &req_exec->compName.value);
  2080. clc_instantiate (comp);
  2081. }
  2082. static void message_handler_req_exec_amf_healthcheck_tmo (
  2083. void *message, unsigned int nodeid)
  2084. {
  2085. struct req_exec_amf_healthcheck_tmo *req_exec = message;
  2086. struct amf_comp *comp;
  2087. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2088. if (comp == NULL) {
  2089. log_printf (LOG_ERR, "'%s' not found", &req_exec->compName.value);
  2090. return;
  2091. }
  2092. TRACE2("Exec healthcheck tmo for '%s'", &comp->name.value);
  2093. escalation_policy_cleanup (comp);
  2094. }
  2095. static void message_handler_req_exec_amf_response (
  2096. void *message, unsigned int nodeid)
  2097. {
  2098. struct req_exec_amf_response *req_exec = message;
  2099. struct amf_comp *comp;
  2100. comp = amf_find_comp (&amf_cluster, &req_exec->compName);
  2101. assert (comp != NULL);
  2102. switch (req_exec->interface) {
  2103. case AMF_RESPONSE_CSISETCALLBACK:
  2104. dprintf ("Exec csi set callback response from '%s', error: %d",
  2105. &req_exec->compName.value, req_exec->error);
  2106. break;
  2107. case AMF_RESPONSE_CSIREMOVECALLBACK:
  2108. dprintf ("Exec csi remove callback response from '%s', error: %d",
  2109. &req_exec->compName.value, req_exec->error);
  2110. break;
  2111. case AMF_RESPONSE_COMPONENTTERMINATECALLBACK:
  2112. dprintf ("Exec component terminate callback response from '%s', error: %s",
  2113. &req_exec->compName.value, req_exec->error);
  2114. break;
  2115. default:
  2116. assert (0);
  2117. break;
  2118. }
  2119. }
  2120. /*
  2121. * Library Interface Implementation
  2122. */
  2123. static void message_handler_req_lib_amf_componentregister (
  2124. void *conn,
  2125. void *msg)
  2126. {
  2127. struct req_lib_amf_componentregister *req_lib = msg;
  2128. struct amf_comp *comp;
  2129. comp = amf_find_comp (&amf_cluster, &req_lib->compName);
  2130. if (comp) {
  2131. struct req_exec_amf_comp_register req_exec;
  2132. struct iovec iovec;
  2133. struct amf_pd *amf_pd = openais_conn_private_data_get (conn);
  2134. TRACE2("Lib comp register '%s'", &req_lib->compName.value);
  2135. comp->conn = conn;
  2136. amf_pd->comp = comp;
  2137. req_exec.header.size = sizeof (struct req_exec_amf_comp_register);
  2138. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  2139. MESSAGE_REQ_EXEC_AMF_COMPONENT_REGISTER);
  2140. memcpy (&req_exec.compName, &req_lib->compName, sizeof (SaNameT));
  2141. memcpy (&req_exec.proxyCompName,
  2142. &req_lib->proxyCompName, sizeof (SaNameT));
  2143. iovec.iov_base = (char *)&req_exec;
  2144. iovec.iov_len = sizeof (req_exec);
  2145. assert (totempg_groups_mcast_joined (openais_group_handle,
  2146. &iovec, 1, TOTEMPG_AGREED) == 0);
  2147. } else {
  2148. struct res_lib_amf_componentregister res_lib;
  2149. log_printf (LOG_ERR, "Lib comp register: comp '%s' not found", &req_lib->compName.value);
  2150. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTREGISTER;
  2151. res_lib.header.size = sizeof (struct res_lib_amf_componentregister);
  2152. res_lib.header.error = SA_AIS_ERR_INVALID_PARAM;
  2153. openais_conn_send_response (
  2154. conn, &res_lib, sizeof (struct res_lib_amf_componentregister));
  2155. }
  2156. }
  2157. static void message_handler_req_lib_amf_componentunregister (
  2158. void *conn,
  2159. void *msg)
  2160. {
  2161. #ifdef COMPILE_OUT
  2162. struct req_lib_amf_componentunregister *req_lib_amf_componentunregister = (struct req_lib_amf_componentunregister *)message;
  2163. struct req_exec_amf_componentunregister req_exec_amf_componentunregister;
  2164. struct iovec iovec;
  2165. struct amf_comp *component;
  2166. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_componentunregister()\n");
  2167. req_exec_amf_componentunregister.header.size = sizeof (struct req_exec_amf_componentunregister);
  2168. req_exec_amf_componentunregister.header.id =
  2169. SERVICE_ID_MAKE (AMF_SERVICE, MESSAGE_REQ_EXEC_AMF_COMPONENTUNREGISTER);
  2170. message_source_set (&req_exec_amf_componentunregister.source, conn_info);
  2171. memcpy (&req_exec_amf_componentunregister.req_lib_amf_componentunregister,
  2172. req_lib_amf_componentunregister,
  2173. sizeof (struct req_lib_amf_componentunregister));
  2174. component = amf_find_comp (&amf_cluster, &req_lib_amf_componentunregister->compName);
  2175. if (component && component->registered && component->local) {
  2176. // component->probableCause = SA_AMF_NOT_RESPONDING;
  2177. }
  2178. iovec.iov_base = (char *)&req_exec_amf_componentunregister;
  2179. iovec.iov_len = sizeof (req_exec_amf_componentunregister);
  2180. assert (totempg_groups_mcast_joined (openais_group_handle,
  2181. &iovec, 1, TOTEMPG_AGREED) == 0);
  2182. #endif
  2183. }
  2184. static void message_handler_req_lib_amf_pmstart (
  2185. void *conn,
  2186. void *msg)
  2187. {
  2188. }
  2189. static void message_handler_req_lib_amf_pmstop (
  2190. void *conn,
  2191. void *msg)
  2192. {
  2193. }
  2194. static void message_handler_req_lib_amf_healthcheckstart (
  2195. void *conn, void *msg)
  2196. {
  2197. struct req_lib_amf_healthcheckstart *req_lib = msg;
  2198. struct res_lib_amf_healthcheckstart res_lib;
  2199. struct amf_healthcheck *healthcheck;
  2200. struct amf_comp *comp;
  2201. SaAisErrorT error = SA_AIS_OK;
  2202. comp = amf_find_comp (&amf_cluster, &req_lib->compName);
  2203. if (comp == 0) {
  2204. log_printf (LOG_ERR, "Healthcheckstart: Component '%s' not found",
  2205. req_lib->compName.value);
  2206. error = SA_AIS_ERR_NOT_EXIST;
  2207. goto error_exit;
  2208. }
  2209. healthcheck = amf_find_healthcheck (comp, &req_lib->healthcheckKey);
  2210. if (healthcheck == 0) {
  2211. log_printf (LOG_ERR, "Healthcheckstart: Healthcheck '%s' not found",
  2212. req_lib->healthcheckKey.key);
  2213. error = SA_AIS_ERR_NOT_EXIST;
  2214. goto error_exit;
  2215. }
  2216. dprintf ("Healthcheckstart: '%s', key '%s'",
  2217. req_lib->compName.value, req_lib->healthcheckKey.key);
  2218. /*
  2219. * Determine if this healthcheck is already active
  2220. */
  2221. if (healthcheck->active) {
  2222. error = SA_AIS_ERR_EXIST;
  2223. goto error_exit;
  2224. }
  2225. /*
  2226. * Initialise
  2227. */
  2228. healthcheck->invocationType = req_lib->invocationType;
  2229. healthcheck->timer_handle_duration = 0;
  2230. healthcheck->timer_handle_period = 0;
  2231. healthcheck->active = 0;
  2232. if (comp->conn == NULL) {
  2233. comp->conn = conn;
  2234. }
  2235. healthcheck_activate (healthcheck);
  2236. error_exit:
  2237. res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKSTART;
  2238. res_lib.header.size = sizeof (res_lib);
  2239. res_lib.header.error = error;
  2240. openais_conn_send_response (conn, &res_lib,
  2241. sizeof (struct res_lib_amf_healthcheckstart));
  2242. }
  2243. static void message_handler_req_lib_amf_healthcheckconfirm (
  2244. void *conn,
  2245. void *msg)
  2246. {
  2247. }
  2248. static void message_handler_req_lib_amf_healthcheckstop (
  2249. void *conn,
  2250. void *msg)
  2251. {
  2252. struct req_lib_amf_healthcheckstop *req_lib = msg;
  2253. struct res_lib_amf_healthcheckstop res_lib;
  2254. struct amf_healthcheck *healthcheck;
  2255. struct amf_comp *comp;
  2256. SaAisErrorT error = SA_AIS_OK;
  2257. dprintf ("healthcheck stop\n");
  2258. comp = amf_find_comp (&amf_cluster, &req_lib->compName);
  2259. if (comp == 0) {
  2260. log_printf (LOG_ERR, "Healthcheckstop: Component '%s' not found",
  2261. req_lib->compName.value);
  2262. error = SA_AIS_ERR_NOT_EXIST;
  2263. goto error_exit;
  2264. }
  2265. healthcheck = amf_find_healthcheck (comp, &req_lib->healthcheckKey);
  2266. if (healthcheck == 0) {
  2267. log_printf (LOG_ERR, "Healthcheckstop: Healthcheck '%s' not found",
  2268. req_lib->healthcheckKey.key);
  2269. error = SA_AIS_ERR_NOT_EXIST;
  2270. goto error_exit;
  2271. }
  2272. healthcheck_deactivate (healthcheck);
  2273. error_exit:
  2274. res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKSTOP;
  2275. res_lib.header.size = sizeof (res_lib);
  2276. res_lib.header.error = error;
  2277. openais_conn_send_response (conn, &res_lib, sizeof (res_lib));
  2278. }
  2279. static void message_handler_req_lib_amf_hastateget (
  2280. void *conn,
  2281. void *msg)
  2282. {
  2283. #ifdef COMPILE_OUT
  2284. struct req_lib_amf_hastateget *req_lib_amf_hastateget = (struct req_lib_amf_hastateget *)msg;
  2285. struct res_lib_amf_hastateget res_lib_amf_hastateget;
  2286. struct amf_comp *component;
  2287. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_hastateget()\n");
  2288. res_lib_amf_hastateget.header.id = MESSAGE_RES_AMF_HASTATEGET;
  2289. res_lib_amf_hastateget.header.size = sizeof (struct res_lib_amf_hastateget);
  2290. res_lib_amf_hastateget.header.error = SA_ERR_NOT_EXIST;
  2291. #ifdef COMPILE_OUT
  2292. component = component_in_protectiongroup_find (&req_lib_amf_hastateget->csiName, &req_lib_amf_hastateget->compName);
  2293. #endif
  2294. if (component) {
  2295. memcpy (&res_lib_amf_hastateget.haState,
  2296. &component->currentHAState, sizeof (SaAmfHAStateT));
  2297. res_lib_amf_hastateget.header.error = SA_AIS_OK;
  2298. }
  2299. openais_conn_send_response (conn, &res_lib_amf_hastateget, sizeof (struct res_lib_amf_hastateget));
  2300. #endif
  2301. }
  2302. static void message_handler_req_lib_amf_protectiongrouptrack (
  2303. void *conn,
  2304. void *msg)
  2305. {
  2306. #ifdef COMPILE_OUT
  2307. struct req_lib_amf_protectiongrouptrack *req_lib_amf_protectiongrouptrack = (struct req_lib_amf_protectiongrouptrack *)message;
  2308. struct res_lib_amf_protectiongrouptrack res_lib_amf_protectiongrouptrack;
  2309. struct libamf_ci_trackentry *track = 0;
  2310. int i;
  2311. struct saAmfProtectionGroup *amfProtectionGroup;
  2312. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_protectiongrouptrack()\n");
  2313. amfProtectionGroup = protectiongroup_find (&req_lib_amf_protectiongrouptrack->csiName);
  2314. if (amfProtectionGroup) {
  2315. log_printf (LOG_LEVEL_DEBUG, "protectiongrouptrack: Got valid track start on CSI: %s.\n", getSaNameT (&req_lib_amf_protectiongrouptrack->csiName));
  2316. for (i = 0; i < conn_info->ais_ci.u.libamf_ci.trackEntries; i++) {
  2317. if (conn_info->ais_ci.u.libamf_ci.tracks[i].active == 0) {
  2318. track = &conn_info->ais_ci.u.libamf_ci.tracks[i];
  2319. break;
  2320. }
  2321. }
  2322. if (track == 0) {
  2323. grow_amf_track_table (conn_info, 1);
  2324. track = &conn_info->ais_ci.u.libamf_ci.tracks[i];
  2325. }
  2326. track->active = 1;
  2327. track->trackFlags = req_lib_amf_protectiongrouptrack->trackFlags;
  2328. track->notificationBufferAddress = req_lib_amf_protectiongrouptrack->notificationBufferAddress;
  2329. memcpy (&track->csiName,
  2330. &req_lib_amf_protectiongrouptrack->csiName, sizeof (SaNameT));
  2331. conn_info->ais_ci.u.libamf_ci.trackActive += 1;
  2332. list_add (&conn_info->conn_list, &library_notification_send_listhead);
  2333. /*
  2334. * If SA_TRACK_CURRENT is specified, write out all current connections
  2335. */
  2336. } else {
  2337. log_printf (LOG_LEVEL_DEBUG, "invalid track start, csi not registered with system.\n");
  2338. }
  2339. res_lib_amf_protectiongrouptrack.header.id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACK;
  2340. res_lib_amf_protectiongrouptrack.header.size = sizeof (struct res_lib_amf_protectiongrouptrack);
  2341. res_lib_amf_protectiongrouptrack.header.error = SA_ERR_NOT_EXIST;
  2342. if (amfProtectionGroup) {
  2343. res_lib_amf_protectiongrouptrack.header.error = SA_AIS_OK;
  2344. }
  2345. openais_conn_send_response (conn, &res_lib_amf_protectiongrouptrack,
  2346. sizeof (struct res_lib_amf_protectiongrouptrack));
  2347. if (amfProtectionGroup &&
  2348. req_lib_amf_protectiongrouptrack->trackFlags & SA_TRACK_CURRENT) {
  2349. protectiongroup_notification_send (conn_info,
  2350. track->notificationBufferAddress,
  2351. amfProtectionGroup,
  2352. 0,
  2353. 0,
  2354. SA_TRACK_CHANGES_ONLY);
  2355. track->trackFlags &= ~SA_TRACK_CURRENT;
  2356. }
  2357. #endif
  2358. }
  2359. static void message_handler_req_lib_amf_csiquiescingcomplete (
  2360. void *conn,
  2361. void *msg)
  2362. {
  2363. }
  2364. static void message_handler_req_lib_amf_protectiongrouptrackstop (
  2365. void *conn,
  2366. void *msg)
  2367. {
  2368. #ifdef COMPILE_OUT
  2369. struct req_lib_amf_protectiongrouptrackstop *req_lib_amf_protectiongrouptrackstop = (struct req_lib_amf_protectiongrouptrackstop *)message;
  2370. struct res_lib_amf_protectiongrouptrackstop res_lib_amf_protectiongrouptrackstop;
  2371. struct libamf_ci_trackentry *track = 0;
  2372. int i;
  2373. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_protectiongrouptrackstop()\n");
  2374. for (i = 0; i < conn_info->ais_ci.u.libamf_ci.trackEntries; i++) {
  2375. if (name_match (&req_lib_amf_protectiongrouptrackstop->csiName,
  2376. &conn_info->ais_ci.u.libamf_ci.tracks[i].csiName)) {
  2377. track = &conn_info->ais_ci.u.libamf_ci.tracks[i];
  2378. }
  2379. }
  2380. if (track) {
  2381. log_printf (LOG_LEVEL_DEBUG, "protectiongrouptrackstop: Trackstop on CSI: %s\n", getSaNameT (&req_lib_amf_protectiongrouptrackstop->csiName));
  2382. memset (track, 0, sizeof (struct libamf_ci_trackentry));
  2383. conn_info->ais_ci.u.libamf_ci.trackActive -= 1;
  2384. if (conn_info->ais_ci.u.libamf_ci.trackActive == 0) {
  2385. list_del (&conn_info->conn_list);
  2386. }
  2387. }
  2388. res_lib_amf_protectiongrouptrackstop.header.id = MESSAGE_RES_AMF_PROTECTIONGROUPTRACKSTOP;
  2389. res_lib_amf_protectiongrouptrackstop.header.size = sizeof (struct res_lib_amf_protectiongrouptrackstop);
  2390. res_lib_amf_protectiongrouptrackstop.header.error = SA_ERR_NOT_EXIST;
  2391. if (track) {
  2392. res_lib_amf_protectiongrouptrackstop.header.error = SA_AIS_OK;
  2393. }
  2394. openais_conn_send_response (conn, &res_lib_amf_protectiongrouptrackstop,
  2395. sizeof (struct res_lib_amf_protectiongrouptrackstop));
  2396. #endif
  2397. }
  2398. static void message_handler_req_lib_amf_componenterrorreport (
  2399. void *conn,
  2400. void *msg)
  2401. {
  2402. struct req_lib_amf_componenterrorreport *req_lib = msg;
  2403. struct amf_comp *comp;
  2404. comp = amf_find_comp (&amf_cluster, &req_lib->erroneousComponent);
  2405. if (comp != NULL) {
  2406. struct req_exec_amf_comp_error_report req_exec;
  2407. struct iovec iovec;
  2408. TRACE2("Lib comp error report for '%s'", &comp->name.value);
  2409. req_exec.header.size = sizeof (struct req_exec_amf_comp_error_report);
  2410. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  2411. MESSAGE_REQ_EXEC_AMF_COMPONENT_ERROR_REPORT);
  2412. memcpy (&req_exec.reportingComponent, &req_lib->reportingComponent,
  2413. sizeof (SaNameT));
  2414. memcpy (&req_exec.erroneousComponent, &req_lib->erroneousComponent,
  2415. sizeof (SaNameT));
  2416. memcpy (&req_exec.errorDetectionTime, &req_lib->errorDetectionTime,
  2417. sizeof (SaTimeT));
  2418. memcpy (&req_exec.recommendedRecovery, &req_lib->recommendedRecovery,
  2419. sizeof (SaAmfRecommendedRecoveryT));
  2420. memcpy (&req_exec.ntfIdentifier, &req_lib->ntfIdentifier,
  2421. sizeof (SaNtfIdentifierT));
  2422. iovec.iov_base = (char *)&req_exec;
  2423. iovec.iov_len = sizeof (req_exec);
  2424. assert (totempg_groups_mcast_joined (openais_group_handle,
  2425. &iovec, 1, TOTEMPG_AGREED) == 0);
  2426. } else {
  2427. struct res_lib_amf_componenterrorreport res_lib;
  2428. log_printf (LOG_ERR, "Component %s not found",
  2429. &req_lib->erroneousComponent.value);
  2430. res_lib.header.size = sizeof (struct res_lib_amf_componenterrorreport);
  2431. res_lib.header.id = MESSAGE_RES_AMF_COMPONENTERRORREPORT;
  2432. res_lib.header.error = SA_AIS_ERR_NOT_EXIST;
  2433. openais_conn_send_response (conn, &res_lib,
  2434. sizeof (struct res_lib_amf_componenterrorreport));
  2435. }
  2436. }
  2437. static void message_handler_req_lib_amf_componenterrorclear (
  2438. void *conn,
  2439. void *msg)
  2440. {
  2441. #ifdef COMPILLE_OUT
  2442. struct req_lib_amf_componenterrorclear *req_lib_amf_componenterrorclear = (struct req_lib_amf_componenterrorclear *)message;
  2443. struct req_exec_amf_componenterrorclear req_exec_amf_componenterrorclear;
  2444. struct iovec iovec;
  2445. log_printf (LOG_LEVEL_FROM_LIB, "Handle : message_handler_req_lib_amf_componenterrorclear()\n");
  2446. req_exec_amf_componenterrorclear.header.size = sizeof (struct req_exec_amf_componenterrorclear);
  2447. req_exec_amf_componenterrorclear.header.id =
  2448. SERVICE_ID_MAKE (AMF_SERVICE, MESSAGE_REQ_EXEC_AMF_COMPONENTERRORCLEAR);
  2449. message_source_set (&req_exec_amf_componenterrorclear.source, conn_info);
  2450. memcpy (&req_exec_amf_componenterrorclear.req_lib_amf_componenterrorclear,
  2451. req_lib_amf_componenterrorclear,
  2452. sizeof (struct req_lib_amf_componenterrorclear));
  2453. iovec.iov_base = (char *)&req_exec_amf_componenterrorclear;
  2454. iovec.iov_len = sizeof (req_exec_amf_componenterrorclear);
  2455. assert (totempg_groups_mcast_joined (openais_group_handle,
  2456. &iovec, 1, TOTEMPG_AGREED) == 0);
  2457. #endif
  2458. }
  2459. #if 0
  2460. static void pg_comp_create (
  2461. struct amf_pg *pg,
  2462. struct amf_csi *csi,
  2463. struct amf_comp *comp)
  2464. {
  2465. struct amf_pg_comp *pg_comp;
  2466. dprintf ("creating component for pg\n");
  2467. pg_comp = malloc (sizeof (struct amf_pg_comp));
  2468. assert (pg_comp);
  2469. pg_comp->comp = comp;
  2470. pg_comp->csi = csi;
  2471. list_init (&pg_comp->list);
  2472. list_add_tail (&pg_comp->list, &pg->pg_comp_head);
  2473. }
  2474. #endif
  2475. static void message_handler_req_lib_amf_response (void *conn, void *msg)
  2476. {
  2477. struct res_lib_amf_response res_lib;
  2478. struct req_lib_amf_response *req_lib = msg;
  2479. struct req_exec_amf_response req_exec;
  2480. struct iovec iovec;
  2481. struct amf_pd *pd = openais_conn_private_data_get (conn);
  2482. int res;
  2483. int interface;
  2484. void *data;
  2485. int error = SA_AIS_OK;
  2486. res = invocation_get_and_destroy (req_lib->invocation, &interface, &data);
  2487. if (res == -1) {
  2488. log_printf (LOG_ERR, "Lib response: invocation not found\n");
  2489. error = SA_AIS_ERR_INVALID_PARAM;
  2490. goto end;
  2491. }
  2492. switch (interface) {
  2493. case AMF_RESPONSE_HEALTHCHECKCALLBACK: {
  2494. struct amf_healthcheck *healthcheck = data;
  2495. SaNameT name;
  2496. TRACE3 ("Lib healthcheck response from '%s'",
  2497. comp_dn_make (healthcheck->comp, &name));
  2498. poll_timer_delete (aisexec_poll_handle,
  2499. healthcheck->timer_handle_duration);
  2500. healthcheck->timer_handle_duration = 0;
  2501. poll_timer_add (aisexec_poll_handle,
  2502. healthcheck->saAmfHealthcheckPeriod,
  2503. (void *)healthcheck,
  2504. timer_function_healthcheck_next_fn,
  2505. &healthcheck->timer_handle_period);
  2506. break;
  2507. }
  2508. case AMF_RESPONSE_CSISETCALLBACK: {
  2509. struct amf_csi_assignment *csi_assignment = data;
  2510. dprintf ("Lib csi '%s' set callback response from '%s', error: %d",
  2511. csi_assignment->csi->name.value, csi_assignment->comp->name.value, req_lib->error);
  2512. memcpy (&req_exec.csiName, &csi_assignment->name, sizeof (SaNameT));
  2513. break;
  2514. }
  2515. case AMF_RESPONSE_CSIREMOVECALLBACK: {
  2516. struct amf_csi_assignment *csi_assignment = data;
  2517. dprintf ("Lib csi '%s' remove callback response from '%s', error: %d",
  2518. csi_assignment->csi->name.value, csi_assignment->comp->name.value, req_lib->error);
  2519. memcpy (&req_exec.csiName, &csi_assignment->name, sizeof (SaNameT));
  2520. break;
  2521. }
  2522. case AMF_RESPONSE_COMPONENTTERMINATECALLBACK: {
  2523. struct component_terminate_callback_data *component_terminate_callback_data;
  2524. component_terminate_callback_data = data;
  2525. dprintf ("Lib component terminate callback response, error: %d", req_lib->error);
  2526. comp_healthcheck_deactivate (component_terminate_callback_data->comp);
  2527. escalation_policy_restart (component_terminate_callback_data->comp);
  2528. break;
  2529. }
  2530. default:
  2531. assert (0);
  2532. break;
  2533. }
  2534. /* Keep healthcheck responses node local */
  2535. if (interface != AMF_RESPONSE_HEALTHCHECKCALLBACK) {
  2536. assert (pd && pd->comp);
  2537. req_exec.header.size = sizeof (struct req_exec_amf_response);
  2538. req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
  2539. MESSAGE_REQ_EXEC_AMF_RESPONSE);
  2540. comp_dn_make (pd->comp, &req_exec.compName);
  2541. req_exec.interface = interface;
  2542. req_exec.error = req_lib->error;
  2543. iovec.iov_base = (char *)&req_exec;
  2544. iovec.iov_len = sizeof (req_exec);
  2545. assert (totempg_groups_mcast_joined (openais_group_handle,
  2546. &iovec, 1, TOTEMPG_AGREED) == 0);
  2547. }
  2548. end:
  2549. res_lib.header.id = MESSAGE_RES_AMF_RESPONSE;
  2550. res_lib.header.size = sizeof (struct res_lib_amf_response);
  2551. res_lib.header.error = error;
  2552. openais_conn_send_response (conn, &res_lib, sizeof (res_lib));
  2553. }