|
|
6f51e1 |
From ba30cc562f5ebd58955502a19edbf9720a45b655 Mon Sep 17 00:00:00 2001
|
|
|
6f51e1 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
6f51e1 |
Date: Tue, 8 Aug 2017 13:02:53 -0400
|
|
|
6f51e1 |
Subject: [PATCH] Ticket 49298 - force sync() on shutdown
|
|
|
6f51e1 |
|
|
|
6f51e1 |
Bug Description: During shutdown on xfs we would occasionally
|
|
|
6f51e1 |
see a broke dse.ldif (specifically, empty). This happens due to
|
|
|
6f51e1 |
a bug in xfs where the directory isn't synced on rename().
|
|
|
6f51e1 |
|
|
|
6f51e1 |
Fix Description: As we shutdown call sync() to force all our
|
|
|
6f51e1 |
writes to disk - dse.ldif, logs, db, all of it.
|
|
|
6f51e1 |
|
|
|
6f51e1 |
https://pagure.io/389-ds-base/issue/49298
|
|
|
6f51e1 |
---
|
|
|
6f51e1 |
ldap/servers/slapd/dse.c | 59 +++++++++++++++++++++++++++++------------------
|
|
|
6f51e1 |
ldap/servers/slapd/main.c | 9 ++++----
|
|
|
6f51e1 |
2 files changed, 42 insertions(+), 26 deletions(-)
|
|
|
6f51e1 |
|
|
|
6f51e1 |
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
|
|
6f51e1 |
index 5715c83..fa1aacc 100644
|
|
|
6f51e1 |
--- a/ldap/servers/slapd/dse.c
|
|
|
6f51e1 |
+++ b/ldap/servers/slapd/dse.c
|
|
|
6f51e1 |
@@ -40,6 +40,8 @@
|
|
|
6f51e1 |
#include "slap.h"
|
|
|
6f51e1 |
#include <pwd.h>
|
|
|
6f51e1 |
|
|
|
6f51e1 |
+#include <unistd.h> /* provides fsync/close */
|
|
|
6f51e1 |
+
|
|
|
6f51e1 |
/* #define SLAPI_DSE_DEBUG */ /* define this to force trace log */
|
|
|
6f51e1 |
/* messages to always be logged */
|
|
|
6f51e1 |
|
|
|
6f51e1 |
@@ -72,11 +74,11 @@
|
|
|
6f51e1 |
struct dse_callback
|
|
|
6f51e1 |
{
|
|
|
6f51e1 |
int operation;
|
|
|
6f51e1 |
- int flags;
|
|
|
6f51e1 |
- Slapi_DN *base;
|
|
|
6f51e1 |
- int scope;
|
|
|
6f51e1 |
- char *filter; /* NULL means match all entries */
|
|
|
6f51e1 |
- Slapi_Filter *slapifilter; /* NULL means match all entries */
|
|
|
6f51e1 |
+ int flags;
|
|
|
6f51e1 |
+ Slapi_DN *base;
|
|
|
6f51e1 |
+ int scope;
|
|
|
6f51e1 |
+ char *filter; /* NULL means match all entries */
|
|
|
6f51e1 |
+ Slapi_Filter *slapifilter; /* NULL means match all entries */
|
|
|
6f51e1 |
int (*fn)(Slapi_PBlock *,Slapi_Entry *,Slapi_Entry *,int*,char*,void *);
|
|
|
6f51e1 |
void *fn_arg;
|
|
|
6f51e1 |
struct slapdplugin *plugin;
|
|
|
6f51e1 |
@@ -89,13 +91,14 @@ struct dse
|
|
|
6f51e1 |
char *dse_tmpfile; /* and written to when changes are made via LDAP */
|
|
|
6f51e1 |
char *dse_fileback; /* contain the latest info, just before a new change */
|
|
|
6f51e1 |
char *dse_filestartOK; /* contain the latest info with which the server has successfully started */
|
|
|
6f51e1 |
+ char *dse_configdir; /* The location of config files - allows us to fsync the dir post rename */
|
|
|
6f51e1 |
Avlnode *dse_tree;
|
|
|
6f51e1 |
struct dse_callback *dse_callback;
|
|
|
6f51e1 |
Slapi_RWLock *dse_rwlock; /* a read-write lock to protect the whole dse backend */
|
|
|
6f51e1 |
- char **dse_filelist; /* these are additional read only files used to */
|
|
|
6f51e1 |
- /* initialize the dse */
|
|
|
6f51e1 |
- int dse_is_updateable; /* if non-zero, this DSE can be written to */
|
|
|
6f51e1 |
- int dse_readonly_error_reported; /* used to ensure that read-only errors are logged only once */
|
|
|
6f51e1 |
+ char **dse_filelist; /* these are additional read only files used to */
|
|
|
6f51e1 |
+ /* initialize the dse */
|
|
|
6f51e1 |
+ int dse_is_updateable; /* if non-zero, this DSE can be written to */
|
|
|
6f51e1 |
+ int dse_readonly_error_reported; /* used to ensure that read-only errors are logged only once */
|
|
|
6f51e1 |
};
|
|
|
6f51e1 |
|
|
|
6f51e1 |
struct dse_node
|
|
|
6f51e1 |
@@ -361,37 +364,39 @@ dse_new( char *filename, char *tmpfilename, char *backfilename, char *startokfil
|
|
|
6f51e1 |
if (!strstr(filename, realconfigdir))
|
|
|
6f51e1 |
{
|
|
|
6f51e1 |
pdse->dse_filename = slapi_ch_smprintf("%s/%s", realconfigdir, filename );
|
|
|
6f51e1 |
- }
|
|
|
6f51e1 |
- else
|
|
|
6f51e1 |
+ } else {
|
|
|
6f51e1 |
pdse->dse_filename = slapi_ch_strdup(filename);
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
|
|
|
6f51e1 |
if (!strstr(tmpfilename, realconfigdir)) {
|
|
|
6f51e1 |
pdse->dse_tmpfile = slapi_ch_smprintf("%s/%s", realconfigdir, tmpfilename );
|
|
|
6f51e1 |
- }
|
|
|
6f51e1 |
- else
|
|
|
6f51e1 |
+ } else {
|
|
|
6f51e1 |
pdse->dse_tmpfile = slapi_ch_strdup(tmpfilename);
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
+
|
|
|
6f51e1 |
+ pdse->dse_configdir = slapi_ch_strdup(realconfigdir);
|
|
|
6f51e1 |
|
|
|
6f51e1 |
if ( backfilename != NULL )
|
|
|
6f51e1 |
{
|
|
|
6f51e1 |
if (!strstr(backfilename, realconfigdir)) {
|
|
|
6f51e1 |
pdse->dse_fileback = slapi_ch_smprintf("%s/%s", realconfigdir, backfilename );
|
|
|
6f51e1 |
- }
|
|
|
6f51e1 |
- else
|
|
|
6f51e1 |
+ } else {
|
|
|
6f51e1 |
pdse->dse_fileback = slapi_ch_strdup(backfilename);
|
|
|
6f51e1 |
- }
|
|
|
6f51e1 |
- else
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
+ } else {
|
|
|
6f51e1 |
pdse->dse_fileback = NULL;
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
|
|
|
6f51e1 |
if ( startokfilename != NULL )
|
|
|
6f51e1 |
{
|
|
|
6f51e1 |
if (!strstr(startokfilename, realconfigdir)) {
|
|
|
6f51e1 |
pdse->dse_filestartOK = slapi_ch_smprintf("%s/%s", realconfigdir, startokfilename );
|
|
|
6f51e1 |
- }
|
|
|
6f51e1 |
- else
|
|
|
6f51e1 |
+ } else {
|
|
|
6f51e1 |
pdse->dse_filestartOK = slapi_ch_strdup(startokfilename);
|
|
|
6f51e1 |
- }
|
|
|
6f51e1 |
- else
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
+ } else {
|
|
|
6f51e1 |
pdse->dse_filestartOK = NULL;
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
|
|
|
6f51e1 |
pdse->dse_tree= NULL;
|
|
|
6f51e1 |
pdse->dse_callback= NULL;
|
|
|
6f51e1 |
@@ -440,6 +445,7 @@ dse_destroy(struct dse *pdse)
|
|
|
6f51e1 |
slapi_ch_free((void **)&(pdse->dse_tmpfile));
|
|
|
6f51e1 |
slapi_ch_free((void **)&(pdse->dse_fileback));
|
|
|
6f51e1 |
slapi_ch_free((void **)&(pdse->dse_filestartOK));
|
|
|
6f51e1 |
+ slapi_ch_free((void **)&(pdse->dse_configdir));
|
|
|
6f51e1 |
dse_callback_deletelist(&pdse->dse_callback);
|
|
|
6f51e1 |
charray_free(pdse->dse_filelist);
|
|
|
6f51e1 |
nentries = avl_free(pdse->dse_tree, dse_internal_delete_entry);
|
|
|
6f51e1 |
@@ -991,8 +997,9 @@ dse_write_file_nolock(struct dse* pdse)
|
|
|
6f51e1 |
FPWrapper fpw;
|
|
|
6f51e1 |
int rc = 0;
|
|
|
6f51e1 |
|
|
|
6f51e1 |
- if (dont_ever_write_dse_files)
|
|
|
6f51e1 |
+ if (dont_ever_write_dse_files) {
|
|
|
6f51e1 |
return rc;
|
|
|
6f51e1 |
+ }
|
|
|
6f51e1 |
|
|
|
6f51e1 |
fpw.fpw_rc = 0;
|
|
|
6f51e1 |
fpw.fpw_prfd = NULL;
|
|
|
6f51e1 |
@@ -1042,6 +1049,14 @@ dse_write_file_nolock(struct dse* pdse)
|
|
|
6f51e1 |
pdse->dse_tmpfile, pdse->dse_filename,
|
|
|
6f51e1 |
rc, slapd_system_strerror( rc ));
|
|
|
6f51e1 |
}
|
|
|
6f51e1 |
+ /*
|
|
|
6f51e1 |
+ * We have now written to the tmp location, and renamed it
|
|
|
6f51e1 |
+ * we need to open and fsync the dir to make the rename stick.
|
|
|
6f51e1 |
+ */
|
|
|
6f51e1 |
+ int fp_configdir = open(pdse->dse_configdir, O_PATH | O_DIRECTORY);
|
|
|
6f51e1 |
+ fsync(fp_configdir);
|
|
|
6f51e1 |
+ close(fp_configdir);
|
|
|
6f51e1 |
+
|
|
|
6f51e1 |
}
|
|
|
6f51e1 |
}
|
|
|
6f51e1 |
if (fpw.fpw_prfd)
|
|
|
6f51e1 |
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
|
|
|
6f51e1 |
index ba1f5e8..3351464 100644
|
|
|
6f51e1 |
--- a/ldap/servers/slapd/main.c
|
|
|
6f51e1 |
+++ b/ldap/servers/slapd/main.c
|
|
|
6f51e1 |
@@ -1154,11 +1154,12 @@ cleanup:
|
|
|
6f51e1 |
ndn_cache_destroy();
|
|
|
6f51e1 |
NSS_Shutdown();
|
|
|
6f51e1 |
PR_Cleanup();
|
|
|
6f51e1 |
-#if defined( hpux )
|
|
|
6f51e1 |
- exit( return_value );
|
|
|
6f51e1 |
-#else
|
|
|
6f51e1 |
+ /*
|
|
|
6f51e1 |
+ * Server has stopped, lets force everything to disk: logs
|
|
|
6f51e1 |
+ * db, dse.ldif, all of it.
|
|
|
6f51e1 |
+ */
|
|
|
6f51e1 |
+ sync();
|
|
|
6f51e1 |
return return_value;
|
|
|
6f51e1 |
-#endif
|
|
|
6f51e1 |
}
|
|
|
6f51e1 |
|
|
|
6f51e1 |
|
|
|
6f51e1 |
--
|
|
|
6f51e1 |
2.9.4
|
|
|
6f51e1 |
|