mirror of
https://github.com/samba-team/samba.git
synced 2025-02-25 17:57:42 +03:00
s4:dsdb/descriptor: skip duplicates in descriptor_sd_propagation_object()
We're now sure that the security descriptor propagation happened first for parent objects. It means we can safely skip processing the same object twice in descriptor_sd_propagation_object(). For the database with ~ 22000 objects it reduced the commit time from 2m 50s down to 2m 24s. The statistics are changed from: descriptor_prepare_commit: changes: num_registrations=50000 descriptor_prepare_commit: changes: num_registered=22000 descriptor_prepare_commit: changes: num_toplevel=5 descriptor_prepare_commit: changes: num_processed=5200 descriptor_prepare_commit: objects: num_processed=68800 to: descriptor_prepare_commit: changes: num_registrations=50000 descriptor_prepare_commit: changes: num_registered=22000 descriptor_prepare_commit: changes: num_toplevel=5 descriptor_prepare_commit: changes: num_processed=5200 descriptor_prepare_commit: objects: num_processed=22000 descriptor_prepare_commit: objects: num_skipped=41600 It means that we have "changes: num_registered" and "objects: num_processed" exactly match the number of replicated objects. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Autobuild-User(master): Stefan Metzmacher <metze@samba.org> Autobuild-Date(master): Wed Mar 30 12:06:21 UTC 2022 on sn-devel-184
This commit is contained in:
parent
bd1e667a62
commit
f7f65ceb46
@ -90,7 +90,9 @@ struct descriptor_transaction {
|
||||
size_t num_processed;
|
||||
} changes;
|
||||
struct {
|
||||
struct db_context *map;
|
||||
size_t num_processed;
|
||||
size_t num_skipped;
|
||||
} objects;
|
||||
};
|
||||
|
||||
@ -1088,6 +1090,11 @@ static void descriptor_changes_parser(TDB_DATA key, TDB_DATA data, void *private
|
||||
*c_ptr = talloc_get_type_abort((void *)ptr, struct descriptor_changes);
|
||||
}
|
||||
|
||||
static void descriptor_object_parser(TDB_DATA key, TDB_DATA data, void *private_data)
|
||||
{
|
||||
SMB_ASSERT(data.dsize == 0);
|
||||
}
|
||||
|
||||
static int descriptor_extended_sec_desc_propagation(struct ldb_module *module,
|
||||
struct ldb_request *req)
|
||||
{
|
||||
@ -1263,25 +1270,63 @@ static int descriptor_sd_propagation_object(struct ldb_module *module,
|
||||
struct GUID guid;
|
||||
int ret;
|
||||
TDB_DATA key;
|
||||
TDB_DATA empty_val = { .dsize = 0, };
|
||||
NTSTATUS status;
|
||||
struct descriptor_changes *c = NULL;
|
||||
|
||||
*stop = false;
|
||||
|
||||
t->objects.num_processed += 1;
|
||||
|
||||
/*
|
||||
* We get the GUID of the object
|
||||
* in order to check if there's
|
||||
* a descriptor_changes in our list.
|
||||
* in order to have the cache key
|
||||
* for the object.
|
||||
*/
|
||||
|
||||
status = dsdb_get_extended_dn_guid(msg->dn, &guid, "GUID");
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return ldb_operr(ldb);
|
||||
}
|
||||
|
||||
key = make_tdb_data((const void*)&guid, sizeof(guid));
|
||||
|
||||
/*
|
||||
* Check if we already processed this object.
|
||||
*/
|
||||
status = dbwrap_parse_record(t->objects.map, key,
|
||||
descriptor_object_parser, NULL);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/*
|
||||
* All work is already one
|
||||
*/
|
||||
t->objects.num_skipped += 1;
|
||||
*stop = true;
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
ldb_debug(ldb, LDB_DEBUG_FATAL,
|
||||
"dbwrap_parse_record() - %s\n",
|
||||
nt_errstr(status));
|
||||
return ldb_module_operr(module);
|
||||
}
|
||||
|
||||
t->objects.num_processed += 1;
|
||||
|
||||
/*
|
||||
* Remember that we're processing this object.
|
||||
*/
|
||||
status = dbwrap_store(t->objects.map, key, empty_val, TDB_INSERT);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ldb_debug(ldb, LDB_DEBUG_FATAL,
|
||||
"dbwrap_parse_record() - %s\n",
|
||||
nt_errstr(status));
|
||||
return ldb_module_operr(module);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that if there's a descriptor_change in our list,
|
||||
* which we may be able to remove from the pending list
|
||||
* when we processed the object.
|
||||
*/
|
||||
|
||||
status = dbwrap_parse_record(t->changes.map, key, descriptor_changes_parser, &c);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
c = NULL;
|
||||
@ -1599,6 +1644,12 @@ static int descriptor_start_transaction(struct ldb_module *module)
|
||||
*t = (struct descriptor_transaction) { .mem = NULL, };
|
||||
return ldb_module_oom(module);
|
||||
}
|
||||
t->objects.map = db_open_rbt(t->mem);
|
||||
if (t->objects.map == NULL) {
|
||||
TALLOC_FREE(t->mem);
|
||||
*t = (struct descriptor_transaction) { .mem = NULL, };
|
||||
return ldb_module_oom(module);
|
||||
}
|
||||
|
||||
return ldb_next_start_trans(module);
|
||||
}
|
||||
@ -1748,6 +1799,7 @@ static int descriptor_prepare_commit(struct ldb_module *module)
|
||||
|
||||
DBG_NOTICE("changes: num_processed=%zu\n", t->changes.num_processed);
|
||||
DBG_NOTICE("objects: num_processed=%zu\n", t->objects.num_processed);
|
||||
DBG_NOTICE("objects: num_skipped=%zu\n", t->objects.num_skipped);
|
||||
|
||||
return ldb_next_prepare_commit(module);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user