ldb: pack_format_override option
authorAaron Haslett <aaronhaslett@catalyst.net.nz>
Thu, 23 May 2019 07:49:39 +0000 (19:49 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 29 May 2019 04:41:25 +0000 (04:41 +0000)
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 <aaronhaslett@catalyst.net.nz>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

lib/ldb/ldb_key_value/ldb_kv.c
lib/ldb/ldb_key_value/ldb_kv.h

index 174651ce1058746017dc402c53772eff788a4bda..d9b7b0af46a1e05dc1cccc18604f8ec6f4cda230 100644 (file)
@@ -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
         *
index ce9a447186c21d747ad7c98a2c9a362e3c735811..8da970fd2f981c73f0e6eb2518688365595adf9f 100644 (file)
@@ -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 */