| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- /** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- /* upgrade.c --- upgrade from a previous version of the database */
- #include "back-ldbm.h"
- /*
- * ldbm_compat_versions holds DBVERSION strings for all versions of the
- * database with which we are (upwards) compatible. If check_db_version
- * encounters a database with a version that is not listed in this array,
- * we display a warning message.
- */
- db_upgrade_info ldbm_version_suss[] = {
- /* for bdb/#.#/..., we don't have to put the version number in the 2nd col
- since DBVERSION keeps it */
- {BDB_IMPL, 0, 0, DBVERSION_NEW_IDL, DBVERSION_NO_UPGRADE},
- {LDBM_VERSION, 4, 2, DBVERSION_NEW_IDL, DBVERSION_NO_UPGRADE},
- {LDBM_VERSION_OLD, 4, 2, DBVERSION_OLD_IDL, DBVERSION_NO_UPGRADE},
- {LDBM_VERSION_62, 4, 2, DBVERSION_OLD_IDL, DBVERSION_NO_UPGRADE},
- {LDBM_VERSION_61, 3, 3, DBVERSION_OLD_IDL, DBVERSION_UPGRADE_3_4},
- {LDBM_VERSION_60, 3, 3, DBVERSION_OLD_IDL, DBVERSION_UPGRADE_3_4},
- {NULL,0,0}
- };
- /* clear the following flag to suppress "database files do not exist" warning
- int ldbm_warn_if_no_db = 0;
- */
- /* global LDBM version in the db home */
- int
- lookup_dbversion(char *dbversion, int flag)
- {
- int i, matched = 0;
- int rval = DBVERSION_NO_UPGRADE;
- for ( i = 0; ldbm_version_suss[i].old_version_string != NULL; ++i )
- {
- if (PL_strncasecmp(dbversion, ldbm_version_suss[i].old_version_string,
- strlen(ldbm_version_suss[i].old_version_string)) == 0)
- {
- matched = 1;
- break;
- }
- }
- if ( matched )
- {
- if ( flag & DBVERSION_TYPE )
- {
- rval |= ldbm_version_suss[i].type;
- }
- if ( flag & DBVERSION_ACTION )
- {
- int dbmajor = 0, dbminor = 0;
- if (0 == ldbm_version_suss[i].old_dbversion_major)
- {
- /* case of bdb/#.#/... */
- char *p = strchr(dbversion, '/');
- char *endp = dbversion + strlen(dbversion);
- if (NULL != p && p < endp)
- {
- char *dotp = strchr(++p, '.');
- if (NULL != dotp)
- {
- *dotp = '\0';
- dbmajor = strtol(p, (char **)NULL, 10);
- dbminor = strtol(++dotp, (char **)NULL, 10);
- }
- else
- {
- dbmajor = strtol(p, (char **)NULL, 10);
- }
- }
- }
- else
- {
- dbmajor = ldbm_version_suss[i].old_dbversion_major;
- dbminor = ldbm_version_suss[i].old_dbversion_minor;
- }
- if (dbmajor < DB_VERSION_MAJOR)
- {
- /* 3.3 -> 4.x */
- rval |= ldbm_version_suss[i].action;
- }
- else if (dbminor < DB_VERSION_MINOR)
- {
- /* 4.low -> 4.high */
- rval |= DBVERSION_UPGRADE_4_4;
- }
- }
- }
- return rval;
- }
- /*
- * this function reads the db/DBVERSION file and check
- * 1) if the db version is supported, and
- * 2) if the db version requires some migration operation
- *
- * return: 0: supported
- * DBVERSION_NOT_SUPPORTED: not supported
- *
- * action: 0: nothing is needed
- * DBVERSION_UPGRADE_3_4: db3->db4 uprev is needed
- * DBVERSION_UPGRADE_4_4: db4->db4 uprev is needed
- */
- int
- check_db_version( struct ldbminfo *li, int *action )
- {
- int value = 0;
- char *ldbmversion = NULL;
- char *dataversion = NULL;
- *action = 0;
- dbversion_read(li, li->li_directory, &ldbmversion, &dataversion);
- if (NULL == ldbmversion || '\0' == *ldbmversion) {
- slapi_ch_free_string(&dataversion);
- return 0;
- }
- value = lookup_dbversion( ldbmversion, DBVERSION_TYPE | DBVERSION_ACTION );
- if ( !value )
- {
- LDAPDebug( LDAP_DEBUG_ANY,
- "ERROR: Database version mismatch (expecting "
- "'%s' but found '%s' in directory %s)\n",
- LDBM_VERSION, ldbmversion, li->li_directory );
- /*
- * A non-zero return here will cause slapd to exit during startup.
- */
- slapi_ch_free_string(&ldbmversion);
- slapi_ch_free_string(&dataversion);
- return DBVERSION_NOT_SUPPORTED;
- }
- if ( value & DBVERSION_UPGRADE_3_4 )
- {
- dblayer_set_recovery_required(li);
- *action = DBVERSION_UPGRADE_3_4;
- }
- else if ( value & DBVERSION_UPGRADE_4_4 )
- {
- dblayer_set_recovery_required(li);
- *action = DBVERSION_UPGRADE_4_4;
- }
- slapi_ch_free_string(&ldbmversion);
- slapi_ch_free_string(&dataversion);
- return 0;
- }
- /*
- * this function reads the db/<inst>/DBVERSION file and check
- * 1) if the db version is supported, and
- * 2) if the db version matches the idl configuration
- * (nsslapd-idl-switch: new|old)
- * note that old idl will disappear from the next major update (6.5? 7.0?)
- *
- * return: 0: supported and the version matched
- * DBVERSION_NEED_IDL_OLD2NEW: old->new uprev is needed
- * (used in convindices)
- * DBVERSION_NEED_IDL_NEW2OLD: old db is found, for the new idl config
- * DBVERSION_NOT_SUPPORTED: not supported
- *
- * DBVERSION_UPGRADE_3_4: db3->db4 uprev is needed
- * DBVERSION_UPGRADE_4_4: db4->db4 uprev is needed
- */
- int
- check_db_inst_version( ldbm_instance *inst )
- {
- int value = 0;
- char *ldbmversion = NULL;
- char *dataversion = NULL;
- int rval = 0;
- char inst_dir[MAXPATHLEN*2];
- char *inst_dirp = NULL;
- inst_dirp =
- dblayer_get_full_inst_dir(inst->inst_li, inst, inst_dir, MAXPATHLEN*2);
- dbversion_read(inst->inst_li, inst_dirp, &ldbmversion, &dataversion);
- if (NULL == ldbmversion || '\0' == *ldbmversion) {
- return rval;
- }
-
- value = lookup_dbversion( ldbmversion, DBVERSION_TYPE | DBVERSION_ACTION );
- if ( !value )
- {
- LDAPDebug( LDAP_DEBUG_ANY,
- "ERROR: Database version mismatch (expecting "
- "'%s' but found '%s' in directory %s)\n",
- LDBM_VERSION, ldbmversion, inst->inst_dir_name );
- /*
- * A non-zero return here will cause slapd to exit during startup.
- */
- slapi_ch_free_string(&ldbmversion);
- slapi_ch_free_string(&dataversion);
- return DBVERSION_NOT_SUPPORTED;
- }
- /* recognize the difference between an old/new database regarding idl
- * (406922) */
- if (idl_get_idl_new() && !(value & DBVERSION_NEW_IDL) )
- {
- rval |= DBVERSION_NEED_IDL_OLD2NEW;
- }
- else if (!idl_get_idl_new() && !(value & DBVERSION_OLD_IDL) )
- {
- rval |= DBVERSION_NEED_IDL_NEW2OLD;
- }
- if ( value & DBVERSION_UPGRADE_3_4 )
- {
- rval |= DBVERSION_UPGRADE_3_4;
- }
- else if ( value & DBVERSION_UPGRADE_4_4 )
- {
- rval |= DBVERSION_UPGRADE_4_4;
- }
- if (inst_dirp != inst_dir)
- slapi_ch_free_string(&inst_dirp);
- slapi_ch_free_string(&ldbmversion);
- slapi_ch_free_string(&dataversion);
- return rval;
- }
- /*
- * adjust_idl_switch
- * if the current nsslapd-idl-switch is different from ldbmversion,
- * update the value of nsslapd-idl-switch (in LDBM_CONFIG_ENTRY)
- */
- int
- adjust_idl_switch(char *ldbmversion, struct ldbminfo *li)
- {
- int rval = 0;
- li->li_flags |= LI_FORCE_MOD_CONFIG;
- if ((0 == PL_strncasecmp(ldbmversion, BDB_IMPL, strlen(BDB_IMPL))) ||
- (0 == PL_strcmp(ldbmversion, LDBM_VERSION))) /* db: new idl */
- {
- if (!idl_get_idl_new()) /* config: old idl */
- {
- replace_ldbm_config_value(CONFIG_IDL_SWITCH, "new", li);
- LDAPDebug(LDAP_DEBUG_ANY,
- "Warning: Dbversion %s does not meet nsslapd-idl-switch: \"old\"; "
- "nsslapd-idl-switch is updated to \"new\"\n",
- ldbmversion, 0, 0);
- }
- }
- else if ((0 == strcmp(ldbmversion, LDBM_VERSION_OLD)) ||
- (0 == PL_strcmp(ldbmversion, LDBM_VERSION_61)) ||
- (0 == PL_strcmp(ldbmversion, LDBM_VERSION_62)) ||
- (0 == strcmp(ldbmversion, LDBM_VERSION_60))) /* db: old */
- {
- if (idl_get_idl_new()) /* config: new */
- {
- replace_ldbm_config_value(CONFIG_IDL_SWITCH, "old", li);
- LDAPDebug(LDAP_DEBUG_ANY,
- "Warning: Dbversion %s does not meet nsslapd-idl-switch: \"new\"; "
- "nsslapd-idl-switch is updated to \"old\"\n",
- ldbmversion, 0, 0);
- }
- }
- else
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "Warning: Dbversion %s is not supported\n",
- ldbmversion, 0, 0);
- rval = 1;
- }
- /* ldbminfo is a common resource; should clean up when the job is done */
- li->li_flags &= ~LI_FORCE_MOD_CONFIG;
- return rval;
- }
- /* Do the work to upgrade a database if needed */
- /* When we're called, the database files have been opened, and any
- recovery needed has been performed. */
- int ldbm_upgrade(ldbm_instance *inst, int action)
- {
- int rval = 0;
- if (0 == action)
- {
- return rval;
- }
- if (action & DBVERSION_UPGRADE_3_4) /* upgrade from db3 to db4 */
- {
- /* basically, db4 supports db3.
- * so, what we need to do is rename XXX.db3 to XXX.db4 */
- int rval = dblayer_update_db_ext(inst, LDBM_SUFFIX_OLD, LDBM_SUFFIX);
- if (0 == rval)
- {
- if (idl_get_idl_new())
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ldbm_upgrade: Upgrading instance %s to %s%s is successfully done.\n",
- inst->inst_name, LDBM_VERSION_BASE, PACKAGE_VERSION);
- }
- else
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ldbm_upgrade: Upgrading instance %s to %s%s is successfully done.\n",
- inst->inst_name, LDBM_VERSION_OLD, 0);
- }
- }
- else
- {
- /* recovery effort ... */
- dblayer_update_db_ext(inst, LDBM_SUFFIX, LDBM_SUFFIX_OLD);
- return rval;
- }
- }
- return 0; /* Means that the database is new */
- }
- /* Here's the upgrade process :
- Delete all the keys from the parentid index
- Scan the id2entry file:
- Remove any hassubordinates attribute present
- Update the parentid index, maintaining a hash of high-count parents
- Scan the newly created parentid index updating the subordinatecount attributes.
- Most of the functionality is implemented in the import code.
- */
- #if 0
- static int upgrade_db_3x_40(backend *be)
- {
- struct ldbminfo *li = (struct ldbminfo *) be->be_database->plg_private;
- int ret = 0;
- back_txn txn;
- static char* indexes_modified[] = {"parentid", "numsubordinates", NULL};
- LDAPDebug( LDAP_DEBUG_ANY, "WARNING: Detected a database older than this server, upgrading data...\n",0,0,0);
- dblayer_txn_init(li,&txn);
- ret = dblayer_txn_begin(li,NULL,&txn);
- if (0 != ret) {
- ldbm_nasty(filename,69,ret);
- goto error;
- }
- ret = indexfile_delete_all_keys(be,"parentid",&txn);
- if (0 != ret) {
- ldbm_nasty(filename,70,ret);
- goto error;
- }
- {
- Slapi_Mods smods;
- slapi_mods_init(&smods,1);
- /* Mods are to remove the hassubordinates attribute */
- slapi_mods_add(&smods, LDAP_MOD_DELETE, "hassubordinates", 0, NULL);
- /* This function takes care of generating the subordinatecount attribute and indexing it */
- ret = indexfile_primary_modifyall(be,slapi_mods_get_ldapmods_byref(&smods),indexes_modified,&txn);
- slapi_mods_done(&smods);
- }
- if (0 != ret) {
- ldbm_nasty(filename,61,ret);
- }
- error:
- if (0 != ret ) {
- dblayer_txn_abort(li,&txn);
- } else {
- ret = dblayer_txn_commit(li,&txn);
- if (0 != ret) {
- ldbm_nasty(filename,60,ret);
- } else {
- /* Now update DBVERSION file */
- }
- }
- if (0 == ret) {
- LDAPDebug( LDAP_DEBUG_ANY, "...upgrade complete.\n",0,0,0);
- } else {
- LDAPDebug( LDAP_DEBUG_ANY, "ERROR: Attempt to upgrade the older database FAILED.\n",0,0,0);
- }
- return ret;
- }
- #endif
|