testamf1.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * Copyright (c) 2002-2003 MontaVista Software, Inc.
  3. * Copyright (c) 2006 Ericsson AB.
  4. * Copyright (c) 2006 Sun Microsystems, Inc.
  5. *
  6. * All rights reserved.
  7. *
  8. * Author: Steven Dake (sdake@mvista.com)
  9. * Hans Feldt
  10. *
  11. * This software licensed under BSD license, the text of which follows:
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright notice,
  17. * this list of conditions and the following disclaimer.
  18. * - Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  22. * contributors may be used to endorse or promote products derived from this
  23. * software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  35. * THE POSSIBILITY OF SUCH DAMAGE.
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <errno.h>
  41. #include <signal.h>
  42. #include <unistd.h>
  43. #include <sys/types.h>
  44. #include <sys/socket.h>
  45. #include <sys/un.h>
  46. #include <sched.h>
  47. #include <sys/stat.h>
  48. #include <fcntl.h>
  49. #include "saAis.h"
  50. #include "saAmf.h"
  51. SaAmfHandleT handle;
  52. SaAmfHealthcheckKeyT key0 = {
  53. .key = "key1",
  54. .keyLen = 4
  55. };
  56. SaNameT compNameGlobal;
  57. int good_health = 0;
  58. int good_health_limit = 0;
  59. void printSaNameT (SaNameT *name)
  60. {
  61. int i;
  62. for (i = 0; i < name->length; i++) {
  63. printf ("%c", name->value[i]);
  64. }
  65. }
  66. void setSanameT (SaNameT *name, char *str) {
  67. name->length = strlen (str);
  68. memcpy (name->value, str, name->length);
  69. }
  70. static unsigned int healthcheck_no = 0;
  71. int stop = 0;
  72. void HealthcheckCallback (SaInvocationT invocation,
  73. const SaNameT *compName,
  74. SaAmfHealthcheckKeyT *healthcheckKey)
  75. {
  76. SaAisErrorT res;
  77. if( !good_health && healthcheck_no++);
  78. if (healthcheck_no == good_health_limit ) {
  79. res = saAmfResponse (handle, invocation, SA_AIS_OK);
  80. res = saAmfHealthcheckStop (handle,
  81. &compNameGlobal,
  82. &key0);
  83. printf ("healthcheck stop result %d (should be %d)\n", res, SA_AIS_OK);
  84. printf ("COMPONENT REPORTING ERROR %s\n", compNameGlobal.value);
  85. saAmfComponentErrorReport (handle, compName, 0, SA_AMF_COMPONENT_RESTART, 0);
  86. printf ("COMPONENT DONE REPORTING ERROR\n");
  87. } else {
  88. res = saAmfResponse (handle, invocation, SA_AIS_OK);
  89. }
  90. }
  91. void ComponentTerminateCallback (
  92. SaInvocationT invocation,
  93. const SaNameT *compName)
  94. {
  95. printf ("ComponentTerminateCallback\n");
  96. saAmfResponse (handle, invocation, SA_AIS_OK);
  97. exit (0);
  98. }
  99. #if 0
  100. #include <sys/time.h>
  101. #define TRU "%d"
  102. #define TRS "%s"
  103. #define TR(format,x) do { \
  104. struct timeval t;\
  105. gettimeofday(&t,NULL); \
  106. printf("%s:%d: %s : %d : %u: %u :%s : " format "\n",\
  107. __FILE__,__LINE__,__FUNCTION__, \
  108. (int)getpid(),(int)t.tv_sec, (int)t.tv_usec,#x,x); \
  109. }while(0)
  110. #else
  111. #define TRU "%d"
  112. #define TRS "%s"
  113. #define TR(format,x)
  114. #endif
  115. void CSISetCallback (
  116. SaInvocationT invocation,
  117. const SaNameT *compName,
  118. SaAmfHAStateT haState,
  119. SaAmfCSIDescriptorT *csiDescriptor)
  120. {
  121. SaAmfHAStateT state;
  122. int res;
  123. switch (haState) {
  124. case SA_AMF_HA_ACTIVE:
  125. printf ("%d: Component '%s' requested to enter hastate SA_AMF_ACTIVE"
  126. " for \n\tCSI '%s'\n",
  127. (int)getpid(), compName->value, csiDescriptor->csiName.value);
  128. res = saAmfResponse (handle, invocation, SA_AIS_OK);
  129. if (res != SA_AIS_OK) {
  130. fprintf (stderr, "%d: saAmfResponse failed: %d\n", (int)getpid(), res);
  131. exit (-1);
  132. }
  133. res = saAmfHAStateGet (handle, compName, &csiDescriptor->csiName, &state);
  134. if (res != SA_AIS_OK || haState != state) {
  135. fprintf (stderr, "saAmfHAStateGet failed: %d\n", res);
  136. exit (-1);
  137. }
  138. int i;
  139. TR(TRU, csiDescriptor->csiAttr.number);
  140. for(i=0; i<csiDescriptor->csiAttr.number; i++) {
  141. if( strcmp((char*)csiDescriptor->csiAttr.attr[i].attrName, "good_health_limit") == 0){
  142. good_health = strcmp((char*)csiDescriptor->csiAttr.attr[i].attrValue, "0") ? 0 : 1;
  143. good_health_limit = atoi((char*)csiDescriptor->csiAttr.attr[i].attrValue);
  144. }
  145. #if 0
  146. TR(TRS,csiDescriptor->csiAttr.attr[i].attrName);
  147. TR(TRS, csiDescriptor->csiAttr.attr[i].attrValue);
  148. #endif
  149. }
  150. TR(TRU, csiDescriptor->csiFlags);
  151. printSaNameT((SaNameT*) &csiDescriptor->csiStateDescriptor.activeDescriptor.activeCompName);
  152. TR(TRU, csiDescriptor->csiStateDescriptor.activeDescriptor.transitionDescriptor);
  153. break;
  154. case SA_AMF_HA_STANDBY:
  155. printf ("%d: Component '%s' requested to enter hastate SA_AMF_STANDBY "
  156. "for \n\tCSI '%s'\n",
  157. (int)getpid(), compName->value, csiDescriptor->csiName.value);
  158. res = saAmfResponse (handle, invocation, SA_AIS_OK);
  159. TR(TRU,csiDescriptor->csiAttr.number);
  160. for(i=0; i<csiDescriptor->csiAttr.number; i++) {
  161. if(!strcmp((char*)csiDescriptor->csiAttr.attr[i].attrName, "good_health") &&
  162. !strcmp((char*)csiDescriptor->csiAttr.attr[i].attrValue, "true")){
  163. good_health = 1;
  164. }
  165. TR(TRS,csiDescriptor->csiAttr.attr[i].attrName);
  166. TR(TRS,csiDescriptor->csiAttr.attr[i].attrValue);
  167. }
  168. TR(TRU,csiDescriptor->csiFlags);
  169. printSaNameT((SaNameT*) &csiDescriptor->csiStateDescriptor.standbyDescriptor.activeCompName);
  170. TR(TRU,csiDescriptor->csiStateDescriptor.standbyDescriptor.standbyRank);
  171. break;
  172. case SA_AMF_HA_QUIESCED:
  173. printf ("%d: Component '%s' requested to enter hastate SA_AMF_HA_QUIESCED "
  174. "for \n\tCSI '%s'\n",
  175. (int)getpid(), compName->value, csiDescriptor->csiName.value);
  176. res = saAmfResponse (handle, invocation, SA_AIS_OK);
  177. break;
  178. case SA_AMF_HA_QUIESCING:
  179. break;
  180. }
  181. }
  182. void CSIRemoveCallback (
  183. SaInvocationT invocation,
  184. const SaNameT *compName,
  185. const SaNameT *csiName,
  186. SaAmfCSIFlagsT csiFlags)
  187. {
  188. int res;
  189. printf ("CSIRemoveCallback for component '");
  190. printSaNameT ((SaNameT *)compName);
  191. printf ("' in CSI '");
  192. printSaNameT ((SaNameT *)csiName);
  193. printf ("'\n");
  194. res = saAmfResponse (handle, invocation, SA_AIS_OK);
  195. }
  196. #ifdef COMPILE_OUT
  197. void ProtectionGroupTrackCallback (
  198. const SaNameT *csiName,
  199. SaAmfProtectionGroupNotificationT *notificationBuffer,
  200. SaUint32T numberOfItems,
  201. SaUint32T numberOfMembers,
  202. SaAisErrorT error)
  203. {
  204. int i;
  205. printf ("ProtectionGroupTrackCallback items %d members %d\n", (int)numberOfItems, (int)numberOfMembers);
  206. printf ("buffer is %p\n", notificationBuffer);
  207. for (i = 0; i < numberOfItems; i++) {
  208. printf ("component name");
  209. printSaNameT (&notificationBuffer[i].member.compName);
  210. printf ("\n");
  211. printf ("\treadiness state is %d\n", notificationBuffer[i].member.readinessState);
  212. printf ("\thastate %d\n", notificationBuffer[i].member.haState);
  213. printf ("\tchange is %d\n", notificationBuffer[i].change);
  214. }
  215. }
  216. #endif
  217. SaAmfCallbacksT amfCallbacks = {
  218. .saAmfHealthcheckCallback = HealthcheckCallback,
  219. .saAmfComponentTerminateCallback = ComponentTerminateCallback,
  220. .saAmfCSISetCallback = CSISetCallback,
  221. .saAmfCSIRemoveCallback = CSIRemoveCallback,
  222. };
  223. SaAmfCallbacksT amfCallbacks;
  224. SaVersionT version = { 'B', 1, 1 };
  225. #if ! defined(TS_CLASS) && (defined(OPENAIS_BSD) || defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS))
  226. static struct sched_param sched_param = {
  227. sched_priority: 99
  228. };
  229. #endif
  230. void sigintr_handler (int signum) {
  231. exit (0);
  232. }
  233. void write_pid (void) {
  234. char pid[256];
  235. char filename[256];
  236. int fd;
  237. int res;
  238. sprintf (filename, "/var/run/openais_cleanup_%s", compNameGlobal.value);
  239. fd = open (filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
  240. if (fd == -1) {
  241. printf("%d: Failed using /var/run for pid file, using /tmp\n", (int)getpid());
  242. sprintf (filename, "/tmp/openais_cleanup_%s", compNameGlobal.value);
  243. fd = open (filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
  244. }
  245. sprintf (pid, "%d", (int)getpid());
  246. res = write (fd, pid, strlen (pid));
  247. close (fd);
  248. }
  249. int main (int argc, char **argv) {
  250. int result;
  251. SaSelectionObjectT select_fd;
  252. fd_set read_fds;
  253. extern char *optarg;
  254. extern int optind;
  255. char *name = getenv ("SA_AMF_COMPONENT_NAME");
  256. /* test that it exist */
  257. if (name == NULL) {
  258. fprintf(stderr, "SA_AMF_COMPONENT_NAME missing\n");
  259. exit (-1);
  260. }
  261. /* test for correct value */
  262. #if 0
  263. if (strstr (name, "safComp=A,safSu=SERVICE_X_") == NULL) {
  264. fprintf(stderr, "SA_AMF_COMPONENT_NAME value wrong\n");
  265. exit (-2);
  266. }
  267. #endif
  268. printf("%d: Hello world from %s\n", (int)getpid(), name);
  269. signal (SIGINT, sigintr_handler);
  270. #if ! defined(TS_CLASS) && (defined(OPENAIS_BSD) || defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS))
  271. result = sched_setscheduler (0, SCHED_RR, &sched_param);
  272. if (result == -1) {
  273. printf ("%d: couldn't set sched priority\n", (int)getpid());
  274. }
  275. #endif
  276. result = saAmfInitialize (&handle, &amfCallbacks, &version);
  277. if (result != SA_AIS_OK) {
  278. printf ("initialize result is %d\n", result);
  279. exit (1);
  280. }
  281. FD_ZERO (&read_fds);
  282. saAmfSelectionObjectGet (handle, &select_fd);
  283. FD_SET (select_fd, &read_fds);
  284. saAmfComponentNameGet (handle, &compNameGlobal);
  285. write_pid ();
  286. result = saAmfHealthcheckStart (handle,
  287. &compNameGlobal,
  288. &key0,
  289. SA_AMF_HEALTHCHECK_AMF_INVOKED,
  290. SA_AMF_COMPONENT_FAILOVER);
  291. if (result != SA_AIS_OK) {
  292. printf ("Error: healthcheck start result %d\n", result);
  293. }
  294. {
  295. SaNameT badname;
  296. strcpy ((char*)badname.value, "badname");
  297. badname.length = 7;
  298. result = saAmfComponentRegister (handle, &badname, NULL);
  299. if (result != SA_AIS_ERR_INVALID_PARAM) {
  300. printf ("Error: register result is %d\n", result);
  301. }
  302. }
  303. result = saAmfComponentRegister (handle, &compNameGlobal, NULL);
  304. if (result != SA_AIS_OK) {
  305. printf ("Error: register result is %d\n", result);
  306. }
  307. /*
  308. * Test already started healthcheck
  309. */
  310. result = saAmfHealthcheckStart (handle,
  311. &compNameGlobal,
  312. &key0,
  313. SA_AMF_HEALTHCHECK_AMF_INVOKED,
  314. SA_AMF_COMPONENT_FAILOVER);
  315. if (result != SA_AIS_ERR_EXIST) {
  316. printf ("Error: healthcheck start result %d\n", result);
  317. }
  318. do {
  319. select (select_fd + 1, &read_fds, 0, 0, 0);
  320. result = saAmfDispatch (handle, SA_DISPATCH_ALL);
  321. if (result != SA_AIS_OK) {
  322. exit (-1);
  323. }
  324. } while (result && stop == 0);
  325. printf ("healthchecks stopped for 5 seconds\n");
  326. sleep (5);
  327. result = saAmfHealthcheckStart (handle,
  328. &compNameGlobal,
  329. &key0,
  330. SA_AMF_HEALTHCHECK_AMF_INVOKED,
  331. SA_AMF_COMPONENT_FAILOVER);
  332. do {
  333. select (select_fd + 1, &read_fds, 0, 0, 0);
  334. result = saAmfDispatch (handle, SA_DISPATCH_ALL);
  335. } while (result);
  336. saAmfFinalize (handle);
  337. exit (0);
  338. }