service.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  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. struct corosync_service_engine *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT];
  75. static unsigned int object_internal_configuration_handle;
  76. static unsigned int default_services_requested (struct corosync_api_v1 *corosync_api)
  77. {
  78. unsigned int object_service_handle;
  79. unsigned int object_find_handle;
  80. char *value;
  81. /*
  82. * Don't link default services if they have been disabled
  83. */
  84. corosync_api->object_find_create (
  85. OBJECT_PARENT_HANDLE,
  86. "aisexec",
  87. strlen ("aisexec"),
  88. &object_find_handle);
  89. if (corosync_api->object_find_next (
  90. object_find_handle,
  91. &object_service_handle) == 0) {
  92. if ( ! corosync_api->object_key_get (object_service_handle,
  93. "defaultservices",
  94. strlen ("defaultservices"),
  95. (void *)&value,
  96. NULL)) {
  97. if (value && strcmp (value, "no") == 0) {
  98. return 0;
  99. }
  100. }
  101. }
  102. corosync_api->object_find_destroy (object_find_handle);
  103. return (-1);
  104. }
  105. unsigned int corosync_service_link_and_init (
  106. struct corosync_api_v1 *corosync_api,
  107. char *service_name,
  108. unsigned int service_ver)
  109. {
  110. struct corosync_service_engine_iface_ver0 *iface_ver0;
  111. void *iface_ver0_p;
  112. unsigned int handle;
  113. struct corosync_service_engine *service;
  114. unsigned int res;
  115. unsigned int object_service_handle;
  116. /*
  117. * reference the service interface
  118. */
  119. iface_ver0_p = NULL;
  120. lcr_ifact_reference (
  121. &handle,
  122. service_name,
  123. service_ver,
  124. &iface_ver0_p,
  125. (void *)0);
  126. iface_ver0 = (struct corosync_service_engine_iface_ver0 *)iface_ver0_p;
  127. if (iface_ver0 == 0) {
  128. log_printf(LOG_LEVEL_ERROR, "Service failed to load '%s'.\n", service_name);
  129. return (-1);
  130. }
  131. /*
  132. * Initialize service
  133. */
  134. service = iface_ver0->corosync_get_service_engine_ver0();
  135. ais_service[service->id] = service;
  136. if (service->config_init_fn) {
  137. res = service->config_init_fn (corosync_api);
  138. }
  139. if (service->exec_init_fn) {
  140. res = service->exec_init_fn (corosync_api);
  141. }
  142. /*
  143. * Store service in object database
  144. */
  145. corosync_api->object_create (object_internal_configuration_handle,
  146. &object_service_handle,
  147. "service",
  148. strlen ("service"));
  149. corosync_api->object_key_create (object_service_handle,
  150. "name",
  151. strlen ("name"),
  152. service_name,
  153. strlen (service_name) + 1);
  154. corosync_api->object_key_create (object_service_handle,
  155. "ver",
  156. strlen ("ver"),
  157. &service_ver,
  158. sizeof (service_ver));
  159. res = corosync_api->object_key_create (object_service_handle,
  160. "handle",
  161. strlen ("handle"),
  162. &handle,
  163. sizeof (handle));
  164. corosync_api->object_key_create (object_service_handle,
  165. "service_id",
  166. strlen ("service_id"),
  167. &service->id,
  168. sizeof (service->id));
  169. log_printf (LOG_LEVEL_NOTICE, "Service initialized '%s'\n", service->name);
  170. return (res);
  171. }
  172. static int corosync_service_unlink_common (
  173. struct corosync_api_v1 *corosync_api,
  174. unsigned int object_service_handle,
  175. const char *service_name,
  176. unsigned int service_version)
  177. {
  178. unsigned int res;
  179. unsigned short *service_id;
  180. unsigned int *found_service_handle;
  181. res = corosync_api->object_key_get (object_service_handle,
  182. "handle",
  183. strlen ("handle"),
  184. (void *)&found_service_handle,
  185. NULL);
  186. res = corosync_api->object_key_get (object_service_handle,
  187. "service_id",
  188. strlen ("service_id"),
  189. (void *)&service_id,
  190. NULL);
  191. log_printf(LOG_LEVEL_NOTICE, "Unloading corosync component: %s v%u\n",
  192. service_name, service_version);
  193. if (ais_service[*service_id]->exec_exit_fn) {
  194. ais_service[*service_id]->exec_exit_fn ();
  195. }
  196. ais_service[*service_id] = NULL;
  197. return lcr_ifact_release (*found_service_handle);
  198. }
  199. extern unsigned int corosync_service_unlink_and_exit (
  200. struct corosync_api_v1 *corosync_api,
  201. char *service_name,
  202. unsigned int service_ver)
  203. {
  204. unsigned int res;
  205. unsigned int object_service_handle;
  206. char *found_service_name;
  207. unsigned int *found_service_ver;
  208. unsigned int object_find_handle;
  209. corosync_api->object_find_create (
  210. object_internal_configuration_handle,
  211. "service",
  212. strlen ("service"),
  213. &object_find_handle);
  214. while (corosync_api->object_find_next (
  215. object_find_handle,
  216. &object_service_handle) == 0) {
  217. corosync_api->object_key_get (object_service_handle,
  218. "name",
  219. strlen ("name"),
  220. (void *)&found_service_name,
  221. NULL);
  222. corosync_api->object_key_get (object_service_handle,
  223. "ver",
  224. strlen ("ver"),
  225. (void *)&found_service_ver,
  226. NULL);
  227. /*
  228. * If service found and linked exit it
  229. */
  230. if ((strcmp (service_name, found_service_name) == 0) &&
  231. (service_ver == *found_service_ver)) {
  232. res = corosync_service_unlink_common (
  233. corosync_api, object_service_handle,
  234. service_name, service_ver);
  235. corosync_api->object_destroy (object_service_handle);
  236. return res;
  237. }
  238. }
  239. corosync_api->object_find_destroy (object_find_handle);
  240. return (-1);
  241. }
  242. extern unsigned int corosync_service_unlink_all (
  243. struct corosync_api_v1 *corosync_api)
  244. {
  245. char *service_name;
  246. unsigned int *service_ver;
  247. unsigned int object_service_handle;
  248. unsigned int object_find_handle;
  249. int found;
  250. log_printf(LOG_LEVEL_NOTICE, "Unloading all corosync components\n");
  251. /*
  252. * TODO
  253. * Deleting of keys not supported during iteration at this time
  254. * hence this ugly hack
  255. */
  256. while(corosync_api->object_find_create (
  257. object_internal_configuration_handle,
  258. "service",
  259. strlen ("service"),
  260. &object_find_handle) == 0)
  261. {
  262. found = 0;
  263. while(corosync_api->object_find_next (
  264. object_find_handle,
  265. &object_service_handle) == 0)
  266. found = 1;
  267. if(!found)
  268. break;
  269. corosync_api->object_key_get (
  270. object_service_handle,
  271. "name",
  272. strlen ("name"),
  273. (void *)&service_name,
  274. NULL);
  275. corosync_api->object_key_get (
  276. object_service_handle,
  277. "ver",
  278. strlen ("ver"),
  279. (void *)&service_ver,
  280. NULL);
  281. corosync_service_unlink_common (
  282. corosync_api, object_service_handle,
  283. service_name, *service_ver);
  284. corosync_api->object_destroy (object_service_handle);
  285. corosync_api->object_find_destroy (object_find_handle);
  286. }
  287. return (0);
  288. }
  289. /*
  290. * Links default services into the executive
  291. */
  292. unsigned int corosync_service_defaults_link_and_init (struct corosync_api_v1 *corosync_api)
  293. {
  294. unsigned int i;
  295. unsigned int object_service_handle;
  296. char *found_service_name;
  297. char *found_service_ver;
  298. unsigned int found_service_ver_atoi;
  299. unsigned int object_find_handle;
  300. corosync_api->object_create (OBJECT_PARENT_HANDLE,
  301. &object_internal_configuration_handle,
  302. "internal_configuration",
  303. strlen ("internal_configuration"));
  304. corosync_api->object_find_create (
  305. OBJECT_PARENT_HANDLE,
  306. "service",
  307. strlen ("service"),
  308. &object_find_handle);
  309. while (corosync_api->object_find_next (
  310. object_find_handle,
  311. &object_service_handle) == 0) {
  312. corosync_api->object_key_get (object_service_handle,
  313. "name",
  314. strlen ("name"),
  315. (void *)&found_service_name,
  316. NULL);
  317. corosync_api->object_key_get (object_service_handle,
  318. "ver",
  319. strlen ("ver"),
  320. (void *)&found_service_ver,
  321. NULL);
  322. found_service_ver_atoi = atoi (found_service_ver);
  323. corosync_service_link_and_init (
  324. corosync_api,
  325. found_service_name,
  326. found_service_ver_atoi);
  327. }
  328. corosync_api->object_find_destroy (object_find_handle);
  329. if (default_services_requested (corosync_api) == 0) {
  330. return (0);
  331. }
  332. for (i = 0;
  333. i < sizeof (default_services) / sizeof (struct default_service); i++) {
  334. corosync_service_link_and_init (
  335. corosync_api,
  336. default_services[i].name,
  337. default_services[i].ver);
  338. }
  339. return (0);
  340. }