cl4_init.c 8.6 KB

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