From d0f04dd3eefec7264928b187148653343c649c48 Mon Sep 17 00:00:00 2001 From: William Brown Date: Nov 27 2019 23:51:57 +0000 Subject: Ticket 50664 - DS can fail to recover if an empty directory exists in db Bug Description: In count_dbfiles_in_dir, when the recurse option is set to false, the counter was zerod. Depending on the opendir (inode, dirent) ordering of directories in a be folder (ie userRoot), this could cause an empty directory to be examined last via the recurse option, when then would clear the counter. If the counter is cleared, the server believes no db files exist. Fix Description: Remove the counter-zeroing on recurse == false which requires us to check the original caller DOES zero the value (I checked, it does). https://pagure.io/389-ds-base/issue/50664 Author: William Brown , Thomas E Lackey Review by: ??? --- diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c index 10f6d40..e02fc07 100644 --- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c +++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c @@ -3946,6 +3946,7 @@ read_metadata(struct ldbminfo *li) prfd = PR_Open(filename, PR_RDONLY, priv->dblayer_file_mode); if (NULL == prfd || 0 == prfinfo.size) { /* file empty or not present--means the database needs recovered */ + /* Note count is correctly zerod! */ int count = 0; for (dirp = conf->bdb_data_directories; dirp && *dirp; dirp++) { count_dbfiles_in_dir(*dirp, &count, 1 /* recurse */); @@ -4379,6 +4380,15 @@ dblayer_database_size(struct ldbminfo *li, unsigned int *size) } +/* + * Obtain a count of all the BDB files in the indicated directory. + * + * directory : The path to examine. + * count : Output parameter for the final count. + * recurse : 0/1, recursion is not complete, it only goes down one level. + * + * IMPORTANT: 'count' must be set to 0 by the caller before being passed. + */ static int count_dbfiles_in_dir(char *directory, int *count, int recurse) { @@ -4388,12 +4398,6 @@ count_dbfiles_in_dir(char *directory, int *count, int recurse) int return_value = 0; PRDir *dirhandle = NULL; - if (!recurse) { - /* It is really the callers responsibility to set count to 0 before - * calling. However, if recurse isn't true, we can make sure it is - * set to 0. */ - *count = 0; - } dirhandle = PR_OpenDir(directory); if (NULL != dirhandle) { PRDirEntry *direntry = NULL;