ldap/servers/slapd/back-ldbm/dblayer.c | 166 +++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/instance.c | 12 +
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 18 ++
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 9 +
ldap/servers/slapd/bulk_import.c | 3
ldap/servers/slapd/slapi-plugin.h | 2
7 files changed, 217 insertions(+), 2 deletions(-)
New commits:
commit 900c32f3b0610c3daf31023769fa541e03351b84
Author: Ludwig Krispenz <lkrispen@redhat.com>
Date: Tue Jun 28 17:07:34 2016 +0200
Ticket 48402 - v3 allow plugins to detect a restore or import
Bug Description: RFE
plugins do not know if the database was imported or restored, it could require
different behaviour
Fix Description: set flags in the backends whenever an import or restore was detected.
see: http://www.port389.org/docs/389ds/design/detect-startup-after-import-or-restore.html
https://fedorahosted.org/389/ticket/48402
Reviewed by: Noriko, thanks
diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c
index 6b56937..64d558c 100644
--- a/ldap/servers/slapd/back-ldbm/archive.c
+++ b/ldap/servers/slapd/back-ldbm/archive.c
@@ -69,6 +69,12 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
if (run_from_cmdline) {
mapping_tree_init();
ldbm_config_load_dse_info(li);
+
+ /* initialize a restore file to be able to detect a startup after restore */
+ if (dblayer_restore_file_init(li)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "archive2db: failed to write restore file.\n");
+ return -1;
+ }
}
if (backendname) {
inst = ldbm_instance_find_by_name(li, backendname);
@@ -249,6 +255,9 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
}
}
out:
+ if (run_from_cmdline && ( 0 == return_value )) {
+ dblayer_restore_file_update(li, directory);
+ }
slapi_ch_free_string(&directory);
return return_value;
}
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 783d104..c8d242e 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -203,6 +203,8 @@ static void dblayer_push_pvt_txn(back_txn *txn);
static back_txn *dblayer_get_pvt_txn();
static void dblayer_pop_pvt_txn();
+static int dblayer_post_restore = 0;
+
#define MEGABYTE (1024 * 1024)
#define GIGABYTE (1024 * MEGABYTE)
@@ -1404,6 +1406,9 @@ dblayer_start(struct ldbminfo *li, int dbmode)
/* The error message was output by read_metadata() */
return -1;
}
+ if (dblayer_restore_file_check(li)) {
+ dblayer_set_restored();
+ }
}
dblayer_free_env(&priv->dblayer_env);
@@ -7054,6 +7059,167 @@ error_out:
return return_value;
}
+static char *
+dblayer_import_file_name(ldbm_instance *inst)
+{
+ char *fname = slapi_ch_smprintf("%s/.import_%s",
+ inst->inst_parent_dir_name,
+ inst->inst_dir_name);
+ return fname;
+}
+
+static char *
+dblayer_restore_file_name(struct ldbminfo *li)
+{
+ char *fname = slapi_ch_smprintf("%s/../.restore", li->li_directory);
+
+ return fname;
+}
+
+static int
+dblayer_file_open(char *fname, int flags, int mode, PRFileDesc **prfd)
+{
+ int rc = 0;
+ *prfd = PR_Open(fname, flags, mode );
+
+ if (NULL == *prfd) rc = PR_GetError();
+ if (rc && rc != PR_FILE_NOT_FOUND_ERROR ) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "Failed to open file: %s, error: (%d) %s\n",
+ fname, rc, slapd_pr_strerror(rc));
+ }
+ return rc;
+}
+
+int
+dblayer_import_file_init(ldbm_instance *inst)
+{
+ int rc = -1;
+ PRFileDesc *prfd = NULL;
+ char *fname = dblayer_import_file_name(inst);
+ rc = dblayer_file_open(fname, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, inst->inst_li->li_mode, &prfd);
+ if (prfd) {
+ PR_Close(prfd);
+ rc = 0;
+ }
+ slapi_ch_free_string(&fname);
+ return rc;
+}
+
+int
+dblayer_restore_file_init(struct ldbminfo *li)
+{
+ int rc = -1;
+ PRFileDesc *prfd;
+ char *fname = dblayer_restore_file_name(li);
+ rc = dblayer_file_open(fname, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, li->li_mode, &prfd);
+ if (prfd) {
+ PR_Close(prfd);
+ rc = 0;
+ }
+ slapi_ch_free_string(&fname);
+ return rc;
+
+}
+void
+dblayer_import_file_update(ldbm_instance *inst)
+{
+ int rc;
+ PRFileDesc *prfd;
+ char *fname = dblayer_import_file_name(inst);
+ dblayer_file_open(fname, PR_RDWR, inst->inst_li->li_mode, &prfd);
+
+ if (prfd) {
+ char *line = slapi_ch_smprintf("import of %s succeeded",inst->inst_dir_name);
+ slapi_write_buffer(prfd, line, strlen(line));
+ slapi_ch_free_string(&line);
+ PR_Close(prfd);
+ }
+ slapi_ch_free_string(&fname);
+}
+
+int
+dblayer_file_check(char *fname, int mode)
+{
+ int rc = 0;
+ int err;
+ PRFileDesc *prfd;
+ err = dblayer_file_open(fname, PR_RDWR, mode, &prfd);
+
+ if (prfd) {
+ /* file exists, additional check on size */
+ PRFileInfo64 prfinfo;
+ rc = 1;
+ /* read it */
+ err = PR_GetOpenFileInfo64(prfd, &prfinfo);
+ if (err == PR_SUCCESS && 0 == prfinfo.size) {
+ /* it is empty restore or import has failed */
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Previous import or restore failed, file: %s is empty\n", fname);
+ }
+ PR_Close(prfd);
+ PR_Delete(fname);
+ } else {
+ if (PR_FILE_NOT_FOUND_ERROR == err) {
+ rc = 0;
+ } else {
+ /* file exists, but we cannot open it */
+ rc = 1;
+ /* error is already looged try to delete it*/
+ PR_Delete(fname);
+ }
+ }
+
+ return rc;
+
+}
+int
+dblayer_import_file_check(ldbm_instance *inst)
+{
+ int rc;
+ char *fname = dblayer_import_file_name(inst);
+ rc = dblayer_file_check(fname, inst->inst_li->li_mode);
+ slapi_ch_free_string(&fname);
+ return rc;
+}
+
+int
+dblayer_restore_file_check(struct ldbminfo *li)
+{
+ int rc;
+ char *fname = dblayer_restore_file_name(li);
+ rc = dblayer_file_check(fname, li->li_mode);
+ slapi_ch_free_string(&fname);
+ return rc;
+}
+
+void
+dblayer_restore_file_update(struct ldbminfo *li, char *directory)
+{
+ int rc;
+ PRFileDesc *prfd;
+ char *fname = dblayer_restore_file_name(li);
+ dblayer_file_open(fname, PR_RDWR, li->li_mode, &prfd);
+ if (prfd) {
+ char *line = slapi_ch_smprintf("restore of %s succeeded", directory);
+ slapi_write_buffer(prfd, line, strlen(line));
+ slapi_ch_free_string(&line);
+ PR_Close(prfd);
+ }
+}
+
+int
+dblayer_is_restored(void)
+{
+ return dblayer_post_restore;
+}
+
+void
+dblayer_set_restored(void)
+{
+ dblayer_post_restore = 1;
+}
+
/*
* inst_dir_name is a relative path (from 6.21)
* ==> txn log stores relative paths and becomes relocatable
diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
index 53d922e..f059e8a 100644
--- a/ldap/servers/slapd/back-ldbm/instance.c
+++ b/ldap/servers/slapd/back-ldbm/instance.c
@@ -299,7 +299,16 @@ ldbm_instance_stop(backend *be)
return rc;
}
-
+static void
+ldbm_instance_set_flags(ldbm_instance *inst)
+{
+ if (dblayer_is_restored()) {
+ slapi_be_set_flag(inst->inst_be, SLAPI_BE_FLAG_POST_RESTORE);
+ }
+ if (dblayer_import_file_check(inst)) {
+ slapi_be_set_flag(inst->inst_be, SLAPI_BE_FLAG_POST_IMPORT);
+ }
+}
/* Walks down the set of instances, starting each one. */
int
@@ -313,6 +322,7 @@ ldbm_instance_startall(struct ldbminfo *li)
while (inst_obj != NULL) {
int rc1;
inst = (ldbm_instance *) object_get_data(inst_obj);
+ ldbm_instance_set_flags(inst);
rc1 = ldbm_instance_start(inst->inst_be);
if (rc1 != 0) {
rc = rc1;
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 5898361..7aae93d 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -690,6 +690,14 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb )
return -1;
}
+ if ((task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE)) {
+ if (dblayer_import_file_init(inst)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "ldbm_back_ldif2ldbm: failed to write import file\n");
+ return -1;
+ }
+ }
+
/***** prepare & init libdb and dblayer *****/
if (! (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE)) {
@@ -766,7 +774,15 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb )
/* always use "new" import code now */
slapi_pblock_set(pb, SLAPI_BACKEND, inst->inst_be);
- return ldbm_back_ldif2ldbm_deluxe(pb);
+ ret = ldbm_back_ldif2ldbm_deluxe(pb);
+ if (ret == 0) {
+ if (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) {
+ dblayer_import_file_update(inst);
+ } else {
+ slapi_be_set_flag(inst->inst_be, SLAPI_BE_FLAG_POST_IMPORT);
+ }
+ }
+ return ret;
fail:
/* DON'T enable the backend -- leave it offline */
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 8c813dd..1647163 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -168,6 +168,15 @@ int ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info);
int ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info);
int ldbm_back_ctrl_info(Slapi_Backend *be, int cmd, void *info);
+int dblayer_is_restored(void);
+void dblayer_set_restored(void);
+int dblayer_restore_file_check(struct ldbminfo *li);
+int dblayer_restore_file_init(struct ldbminfo *li);
+void dblayer_restore_file_update(struct ldbminfo *li, char *directory);
+int dblayer_import_file_init(ldbm_instance *inst);
+void dblayer_import_file_update(ldbm_instance *inst);
+int dblayer_import_file_check(ldbm_instance *inst);
+
/*
* dn2entry.c
*/
diff --git a/ldap/servers/slapd/bulk_import.c b/ldap/servers/slapd/bulk_import.c
index c63faa1..35f9855 100644
--- a/ldap/servers/slapd/bulk_import.c
+++ b/ldap/servers/slapd/bulk_import.c
@@ -146,6 +146,9 @@ process_bulk_import_op (Slapi_PBlock *pb, int state, Slapi_Entry *e)
"failed; error = %d\n", rc);
return LDAP_OPERATIONS_ERROR;
}
+ if (state == SLAPI_BI_STATE_DONE) {
+ slapi_be_set_flag(be, SLAPI_BE_FLAG_POST_IMPORT);
+ }
return LDAP_SUCCESS;
}
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index a7e544a..89853c0 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6460,6 +6460,8 @@ void slapi_be_set_flag(Slapi_Backend * be, int flag);
void slapi_be_unset_flag(Slapi_Backend * be, int flag);
#define SLAPI_BE_FLAG_REMOTE_DATA 0x1 /* entries held by backend are remote */
#define SLAPI_BE_FLAG_DONT_BYPASS_FILTERTEST 0x10 /* force to call filter_test (search only) */
+#define SLAPI_BE_FLAG_POST_IMPORT 0x100 /* backend was imported */
+#define SLAPI_BE_FLAG_POST_RESTORE 0x200 /* startup after restore */
/* These functions allow a plugin to register for callback when
--
389-commits mailing list
389-commits@lists.fedoraproject.org
https://lists.fedoraproject.org/admin/lists/389-commits@lists.fedoraproject.org
No comments:
Post a Comment