ldap/servers/slapd/config.c | 32 ++++-----------------
ldap/servers/slapd/dse.c | 60 ++++++++++++++++++++++++++--------------
ldap/servers/slapd/proto-slap.h | 1
3 files changed, 47 insertions(+), 46 deletions(-)
New commits:
commit b3ca9eec5d50c2ca503582e55b6681b9b3ad6ad3
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Fri Nov 23 11:15:52 2012 +0100
Ticket 518 - dse.ldif is 0 length after server kill or machine kill
Bug Description: If a machine is powered off while slapd is running, dse.ldif can
have 0 bytes and
server doesn't start even if a dse.ldif.tmp or dse.ldif.bak
exists
Fix Description: I see no way to prevent a 0 byte ldif in case of a machine crash from
slapd code,
but the server should try all avaialble backup dse.ldif files to be
able to start,
https://fedorahosted.org/389/ticket/518
Reviewed by: RichM (Thanks)
diff --git a/ldap/servers/slapd/config.c b/ldap/servers/slapd/config.c
index d97a575..3edc24b 100644
--- a/ldap/servers/slapd/config.c
+++ b/ldap/servers/slapd/config.c
@@ -165,6 +165,7 @@ slapd_bootstrap_config(const char *configdir)
char *buf = 0;
char *lastp = 0;
char *entrystr = 0;
+ char tmpfile[MAXPATHLEN+1];
if (NULL == configdir) {
slapi_log_error(SLAPI_LOG_FATAL,
@@ -173,33 +174,14 @@ slapd_bootstrap_config(const char *configdir)
}
PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir,
CONFIG_FILENAME);
- if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS )
- {
- /* the "real" file does not exist; see if there is a tmpfile */
- char tmpfile[MAXPATHLEN+1];
- slapi_log_error(SLAPI_LOG_FATAL, "config",
- "The configuration file %s does not exist\n", configfile);
- PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir,
+ PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir,
CONFIG_FILENAME);
- if ( PR_GetFileInfo( tmpfile, &prfinfo ) == PR_SUCCESS ) {
- rc = PR_Rename(tmpfile, configfile);
- if (rc == PR_SUCCESS) {
- slapi_log_error(SLAPI_LOG_FATAL, "config",
- "The configuration file %s was restored from backup %s\n",
- configfile, tmpfile);
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, "config",
- "The configuration file %s was not restored from backup %s, error
%d\n",
- configfile, tmpfile, rc);
- return rc; /* Fail */
- }
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, "config",
- "The backup configuration file %s does not exist, either.\n",
- tmpfile);
- return rc; /* Fail */
- }
+ if ( (rc = dse_check_file(configfile, tmpfile)) == 0 ) {
+ PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.bak", configdir,
+ CONFIG_FILENAME);
+ rc = dse_check_file(configfile, tmpfile);
}
+
if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS )
{
PRErrorCode prerr = PR_GetError();
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index 3d2955c..53d8736 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -651,6 +651,40 @@ dse_updateNumSubOfParent(struct dse *pdse, const Slapi_DN *child, int
op)
slapi_sdn_done(&parent);
}
+/* check if a file is valid, or if a provided backup file can be used.
+ * there is no way to determine if the file contents is usable, the only
+ * checks that can be done is that the file exists and that it is not size 0
+ */
+int
+dse_check_file(char *filename, char *backupname)
+{
+ int rc= 0; /* Fail */
+ PRFileInfo prfinfo;
+
+ if (PR_GetFileInfo( filename, &prfinfo ) == PR_SUCCESS) {
+ if ( prfinfo.size > 0)
+ return (1);
+ else {
+ rc = PR_Delete (filename);
+ }
+ }
+
+ if (backupname)
+ rc = PR_Rename (backupname, filename);
+ else
+ return (0);
+
+ if ( PR_GetFileInfo( filename, &prfinfo ) == PR_SUCCESS && prfinfo.size
> 0 ) {
+ slapi_log_error(SLAPI_LOG_FATAL, "dse",
+ "The configuration file %s was restored from backup %s\n",
filename, backupname);
+ return (1);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, "dse",
+ "The configuration file %s was not restored from backup %s, error
%d\n",
+ filename, backupname, rc);
+ return (0);
+ }
+}
static int
dse_read_one_file(struct dse *pdse, const char *filename, Slapi_PBlock *pb,
int primary_file )
@@ -669,27 +703,11 @@ dse_read_one_file(struct dse *pdse, const char *filename,
Slapi_PBlock *pb,
if ( (NULL != pdse) && (NULL != filename) )
{
- if ( (rc = PR_GetFileInfo( filename, &prfinfo )) != PR_SUCCESS )
- {
- /* the "real" file does not exist; see if there is a tmpfile */
- if ( pdse->dse_tmpfile &&
- PR_GetFileInfo( pdse->dse_tmpfile, &prfinfo ) == PR_SUCCESS ) {
- rc = PR_Rename(pdse->dse_tmpfile, filename);
- if (rc == PR_SUCCESS) {
- slapi_log_error(SLAPI_LOG_FATAL, "dse",
- "The configuration file %s was restored from
backup %s\n",
- filename, pdse->dse_tmpfile);
- rc = 1;
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, "dse",
- "The configuration file %s was not restored from
backup %s, error %d\n",
- filename, pdse->dse_tmpfile, rc);
- rc = 0;
- }
- } else {
- rc = 0; /* fail */
- }
- }
+ /* check if the "real" file exists and cam be used, if not try tmp as
backup */
+ rc = dse_check_file(filename, pdse->dse_tmpfile);
+ if (!rc)
+ rc = dse_check_file(filename, pdse->dse_fileback);
+
if ( (rc = PR_GetFileInfo( filename, &prfinfo )) != PR_SUCCESS )
{
slapi_log_error(SLAPI_LOG_FATAL, "dse",
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index d206c6d..a17f40d 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -661,6 +661,7 @@ struct dse *dse_new( char *filename, char *tmpfilename, char
*backfilename, char
struct dse *dse_new_with_filelist(char *filename, char *tmpfilename, char *backfilename,
char *startokfilename, const char *configdir, char **filelist);
int dse_deletedse(Slapi_PBlock *pb);
int dse_destroy(struct dse *pdse);
+int dse_check_file(char *filename, char *backupname);
int dse_read_file(struct dse *pdse, Slapi_PBlock *pb);
int dse_bind( Slapi_PBlock *pb );
int dse_unbind( Slapi_PBlock *pb );