andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 4 months ago
Clone

Blame 0034-Ticket-518-dse.ldif-is-0-length-after-server-kill-or.patch

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