cl4_init.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* cl4_init.c - implments initialization/cleanup functions for
  13. 4.0 style changelog
  14. */
  15. #include <string.h>
  16. #include "slapi-plugin.h"
  17. #include "cl4.h"
  18. #include "repl.h"
  19. /* forward declarations */
  20. static int changelog4_create_be();
  21. static int changelog4_start_be ();
  22. static int changelog4_close();
  23. static int changelog4_remove();
  24. /*
  25. * Initialise the 4.0 Changelog
  26. */
  27. int changelog4_init ()
  28. {
  29. int rc= 0; /* OK */
  30. Slapi_Backend *rbe;
  31. changeNumber first_change = 0UL, last_change = 0UL;
  32. int lderr;
  33. if (changelog4_create_be() < 0 )
  34. {
  35. rc= -1;
  36. }
  37. else
  38. {
  39. rc = changelog4_start_be ();
  40. }
  41. if(rc == 0)
  42. {
  43. rbe = get_repl_backend();
  44. if(rbe!=NULL)
  45. {
  46. /* We have a Change Log. Check it's valid. */
  47. /* changelog has to be started before its
  48. data version can be read */
  49. const char *sdv= get_server_dataversion();
  50. const char *cdv= get_changelog_dataversion();
  51. char *suffix = changelog4_get_suffix ();
  52. if(!cdv || strcmp(sdv,cdv)!=0)
  53. {
  54. /* The SDV and CDV are not the same. The Change Log is invalid.
  55. It must be removed. */
  56. /* ONREPL - currently we go through this code when the changelog
  57. is first created because we can't tell new backend from the
  58. existing one.*/
  59. rc = changelog4_close();
  60. rc = changelog4_remove();
  61. /* now restart the changelog */
  62. changelog4_start_be ();
  63. create_entity( suffix, "extensibleobject");
  64. /* Write the Server Data Version onto the changelog suffix entry */
  65. /* JCMREPL - And the changelog database version number */
  66. set_changelog_dataversion(sdv);
  67. slapi_ch_free ((void **)&suffix);
  68. }
  69. }
  70. }
  71. if(rc != 0)
  72. {
  73. slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name,
  74. "An error occurred configuring the changelog database\n" );
  75. }
  76. first_change = replog_get_firstchangenum( &lderr );
  77. last_change = replog_get_lastchangenum( &lderr );
  78. ldapi_initialize_changenumbers( first_change, last_change );
  79. return rc;
  80. }
  81. static int
  82. changelog4_close()
  83. {
  84. int rc= 0 /* OK */;
  85. Slapi_Backend *rbe= get_repl_backend();
  86. Slapi_PBlock *pb = slapi_pblock_new ();
  87. IFP closefn = NULL;
  88. rc = slapi_be_getentrypoint (rbe, SLAPI_PLUGIN_CLOSE_FN, (void**)&closefn, pb);
  89. if (rc != 0)
  90. {
  91. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  92. "Error: backend close entry point is missing. "
  93. "Replication subsystem disabled.\n");
  94. slapi_pblock_destroy (pb);
  95. set_repl_backend( NULL );
  96. return -1;
  97. }
  98. rc = closefn (pb);
  99. if (rc != 0)
  100. {
  101. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Error: the changelog database could "
  102. "not be closed. Replication subsystem disabled.\n");
  103. set_repl_backend( NULL );
  104. rc = -1;
  105. }
  106. slapi_pblock_destroy (pb);
  107. return rc;
  108. }
  109. static int
  110. changelog4_remove()
  111. {
  112. int rc= 0 /* OK */;
  113. Slapi_Backend *rbe= get_repl_backend();
  114. Slapi_PBlock *pb = slapi_pblock_new ();
  115. IFP rmdbfn = NULL;
  116. rc = slapi_be_getentrypoint (rbe, SLAPI_PLUGIN_DB_RMDB_FN, (void**)&rmdbfn, pb);
  117. if (rc != 0)
  118. {
  119. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  120. "Error: backend rmdb entry point is missing. "
  121. "Replication subsystem disabled.\n");
  122. slapi_pblock_destroy (pb);
  123. set_repl_backend( NULL );
  124. return -1;
  125. }
  126. rc = rmdbfn (pb);
  127. if (rc != 0)
  128. {
  129. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Error: the changelog database could "
  130. "not be removed. Replication subsystem disabled.\n");
  131. rc = -1;
  132. }
  133. else
  134. {
  135. slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "New database generation computed. "
  136. "Changelog database removed.\n");
  137. }
  138. slapi_pblock_destroy (pb);
  139. return rc;
  140. }
  141. static Slapi_Backend *repl_backend = NULL;
  142. Slapi_Backend
  143. *get_repl_backend()
  144. {
  145. return repl_backend;
  146. }
  147. void
  148. set_repl_backend(Slapi_Backend *be)
  149. {
  150. repl_backend = be;
  151. }
  152. int changelog4_shutdown ()
  153. {
  154. /* ONREPL - will shutdown the backend */
  155. int rc = 1;
  156. return rc;
  157. }
  158. static void changelog4_init_trimming ()
  159. {
  160. char *cl_maxage = changelog4_get_maxage ();
  161. unsigned long cl_maxentries = changelog4_get_maxentries ();
  162. time_t ageval = slapi_parse_duration(cl_maxage);
  163. slapi_ch_free ((void **)&cl_maxage);
  164. init_changelog_trimming(cl_maxentries, ageval );
  165. }
  166. /*
  167. * Function: changelog4_create_be
  168. * Arguments: none
  169. * Returns: 0 on success, non-0 on error
  170. * Description: configures changelog backend instance.
  171. */
  172. static int
  173. changelog4_create_be()
  174. {
  175. int i, dir_count = 5;
  176. Slapi_Backend *rbe;
  177. slapi_be_config config;
  178. char *cl_dir = changelog4_get_dir ();
  179. char *cl_suffix;
  180. if ( cl_dir == NULL ) {
  181. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  182. "Error: no directory specified for changelog database.\n");
  183. return -1;
  184. }
  185. cl_suffix = changelog4_get_suffix ();
  186. if ( cl_suffix == NULL ) {
  187. slapi_ch_free ((void **)&cl_dir);
  188. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  189. "Error: no suffix specified for changelog database.\n");
  190. return -1;
  191. }
  192. /* setup configuration parameters for backend initialization */
  193. config.type = CHANGELOG_LDBM_TYPE;
  194. config.suffix = cl_suffix;
  195. config.is_private = 1; /* yes */
  196. config.log_change = 0; /* no */
  197. config.directives = (slapi_config_directive*)slapi_ch_calloc(
  198. dir_count, sizeof(slapi_config_directive));
  199. config.dir_count = dir_count;
  200. for (i = 0; i < dir_count; i++)
  201. {
  202. config.directives[i].file_name = "(internal)";
  203. config.directives[i].lineno = 0;
  204. }
  205. /* setup indexes */
  206. config.directives[0].argv = NULL;
  207. config.directives[0].argc = 3;
  208. charray_add( &(config.directives[0].argv), slapi_ch_strdup( "index" ));
  209. charray_add( &(config.directives[0].argv), slapi_ch_strdup( attr_changenumber ));
  210. charray_add( &(config.directives[0].argv), slapi_ch_strdup( "eq" ));
  211. /* Set up the database directory */
  212. config.directives[1].argv = NULL;
  213. config.directives[1].argc = 2;
  214. charray_add( &(config.directives[1].argv), slapi_ch_strdup( "directory" ));
  215. charray_add( &(config.directives[1].argv), slapi_ch_strdup( cl_dir ));
  216. /* Override the entry cache size */
  217. config.directives[2].argv = NULL;
  218. config.directives[2].argc = 2;
  219. charray_add( &(config.directives[2].argv), slapi_ch_strdup( "cachesize" ));
  220. charray_add( &(config.directives[2].argv), slapi_ch_strdup( "10" ));
  221. /* Override the database cache size */
  222. config.directives[3].argv = NULL;
  223. config.directives[3].argc = 2;
  224. charray_add( &(config.directives[3].argv), slapi_ch_strdup( "dbcachesize" ));
  225. charray_add( &(config.directives[3].argv), slapi_ch_strdup( "1000000" ));
  226. /* Override the allids threshold */
  227. config.directives[4].argv = NULL;
  228. config.directives[4].argc = 2;
  229. charray_add( &(config.directives[4].argv), slapi_ch_strdup( "allidsthreshold" ));
  230. /* assumes sizeof(int) >= 32 bits */
  231. charray_add( &(config.directives[4].argv), slapi_ch_strdup( "2147483647" ));
  232. /* rbe = slapi_be_create_instance(&config, LDBM_TYPE); */
  233. rbe= NULL;
  234. /* free memory allocated to argv */
  235. for (i = 0; i < dir_count; i++)
  236. {
  237. charray_free (config.directives[i].argv);
  238. }
  239. slapi_ch_free ((void **)&config.directives);
  240. slapi_ch_free ((void **)&cl_dir);
  241. slapi_ch_free ((void **)&cl_suffix);
  242. if (rbe == NULL)
  243. {
  244. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  245. "Error: failed to create changelog backend. "
  246. "Replication disabled.\n");
  247. return -1;
  248. }
  249. set_repl_backend (rbe);
  250. changelog4_init_trimming ();
  251. return 0;
  252. }
  253. /* Name: changelog4_start_be
  254. * Parameters: none
  255. * Return: 0 if successful, non 0 otherwise
  256. * Description: starts the changelog backend; backend must be configured
  257. * first via call to changelog4_create_be
  258. */
  259. static int
  260. changelog4_start_be ()
  261. {
  262. int rc;
  263. IFP startfn = NULL;
  264. Slapi_PBlock *pb;
  265. Slapi_Backend *rbe = get_repl_backend ();
  266. if (rbe)
  267. {
  268. pb = slapi_pblock_new();
  269. rc = slapi_be_getentrypoint(rbe, SLAPI_PLUGIN_START_FN, (void**)&startfn, pb);
  270. if (rc != 0)
  271. {
  272. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  273. "Error: backend start entry point is missing. "
  274. "Replication subsystem disabled.\n");
  275. slapi_pblock_destroy (pb);
  276. set_repl_backend( NULL );
  277. return -1;
  278. }
  279. rc = startfn (pb);
  280. slapi_pblock_destroy (pb);
  281. if (rc != 0)
  282. {
  283. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  284. "Error: Failed to start changelog backend. "
  285. "Replication subsystem disabled.\n");
  286. set_repl_backend( NULL );
  287. return -1;
  288. }
  289. }
  290. return 0;
  291. }