|
|
cc3dff |
From 298ada3b2f7b8aa770df9a5a7d8129f46b4417d7 Mon Sep 17 00:00:00 2001
|
|
|
cc3dff |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
cc3dff |
Date: Mon, 16 Dec 2013 13:03:19 -0800
|
|
|
cc3dff |
Subject: [PATCH 73/78] Ticket #47606 - replica init/bulk import errors should
|
|
|
cc3dff |
be more verbose
|
|
|
cc3dff |
|
|
|
cc3dff |
Description:
|
|
|
cc3dff |
1. maxbersize: If the size of an entry is larger than the consumer's
|
|
|
cc3dff |
maxbersize, the following error used to be logged:
|
|
|
cc3dff |
Incoming BER Element was too long, max allowable is ### bytes.
|
|
|
cc3dff |
Change the nsslapd-maxbersize attribute in cn=config to increase.
|
|
|
cc3dff |
This message does not indicate how large the maxbersize needs to be.
|
|
|
cc3dff |
This patch adds the code to retrieve the failed ber size.
|
|
|
cc3dff |
Revised message:
|
|
|
cc3dff |
Incoming BER Element was @@@ bytes, max allowable is ### bytes.
|
|
|
cc3dff |
Change the nsslapd-maxbersize attribute in cn=config to increase.
|
|
|
cc3dff |
Note: There is no lber API that returns the ber size if it fails to
|
|
|
cc3dff |
handle the ber. This patch borrows the internal structure of ber
|
|
|
cc3dff |
and get the size. This could be risky since the size or structure
|
|
|
cc3dff |
of the ber could be updated in the openldap/mozldap lber.
|
|
|
cc3dff |
2. cache size: The bulk import depends upon the nsslapd-cachememsize
|
|
|
cc3dff |
value in the backend instance entry (e.g., cn=userRoot,cn=ldbm
|
|
|
cc3dff |
database,cn=plugins,cn=config). If an entry size is larger than
|
|
|
cc3dff |
the cachememsize, the bulk import used to fail with this message:
|
|
|
cc3dff |
import userRoot: REASON: entry too large (@@@ bytes) for the
|
|
|
cc3dff |
import buffer size (### bytes). Try increasing nsslapd-
|
|
|
cc3dff |
cachememsize.
|
|
|
cc3dff |
Also, the message follows the skipping entry message:
|
|
|
cc3dff |
import userRoot: WARNING: skipping entry "<DN>"
|
|
|
cc3dff |
but actually, it did NOT "skip" the entry and continue the bulk
|
|
|
cc3dff |
import, but it failed there and completely wiped out the backend
|
|
|
cc3dff |
database.
|
|
|
cc3dff |
This patch modifies the message as follows:
|
|
|
cc3dff |
import userRoot: REASON: entry too large (@@@ bytes) for the
|
|
|
cc3dff |
effective import buffer size (### bytes). Try increasing nsslapd-
|
|
|
cc3dff |
cachememsize for the backend instance "userRoot".
|
|
|
cc3dff |
and as the message mentions, it just skips the failed entry and
|
|
|
cc3dff |
continues the bulk import.
|
|
|
cc3dff |
3. In repl5_tot_result_threadmain, when conn_read_result_ex returns
|
|
|
cc3dff |
non zero (non SUCCESS), it sets abort, but does not set any error
|
|
|
cc3dff |
code to rc (return code), which is not considered as "finished" in
|
|
|
cc3dff |
repl5_tot_waitfor_async_results and it contines waiting until the
|
|
|
cc3dff |
code reaches the max loop count (about 5 minutes). This patch sets
|
|
|
cc3dff |
LDAP_CONNECT_ERROR to the return code along with setting abort, if
|
|
|
cc3dff |
conn_read_result_ex returns CONN_NOT_CONNECTED. This makes the bulk
|
|
|
cc3dff |
import finishes quickly when it fails.
|
|
|
cc3dff |
|
|
|
cc3dff |
https://fedorahosted.org/389/ticket/47606
|
|
|
cc3dff |
|
|
|
cc3dff |
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
|
|
|
cc3dff |
(cherry picked from commit 1119083d3d99993421609783efcb8962d78724fc)
|
|
|
cc3dff |
(cherry picked from commit fde9ed5bf74b4ea1fff875bcb421137c78af1227)
|
|
|
cc3dff |
(cherry picked from commit c9d0b6ccad84dd56a536da883f5a8e5acb01bc4e)
|
|
|
cc3dff |
---
|
|
|
cc3dff |
.../plugins/replication/repl5_tot_protocol.c | 3 ++
|
|
|
cc3dff |
ldap/servers/slapd/back-ldbm/import-threads.c | 8 ++---
|
|
|
cc3dff |
ldap/servers/slapd/connection.c | 36 ++++++++++++++++++----
|
|
|
cc3dff |
ldap/servers/slapd/openldapber.h | 25 +++++++++++++++
|
|
|
cc3dff |
4 files changed, 62 insertions(+), 10 deletions(-)
|
|
|
cc3dff |
create mode 100644 ldap/servers/slapd/openldapber.h
|
|
|
cc3dff |
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
|
|
cc3dff |
index a241128..3895ace 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
|
|
cc3dff |
@@ -203,6 +203,9 @@ static void repl5_tot_result_threadmain(void *param)
|
|
|
cc3dff |
/* If so then we need to take steps to abort the update process */
|
|
|
cc3dff |
PR_Lock(cb->lock);
|
|
|
cc3dff |
cb->abort = 1;
|
|
|
cc3dff |
+ if (conres == CONN_NOT_CONNECTED) {
|
|
|
cc3dff |
+ cb->rc = LDAP_CONNECT_ERROR;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
PR_Unlock(cb->lock);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
/* Should we stop ? */
|
|
|
cc3dff |
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
|
|
|
cc3dff |
index c0475c6..95433aa 100644
|
|
|
cc3dff |
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
|
|
|
cc3dff |
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
|
|
|
cc3dff |
@@ -3330,11 +3330,11 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
|
|
|
cc3dff |
|
|
|
cc3dff |
newesize = (slapi_entry_size(ep->ep_entry) + sizeof(struct backentry));
|
|
|
cc3dff |
if (newesize > job->fifo.bsize) { /* entry too big */
|
|
|
cc3dff |
- import_log_notice(job, "WARNING: skipping entry \"%s\"",
|
|
|
cc3dff |
- slapi_entry_get_dn(ep->ep_entry));
|
|
|
cc3dff |
import_log_notice(job, "REASON: entry too large (%lu bytes) for "
|
|
|
cc3dff |
- "the import buffer size (%lu bytes). Try increasing nsslapd-cachememsize.",
|
|
|
cc3dff |
- (long unsigned int)newesize, (long unsigned int)job->fifo.bsize);
|
|
|
cc3dff |
+ "the effective import buffer size (%lu bytes). "
|
|
|
cc3dff |
+ "Try increasing nsslapd-cachememsize for the backend instance \"%s\".",
|
|
|
cc3dff |
+ (long unsigned int)newesize, (long unsigned int)job->fifo.bsize,
|
|
|
cc3dff |
+ job->inst->inst_name);
|
|
|
cc3dff |
backentry_clear_entry(ep); /* entry is released in the frontend on failure*/
|
|
|
cc3dff |
backentry_free( &ep ); /* release the backend wrapper, here */
|
|
|
cc3dff |
PR_Unlock(job->wire_lock);
|
|
|
cc3dff |
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
|
|
cc3dff |
index fed3512..02c86c5 100644
|
|
|
cc3dff |
--- a/ldap/servers/slapd/connection.c
|
|
|
cc3dff |
+++ b/ldap/servers/slapd/connection.c
|
|
|
cc3dff |
@@ -1749,6 +1749,32 @@ void connection_make_new_pb(Slapi_PBlock **ppb, Connection *conn)
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
|
|
|
cc3dff |
+#ifdef USE_OPENLDAP
|
|
|
cc3dff |
+#include "openldapber.h"
|
|
|
cc3dff |
+#else
|
|
|
cc3dff |
+#include "mozldap.h"
|
|
|
cc3dff |
+#endif
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+static ber_tag_t
|
|
|
cc3dff |
+_ber_get_len(BerElement *ber, ber_len_t *lenp)
|
|
|
cc3dff |
+{
|
|
|
cc3dff |
+#ifdef USE_OPENLDAP
|
|
|
cc3dff |
+ OLBerElement *lber = (OLBerElement *)ber;
|
|
|
cc3dff |
+#else
|
|
|
cc3dff |
+ MozElement *lber = (MozElement *)ber;
|
|
|
cc3dff |
+#endif
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ if (NULL == lenp) {
|
|
|
cc3dff |
+ return LBER_DEFAULT;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ *lenp = 0;
|
|
|
cc3dff |
+ if (NULL == lber) {
|
|
|
cc3dff |
+ return LBER_DEFAULT;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ *lenp = lber->ber_len;
|
|
|
cc3dff |
+ return lber->ber_tag;
|
|
|
cc3dff |
+}
|
|
|
cc3dff |
+
|
|
|
cc3dff |
/*
|
|
|
cc3dff |
* Utility function called by connection_read_operation(). This is a
|
|
|
cc3dff |
* small wrapper on top of libldap's ber_get_next_buffer_ext().
|
|
|
cc3dff |
@@ -1787,18 +1813,16 @@ get_next_from_buffer( void *buffer, size_t buffer_size, ber_len_t *lenp,
|
|
|
cc3dff |
if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned &&
|
|
|
cc3dff |
!SLAPD_SYSTEM_WOULD_BLOCK_ERROR(errno))
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- if (LBER_OVERFLOW == *tagp)
|
|
|
cc3dff |
- {
|
|
|
cc3dff |
- err = SLAPD_DISCONNECT_BER_TOO_BIG;
|
|
|
cc3dff |
- }
|
|
|
cc3dff |
- else if (errno == ERANGE)
|
|
|
cc3dff |
+ if ((LBER_OVERFLOW == *tagp) || (errno == ERANGE))
|
|
|
cc3dff |
{
|
|
|
cc3dff |
ber_len_t maxbersize = config_get_maxbersize();
|
|
|
cc3dff |
+ ber_len_t tmplen = 0;
|
|
|
cc3dff |
+ (void)_ber_get_len(ber, &tmplen);
|
|
|
cc3dff |
/* openldap does not differentiate between length == 0
|
|
|
cc3dff |
and length > max - all we know is that there was a
|
|
|
cc3dff |
problem with the length - assume too big */
|
|
|
cc3dff |
err = SLAPD_DISCONNECT_BER_TOO_BIG;
|
|
|
cc3dff |
- log_ber_too_big_error(conn, 0, maxbersize);
|
|
|
cc3dff |
+ log_ber_too_big_error(conn, tmplen, maxbersize);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
else
|
|
|
cc3dff |
{
|
|
|
cc3dff |
diff --git a/ldap/servers/slapd/openldapber.h b/ldap/servers/slapd/openldapber.h
|
|
|
cc3dff |
new file mode 100644
|
|
|
cc3dff |
index 0000000..52644a5
|
|
|
cc3dff |
--- /dev/null
|
|
|
cc3dff |
+++ b/ldap/servers/slapd/openldapber.h
|
|
|
cc3dff |
@@ -0,0 +1,25 @@
|
|
|
cc3dff |
+/*
|
|
|
cc3dff |
+ * openldap lber library does not provide an API which returns the ber size
|
|
|
cc3dff |
+ * (ber->ber_len) when the ber tag is LBER_DEFAULT or LBER_OVERFLOW.
|
|
|
cc3dff |
+ * The ber size is useful when issuing an error message to indicate how
|
|
|
cc3dff |
+ * large the maxbersize needs to be set.
|
|
|
cc3dff |
+ * Borrowed from liblber/lber-int.h
|
|
|
cc3dff |
+ */
|
|
|
cc3dff |
+struct lber_options {
|
|
|
cc3dff |
+ short lbo_valid;
|
|
|
cc3dff |
+ unsigned short lbo_options;
|
|
|
cc3dff |
+ int lbo_debug;
|
|
|
cc3dff |
+};
|
|
|
cc3dff |
+struct berelement {
|
|
|
cc3dff |
+ struct lber_options ber_opts;
|
|
|
cc3dff |
+ ber_tag_t ber_tag;
|
|
|
cc3dff |
+ ber_len_t ber_len;
|
|
|
cc3dff |
+ ber_tag_t ber_usertag;
|
|
|
cc3dff |
+ char *ber_buf;
|
|
|
cc3dff |
+ char *ber_ptr;
|
|
|
cc3dff |
+ char *ber_end;
|
|
|
cc3dff |
+ char *ber_sos_ptr;
|
|
|
cc3dff |
+ char *ber_rwptr;
|
|
|
cc3dff |
+ void *ber_memctx;
|
|
|
cc3dff |
+};
|
|
|
cc3dff |
+typedef struct berelement OLBerElement;
|
|
|
cc3dff |
--
|
|
|
cc3dff |
1.8.1.4
|
|
|
cc3dff |
|