cl4_init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. /* cl4_init.c - implments initialization/cleanup functions for
  39. 4.0 style changelog
  40. */
  41. #include <string.h>
  42. #include "slapi-plugin.h"
  43. #include "cl4.h"
  44. #include "repl.h"
  45. /* forward declarations */
  46. static int changelog4_create_be();
  47. static int changelog4_start_be ();
  48. static int changelog4_close();
  49. static int changelog4_remove();
  50. /*
  51. * Initialise the 4.0 Changelog
  52. */
  53. int changelog4_init ()
  54. {
  55. int rc= 0; /* OK */
  56. Slapi_Backend *rbe;
  57. changeNumber first_change = 0UL, last_change = 0UL;
  58. int lderr;
  59. if (changelog4_create_be() < 0 )
  60. {
  61. rc= -1;
  62. }
  63. else
  64. {
  65. rc = changelog4_start_be ();
  66. }
  67. if(rc == 0)
  68. {
  69. rbe = get_repl_backend();
  70. if(rbe!=NULL)
  71. {
  72. /* We have a Change Log. Check it's valid. */
  73. /* changelog has to be started before its
  74. data version can be read */
  75. const char *sdv= get_server_dataversion();
  76. const char *cdv= get_changelog_dataversion();
  77. char *suffix = changelog4_get_suffix ();
  78. if(!cdv || strcmp(sdv,cdv)!=0)
  79. {
  80. /* The SDV and CDV are not the same. The Change Log is invalid.
  81. It must be removed. */
  82. /* ONREPL - currently we go through this code when the changelog
  83. is first created because we can't tell new backend from the
  84. existing one.*/
  85. rc = changelog4_close();
  86. rc = changelog4_remove();
  87. /* now restart the changelog */
  88. changelog4_start_be ();
  89. create_entity( suffix, "extensibleobject");
  90. /* Write the Server Data Version onto the changelog suffix entry */
  91. /* JCMREPL - And the changelog database version number */
  92. set_changelog_dataversion(sdv);
  93. slapi_ch_free ((void **)&suffix);
  94. }
  95. }
  96. }
  97. if(rc != 0)
  98. {
  99. slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name,
  100. "An error occurred configuring the changelog database\n" );
  101. }
  102. first_change = replog_get_firstchangenum( &lderr );
  103. last_change = replog_get_lastchangenum( &lderr );
  104. ldapi_initialize_changenumbers( first_change, last_change );
  105. return rc;
  106. }
  107. static int
  108. changelog4_close()
  109. {
  110. int rc= 0 /* OK */;
  111. Slapi_Backend *rbe= get_repl_backend();
  112. Slapi_PBlock *pb = slapi_pblock_new ();
  113. IFP closefn = NULL;
  114. rc = slapi_be_getentrypoint (rbe, SLAPI_PLUGIN_CLOSE_FN, (void**)&closefn, pb);
  115. if (rc != 0)
  116. {
  117. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  118. "Error: backend close entry point is missing. "
  119. "Replication subsystem disabled.\n");
  120. slapi_pblock_destroy (pb);
  121. set_repl_backend( NULL );
  122. return -1;
  123. }
  124. rc = closefn (pb);
  125. if (rc != 0)
  126. {
  127. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Error: the changelog database could "
  128. "not be closed. Replication subsystem disabled.\n");
  129. set_repl_backend( NULL );
  130. rc = -1;
  131. }
  132. slapi_pblock_destroy (pb);
  133. return rc;
  134. }
  135. static int
  136. changelog4_remove()
  137. {
  138. int rc= 0 /* OK */;
  139. Slapi_Backend *rbe= get_repl_backend();
  140. Slapi_PBlock *pb = slapi_pblock_new ();
  141. IFP rmdbfn = NULL;
  142. rc = slapi_be_getentrypoint (rbe, SLAPI_PLUGIN_DB_RMDB_FN, (void**)&rmdbfn, pb);
  143. if (rc != 0)
  144. {
  145. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  146. "Error: backend rmdb entry point is missing. "
  147. "Replication subsystem disabled.\n");
  148. slapi_pblock_destroy (pb);
  149. set_repl_backend( NULL );
  150. return -1;
  151. }
  152. rc = rmdbfn (pb);
  153. if (rc != 0)
  154. {
  155. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Error: the changelog database could "
  156. "not be removed. Replication subsystem disabled.\n");
  157. rc = -1;
  158. }
  159. else
  160. {
  161. slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "New database generation computed. "
  162. "Changelog database removed.\n");
  163. }
  164. slapi_pblock_destroy (pb);
  165. return rc;
  166. }
  167. static Slapi_Backend *repl_backend = NULL;
  168. Slapi_Backend
  169. *get_repl_backend()
  170. {
  171. return repl_backend;
  172. }
  173. void
  174. set_repl_backend(Slapi_Backend *be)
  175. {
  176. repl_backend = be;
  177. }
  178. int changelog4_shutdown ()
  179. {
  180. /* ONREPL - will shutdown the backend */
  181. int rc = 1;
  182. return rc;
  183. }
  184. static void changelog4_init_trimming ()
  185. {
  186. char *cl_maxage = changelog4_get_maxage ();
  187. unsigned long cl_maxentries = changelog4_get_maxentries ();
  188. time_t ageval = age_str2time (cl_maxage);
  189. slapi_ch_free ((void **)&cl_maxage);
  190. init_changelog_trimming(cl_maxentries, ageval );
  191. }
  192. /*
  193. * Function: changelog4_create_be
  194. * Arguments: none
  195. * Returns: 0 on success, non-0 on error
  196. * Description: configures changelog backend instance.
  197. */
  198. static int
  199. changelog4_create_be()
  200. {
  201. int i, dir_count = 5;
  202. Slapi_Backend *rbe;
  203. slapi_be_config config;
  204. char *cl_dir = changelog4_get_dir ();
  205. char *cl_suffix;
  206. if ( cl_dir == NULL ) {
  207. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  208. "Error: no directory specified for changelog database.\n");
  209. return -1;
  210. }
  211. cl_suffix = changelog4_get_suffix ();
  212. if ( cl_suffix == NULL ) {
  213. slapi_ch_free ((void **)&cl_dir);
  214. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  215. "Error: no suffix specified for changelog database.\n");
  216. return -1;
  217. }
  218. /* setup configuration parameters for backend initialization */
  219. config.type = CHANGELOG_LDBM_TYPE;
  220. config.suffix = cl_suffix;
  221. config.is_private = 1; /* yes */
  222. config.log_change = 0; /* no */
  223. config.directives = (slapi_config_directive*)slapi_ch_calloc(
  224. dir_count, sizeof(slapi_config_directive));
  225. config.dir_count = dir_count;
  226. for (i = 0; i < dir_count; i++)
  227. {
  228. config.directives[i].file_name = "(internal)";
  229. config.directives[i].lineno = 0;
  230. }
  231. /* setup indexes */
  232. config.directives[0].argv = NULL;
  233. config.directives[0].argc = 3;
  234. charray_add( &(config.directives[0].argv), slapi_ch_strdup( "index" ));
  235. charray_add( &(config.directives[0].argv), slapi_ch_strdup( attr_changenumber ));
  236. charray_add( &(config.directives[0].argv), slapi_ch_strdup( "eq" ));
  237. /* Set up the database directory */
  238. config.directives[1].argv = NULL;
  239. config.directives[1].argc = 2;
  240. charray_add( &(config.directives[1].argv), slapi_ch_strdup( "directory" ));
  241. charray_add( &(config.directives[1].argv), slapi_ch_strdup( cl_dir ));
  242. /* Override the entry cache size */
  243. config.directives[2].argv = NULL;
  244. config.directives[2].argc = 2;
  245. charray_add( &(config.directives[2].argv), slapi_ch_strdup( "cachesize" ));
  246. charray_add( &(config.directives[2].argv), slapi_ch_strdup( "10" ));
  247. /* Override the database cache size */
  248. config.directives[3].argv = NULL;
  249. config.directives[3].argc = 2;
  250. charray_add( &(config.directives[3].argv), slapi_ch_strdup( "dbcachesize" ));
  251. charray_add( &(config.directives[3].argv), slapi_ch_strdup( "1000000" ));
  252. /* Override the allids threshold */
  253. config.directives[4].argv = NULL;
  254. config.directives[4].argc = 2;
  255. charray_add( &(config.directives[4].argv), slapi_ch_strdup( "allidsthreshold" ));
  256. /* assumes sizeof(int) >= 32 bits */
  257. charray_add( &(config.directives[4].argv), slapi_ch_strdup( "2147483647" ));
  258. /* rbe = slapi_be_create_instance(&config, LDBM_TYPE); */
  259. rbe= NULL;
  260. /* free memory allocated to argv */
  261. for (i = 0; i < dir_count; i++)
  262. {
  263. charray_free (config.directives[i].argv);
  264. }
  265. slapi_ch_free ((void **)&config.directives);
  266. slapi_ch_free ((void **)&cl_dir);
  267. slapi_ch_free ((void **)&cl_suffix);
  268. if (rbe == NULL)
  269. {
  270. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  271. "Error: failed to create changelog backend. "
  272. "Replication disabled.\n");
  273. return -1;
  274. }
  275. set_repl_backend (rbe);
  276. changelog4_init_trimming ();
  277. return 0;
  278. }
  279. /* Name: changelog4_start_be
  280. * Parameters: none
  281. * Return: 0 if successful, non 0 otherwise
  282. * Description: starts the changelog backend; backend must be configured
  283. * first via call to changelog4_create_be
  284. */
  285. static int
  286. changelog4_start_be ()
  287. {
  288. int rc;
  289. IFP startfn = NULL;
  290. Slapi_PBlock *pb;
  291. Slapi_Backend *rbe = get_repl_backend ();
  292. if (rbe)
  293. {
  294. pb = slapi_pblock_new();
  295. rc = slapi_be_getentrypoint(rbe, SLAPI_PLUGIN_START_FN, (void**)&startfn, pb);
  296. if (rc != 0)
  297. {
  298. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  299. "Error: backend start entry point is missing. "
  300. "Replication subsystem disabled.\n");
  301. slapi_pblock_destroy (pb);
  302. set_repl_backend( NULL );
  303. return -1;
  304. }
  305. rc = startfn (pb);
  306. slapi_pblock_destroy (pb);
  307. if (rc != 0)
  308. {
  309. slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name,
  310. "Error: Failed to start changelog backend. "
  311. "Replication subsystem disabled.\n");
  312. set_repl_backend( NULL );
  313. return -1;
  314. }
  315. }
  316. return 0;
  317. }