autorid: make the whole initialization atomic with one transaction.
authorMichael Adam <obnox@samba.org>
Thu, 20 Mar 2014 23:18:36 +0000 (00:18 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 3 Apr 2014 00:41:25 +0000 (02:41 +0200)
Originally, there were several writing operations:

- store the range HWM
- store the alloc uid HWM
- store the alloc gid HWM
- store the config
- create mappings for a whole list of wellknown sids

Each of these consisted of its own transaction,
the wellknown preallocation even of one transaction per sid.

This change wrapps all of these in one big transaction.
Thereby making the whole initialization atomic, and
with respect to the creation of the wellknown mappings
also more deterministic.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Apr  3 02:41:25 CEST 2014 on sn-devel-104

source3/winbindd/idmap_autorid.c

index 5b4b7ef1e6bc5f1336f42f51007c7ea3d83d4593..7e17b6634e06e5bde146374e213bbafac4f4b93c 100644 (file)
@@ -580,6 +580,39 @@ static NTSTATUS idmap_autorid_preallocate_wellknown(struct idmap_domain *dom)
        return NT_STATUS_IS_OK(status)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
 }
 
+static NTSTATUS idmap_autorid_initialize_action(struct db_context *db,
+                                               void *private_data)
+{
+       struct idmap_domain *dom;
+       struct idmap_tdb_common_context *common;
+       struct autorid_global_config *config;
+       NTSTATUS status;
+
+       dom = (struct idmap_domain *)private_data;
+       common = (struct idmap_tdb_common_context *)dom->private_data;
+       config = (struct autorid_global_config *)common->private_data;
+
+       status = idmap_autorid_init_hwms(autorid_db);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = idmap_autorid_saveconfig(autorid_db, config);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to store configuration data!\n"));
+               return status;
+       }
+
+       status = idmap_autorid_preallocate_wellknown(dom);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to preallocate wellknown sids: %s\n",
+                         nt_errstr(status)));
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 {
        struct idmap_tdb_common_context *commonconfig;
@@ -659,20 +692,15 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 
        commonconfig->db = autorid_db;
 
-       status = idmap_autorid_init_hwms(autorid_db);
+       status = dbwrap_trans_do(autorid_db,
+                                idmap_autorid_initialize_action,
+                                dom);
        if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to init the idmap database: %s\n",
+                         nt_errstr(status)));
                goto error;
        }
 
-       status = idmap_autorid_saveconfig(autorid_db, config);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to store configuration data!\n"));
-               goto error;
-       }
-
-       /* preallocate well-known SIDs in the pool */
-       status = idmap_autorid_preallocate_wellknown(dom);
-
        goto done;
 
 error: