From: Aaron Haslett Date: Thu, 23 May 2019 07:49:39 +0000 (+1200) Subject: ldb: pack_format_override option X-Git-Tag: ldb-2.0.5~578 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b4abb995215c732ff5c0bfaca2cecb7a374edff;p=thirdparty%2Fsamba.git ldb: pack_format_override option For TDB databases, toggling GUID indexing mode will also toggle pack format version 2. This provides a convenient downgrade path for Samba databases, but the process doesn't work for MDB databases because GUID indexing cannot be disabled when the MDB backend is used. This patch addresses that corner case by providing support for a pack_format_override option which will force the database to use pack format version 2. Signed-off-by: Aaron Haslett Signed-off-by: Andrew Bartlett Reviewed-by: Garming Sam Pair-Programmed-With: Andrew Bartlett --- diff --git a/lib/ldb/ldb_key_value/ldb_kv.c b/lib/ldb/ldb_key_value/ldb_kv.c index 174651ce105..d9b7b0af46a 100644 --- a/lib/ldb/ldb_key_value/ldb_kv.c +++ b/lib/ldb/ldb_key_value/ldb_kv.c @@ -307,6 +307,12 @@ static int ldb_kv_check_special_dn(struct ldb_module *module, * and repacks if necessary. */ static int ldb_kv_maybe_repack(struct ldb_kv_private *ldb_kv) { + /* Override option taken from ldb options */ + if (ldb_kv->pack_format_override != 0) { + ldb_kv->target_pack_format_version = + ldb_kv->pack_format_override; + } + if (ldb_kv->pack_format_version != ldb_kv->target_pack_format_version) { int r; @@ -1933,6 +1939,8 @@ int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, ldb_kv->pid = getpid(); + ldb_kv->pack_format_override = 0; + ldb_kv->module = ldb_module_new(ldb, ldb, name, &ldb_kv_ops); if (!ldb_kv->module) { ldb_oom(ldb); @@ -1969,6 +1977,40 @@ int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, } } + /* + * Usually the presence of GUID indexing determines the pack format + * we use but in certain circumstances such as downgrading an + * MDB-backed database, we want to override the target pack format. + * + * We set/get opaques here because in the Samba partitions module, + * 'options' are not passed correctly so sub-databases can't see + * the options they need. + */ + { + const char *pack_format_override = + ldb_options_find(ldb, options, "pack_format_override"); + if (pack_format_override != NULL) { + int ret; + ldb_kv->pack_format_override = + strtoul(pack_format_override, NULL, 0); + ret = ldb_set_opaque(ldb, + "pack_format_override", + (void *)(intptr_t)ldb_kv->pack_format_override); + if (ret != LDB_SUCCESS) { + talloc_free(ldb_kv->module); + return ldb_module_operr(ldb_kv->module); + } + } else { + /* + * NULL -> 0 is fine, otherwise we get back + * the number we needed + */ + ldb_kv->pack_format_override + = (intptr_t)ldb_get_opaque(ldb, + "pack_format_override"); + } + } + /* * Override full DB scans * diff --git a/lib/ldb/ldb_key_value/ldb_kv.h b/lib/ldb/ldb_key_value/ldb_kv.h index ce9a447186c..8da970fd2f9 100644 --- a/lib/ldb/ldb_key_value/ldb_kv.h +++ b/lib/ldb/ldb_key_value/ldb_kv.h @@ -65,6 +65,7 @@ struct ldb_kv_private { unsigned long long sequence_number; uint32_t pack_format_version; uint32_t target_pack_format_version; + uint32_t pack_format_override; /* the low level tdb seqnum - used to avoid loading BASEINFO when possible */