diff options
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 3 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_load.c | 39 | ||||
-rw-r--r-- | source4/dsdb/samdb/samdb.h | 1 | ||||
-rw-r--r-- | source4/dsdb/schema/schema.h | 1 |
4 files changed, 42 insertions, 2 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 41c97bf32a..7b98dd62c1 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 Copyright (C) Simo Sorce 2004-2008 Copyright (C) Matthias Dieter Wallnöfer 2009-2011 + Copyright (C) Matthieu Patou 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -428,6 +429,8 @@ static int samldb_add_handle_msDS_IntId(struct samldb_ctx *ac) struct ldb_context *ldb; struct ldb_result *ldb_res; struct ldb_dn *schema_dn; + struct samldb_msds_intid_persistant *msds_intid_struct; + struct dsdb_schema *schema; ldb = ldb_module_get_ctx(ac->module); schema_dn = ldb_get_schema_basedn(ldb); diff --git a/source4/dsdb/samdb/ldb_modules/schema_load.c b/source4/dsdb/samdb/ldb_modules/schema_load.c index 4c166d51ce..f922aabba9 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_load.c +++ b/source4/dsdb/samdb/ldb_modules/schema_load.c @@ -49,6 +49,10 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct struct dsdb_control_current_partition *ctrl; struct ldb_context *ldb = ldb_module_get_ctx(module); struct dsdb_schema *new_schema; + int interval; + time_t ts, lastts; + struct loadparm_context *lp_ctx = + (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"); struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data); if (!private_data) { @@ -61,6 +65,14 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct return schema; } + lastts = schema->last_refresh; + ts = time(NULL); + interval = lpcfg_parm_int(lp_ctx, NULL, "dsdb", "schema_reload_interval", 120); + if (lastts > (ts - interval)) { + DEBUG(11, ("Less than %d seconds since last reload, returning cached version ts = %d\n", interval, (int)lastts)); + return schema; + } + res = talloc_zero(schema, struct ldb_result); if (res == NULL) { return NULL; @@ -84,7 +96,16 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct talloc_free(res); return NULL; } - + + /* + * We update right now the last refresh timestamp so that if + * the schema partition hasn't change we don't keep on retrying. + * Otherwise if the timestamp was update only when the schema has + * actually changed (and therefor completely reloaded) we would + * continue to hit the database to get the highest USN. + */ + schema->last_refresh = ts; + ctrl = talloc(treq, struct dsdb_control_current_partition); if (!ctrl) { talloc_free(res); @@ -130,7 +151,7 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct if (ret != LDB_SUCCESS) { return schema; } - + if (is_global_schema) { dsdb_make_schema_global(ldb, new_schema); } @@ -226,6 +247,7 @@ static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_ ret = dsdb_set_schema(ldb, (*schema)); (*schema)->refresh_in_progress = false; + (*schema)->last_refresh = time(NULL); if (ret != LDB_SUCCESS) { ldb_debug_set(ldb, LDB_DEBUG_FATAL, @@ -324,9 +346,22 @@ static int schema_load_del_transaction(struct ldb_module *module) static int schema_load_extended(struct ldb_module *module, struct ldb_request *req) { + time_t *lastts; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct dsdb_schema *schema; + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) { return ldb_next_request(module, req); } + lastts = (time_t *)ldb_get_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME); + if (!lastts) { + lastts = talloc(ldb, time_t); + } + schema = dsdb_get_schema(ldb, NULL); + /* Force a refresh */ + schema->last_refresh = 0; + *lastts = 0; + ldb_set_opaque(ldb, DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME, lastts); /* This is a no-op. We reload as soon as we can */ return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index 50f7bf7d13..2a4bd355eb 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -199,6 +199,7 @@ struct dsdb_extended_dn_store_format { bool store_extended_dn_in_ldb; }; +#define DSDB_OPAQUE_LAST_SCHEMA_UPDATE_MSG_OPAQUE_NAME "DSDB_OPAQUE_LAST_SCHEMA_UPDATE" #define DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME "DSDB_OPAQUE_PARTITION_MODULE_MSG" /* this takes a struct dsdb_fsmo_extended_op */ diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h index b1ae76882a..d3dd035e01 100644 --- a/source4/dsdb/schema/schema.h +++ b/source4/dsdb/schema/schema.h @@ -245,6 +245,7 @@ struct dsdb_schema { struct ldb_module *loaded_from_module; struct dsdb_schema *(*refresh_fn)(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema); bool refresh_in_progress; + time_t last_refresh; /* an 'opaque' sequence number that the reload function may also wish to use */ uint64_t reload_seq_number; |