service.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. * Copyright (c) 2006 MontaVista Software, Inc.
  3. * Copyright (c) 2006-2008 Red Hat, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. * Author: Steven Dake (sdake@redhat.com)
  8. *
  9. * This software licensed under BSD license, the text of which follows:
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  20. * contributors may be used to endorse or promote products derived from this
  21. * software without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  33. * THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <assert.h>
  38. #include <corosync/lcr/lcr_ifact.h>
  39. #include <corosync/swab.h>
  40. #include <corosync/totem/totem.h>
  41. #include "mainconfig.h"
  42. #include "util.h"
  43. #include <corosync/engine/logsys.h>
  44. #include "timer.h"
  45. #include <corosync/totem/totempg.h>
  46. #include <corosync/totem/totemip.h>
  47. #include "main.h"
  48. #include "ipc.h"
  49. #include <corosync/engine/coroapi.h>
  50. #include "service.h"
  51. LOGSYS_DECLARE_SUBSYS ("SERV", LOG_INFO);
  52. struct default_service {
  53. char *name;
  54. int ver;
  55. };
  56. static struct default_service default_services[] = {
  57. {
  58. .name = "corosync_evs",
  59. .ver = 0,
  60. },
  61. {
  62. .name = "corosync_cfg",
  63. .ver = 0,
  64. },
  65. {
  66. .name = "corosync_cpg",
  67. .ver = 0,
  68. },
  69. {
  70. .name = "corosync_confdb",
  71. .ver = 0,
  72. },
  73. {
  74. .name = "corosync_pload",
  75. .ver = 0,
  76. },
  77. {
  78. .name = "corosync_quorum",
  79. .ver = 0,
  80. },
  81. };
  82. struct corosync_service_engine *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT];
  83. static unsigned int object_internal_configuration_handle;
  84. static unsigned int default_services_requested (struct corosync_api_v1 *corosync_api)
  85. {
  86. unsigned int object_service_handle;
  87. unsigned int object_find_handle;
  88. char *value;
  89. /*
  90. * Don't link default services if they have been disabled
  91. */
  92. corosync_api->object_find_create (
  93. OBJECT_PARENT_HANDLE,
  94. "aisexec",
  95. strlen ("aisexec"),
  96. &object_find_handle);
  97. if (corosync_api->object_find_next (
  98. object_find_handle,
  99. &object_service_handle) == 0) {
  100. if ( ! corosync_api->object_key_get (object_service_handle,
  101. "defaultservices",
  102. strlen ("defaultservices"),
  103. (void *)&value,
  104. NULL)) {
  105. if (value && strcmp (value, "no") == 0) {
  106. return 0;
  107. }
  108. }
  109. }
  110. corosync_api->object_find_destroy (object_find_handle);
  111. return (-1);
  112. }
  113. unsigned int corosync_service_link_and_init (
  114. struct corosync_api_v1 *corosync_api,
  115. char *service_name,
  116. unsigned int service_ver)
  117. {
  118. struct corosync_service_engine_iface_ver0 *iface_ver0;
  119. void *iface_ver0_p;
  120. unsigned int handle;
  121. struct corosync_service_engine *service;
  122. unsigned int res;
  123. unsigned int object_service_handle;
  124. /*
  125. * reference the service interface
  126. */
  127. iface_ver0_p = NULL;
  128. lcr_ifact_reference (
  129. &handle,
  130. service_name,
  131. service_ver,
  132. &iface_ver0_p,
  133. (void *)0);
  134. iface_ver0 = (struct corosync_service_engine_iface_ver0 *)iface_ver0_p;
  135. if (iface_ver0 == 0) {
  136. log_printf(LOG_LEVEL_ERROR, "Service failed to load '%s'.\n", service_name);
  137. return (-1);
  138. }
  139. /*
  140. * Initialize service
  141. */
  142. service = iface_ver0->corosync_get_service_engine_ver0();
  143. ais_service[service->id] = service;
  144. if (service->config_init_fn) {
  145. res = service->config_init_fn (corosync_api);
  146. }
  147. if (service->exec_init_fn) {
  148. res = service->exec_init_fn (corosync_api);
  149. }
  150. /*
  151. * Store service in object database
  152. */
  153. corosync_api->object_create (object_internal_configuration_handle,
  154. &object_service_handle,
  155. "service",
  156. strlen ("service"));
  157. corosync_api->object_key_create (object_service_handle,
  158. "name",
  159. strlen ("name"),
  160. service_name,
  161. strlen (service_name) + 1);
  162. corosync_api->object_key_create (object_service_handle,
  163. "ver",
  164. strlen ("ver"),
  165. &service_ver,
  166. sizeof (service_ver));
  167. res = corosync_api->object_key_create (object_service_handle,
  168. "handle",
  169. strlen ("handle"),
  170. &handle,
  171. sizeof (handle));
  172. corosync_api->object_key_create (object_service_handle,
  173. "service_id",
  174. strlen ("service_id"),
  175. &service->id,
  176. sizeof (service->id));
  177. log_printf (LOG_LEVEL_NOTICE, "Service initialized '%s'\n", service->name);
  178. return (res);
  179. }
  180. static int corosync_service_unlink_common (
  181. struct corosync_api_v1 *corosync_api,
  182. unsigned int object_service_handle,
  183. const char *service_name,
  184. unsigned int service_version)
  185. {
  186. unsigned int res;
  187. unsigned short *service_id;
  188. unsigned int *found_service_handle;
  189. res = corosync_api->object_key_get (object_service_handle,
  190. "handle",
  191. strlen ("handle"),
  192. (void *)&found_service_handle,
  193. NULL);
  194. res = corosync_api->object_key_get (object_service_handle,
  195. "service_id",
  196. strlen ("service_id"),
  197. (void *)&service_id,
  198. NULL);
  199. log_printf(LOG_LEVEL_NOTICE, "Unloading corosync component: %s v%u\n",
  200. service_name, service_version);
  201. if (ais_service[*service_id]->exec_exit_fn) {
  202. ais_service[*service_id]->exec_exit_fn ();
  203. }
  204. ais_service[*service_id] = NULL;
  205. return lcr_ifact_release (*found_service_handle);
  206. }
  207. extern unsigned int corosync_service_unlink_and_exit (
  208. struct corosync_api_v1 *corosync_api,
  209. char *service_name,
  210. unsigned int service_ver)
  211. {
  212. unsigned int res;
  213. unsigned int object_service_handle;
  214. char *found_service_name;
  215. unsigned int *found_service_ver;
  216. unsigned int object_find_handle;
  217. corosync_api->object_find_create (
  218. object_internal_configuration_handle,
  219. "service",
  220. strlen ("service"),
  221. &object_find_handle);
  222. while (corosync_api->object_find_next (
  223. object_find_handle,
  224. &object_service_handle) == 0) {
  225. corosync_api->object_key_get (object_service_handle,
  226. "name",
  227. strlen ("name"),
  228. (void *)&found_service_name,
  229. NULL);
  230. corosync_api->object_key_get (object_service_handle,
  231. "ver",
  232. strlen ("ver"),
  233. (void *)&found_service_ver,
  234. NULL);
  235. /*
  236. * If service found and linked exit it
  237. */
  238. if ((strcmp (service_name, found_service_name) == 0) &&
  239. (service_ver == *found_service_ver)) {
  240. res = corosync_service_unlink_common (
  241. corosync_api, object_service_handle,
  242. service_name, service_ver);
  243. corosync_api->object_destroy (object_service_handle);
  244. return res;
  245. }
  246. }
  247. corosync_api->object_find_destroy (object_find_handle);
  248. return (-1);
  249. }
  250. extern unsigned int corosync_service_unlink_all (
  251. struct corosync_api_v1 *corosync_api)
  252. {
  253. char *service_name;
  254. unsigned int *service_ver;
  255. unsigned int object_service_handle;
  256. unsigned int object_find_handle;
  257. int found;
  258. log_printf(LOG_LEVEL_NOTICE, "Unloading all corosync components\n");
  259. /*
  260. * TODO
  261. * Deleting of keys not supported during iteration at this time
  262. * hence this ugly hack
  263. */
  264. while(corosync_api->object_find_create (
  265. object_internal_configuration_handle,
  266. "service",
  267. strlen ("service"),
  268. &object_find_handle) == 0)
  269. {
  270. found = 0;
  271. while(corosync_api->object_find_next (
  272. object_find_handle,
  273. &object_service_handle) == 0)
  274. found = 1;
  275. if(!found)
  276. break;
  277. corosync_api->object_key_get (
  278. object_service_handle,
  279. "name",
  280. strlen ("name"),
  281. (void *)&service_name,
  282. NULL);
  283. corosync_api->object_key_get (
  284. object_service_handle,
  285. "ver",
  286. strlen ("ver"),
  287. (void *)&service_ver,
  288. NULL);
  289. corosync_service_unlink_common (
  290. corosync_api, object_service_handle,
  291. service_name, *service_ver);
  292. corosync_api->object_destroy (object_service_handle);
  293. corosync_api->object_find_destroy (object_find_handle);
  294. }
  295. return (0);
  296. }
  297. /*
  298. * Links default services into the executive
  299. */
  300. unsigned int corosync_service_defaults_link_and_init (struct corosync_api_v1 *corosync_api)
  301. {
  302. unsigned int i;
  303. unsigned int object_service_handle;
  304. char *found_service_name;
  305. char *found_service_ver;
  306. unsigned int found_service_ver_atoi;
  307. unsigned int object_find_handle;
  308. corosync_api->object_create (OBJECT_PARENT_HANDLE,
  309. &object_internal_configuration_handle,
  310. "internal_configuration",
  311. strlen ("internal_configuration"));
  312. corosync_api->object_find_create (
  313. OBJECT_PARENT_HANDLE,
  314. "service",
  315. strlen ("service"),
  316. &object_find_handle);
  317. while (corosync_api->object_find_next (
  318. object_find_handle,
  319. &object_service_handle) == 0) {
  320. corosync_api->object_key_get (object_service_handle,
  321. "name",
  322. strlen ("name"),
  323. (void *)&found_service_name,
  324. NULL);
  325. corosync_api->object_key_get (object_service_handle,
  326. "ver",
  327. strlen ("ver"),
  328. (void *)&found_service_ver,
  329. NULL);
  330. found_service_ver_atoi = atoi (found_service_ver);
  331. corosync_service_link_and_init (
  332. corosync_api,
  333. found_service_name,
  334. found_service_ver_atoi);
  335. }
  336. corosync_api->object_find_destroy (object_find_handle);
  337. if (default_services_requested (corosync_api) == 0) {
  338. return (0);
  339. }
  340. for (i = 0;
  341. i < sizeof (default_services) / sizeof (struct default_service); i++) {
  342. corosync_service_link_and_init (
  343. corosync_api,
  344. default_services[i].name,
  345. default_services[i].ver);
  346. }
  347. return (0);
  348. }