start.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /*
  42. * start.c
  43. */
  44. #include "back-ldbm.h"
  45. /*
  46. * Start the LDBM plugin, and all its instances.
  47. */
  48. int
  49. ldbm_back_start( Slapi_PBlock *pb )
  50. {
  51. struct ldbminfo *li;
  52. static int initialized = 0;
  53. char *home_dir;
  54. int action;
  55. int retval;
  56. LDAPDebug( LDAP_DEBUG_TRACE, "ldbm backend starting\n", 0, 0, 0 );
  57. slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
  58. /* parse the config file here */
  59. if (0 != ldbm_config_load_dse_info(li)) {
  60. LDAPDebug( LDAP_DEBUG_ANY, "start: Loading database configuration failed\n",
  61. 0, 0, 0 );
  62. return SLAPI_FAIL_GENERAL;
  63. }
  64. /* register with the binder-based resource limit subsystem so that */
  65. /* lookthroughlimit can be supported on a per-connection basis. */
  66. if ( slapi_reslimit_register( SLAPI_RESLIMIT_TYPE_INT,
  67. LDBM_LOOKTHROUGHLIMIT_AT, &li->li_reslimit_lookthrough_handle )
  68. != SLAPI_RESLIMIT_STATUS_SUCCESS ) {
  69. LDAPDebug( LDAP_DEBUG_ANY, "start: Resource limit registration failed\n",
  70. 0, 0, 0 );
  71. return SLAPI_FAIL_GENERAL;
  72. }
  73. /* If the db directory hasn't been set yet, we need to set it to
  74. * the default. */
  75. if (NULL == li->li_directory || '\0' == li->li_directory[0]) {
  76. /* "get default" is a special string that tells the config
  77. * routines to figure out the default db directory by
  78. * reading cn=config. */
  79. ldbm_config_internal_set(li, CONFIG_DIRECTORY, "get default");
  80. }
  81. /* sanity check the autosizing values,
  82. no value or sum of values larger than 100.
  83. */
  84. if ( (li->li_cache_autosize > 100) ||
  85. (li->li_cache_autosize_split > 100) ||
  86. (li->li_import_cache_autosize > 100) ||
  87. ((li->li_cache_autosize > 0) && (li->li_import_cache_autosize > 0) &&
  88. (li->li_cache_autosize + li->li_import_cache_autosize > 100)) )
  89. {
  90. LDAPDebug( LDAP_DEBUG_ANY, "cache autosizing: bad settings, "
  91. "value or sum of values can not larger than 100.\n", 0, 0, 0 );
  92. } else
  93. /* if cache autosize was selected, select the cache sizes now */
  94. if ((li->li_cache_autosize > 0) || (li->li_import_cache_autosize > 0)) {
  95. size_t pagesize, pages, procpages, availpages;
  96. dblayer_sys_pages(&pagesize, &pages, &procpages, &availpages);
  97. if (pagesize) {
  98. char s[32]; /* big enough to hold %ld */
  99. unsigned long cache_size_to_configure = 0;
  100. int zone_pages, db_pages, entry_pages, import_pages;
  101. Object *inst_obj;
  102. ldbm_instance *inst;
  103. /* autosizing dbCache and entryCache */
  104. if (li->li_cache_autosize > 0) {
  105. zone_pages = (li->li_cache_autosize * pages) / 100;
  106. /* now split it according to user prefs */
  107. db_pages = (li->li_cache_autosize_split * zone_pages) / 100;
  108. /* fudge an extra instance into our calculations... */
  109. entry_pages = (zone_pages - db_pages) /
  110. (objset_size(li->li_instance_set) + 1);
  111. LDAPDebug(LDAP_DEBUG_ANY, "cache autosizing. found %dk physical memory\n",
  112. pages*(pagesize/1024), 0, 0);
  113. LDAPDebug(LDAP_DEBUG_ANY, "cache autosizing: db cache: %dk, "
  114. "each entry cache (%d total): %dk\n",
  115. db_pages*(pagesize/1024), objset_size(li->li_instance_set),
  116. entry_pages*(pagesize/1024));
  117. /* libdb allocates 1.25x the amount we tell it to, but only for values < 500Meg */
  118. if (cache_size_to_configure < (500 * MEGABYTE)) {
  119. cache_size_to_configure = (unsigned long)((db_pages * pagesize) / 1.25);
  120. } else {
  121. cache_size_to_configure = (unsigned long)(db_pages * pagesize);
  122. }
  123. sprintf(s, "%lu", cache_size_to_configure);
  124. ldbm_config_internal_set(li, CONFIG_DBCACHESIZE, s);
  125. li->li_cache_autosize_ec = (unsigned long)entry_pages * pagesize;
  126. for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
  127. inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
  128. inst = (ldbm_instance *)object_get_data(inst_obj);
  129. cache_set_max_entries(&(inst->inst_cache), -1);
  130. cache_set_max_size(&(inst->inst_cache), li->li_cache_autosize_ec);
  131. }
  132. }
  133. /* autosizing importCache */
  134. if (li->li_import_cache_autosize > 0) {
  135. /* For some reason, -1 means 50 ... */
  136. if (li->li_import_cache_autosize == -1) {
  137. li->li_import_cache_autosize = 50;
  138. }
  139. import_pages = (li->li_import_cache_autosize * pages) / 100;
  140. LDAPDebug(LDAP_DEBUG_ANY, "cache autosizing: import cache: %dk \n",
  141. import_pages*(pagesize/1024), NULL, NULL);
  142. sprintf(s, "%lu", (unsigned long)(import_pages * pagesize));
  143. ldbm_config_internal_set(li, CONFIG_IMPORT_CACHESIZE, s);
  144. }
  145. }
  146. }
  147. retval = check_db_version(li, &action);
  148. if (0 != retval)
  149. {
  150. LDAPDebug( LDAP_DEBUG_ANY, "start: db version is not supported\n",
  151. 0, 0, 0);
  152. return SLAPI_FAIL_GENERAL;
  153. }
  154. if (action & (DBVERSION_UPGRADE_3_4|DBVERSION_UPGRADE_4_4))
  155. {
  156. retval = dblayer_start(li,DBLAYER_CLEAN_RECOVER_MODE);
  157. }
  158. else
  159. {
  160. retval = dblayer_start(li,DBLAYER_NORMAL_MODE);
  161. }
  162. if (0 != retval) {
  163. char *msg;
  164. LDAPDebug( LDAP_DEBUG_ANY, "start: Failed to init database, err=%d %s\n",
  165. retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
  166. if (LDBM_OS_ERR_IS_DISKFULL(retval)) return return_on_disk_full(li);
  167. else return SLAPI_FAIL_GENERAL;
  168. }
  169. /* Walk down the instance list, starting all the instances. */
  170. retval = ldbm_instance_startall(li);
  171. if (0 != retval) {
  172. char *msg;
  173. LDAPDebug( LDAP_DEBUG_ANY, "start: Failed to start databases, err=%d %s\n",
  174. retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
  175. if (LDBM_OS_ERR_IS_DISKFULL(retval)) return return_on_disk_full(li);
  176. else {
  177. if ((li->li_cache_autosize > 0) && (li->li_cache_autosize <= 100)) {
  178. LDAPDebug( LDAP_DEBUG_ANY, "Failed to allocate %d byte dbcache. "
  179. "Please reduce the value of %s and restart the server.\n",
  180. li->li_dbcachesize, CONFIG_CACHE_AUTOSIZE, 0);
  181. } else {
  182. LDAPDebug( LDAP_DEBUG_ANY, "Failed to allocate %d byte dbcache. "
  183. "Please reduce %s and Restart the server.\n",
  184. li->li_dbcachesize, CONFIG_CACHE_AUTOSIZE, 0);
  185. }
  186. return SLAPI_FAIL_GENERAL;
  187. }
  188. }
  189. /* write DBVERSION file if one does not exist */
  190. home_dir = dblayer_get_home_dir(li, NULL);
  191. if (!dbversion_exists(li, home_dir))
  192. {
  193. dbversion_write (li, home_dir, NULL);
  194. }
  195. /* this function is called every time new db is initialized */
  196. /* currently it is called the 2nd time when changelog db is */
  197. /* dynamically created. Code below should only be called once */
  198. if (!initialized)
  199. {
  200. ldbm_compute_init();
  201. initialized = 1;
  202. }
  203. /* initialize the USN counter */
  204. ldbm_usn_init(li);
  205. LDAPDebug( LDAP_DEBUG_TRACE, "ldbm backend done starting\n", 0, 0, 0 );
  206. return( 0 );
  207. }