|
|
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 |
|