service.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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 "../lcr/lcr_ifact.h"
  39. #include "swab.h"
  40. #include "totem.h"
  41. #include "mainconfig.h"
  42. #include "util.h"
  43. #include "logsys.h"
  44. #include "timer.h"
  45. #include "totempg.h"
  46. #include "totemip.h"
  47. #include "main.h"
  48. #include "ipc.h"
  49. #include "../include/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. unsigned int res;
  250. log_printf(LOG_LEVEL_NOTICE, "Unloading all corosync components\n");
  251. res = 0;
  252. /*
  253. * TODO
  254. * Deleting of keys not supported during iteration at this time
  255. * hence this ugly hack
  256. */
  257. for (;;) {
  258. corosync_api->object_find_create (
  259. object_internal_configuration_handle,
  260. "service",
  261. strlen ("service"),
  262. &object_find_handle);
  263. res = corosync_api->object_find_next (
  264. object_find_handle,
  265. &object_service_handle);
  266. /*
  267. * Exit from unloading
  268. */
  269. if (res == -1) {
  270. break;
  271. }
  272. corosync_api->object_key_get (
  273. object_service_handle,
  274. "name",
  275. strlen ("name"),
  276. (void *)&service_name,
  277. NULL);
  278. corosync_api->object_key_get (
  279. object_service_handle,
  280. "ver",
  281. strlen ("ver"),
  282. (void *)&service_ver,
  283. NULL);
  284. corosync_service_unlink_common (
  285. corosync_api, object_service_handle,
  286. service_name, *service_ver);
  287. corosync_api->object_destroy (object_service_handle);
  288. corosync_api->object_find_destroy (object_find_handle);
  289. }
  290. return (0);
  291. }
  292. /*
  293. * Links default services into the executive
  294. */
  295. unsigned int corosync_service_defaults_link_and_init (struct corosync_api_v1 *corosync_api)
  296. {
  297. unsigned int i;
  298. unsigned int object_service_handle;
  299. char *found_service_name;
  300. char *found_service_ver;
  301. unsigned int found_service_ver_atoi;
  302. unsigned int object_find_handle;
  303. corosync_api->object_create (OBJECT_PARENT_HANDLE,
  304. &object_internal_configuration_handle,
  305. "internal_configuration",
  306. strlen ("internal_configuration"));
  307. corosync_api->object_find_create (
  308. OBJECT_PARENT_HANDLE,
  309. "service",
  310. strlen ("service"),
  311. &object_find_handle);
  312. while (corosync_api->object_find_next (
  313. object_find_handle,
  314. &object_service_handle) == 0) {
  315. corosync_api->object_key_get (object_service_handle,
  316. "name",
  317. strlen ("name"),
  318. (void *)&found_service_name,
  319. NULL);
  320. corosync_api->object_key_get (object_service_handle,
  321. "ver",
  322. strlen ("ver"),
  323. (void *)&found_service_ver,
  324. NULL);
  325. found_service_ver_atoi = atoi (found_service_ver);
  326. corosync_service_link_and_init (
  327. corosync_api,
  328. found_service_name,
  329. found_service_ver_atoi);
  330. }
  331. corosync_api->object_find_destroy (object_find_handle);
  332. if (default_services_requested (corosync_api) == 0) {
  333. return (0);
  334. }
  335. for (i = 0;
  336. i < sizeof (default_services) / sizeof (struct default_service); i++) {
  337. corosync_service_link_and_init (
  338. corosync_api,
  339. default_services[i].name,
  340. default_services[i].ver);
  341. }
  342. return (0);
  343. }