summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2011-01-07 14:53:39 -0500
committerStephen Gallagher <sgallagh@redhat.com>2011-01-14 08:58:16 -0500
commit09c0743a72604dcae32be246326990bc44e01b44 (patch)
tree7a7a6af3a4faad7df177d8f636524ddd744c25d9
parent337d3d9ba9e271272046feac0d17911d024eb43f (diff)
downloadsssd-09c0743a72604dcae32be246326990bc44e01b44.tar.gz
sssd-09c0743a72604dcae32be246326990bc44e01b44.tar.bz2
sssd-09c0743a72604dcae32be246326990bc44e01b44.zip
Add missing sysdb transaction to group enumerations
We were not enclosing group processing in a transaction, which was resulting in extremely high numbers of disk-writes. This patch adds a transaction around the sdap_process_group code to ensure that these actions take place within a transaction. This patch also adds a check around the missing member code for RFC2307bis so we don't go back to the LDAP server to look up entries that don't exist (since the enumeration first pass would already have guaranteed that we have all real users cached)
-rw-r--r--src/providers/ldap/sdap_async_accounts.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 289b6373..21c3237e 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -959,6 +959,8 @@ struct sdap_process_group_state {
size_t queue_idx;
size_t count;
size_t check_count;
+
+ bool enumeration;
};
#define GROUPMEMBER_REQ_PARALLEL 50
@@ -976,7 +978,8 @@ struct tevent_req *sdap_process_group_send(TALLOC_CTX *memctx,
struct sysdb_ctx *sysdb,
struct sdap_options *opts,
struct sdap_handle *sh,
- struct sysdb_attrs *group)
+ struct sysdb_attrs *group,
+ bool enumeration)
{
struct ldb_message_element *el;
struct sdap_process_group_state *grp_state;
@@ -1016,6 +1019,7 @@ struct tevent_req *sdap_process_group_send(TALLOC_CTX *memctx,
grp_state->queue_len = 0;
grp_state->filter = filter;
grp_state->attrs = attrs;
+ grp_state->enumeration = enumeration;
ret = sysdb_attrs_get_el(group,
opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name,
@@ -1112,15 +1116,23 @@ sdap_process_group_members_2307bis(struct tevent_req *req,
strlen(strdn);
state->sysdb_dns->num_values++;
} else if (ret == ENOENT) {
- /* The user is not in sysdb, need to add it */
- DEBUG(7, ("Searching LDAP for missing user entry\n"));
- ret = sdap_process_missing_member_2307bis(req,
- member_dn,
- memberel->num_values);
- if (ret != EOK) {
- DEBUG(1, ("Error processing missing member #%d (%s):\n",
- i, member_dn));
- return ret;
+ if (!state->enumeration) {
+ /* The user is not in sysdb, need to add it
+ * We don't need to do this if we're in an enumeration,
+ * because all real members should all be populated
+ * already by the first pass of the enumeration.
+ * Also, we don't want to be holding the sysdb
+ * transaction while we're performing LDAP lookups.
+ */
+ DEBUG(7, ("Searching LDAP for missing user entry\n"));
+ ret = sdap_process_missing_member_2307bis(req,
+ member_dn,
+ memberel->num_values);
+ if (ret != EOK) {
+ DEBUG(1, ("Error processing missing member #%d (%s):\n",
+ i, member_dn));
+ return ret;
+ }
}
} else {
DEBUG(1, ("Error checking cache for member #%d (%s):\n",
@@ -1540,6 +1552,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
tevent_req_data(req, struct sdap_get_groups_state);
int ret;
int i;
+ bool enumeration = false;
ret = sdap_get_generic_recv(subreq, state,
&state->count, &state->groups);
@@ -1600,15 +1613,24 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
default:
/* Enumeration */
+ enumeration = true;
break;
}
state->check_count = state->count;
+ ret = sysdb_transaction_start(state->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to start transaction\n"));
+ tevent_req_error(req, ret);
+ return;
+ }
+
for (i = 0; i < state->count; i++) {
subreq = sdap_process_group_send(state, state->ev, state->dom,
state->sysdb, state->opts,
- state->sh, state->groups[i]);
+ state->sh, state->groups[i],
+ enumeration);
if (!subreq) {
tevent_req_error(req, ENOMEM);
@@ -1626,10 +1648,15 @@ static void sdap_get_groups_done(struct tevent_req *subreq)
tevent_req_data(req, struct sdap_get_groups_state);
int ret;
+ errno_t sysret;
ret = sdap_process_group_recv(subreq);
talloc_zfree(subreq);
if (ret) {
+ sysret = sysdb_transaction_cancel(state->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not cancel sysdb transaction\n"));
+ }
tevent_req_error(req, ret);
return;
}
@@ -1650,7 +1677,13 @@ static void sdap_get_groups_done(struct tevent_req *subreq)
return;
}
DEBUG(9, ("Saving %d Groups - Done\n", state->count));
- tevent_req_done(req);
+ sysret = sysdb_transaction_commit(state->sysdb);
+ if (sysret != EOK) {
+ DEBUG(0, ("Couldn't commit transaction\n"));
+ tevent_req_error(req, sysret);
+ } else {
+ tevent_req_done(req);
+ }
}
}