From 45e61fcf61ed9863fbe2b116fe0763fc139bbe0d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 6 Jan 2012 17:19:54 +0100 Subject: s3: Add a "lock_order" argument to db_open This will be used to enforce a lock hierarchy between the databases. We have seen deadlocks between locking.tdb, brlock.tdb, serverid.tdb and notify*.tdb. These should be fixed by refusing a dbwrap_fetch_locked that does not follow a defined lock hierarchy. --- source3/utils/dbwrap_tool.c | 3 ++- source3/utils/dbwrap_torture.c | 3 ++- source3/utils/net_idmap.c | 12 ++++++++---- source3/utils/net_idmap_check.c | 3 ++- source3/utils/net_registry_check.c | 6 ++++-- source3/utils/status.c | 3 ++- 6 files changed, 20 insertions(+), 10 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/dbwrap_tool.c b/source3/utils/dbwrap_tool.c index 7850dc168e..e178d5cc6e 100644 --- a/source3/utils/dbwrap_tool.c +++ b/source3/utils/dbwrap_tool.c @@ -463,7 +463,8 @@ int main(int argc, const char **argv) goto done; } - db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644); + db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644, + DBWRAP_LOCK_ORDER_1); if (db == NULL) { d_fprintf(stderr, "ERROR: could not open dbname\n"); goto done; diff --git a/source3/utils/dbwrap_torture.c b/source3/utils/dbwrap_torture.c index 9907f31f76..fb4ed6d4ec 100644 --- a/source3/utils/dbwrap_torture.c +++ b/source3/utils/dbwrap_torture.c @@ -308,7 +308,8 @@ int main(int argc, const char *argv[]) tdb_flags |= TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH; } - db = db_open(mem_ctx, db_name, 0, tdb_flags, O_RDWR | O_CREAT, 0644); + db = db_open(mem_ctx, db_name, 0, tdb_flags, O_RDWR | O_CREAT, 0644, + DBWRAP_LOCK_ORDER_1); if (db == NULL) { d_fprintf(stderr, "failed to open db '%s': %s\n", db_name, diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index 3a3ae21f07..22734eecd8 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -131,7 +131,8 @@ static int net_idmap_dump(struct net_context *c, int argc, const char **argv) } d_fprintf(stderr, _("dumping id mapping from %s\n"), dbfile); - db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDONLY, 0); + db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDONLY, 0, + DBWRAP_LOCK_ORDER_1); if (db == NULL) { d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"), dbfile, strerror(errno)); @@ -240,7 +241,8 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv) input = stdin; } - db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644); + db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644, + DBWRAP_LOCK_ORDER_1); if (db == NULL) { d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"), dbfile, strerror(errno)); @@ -444,7 +446,8 @@ static int net_idmap_delete(struct net_context *c, int argc, const char **argv) } d_fprintf(stderr, _("deleting id mapping from %s\n"), dbfile); - db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR, 0); + db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR, 0, + DBWRAP_LOCK_ORDER_1); if (db == NULL) { d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"), dbfile, strerror(errno)); @@ -616,7 +619,8 @@ static int net_idmap_aclmapset(struct net_context *c, int argc, const char **arg } if (!(db = db_open(mem_ctx, argv[0], 0, TDB_DEFAULT, - O_RDWR|O_CREAT, 0600))) { + O_RDWR|O_CREAT, 0600, + DBWRAP_LOCK_ORDER_1))) { d_fprintf(stderr, _("db_open failed: %s\n"), strerror(errno)); goto fail; } diff --git a/source3/utils/net_idmap_check.c b/source3/utils/net_idmap_check.c index 3f9f3f53d9..1269410bee 100644 --- a/source3/utils/net_idmap_check.c +++ b/source3/utils/net_idmap_check.c @@ -804,7 +804,8 @@ static bool check_open_db(struct check_ctx* ctx, const char* name, int oflags) } } - ctx->db = db_open(ctx, name, 0, TDB_DEFAULT, oflags, 0); + ctx->db = db_open(ctx, name, 0, TDB_DEFAULT, oflags, 0, + DBWRAP_LOCK_ORDER_1); if (ctx->db == NULL) { d_fprintf(stderr, _("Could not open idmap db (%s) for writing: %s\n"), diff --git a/source3/utils/net_registry_check.c b/source3/utils/net_registry_check.c index 201dc5ebc1..8d1a91c44b 100644 --- a/source3/utils/net_registry_check.c +++ b/source3/utils/net_registry_check.c @@ -354,7 +354,8 @@ static bool check_ctx_open_output(struct check_ctx *ctx) ctx->opt.wipe = true; } - ctx->odb = db_open(ctx, ctx->opt.output, 0, TDB_DEFAULT, oflags, 0644); + ctx->odb = db_open(ctx, ctx->opt.output, 0, TDB_DEFAULT, oflags, 0644, + DBWRAP_LOCK_ORDER_1); if (ctx->odb == NULL) { d_fprintf(stderr, _("Could not open db (%s) for writing: %s\n"), @@ -366,7 +367,8 @@ static bool check_ctx_open_output(struct check_ctx *ctx) static bool check_ctx_open_input(struct check_ctx *ctx) { - ctx->idb = db_open(ctx, ctx->fname, 0, TDB_DEFAULT, O_RDONLY, 0); + ctx->idb = db_open(ctx, ctx->fname, 0, TDB_DEFAULT, O_RDONLY, 0, + DBWRAP_LOCK_ORDER_1); if (ctx->idb == NULL) { d_fprintf(stderr, _("Could not open db (%s) for reading: %s\n"), diff --git a/source3/utils/status.c b/source3/utils/status.c index 8ae8de76a3..8f8f3945cb 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -455,7 +455,8 @@ static int traverse_sessionid(const char *key, struct sessionid *session, int result; struct db_context *db; db = db_open(NULL, lock_path("locking.tdb"), 0, - TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0); + TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0, + DBWRAP_LOCK_ORDER_1); if (!db) { d_printf("%s not initialised\n", -- cgit