diff options
author | Noriko Hosoi <nhosoi@redhat.com> | 2010-09-12 21:59:29 -0700 |
---|---|---|
committer | Noriko Hosoi <nhosoi@redhat.com> | 2010-09-13 10:06:51 -0700 |
commit | 80ce631a97977c273a56b5d4d7e99a7eaf109d57 (patch) | |
tree | 75207bb0b02a57485d87efedabfcc2fe243eeb06 /ldap/servers/slapd/back-ldbm | |
parent | 2a25e6518f6e2bd83dd4750bf023d332edef2063 (diff) | |
download | ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.tar.gz ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.tar.xz ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.zip |
Bug 633168 - Share backend dbEnv with the replication changelog
https://bugzilla.redhat.com/show_bug.cgi?id=633168
Description:
* cl5_api.c, cl5_api.h
- fetches dbEnv from backend using slapi_back_get_info.
- unused macros and DB helper functions and APIs are removed.
* cl5_config.c
- local changelog DB related config parameters are removed.
* Added SLAPI_PLUGIN_BE_PRE_CLOSE_FN and SLAPI_PLUGIN_BE_POST_OPEN_FN to
close changelog DB before dbEnv is closed and to open changelog DB after
dbEnv is opened, respectively.
* Added slapi APIs slapi_back_get_info and slapi_back_set_info to get/set
the backend info.
* back-ldbm
- db2bak[.pl] and bak2db[.pl] backs up and restores the database files
including changelog db.
- changelog dir is backed up in <backupdir>/.repl_changelog_backup.
- underlying implementation ldbm_back_get_info for slapi_back_get_info
is added.
* Added an upgrade script 81changelog.pl
See also:
http://directory.fedoraproject.org/wiki/Move_changelog
Diffstat (limited to 'ldap/servers/slapd/back-ldbm')
-rw-r--r-- | ldap/servers/slapd/back-ldbm/archive.c | 45 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/back-ldbm.h | 4 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/dblayer.c | 705 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/dblayer.h | 4 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/import-threads.c | 37 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/init.c | 4 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/ldbm_modify.c | 2 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 31 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/misc.c | 26 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 5 |
10 files changed, 605 insertions, 258 deletions
diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c index edaa5edf..545a4b0c 100644 --- a/ldap/servers/slapd/back-ldbm/archive.c +++ b/ldap/servers/slapd/back-ldbm/archive.c @@ -151,7 +151,7 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb ) } } - /* now take down ALL BACKENDS */ + /* now take down ALL BACKENDS and changelog */ for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj; inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) { inst = (ldbm_instance *)object_get_data(inst_obj); @@ -167,6 +167,7 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb ) cache_clear(&inst->inst_dncache, CACHE_TYPE_DN); } } + plugin_call_plugins (pb, SLAPI_PLUGIN_BE_PRE_CLOSE_FN); /* now we know nobody's using any of the backend instances, so we * can shutdown the dblayer -- this closes all instances too. * Use DBLAYER_RESTORE_MODE to prevent loss of perfctr memory. @@ -246,7 +247,8 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb ) goto out; } } - /* bring all backends back online */ + /* bring all backends and changelog back online */ + plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_OPEN_FN); for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj; inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) { inst = (ldbm_instance *)object_get_data(inst_obj); @@ -316,8 +318,6 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb ) directory = rel2abspath(rawdirectory); if (stat(directory, &sbuf) == 0) { - int baklen = 0; - if (slapd_comp_path(directory, li->li_directory) == 0) { LDAPDebug(LDAP_DEBUG_ANY, "db2archive: Cannot archive to the db directory.\n", 0, 0, 0); @@ -329,9 +329,7 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb ) goto out; } - baklen = strlen(directory) + 5; /* ".bak\0" */ - dir_bak = slapi_ch_malloc(baklen); - PR_snprintf(dir_bak, baklen, "%s.bak", directory); + dir_bak = slapi_ch_smprintf("%s.bak", directory); LDAPDebug(LDAP_DEBUG_ANY, "db2archive: %s exists. Renaming to %s\n", directory, dir_bak, 0); if (task) { @@ -442,22 +440,33 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb ) } } err: - if (return_value != 0) { - LDAPDebug(LDAP_DEBUG_ANY, "db2archive: Rename %s back to %s\n", - dir_bak, directory, 0); - if (task) { - slapi_task_log_notice(task, "Rename %s back to %s", - dir_bak, directory); + if (return_value) { + if (dir_bak) { + LDAPDebug2Args(LDAP_DEBUG_ANY, + "db2archive failed: renaming %s back to %s\n", + dir_bak, directory); + if (task) { + slapi_task_log_notice(task, + "db2archive failed: renaming %s back to %s", + dir_bak, directory); + } + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "db2archive failed: removing %s\n", directory); + if (task) { + slapi_task_log_notice(task, "db2archive failed: removing %s", + directory); + } } ldbm_delete_dirs(directory); - if (PR_SUCCESS != PR_Rename(dir_bak, directory)) { + if (dir_bak && (PR_SUCCESS != PR_Rename(dir_bak, directory))) { PRErrorCode prerr = PR_GetError(); - LDAPDebug(LDAP_DEBUG_ANY, + LDAPDebug2Args(LDAP_DEBUG_ANY, "db2archive: Failed to rename \"%s\" to \"%s\".\n", - dir_bak, directory, 0); - LDAPDebug(LDAP_DEBUG_ANY, + dir_bak, directory); + LDAPDebug2Args(LDAP_DEBUG_ANY, SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", - prerr, slapd_pr_strerror(prerr), 0); + prerr, slapd_pr_strerror(prerr)); if (task) { slapi_task_log_notice(task, "Failed to rename \"%s\" to \"%s\".", diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index f4a6f434..29d18458 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -844,4 +844,8 @@ typedef struct _back_search_result_set /* Initial entryusn value */ #define INITIALUSN (PRUint64)(-1) +/* changelog backup dir name + * starting with '.' to reduce the risk to match an ordinary backend name */ +#define CHANGELOG_BACKUPDIR ".repl_changelog_backup" + #endif /* _back_ldbm_h_ */ diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index a17ba5ce..cd388c9b 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -4320,6 +4320,50 @@ static int dblayer_force_checkpoint(struct ldbminfo *li) return ret; } +static int +_dblayer_delete_aux_dir(struct ldbminfo *li, char *path) +{ + PRDir *dirhandle = NULL; + PRDirEntry *direntry = NULL; + char filename[MAXPATHLEN]; + dblayer_private *priv = NULL; + struct dblayer_private_env *pEnv = NULL; + int rc = -1; + + if (NULL == li || NULL == path) { + LDAPDebug2Args(LDAP_DEBUG_ANY, + "_dblayer_delete_aux_dir: Invalid LDBM info (0x%x) " + "or path (0x%x)\n", li, path); + return rc; + } + priv = (dblayer_private*)li->li_dblayer_private; + if (priv) { + pEnv = priv->dblayer_env; + } + dirhandle = PR_OpenDir(path); + if (!dirhandle) { + return 0; /* The dir does not exist. */ + } + while (NULL != (direntry = PR_ReadDir(dirhandle, + PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { + if (! direntry->name) + break; + PR_snprintf(filename, sizeof(filename), "%s/%s", path, direntry->name); + if (pEnv && + strcmp(LDBM_FILENAME_SUFFIX , last_four_chars(direntry->name)) == 0) + { + rc = dblayer_db_remove_ex(pEnv, filename, 0, PR_TRUE); + } + else + { + rc = ldbm_delete_dirs(filename); + } + } + PR_CloseDir(dirhandle); + PR_RmDir(path); + return rc; +} + /* TEL: Added startdb flag. If set (1), the DB environment will be started so * that dblayer_db_remove_ex will be used to remove the database files instead * of simply deleting them. That is important when doing a selective restoration @@ -4339,7 +4383,8 @@ static int _dblayer_delete_instance_dir(ldbm_instance *inst, int startdb) if (NULL == li) { - LDAPDebug(LDAP_DEBUG_ANY, "_dblayer_delete_instance_dir: NULL LDBM info\n", 0, 0, 0); + LDAPDebug0Args(LDAP_DEBUG_ANY, + "_dblayer_delete_instance_dir: NULL LDBM info\n"); rval = -1; goto done; } @@ -4461,7 +4506,8 @@ int dblayer_delete_instance_dir(backend *be) * this is used mostly for restores. * dblayer is assumed to be closed. */ -int dblayer_delete_database_ex(struct ldbminfo *li, char *instance) +static int +dblayer_delete_database_ex(struct ldbminfo *li, char *instance, char *cldir) { dblayer_private *priv = NULL; Object *inst_obj; @@ -4504,6 +4550,17 @@ int dblayer_delete_database_ex(struct ldbminfo *li, char *instance) } } + /* changelog path is given; delete it, too. */ + if (cldir) { + ret = _dblayer_delete_aux_dir(li, cldir); + if (ret) { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "dblayer_delete_database: failed to deelete \"%s\"\n", + chdir); + return ret; + } + } + /* now smash everything else in the db/ dir */ dirhandle = PR_OpenDir(priv->dblayer_home_directory); if (! dirhandle) @@ -4567,7 +4624,7 @@ int dblayer_delete_database_ex(struct ldbminfo *li, char *instance) */ int dblayer_delete_database(struct ldbminfo *li) { - return dblayer_delete_database_ex(li, NULL); + return dblayer_delete_database_ex(li, NULL, NULL); } @@ -4830,7 +4887,6 @@ dblayer_copy_directory(struct ldbminfo *li, char *inst_dirp = NULL; char inst_dir[MAXPATHLEN]; char sep; - ldbm_instance *inst; if (!src_dir || '\0' == *src_dir) { @@ -4854,15 +4910,6 @@ dblayer_copy_directory(struct ldbminfo *li, else relative_instance_name++; - inst = ldbm_instance_find_by_name(li, relative_instance_name); - if (NULL == inst) - { - LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; " - "Instance path %s could be invalid.\n", - relative_instance_name, src_dir, 0); - return return_value; - } - if (is_fullpath(src_dir)) { new_src_dir = src_dir; @@ -4870,6 +4917,16 @@ dblayer_copy_directory(struct ldbminfo *li, else { int len; + ldbm_instance *inst = + ldbm_instance_find_by_name(li, relative_instance_name); + if (NULL == inst) + { + LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; " + "Instance path %s could be invalid.\n", + relative_instance_name, src_dir, 0); + return return_value; + } + inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst, inst_dir, MAXPATHLEN); if (!inst_dirp || !*inst_dirp) @@ -5009,21 +5066,98 @@ out: return return_value; } +/* + * Get changelogdir from cn=changelog5,cn=config + * The value does not have trailing spaces nor slashes. + */ +static int +_dblayer_get_changelogdir(struct ldbminfo *li, char **changelogdir) +{ + Slapi_PBlock *pb = NULL; + Slapi_Entry **entries = NULL; + Slapi_Attr *attr = NULL; + Slapi_Value *v = NULL; + const char *s = NULL; + char *attrs[2]; + int rc = -1; + + if (NULL == li || NULL == changelogdir) { + LDAPDebug2Args(LDAP_DEBUG_ANY, + "ERROR: _dblayer_get_changelogdir: Invalid arg: " + "li: 0x%x, changelogdir: 0x%x\n", li, changelogdir); + return rc; + } + *changelogdir = NULL; + pb = slapi_pblock_new(); + attrs[0] = CHANGELOGDIRATTR; + attrs[1] = NULL; + slapi_search_internal_set_pb(pb, CHANGELOGENTRY, + LDAP_SCOPE_BASE, "cn=*", attrs, 0, NULL, NULL, + li->li_identity, 0); + slapi_search_internal_pb(pb); + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + + if (LDAP_NO_SUCH_OBJECT == rc) { + /* No changelog; Most likely standalone or not a master. */ + rc = LDAP_SUCCESS; + goto bail; + } + if (LDAP_SUCCESS != rc) { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ERROR: Failed to search \"%s\"\n", CHANGELOGENTRY); + goto bail; + } + /* rc == LDAP_SUCCESS */ + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + if (NULL == entries) { + /* No changelog */ + goto bail; + } + /* There should be only one entry. */ + rc = slapi_entry_attr_find(entries[0], CHANGELOGDIRATTR, &attr); + if (rc || NULL == attr) { + /* No changelog dir */ + rc = LDAP_SUCCESS; + goto bail; + } + rc = slapi_attr_first_value(attr, &v); + if (rc || NULL == v) { + /* No changelog dir */ + rc = LDAP_SUCCESS; + goto bail; + } + rc = LDAP_SUCCESS; + s = slapi_value_get_string(v); + if (NULL == s) { + /* No changelog dir */ + goto bail; + } + *changelogdir = slapi_ch_strdup(s); + /* Remove trailing spaces and '/' if any */ + normalize_dir(*changelogdir); +bail: + slapi_free_search_results_internal(pb); + slapi_pblock_destroy(pb); + return rc; +} /* Destination Directory is an absolute pathname */ -int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) +int +dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) { dblayer_private *priv = NULL; char **listA = NULL, **listB = NULL, **listi, **listj, *prefix; char *home_dir = NULL; - int return_value = 0; + int return_value = -1; char *pathname1; char *pathname2; back_txn txn; int cnt = 1, ok = 0; - ldbm_instance *inst; Object *inst_obj; + char inst_dir[MAXPATHLEN]; + char *inst_dirp = NULL; + char *changelogdir = NULL; PR_ASSERT(NULL != li); priv = (dblayer_private*)li->li_dblayer_private; @@ -5031,9 +5165,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) home_dir = dblayer_get_home_dir(li, NULL); if (NULL == home_dir || '\0' == *home_dir) { - LDAPDebug(LDAP_DEBUG_ANY, - "Backup failed due to missing db home directory info\n", 0, 0, 0); - return -1; + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Backup: missing db home directory info\n"); + return return_value; } /* @@ -5068,15 +5202,16 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) dblayer_force_checkpoint(li); dblayer_txn_init(li,&txn); return_value=dblayer_txn_begin(li,NULL,&txn); - if (0 != return_value) { - LDAPDebug(LDAP_DEBUG_ANY, - "Backup failed due to transaction failure\n", 0, 0, 0); - return -1; + if (return_value) { + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Backup: transaction error\n"); + return return_value; } if ( g_get_shutdown() || c_get_shutdown() ) { - dblayer_txn_abort(li,&txn); - return -1; + LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n"); + return_value = -1; + goto bail; } /* repeat this until the logfile sets match... */ @@ -5085,73 +5220,104 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) if (priv->dblayer_enable_transactions) { return_value = LOG_ARCHIVE(priv->dblayer_env->dblayer_DB_ENV, &listA, DB_ARCH_LOG, (void *)slapi_ch_malloc); - if ((return_value != 0) || (listA == NULL)) { - LDAPDebug(LDAP_DEBUG_ANY, "BAD: can't get list of logs\n", - 0, 0, 0); - dblayer_txn_abort(li,&txn); - return return_value; + if (return_value || (listA == NULL)) { + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Backup: log archive error\n"); + if (task) { + slapi_task_log_notice(task, "Backup: log archive error\n"); + } + return_value = -1; + goto bail; } } else { ok=1; } if ( g_get_shutdown() || c_get_shutdown() ) { - dblayer_txn_abort(li,&txn); - return -1; + LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n"); + return_value = -1; + goto bail; } for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj; inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) { - char inst_dir[MAXPATHLEN]; - char *inst_dirp = NULL; - inst = (ldbm_instance *)object_get_data(inst_obj); + ldbm_instance *inst = (ldbm_instance *)object_get_data(inst_obj); inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst, - inst_dir, MAXPATHLEN); - if (inst_dirp && *inst_dirp) - { - return_value = dblayer_copy_directory(li, task, inst_dirp, - dest_dir, 0 /* backup */, &cnt, 0, 0, 0); - } - else - { - LDAPDebug(LDAP_DEBUG_ANY, - "ERROR: Instance dir is empty\n", 0, 0, 0); + inst_dir, MAXPATHLEN); + if ((NULL == inst_dirp) || ('\0' == *inst_dirp)) { + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Backup: Instance dir is empty\n"); if (task) { slapi_task_log_notice(task, - "ERROR: Instance dir is empty\n"); + "Backup: Instance dir is empty\n"); } - slapi_ch_free((void **)&listA); - dblayer_txn_abort(li,&txn); - return -1; + return_value = -1; + goto bail; } - if (return_value != 0) { + return_value = dblayer_copy_directory(li, task, inst_dirp, + dest_dir, 0 /* backup */, + &cnt, 0, 0, 0); + if (return_value) { LDAPDebug(LDAP_DEBUG_ANY, - "ERROR: error copying directory (%s -> %s): err=%d\n", - inst_dirp, dest_dir, return_value); + "Backup: error in copying directory " + "(%s -> %s): err=%d\n", + inst_dirp, dest_dir, return_value); if (task) { slapi_task_log_notice(task, - "ERROR: error copying directory (%s -> %s): err=%d", - inst_dirp, dest_dir, return_value); + "Backup: error in copying directory " + "(%s -> %s): err=%d\n", + inst_dirp, dest_dir, return_value); } - slapi_ch_free((void **)&listA); - dblayer_txn_abort(li,&txn); if (inst_dirp != inst_dir) slapi_ch_free_string(&inst_dirp); - return return_value; + goto bail; } if (inst_dirp != inst_dir) slapi_ch_free_string(&inst_dirp); } + /* Get changelogdir, if any */ + _dblayer_get_changelogdir(li, &changelogdir); + if (changelogdir) { + /* dest dir for changelog: dest_dir/repl_changelog_backup */ + char *changelog_destdir = slapi_ch_smprintf("%s/%s", + dest_dir, CHANGELOG_BACKUPDIR); + return_value = dblayer_copy_directory(li, task, changelogdir, + changelog_destdir, + 0 /* backup */, + &cnt, 0, 0, 0); + if (return_value) { + LDAPDebug(LDAP_DEBUG_ANY, + "Backup: error in copying directory " + "(%s -> %s): err=%d\n", + changelogdir, changelog_destdir, return_value); + if (task) { + slapi_task_log_notice(task, + "Backup: error in copying directory " + "(%s -> %s): err=%d\n", + changelogdir, changelog_destdir, return_value); + } + slapi_ch_free_string(&changelog_destdir); + goto bail; + } + /* Copy DBVERSION */ + pathname1 = slapi_ch_smprintf("%s/%s", + changelogdir, DBVERSION_FILENAME); + pathname2 = slapi_ch_smprintf("%s/%s", + changelog_destdir, DBVERSION_FILENAME); + return_value = dblayer_copyfile(pathname1, pathname2, + 0, priv->dblayer_file_mode); + slapi_ch_free_string(&pathname1); + slapi_ch_free_string(&pathname1); + slapi_ch_free_string(&changelog_destdir); + } if (priv->dblayer_enable_transactions) { /* now, get the list of logfiles that still exist */ return_value = LOG_ARCHIVE(priv->dblayer_env->dblayer_DB_ENV, &listB, DB_ARCH_LOG, (void *)slapi_ch_malloc); - if ((return_value != 0) || (listB == NULL)) { - LDAPDebug(LDAP_DEBUG_ANY, "ERROR: can't get list of logs\n", - 0, 0, 0); - slapi_ch_free((void **)&listA); - dblayer_txn_abort(li,&txn); - return return_value; + if (return_value || (listB == NULL)) { + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Backup: can't get list of logs\n"); + goto bail; } /* compare: make sure everything in list A is still in list B */ @@ -5166,8 +5332,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) } if (! found) { ok = 0; /* missing log: start over */ - LDAPDebug(LDAP_DEBUG_ANY, "WARNING: Log %s has been swiped " - "out from under me! (retrying)\n", *listi, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "WARNING: Log %s has been swiped " + "out from under me! (retrying)\n", *listi); if (task) { slapi_task_log_notice(task, "WARNING: Log %s has been swiped out from under me! " @@ -5177,8 +5344,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) } if ( g_get_shutdown() || c_get_shutdown() ) { - dblayer_txn_abort(li,&txn); - return -1; + LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n"); + return_value = -1; + goto bail; } if (ok) { @@ -5201,8 +5369,8 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) for (listptr = listB; listptr && *listptr && ok; ++listptr) { PR_snprintf(pathname1, p1len, "%s/%s", prefix, *listptr); PR_snprintf(pathname2, p2len, "%s/%s", dest_dir, *listptr); - LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n", - cnt, pathname2, 0); + LDAPDebug2Args(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n", + cnt, pathname2); if (task) { slapi_task_log_notice(task, @@ -5213,9 +5381,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) return_value = dblayer_copyfile(pathname1, pathname2, 0, priv->dblayer_file_mode); if (0 > return_value) { - LDAPDebug(LDAP_DEBUG_ANY, "Error copying file '%s' " - "(err=%d) -- Starting over...\n", - pathname1, return_value, 0); + LDAPDebug2Args(LDAP_DEBUG_ANY, "Backup: error in " + "copying file '%s' (err=%d) -- Starting over...\n", + pathname1, return_value); if (task) { slapi_task_log_notice(task, "Error copying file '%s' (err=%d) -- Starting " @@ -5224,8 +5392,11 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) ok = 0; } if ( g_get_shutdown() || c_get_shutdown() ) { - dblayer_txn_abort(li,&txn); - return -1; + LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n"); + return_value = -1; + slapi_ch_free((void **)&pathname1); + slapi_ch_free((void **)&pathname2); + goto bail; } cnt++; } @@ -5238,22 +5409,28 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) } } while (!ok); - - if ( g_get_shutdown() || c_get_shutdown() ) { - dblayer_txn_abort(li,&txn); - return -1; - } - /* now copy the version file */ pathname1 = slapi_ch_smprintf("%s/%s", home_dir, DBVERSION_FILENAME); pathname2 = slapi_ch_smprintf("%s/%s", dest_dir, DBVERSION_FILENAME); - LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n", - cnt, pathname2, 0); + LDAPDebug2Args(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n", cnt, pathname2); if (task) { slapi_task_log_notice(task, "Backing up file %d (%s)", cnt, pathname2); slapi_task_log_status(task, "Backing up file %d (%s)", cnt, pathname2); } - return_value = dblayer_copyfile(pathname1,pathname2,0,priv->dblayer_file_mode); + return_value = + dblayer_copyfile(pathname1, pathname2, 0, priv->dblayer_file_mode); + if (return_value) { + LDAPDebug(LDAP_DEBUG_ANY, + "Backup: error in copying version file " + "(%s -> %s): err=%d\n", + pathname1, pathname2, return_value); + if (task) { + slapi_task_log_notice(task, + "Backup: error in copying version file " + "(%s -> %s): err=%d\n", + pathname1, pathname2, return_value); + } + } slapi_ch_free((void **)&pathname1); slapi_ch_free((void **)&pathname2); @@ -5261,8 +5438,11 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task) if (0 == return_value) /* if everything went well, backup the index conf */ return_value = dse_conf_backup(li, dest_dir); - - return_value = dblayer_txn_abort(li,&txn); +bail: + slapi_ch_free((void **)&listA); + slapi_ch_free((void **)&listB); + dblayer_txn_abort(li,&txn); + slapi_ch_free_string(&changelogdir); return return_value; } @@ -5560,7 +5740,7 @@ static int dblayer_fri_restore(char *home_dir, char *src_dir, dblayer_private *p int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *bename) { dblayer_private *priv = NULL; - int return_value = 0; + int return_value = 0; int tmp_rval; char filename1[MAXPATHLEN]; char filename2[MAXPATHLEN]; @@ -5576,6 +5756,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * char *real_src_dir = NULL; int frirestore = 0; /* Is a an FRI/single instance restore. 0 for no, 1 for yes */ struct stat sbuf; + char *changelogdir = NULL; + char *restore_dir = NULL; + char *prefix = NULL; + int cnt = 1; PR_ASSERT(NULL != li); priv = (dblayer_private*)li->li_dblayer_private; @@ -5595,8 +5779,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * if (NULL == home_dir || '\0' == *home_dir) { - LDAPDebug(LDAP_DEBUG_ANY, - "Restore failed due to missing db home directory info\n", 0, 0, 0); + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Restore: missing db home directory info\n"); return -1; } @@ -5605,27 +5789,27 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * /* We check on the source staging area, no point in going further if it * isn't there */ if (stat(src_dir, &sbuf) < 0) { - LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not " - "exist.\n", src_dir, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s does not " + "exist.\n", src_dir); if (task) { - slapi_task_log_notice(task, - "Backup directory %s does not exist.\n", src_dir); + slapi_task_log_notice(task, "Restore: backup directory %s does not " + "exist.\n", src_dir); } return LDAP_UNWILLING_TO_PERFORM; } else if (!S_ISDIR(sbuf.st_mode)) { - LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s is not " - "a directory.\n", src_dir, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s is not " + "a directory.\n", src_dir); if (task) { - slapi_task_log_notice(task, - "Backup directory %s is not a directory.\n", src_dir); + slapi_task_log_notice(task, "Restore: backup directory %s is not " + "a directory.\n", src_dir); } return LDAP_UNWILLING_TO_PERFORM; } if (!dbversion_exists(li, src_dir)) { - LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not " - "contain a complete backup\n", src_dir, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s does not " + "contain a complete backup\n", src_dir); if (task) { - slapi_task_log_notice(task, "Backup directory %s does not " + slapi_task_log_notice(task, "Restore: backup directory %s does not " "contain a complete backup", src_dir ); } return LDAP_UNWILLING_TO_PERFORM; @@ -5646,34 +5830,50 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * while ((direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT)) && direntry->name) { - PR_snprintf(filename1, MAXPATHLEN, "%s/%s", src_dir, direntry->name); + PR_snprintf(filename1, sizeof(filename1), "%s/%s", + src_dir, direntry->name); if(!frirestore || strcmp(direntry->name,bename)==0) { tmp_rval = PR_GetFileInfo(filename1, &info); if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) { + /* Is it CHANGELOG_BACKUPDIR? */ + if (0 == strcmp(CHANGELOG_BACKUPDIR, direntry->name)) { + /* Yes, this is a changelog backup. */ + /* Get the changelog path */ + _dblayer_get_changelogdir(li, &changelogdir); + continue; + } inst = ldbm_instance_find_by_name(li, (char *)direntry->name); if ( inst == NULL) { - LDAPDebug(LDAP_DEBUG_ANY, - "ERROR: target server has no %s configured\n", direntry->name, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: target server has no %s configured\n", + direntry->name); if (task) { slapi_task_log_notice(task, - "ERROR: target server has no %s configured\n", direntry->name); + "Restore: target server has no %s configured\n", + direntry->name); } PR_CloseDir(dirhandle); - return LDAP_UNWILLING_TO_PERFORM; + return_value = LDAP_UNWILLING_TO_PERFORM; + goto error_out; } if (slapd_comp_path(src_dir, inst->inst_parent_dir_name) == 0) { - LDAPDebug(LDAP_DEBUG_ANY, - "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name, 0); + LDAPDebug2Args(LDAP_DEBUG_ANY, + "Restore: backup dir %s and target dir %s " + "are identical\n", + src_dir, inst->inst_parent_dir_name); if (task) { slapi_task_log_notice(task, - "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name); + "Restore: backup dir %s and target dir %s " + "are identical\n", + src_dir, inst->inst_parent_dir_name); } PR_CloseDir(dirhandle); - return LDAP_UNWILLING_TO_PERFORM; + return_value = LDAP_UNWILLING_TO_PERFORM; + goto error_out; } } } @@ -5682,10 +5882,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * } /* We delete the existing database */ - - return_value = dblayer_delete_database_ex(li, bename); + /* changelogdir is taken care only when it's not NULL. */ + return_value = dblayer_delete_database_ex(li, bename, changelogdir); if (return_value) { - return return_value; + goto error_out; } if (frirestore) /*if we are restoring a single backend*/ @@ -5693,7 +5893,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * char *new_src_dir = NULL; return_value = dblayer_fri_restore(home_dir,src_dir,priv,task,&new_src_dir,bename); if (return_value) { - return return_value; + goto error_out; } /* Now modify the src_dir to point to our recovery area and carry on as if nothing had happened... */ real_src_dir = new_src_dir; @@ -5707,91 +5907,141 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * /* We want to treat the logfiles specially: if there's * a log file directory configured, copy the logfiles there * rather than to the db dirctory */ - if (0 == return_value) { - dirhandle = PR_OpenDir(real_src_dir); - if (NULL != dirhandle) { - char *restore_dir; - char *prefix = NULL; - int cnt = 1; - - - while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { - if (NULL == direntry->name) { - /* NSPR doesn't behave like the docs say it should */ - break; - } - - - /* Is this entry a directory? */ - PR_snprintf(filename1, MAXPATHLEN, "%s/%s", real_src_dir, direntry->name); - tmp_rval = PR_GetFileInfo(filename1, &info); - if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) { - /* This is an instance directory. It contains the *.db# - * files for the backend instance. - * restore directory is supposed to be where the backend - * directory is located. - */ - - inst = ldbm_instance_find_by_name(li, (char *)direntry->name); - if (inst == NULL) - continue; + dirhandle = PR_OpenDir(real_src_dir); + if (NULL == dirhandle) { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: failed to open the directory \"%s\"\n", real_src_dir); + if (task) { + slapi_task_log_notice(task, + "Restore: failed to open the directory \"%s\"\n", real_src_dir); + } + return_value = -1; + goto error_out; + } + + while (NULL != + (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { + if (NULL == direntry->name) { + /* NSPR doesn't behave like the docs say it should */ + break; + } - restore_dir = inst->inst_parent_dir_name; - /* If we're doing a partial restore, we need to reset the LSNs on the data files */ - if (dblayer_copy_directory(li, task, filename1, - restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0) - continue; - else - { - LDAPDebug(LDAP_DEBUG_ANY, - "restore: failed to copy directory %s\n", - filename1, 0, 0); + /* Is this entry a directory? */ + PR_snprintf(filename1, sizeof(filename1), "%s/%s", + real_src_dir, direntry->name); + tmp_rval = PR_GetFileInfo(filename1, &info); + if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) { + /* This is an instance directory. It contains the *.db# + * files for the backend instance. + * restore directory is supposed to be where the backend + * directory is located. + */ + if (0 == strcmp(CHANGELOG_BACKUPDIR, direntry->name)) { + if (changelogdir) { + char *cldirname = PL_strrchr(changelogdir, '/'); + char *p = filename1 + strlen(filename1); + if (NULL == cldirname) { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: broken changelog dir path %s\n", + changelogdir); if (task) { slapi_task_log_notice(task, - "Failed to copy directory %s", filename1); + "Restore: broken changelog dir path %s\n", + changelogdir); } - break; + goto error_out; + } + PR_snprintf(p, sizeof(filename1) - (p - filename1), + "/%s", cldirname+1); + /* Get the parent dir of changelogdir */ + *cldirname = '\0'; + return_value = dblayer_copy_directory(li, task, filename1, + changelogdir, 1 /* restore */, &cnt, 0, 0, 0); + *cldirname = '/'; + if (return_value) { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: failed to copy directory %s\n", + filename1); + if (task) { + slapi_task_log_notice(task, + "Restore: failed to copy directory %s", + filename1); + } + goto error_out; } + /* Copy DBVERSION */ + p = filename1 + strlen(filename1); + PR_snprintf(p, sizeof(filename1) - (p - filename1), + "/%s", DBVERSION_FILENAME); + PR_snprintf(filename2, sizeof(filename2), "%s/%s", + changelogdir, DBVERSION_FILENAME); + return_value = dblayer_copyfile(filename1, filename2, + 0, priv->dblayer_file_mode); } + continue; + } - if (doskip(direntry->name)) - continue; + inst = ldbm_instance_find_by_name(li, (char *)direntry->name); + if (inst == NULL) + continue; - /* Is this a log file ? */ - /* Log files have names of the form "log.xxxxx" */ - /* We detect these by looking for the prefix "log." and - * the lack of the ".db#" suffix */ - is_a_logfile = dblayer_is_logfilename(direntry->name); - if (is_a_logfile) { - seen_logfiles = 1; - } - if (is_a_logfile && (NULL != priv->dblayer_log_directory) && - (0 != strlen(priv->dblayer_log_directory)) ) { - prefix = priv->dblayer_log_directory; - } else { - prefix = home_dir; - } - mkdir_p(prefix, 0700); - PR_snprintf(filename1, MAXPATHLEN, "%s/%s", real_src_dir, direntry->name); - PR_snprintf(filename2, MAXPATHLEN, "%s/%s", prefix, direntry->name); - LDAPDebug(LDAP_DEBUG_ANY, "Restoring file %d (%s)\n", - cnt, filename2, 0); + restore_dir = inst->inst_parent_dir_name; + /* If we're doing a partial restore, we need to reset the LSNs on the data files */ + if (dblayer_copy_directory(li, task, filename1, + restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0) + continue; + else + { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: failed to copy directory %s\n", + filename1); if (task) { - slapi_task_log_notice(task, "Restoring file %d (%s)", - cnt, filename2); - slapi_task_log_status(task, "Restoring file %d (%s)", - cnt, filename2); + slapi_task_log_notice(task, + "Restore: failed to copy directory %s", filename1); } - return_value = dblayer_copyfile(filename1, filename2, 0, - priv->dblayer_file_mode); - if (0 > return_value) - break; - - cnt++; + goto error_out; } - PR_CloseDir(dirhandle); } + + if (doskip(direntry->name)) + continue; + + /* Is this a log file ? */ + /* Log files have names of the form "log.xxxxx" */ + /* We detect these by looking for the prefix "log." and + * the lack of the ".db#" suffix */ + is_a_logfile = dblayer_is_logfilename(direntry->name); + if (is_a_logfile) { + seen_logfiles = 1; + } + if (is_a_logfile && (NULL != priv->dblayer_log_directory) && + (0 != strlen(priv->dblayer_log_directory)) ) { + prefix = priv->dblayer_log_directory; + } else { + prefix = home_dir; + } + mkdir_p(prefix, 0700); + PR_snprintf(filename1, sizeof(filename1), "%s/%s", + real_src_dir, direntry->name); + PR_snprintf(filename2, sizeof(filename2), "%s/%s", + prefix, direntry->name); + LDAPDebug2Args(LDAP_DEBUG_ANY, "Restoring file %d (%s)\n", + cnt, filename2); + if (task) { + slapi_task_log_notice(task, "Restoring file %d (%s)", + cnt, filename2); + slapi_task_log_status(task, "Restoring file %d (%s)", + cnt, filename2); + } + return_value = dblayer_copyfile(filename1, filename2, 0, + priv->dblayer_file_mode); + if (0 > return_value) { + goto error_out; + } + cnt++; } + PR_CloseDir(dirhandle); + /* We're done ! */ /* [605024] check the DBVERSION and reset idl-switch if needed */ @@ -5802,8 +6052,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * if (dbversion_read(li, home_dir, &ldbmversion, &dataversion) != 0) { - LDAPDebug(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion " - "file in %s\n", home_dir, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion " + "file in %s\n", home_dir); } else { @@ -5862,10 +6112,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * tmp_rval = dblayer_start(li, dbmode); if (0 != tmp_rval) { - LDAPDebug(LDAP_DEBUG_ANY, - "dblayer_restore: Failed to init database\n", 0, 0, 0); + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Restore: failed to init database\n"); if (task) { - slapi_task_log_notice(task, "Failed to init database"); + slapi_task_log_notice(task, "Restore: failed to init database"); } return_value = tmp_rval; goto error_out; @@ -5875,16 +6125,16 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * /* check the DSE_* files, if any */ tmp_rval = dse_conf_verify(li, real_src_dir, bename); if (0 != tmp_rval) - LDAPDebug(LDAP_DEBUG_ANY, - "Warning: Unable to verify the index configuration\n", 0, 0, 0); + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Warning: Unable to verify the index configuration\n"); } if (li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) { /* command line: close the database down again */ tmp_rval = dblayer_close(li, dbmode); if (0 != tmp_rval) { - LDAPDebug(LDAP_DEBUG_ANY, - "dblayer_restore: Failed to close database\n", 0, 0, 0); + LDAPDebug0Args(LDAP_DEBUG_ANY, + "Restore: Failed to close database\n"); } } else { allinstance_set_busy(li); /* on-line mode */ @@ -5894,20 +6144,24 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * error_out: /* Free the restore src dir, but only if we allocated it above */ - if (real_src_dir != src_dir) { + if (real_src_dir && (real_src_dir != src_dir)) { /* If this was an FRI restore and the staging area exists, go ahead and remove it */ if (frirestore && PR_Access(real_src_dir, PR_ACCESS_EXISTS) == PR_SUCCESS) { int ret1 = 0; - LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removing staging area %s.\n",real_src_dir, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: Removing staging area %s.\n", real_src_dir); ret1 = ldbm_delete_dirs(real_src_dir); if (ret1) { - LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removal of staging area %s failed!\n", real_src_dir, 0, 0); + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "Restore: Removal of staging area %s failed!\n", + real_src_dir); } } - slapi_ch_free((void**)&real_src_dir); + slapi_ch_free_string(&real_src_dir); } + slapi_ch_free_string(&changelogdir); return return_value; } @@ -6136,3 +6390,60 @@ void dblayer_set_recovery_required(struct ldbminfo *li) li->li_dblayer_private->dblayer_recovery_required = 1; } +int +ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info) +{ + int rc = -1; + if (!be || !info) { + return rc; + } + + switch (cmd) { + case BACK_INFO_DBENV: + { + struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private; + if (li) { + dblayer_private *prv = (dblayer_private*)li->li_dblayer_private; + if (prv && prv->dblayer_env && prv->dblayer_env->dblayer_DB_ENV) { + *(DB_ENV **)info = prv->dblayer_env->dblayer_DB_ENV; + rc = 0; + } + } + break; + } + case BACK_INFO_INDEXPAGESIZE: + { + struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private; + if (li) { + dblayer_private *prv = (dblayer_private*)li->li_dblayer_private; + if (prv && prv->dblayer_index_page_size) { + *(size_t *)info = prv->dblayer_index_page_size; + } else { + *(size_t *)info = DBLAYER_INDEX_PAGESIZE; + } + rc = 0; + } + break; + } + default: + break; + } + + return rc; +} + +int +ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info) +{ + int rc = -1; + if (!be || !info) { + return rc; + } + + switch (cmd) { + default: + break; + } + + return rc; +} diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h index d0d05b4a..419b263b 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.h +++ b/ldap/servers/slapd/back-ldbm/dblayer.h @@ -207,4 +207,8 @@ void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv); /* Return the last four characters of a string; used for comparing extensions. */ char* last_four_chars(const char* s); +/* To support backingup/restoring changelog dir */ +#define CHANGELOGENTRY "cn=changelog5,cn=config" +#define CHANGELOGDIRATTR "nsslapd-changelogdir" + #endif /* _DBLAYER_H_ */ diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c index 1fc269b9..1d490546 100644 --- a/ldap/servers/slapd/back-ldbm/import-threads.c +++ b/ldap/servers/slapd/back-ldbm/import-threads.c @@ -549,6 +549,7 @@ import_producer(void *param) } continue; } + /* From here, e != NULL */ if (0 == my_version) { /* after the first entry version string won't be given */ my_version = -1; @@ -556,10 +557,7 @@ import_producer(void *param) if (! import_entry_belongs_here(e, inst->inst_be)) { /* silently skip */ - if (e) { - slapi_entry_free(e); - } - + slapi_entry_free(e); continue; } @@ -569,9 +567,7 @@ import_producer(void *param) "violates schema, ending line %d of file " "\"%s\"", escape_string(slapi_entry_get_dn(e), ebuf), curr_lineno, curr_filename); - if (e) { - slapi_entry_free(e); - } + slapi_entry_free(e); job->skipped++; continue; @@ -625,9 +621,7 @@ import_producer(void *param) "violates attribute syntax, ending line %d of " "file \"%s\"", escape_string(slapi_entry_get_dn(e), ebuf), curr_lineno, curr_filename); - if (e) { - slapi_entry_free(e); - } + slapi_entry_free(e); job->skipped++; continue; @@ -640,8 +634,10 @@ import_producer(void *param) } ep = import_make_backentry(e, id); - if (!ep || !ep->ep_entry) + if (!ep) { + slapi_entry_free(e); goto error; + } /* check for include/exclude subtree lists */ if (! ldbm_back_ok_to_dump(backentry_get_ndn(ep), @@ -729,8 +725,8 @@ import_producer(void *param) "ending line %d of file \"%s\"", escape_string(slapi_entry_get_dn(e), ebuf), curr_lineno, curr_filename); - import_log_notice(job, "REASON: entry too large (%ld bytes) for " - "the buffer size (%lu bytes)", newesize, job->fifo.bsize); + import_log_notice(job, "REASON: entry too large (%u bytes) for " + "the buffer size (%u bytes)", newesize, job->fifo.bsize); backentry_free(&ep); job->skipped++; continue; @@ -1422,6 +1418,7 @@ upgradedn_producer(void *param) continue; } + /* From here, e != NULL */ /* Check DN syntax attr values if it contains '\\' or not */ /* Start from the rdn */ if (entryrdn_get_switch()) { /* subtree-rename: on */ @@ -1615,7 +1612,7 @@ upgradedn_producer(void *param) upgradedn_free_list(&ud_list); ep = import_make_backentry(e, temp_id); - if (!ep || !ep->ep_entry) { + if (!ep) { slapi_entry_free(e); e = NULL; goto error; } @@ -2130,7 +2127,7 @@ import_foreman(void *param) * Note: FLAG_UPGRADEDNFORMAT only. */ Slapi_Attr *orig_entrydn = NULL; - Slapi_Attr *new_entrydn = slapi_attr_new(); + Slapi_Attr *new_entrydn = NULL; Slapi_Attr *nsuniqueid = NULL; const char *uuidstr = NULL; char *new_dn = NULL; @@ -2150,6 +2147,7 @@ import_foreman(void *param) orig_dn, fi->entry->ep_id); goto cont; } + new_entrydn = slapi_attr_new(); new_dn = slapi_create_dn_string("nsuniqueid=%s+%s", uuidstr, orig_dn); /* releasing original dn */ @@ -2724,6 +2722,10 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry) Slapi_Attr *attr = NULL; size_t newesize = 0; + if (!entry) { + return -1; + } + PR_Lock(job->wire_lock); /* Let's do this inside the lock !*/ id = job->lead_ID + 1; @@ -2732,7 +2734,7 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry) /* make into backentry */ ep = import_make_backentry(entry, id); - if (!ep || !ep->ep_entry) { + if (!ep) { import_abort_all(job, 1); PR_Unlock(job->wire_lock); return -1; @@ -3157,9 +3159,10 @@ dse_conf_verify_core(struct ldbminfo *li, char *src_dir, char *file_name, char * if (entry_filter != NULL) /* Single instance restoration */ { - if (NULL == strstr(estr, entry_filter)) + if (NULL == strstr(estr, entry_filter)) { slapi_ch_free_string(&estr); continue; + } } e = slapi_str2entry(estr, 0); diff --git a/ldap/servers/slapd/back-ldbm/init.c b/ldap/servers/slapd/back-ldbm/init.c index f1f71840..83951aea 100644 --- a/ldap/servers/slapd/back-ldbm/init.c +++ b/ldap/servers/slapd/back-ldbm/init.c @@ -248,6 +248,10 @@ ldbm_back_init( Slapi_PBlock *pb ) (void *) ldbm_back_wire_import ); rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_SCHEMA_FN, (void *) ldbm_back_add_schema ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_GET_INFO_FN, + (void *) ldbm_back_get_info ); + rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SET_INFO_FN, + (void *) ldbm_back_set_info ); if ( rc != 0 ) { LDAPDebug( LDAP_DEBUG_ANY, "ldbm_back_init failed\n", 0, 0, 0 ); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c index 529f55e0..5e3b9b53 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c @@ -190,7 +190,7 @@ int ldbm_back_modify( Slapi_PBlock *pb ) { backend *be; - ldbm_instance *inst; + ldbm_instance *inst = NULL; struct ldbminfo *li; struct backentry *e = NULL, *ec = NULL; Slapi_Entry *postentry = NULL; diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c index 25cc265c..e0b09fb4 100644 --- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c @@ -1389,6 +1389,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb ) &eargs, DB2LDIF_ENTRYRDN, &psrdn); if (rc) { slapi_rdn_done(&psrdn); + backentry_free(&ep); continue; } } @@ -1424,6 +1425,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb ) "%d\n", pid); slapi_ch_free_string(&rdn); slapi_rdn_done(&psrdn); + backentry_free(&ep); continue; } } @@ -1436,6 +1438,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb ) rdn, temp_id); slapi_ch_free_string(&rdn); slapi_rdn_done(&psrdn); + backentry_free(&ep); continue; } } @@ -1932,6 +1935,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) rdn, temp_id, pid, run_from_cmdline, NULL, index_ext, &psrdn); if (rc) { + backentry_free(&ep); continue; } } @@ -1966,6 +1970,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) "%d\n", pid); slapi_ch_free_string(&rdn); slapi_rdn_done(&psrdn); + backentry_free(&ep); continue; } } @@ -1978,6 +1983,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb) rdn, temp_id); slapi_ch_free_string(&rdn); slapi_rdn_done(&psrdn); + backentry_free(&ep); continue; } } @@ -2448,7 +2454,6 @@ ldbm_exclude_attr_from_export( struct ldbminfo *li , const char *attr, int upgradedb_core(Slapi_PBlock *pb, ldbm_instance *inst); int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir, int restore); int upgradedb_delete_indices_4cmd(ldbm_instance *inst, int flags); -static void normalize_dir(char *dir); /* * ldbm_back_upgradedb - @@ -2797,26 +2802,6 @@ fail0: return rval + upgrade_rval; } -static void -normalize_dir(char *dir) -{ - char *p = NULL; - int l = 0; - - if (NULL == dir) { - return; - } - l = strlen(dir); - - for (p = dir + l - 1; p && *p; p--) { - if (' ' != *p && '\t' != *p && '/' != *p && '\\' != *p) { - break; - } - } - *(p+1) = '\0'; -} - - #define LOG "log." #define LOGLEN 4 int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir, @@ -3070,7 +3055,7 @@ _get_and_add_parent_rdns(backend *be, slapi_log_error(SLAPI_LOG_FATAL, "ldif2dbm", "_get_and_add_parent_rdns: " "Failed to convert DN %s to RDN\n", - slapi_sdn_get_dn(bdn->dn_sdn)); + slapi_rdn_get_rdn(&mysrdn)); slapi_rdn_done(&mysrdn); CACHE_RETURN(&inst->inst_dncache, &bdn); goto bail; @@ -3162,7 +3147,7 @@ _get_and_add_parent_rdns(backend *be, slapi_log_error(SLAPI_LOG_FATAL, "ldif2dbm", "_get_and_add_parent_rdns: " "Failed to merge Slapi_RDN %s to RDN\n", - slapi_sdn_get_dn(bdn->dn_sdn)); + slapi_rdn_get_rdn(&mysrdn)); goto bail; } } diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c index 4b4a7200..13b87fd7 100644 --- a/ldap/servers/slapd/back-ldbm/misc.c +++ b/ldap/servers/slapd/back-ldbm/misc.c @@ -483,12 +483,14 @@ get_value_from_string(const char *string, char *type, char **value) ldif_getline_fixline(startptr, tmpptr); startptr = tmpptr; rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval); - if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) { + if (0 > rc || NULL == tmptype.bv_val || + NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) { slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "parse " "failed: %d\n", rc); if (freeval) { slapi_ch_free_string(&bvvalue.bv_val); } + rc = -1; /* set non-0 to rc */ goto bail; } if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) { @@ -498,8 +500,10 @@ get_value_from_string(const char *string, char *type, char **value) if (freeval) { slapi_ch_free_string(&bvvalue.bv_val); } + rc = -1; /* set non-0 to rc */ goto bail; } + rc = 0; /* set 0 to rc */ if (freeval) { *value = bvvalue.bv_val; /* just hand off the memory */ bvvalue.bv_val = NULL; @@ -609,3 +613,23 @@ bail: slapi_ch_free_string(©); return rc; } + +void +normalize_dir(char *dir) +{ + char *p = NULL; + int l = 0; + + if (NULL == dir) { + return; + } + l = strlen(dir); + + for (p = dir + l - 1; p && *p && (p > dir); p--) { + if ((' ' != *p) && ('\t' != *p) && ('/' != *p) && ('\\' != *p)) { + break; + } + } + *(p+1) = '\0'; +} + diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index 615d9373..363bec27 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -173,6 +173,9 @@ int dblayer_db_uses_logging(DB_ENV *db_env); int dblayer_bt_compare(DB *db, const DBT *dbt1, const DBT *dbt2); int dblayer_remove_env(struct ldbminfo *li); +int ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info); +int ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info); + /* * dn2entry.c */ @@ -364,7 +367,7 @@ int is_fullpath(char *path); char get_sep(char *path); int get_value_from_string(const char *string, char *type, char **value); int get_values_from_string(const char *string, char *type, char ***valuearray); - +void normalize_dir(char *dir); /* * nextid.c |