From fc480dfeba2b35304411e92dc3fe2e25e789405b Mon Sep 17 00:00:00 2001 From: dimitr Date: Thu, 11 Dec 2008 07:29:11 +0000 Subject: [PATCH] Backported fix for CORE-1963: Possible server crash on commit when granting/revoking privileges from multiple connections simultaneously. --- src/jrd/dfw.epp | 35 +++++++++++++++++++++++++++++++---- src/jrd/dfw_proto.h | 3 ++- src/jrd/grant.epp | 8 ++++---- src/jrd/ini.epp | 28 ++++++++++------------------ src/jrd/jrd.h | 14 ++++++-------- 5 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/jrd/dfw.epp b/src/jrd/dfw.epp index 060487bec1..b3dc7078b5 100644 --- a/src/jrd/dfw.epp +++ b/src/jrd/dfw.epp @@ -434,7 +434,7 @@ void DFW_merge_work(jrd_tra* transaction, } -void DFW_perform_system_work(void) +void DFW_perform_system_work(thread_db* tdbb) { /************************************** * @@ -447,7 +447,12 @@ void DFW_perform_system_work(void) * system transaction. * **************************************/ - Database* dbb = GET_DBB(); + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); + + THREAD_EXIT(); + Firebird::MutexLockGuard guard(dbb->dbb_mutexes[DBB_MUTX_sys_dfw]); + THREAD_ENTER(); DFW_perform_work(dbb->dbb_sys_trans); } @@ -626,8 +631,30 @@ void DFW_perform_post_commit_work(jrd_tra* transaction) } -DeferredWork* DFW_post_work(jrd_tra* transaction, enum dfw_t type, const dsc* desc, - USHORT id) +DeferredWork* DFW_post_system_work(thread_db* tdbb, enum dfw_t type, const dsc* desc, USHORT id) +{ +/************************************** + * + * D F W _ p o s t _ s y s t e m _ w o r k + * + ************************************** + * + * Functional description + * Post work to be deferred to commit time. + * + **************************************/ + SET_TDBB(tdbb); + Database* const dbb = tdbb->getDatabase(); + + THREAD_EXIT(); + Firebird::MutexLockGuard guard(dbb->dbb_mutexes[DBB_MUTX_sys_dfw]); + THREAD_ENTER(); + + return DFW_post_work(dbb->dbb_sys_trans, type, desc, id); +} + + +DeferredWork* DFW_post_work(jrd_tra* transaction, enum dfw_t type, const dsc* desc, USHORT id) { /************************************** * diff --git a/src/jrd/dfw_proto.h b/src/jrd/dfw_proto.h index d6c272a4c9..f3cbab6958 100644 --- a/src/jrd/dfw_proto.h +++ b/src/jrd/dfw_proto.h @@ -27,9 +27,10 @@ USHORT DFW_assign_index_type(Jrd::DeferredWork*, SSHORT, SSHORT); void DFW_delete_deferred(Jrd::jrd_tra*, SLONG); void DFW_merge_work(Jrd::jrd_tra*, SLONG, SLONG); -void DFW_perform_system_work(void); +void DFW_perform_system_work(Jrd::thread_db*); void DFW_perform_work(Jrd::jrd_tra*); void DFW_perform_post_commit_work(Jrd::jrd_tra*); +Jrd::DeferredWork* DFW_post_system_work(Jrd::thread_db*, enum Jrd::dfw_t, const dsc*, USHORT); Jrd::DeferredWork* DFW_post_work(Jrd::jrd_tra*, enum Jrd::dfw_t, const dsc*, USHORT); Jrd::DeferredWork* DFW_post_work_arg(Jrd::jrd_tra*, Jrd::DeferredWork*, const dsc*, USHORT); void DFW_update_index(const TEXT*, USHORT, const Jrd::SelectivityList&); diff --git a/src/jrd/grant.epp b/src/jrd/grant.epp index cf49b4a576..cda1bb185b 100644 --- a/src/jrd/grant.epp +++ b/src/jrd/grant.epp @@ -192,7 +192,7 @@ bool GRANT_privileges( thread_db* tdbb, SSHORT phase, DeferredWork* work, break; } - DFW_perform_system_work(); + DFW_perform_system_work(tdbb); return false; } @@ -258,7 +258,7 @@ static void define_default_class( desc.dsc_ttype() = ttype_metadata; desc.dsc_address = (UCHAR *) relation_name; desc.dsc_length = strlen(relation_name); - DFW_post_work(dbb->dbb_sys_trans, dfw_scan_relation, &desc, 0); + DFW_post_system_work(tdbb, dfw_scan_relation, &desc, 0); } @@ -611,7 +611,7 @@ static void purge_default_class( TEXT* object_name, SSHORT obj_type) desc.dsc_ttype() = ttype_metadata; desc.dsc_address = (UCHAR *) object_name; desc.dsc_length = strlen(object_name); - DFW_post_work(dbb->dbb_sys_trans, dfw_scan_relation, &desc, 0); + DFW_post_system_work(tdbb, dfw_scan_relation, &desc, 0); } #endif // NOT_USED_OR_REPLACED @@ -796,7 +796,7 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb, desc.dsc_ttype() = ttype_metadata; desc.dsc_address = (UCHAR *) relation_name; desc.dsc_length = strlen(relation_name); - DFW_post_work(dbb->dbb_sys_trans, dfw_update_format, &desc, 0); + DFW_post_system_work(tdbb, dfw_update_format, &desc, 0); } return aggregate_public; diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 24721ed1bc..32cc7254b7 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -420,7 +420,7 @@ void INI_format(const TEXT* owner, const TEXT* charset) store_functions(tdbb, dbb); - DFW_perform_system_work(); + DFW_perform_system_work(tdbb); add_relation_fields(0); @@ -821,7 +821,7 @@ void INI_update_database() dbb->dbb_minor_version = header->hdr_ods_minor; CCH_RELEASE(tdbb, &window); - DFW_perform_system_work(); + DFW_perform_system_work(tdbb); } #ifdef NOT_USED_OR_REPLACED @@ -888,7 +888,7 @@ static void add_global_fields( USHORT minor_version) CMP_release(tdbb, handle); } - DFW_perform_system_work(); + DFW_perform_system_work(tdbb); } @@ -1081,7 +1081,7 @@ static void add_relation_fields( USHORT minor_version) INTL_ASSIGN_DSC(&desc, CS_METADATA, COLLATE_NONE); desc.dsc_address = (UCHAR*) names[relfld[RFLD_R_NAME]]; desc.dsc_length = strlen((char*)desc.dsc_address); - DFW_post_work(dbb->dbb_sys_trans, dfw_update_format, &desc, 0); + DFW_post_system_work(tdbb, dfw_update_format, &desc, 0); } } } @@ -1093,7 +1093,7 @@ static void add_relation_fields( USHORT minor_version) CMP_release(tdbb, m_handle); } - DFW_perform_system_work(); + DFW_perform_system_work(tdbb); } @@ -1336,15 +1336,13 @@ static void store_generator(thread_db* tdbb, const gen* generator, jrd_req** han SET_TDBB(tdbb); Database* dbb = tdbb->getDatabase(); - jrd_tra* trans = dbb->dbb_sys_trans; - STORE(REQUEST_HANDLE * handle) X IN RDB$GENERATORS PAD(generator->gen_name, X.RDB$GENERATOR_NAME); X.RDB$GENERATOR_ID = generator->gen_id; X.RDB$SYSTEM_FLAG = RDB_system; if (generator->gen_description) { - blb* blob = BLB_create(tdbb, trans, &X.RDB$DESCRIPTION); + blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$DESCRIPTION); BLB_put_segment(tdbb, blob, reinterpret_cast(generator->gen_description), @@ -1377,8 +1375,6 @@ static void store_global_field(thread_db* tdbb, const gfld* gfield, jrd_req** ha SET_TDBB(tdbb); Database* dbb = tdbb->getDatabase(); - jrd_tra* trans = dbb->dbb_sys_trans; - STORE(REQUEST_HANDLE * handle) X IN RDB$FIELDS PAD(names[(USHORT)gfield->gfld_name], X.RDB$FIELD_NAME); X.RDB$FIELD_LENGTH = gfield->gfld_length; @@ -1390,7 +1386,7 @@ static void store_global_field(thread_db* tdbb, const gfld* gfield, jrd_req** ha X.RDB$SEGMENT_LENGTH.NULL = TRUE; if (gfield->gfld_dflt_blr) { - blb* blob = BLB_create(tdbb, trans, &X.RDB$DEFAULT_VALUE); + blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$DEFAULT_VALUE); BLB_put_segment(tdbb, blob, gfield->gfld_dflt_blr, @@ -1543,8 +1539,6 @@ static void store_intlnames(thread_db* tdbb, Database* dbb) CMP_release(tdbb, handle); handle = NULL; - jrd_tra* trans = dbb->dbb_sys_trans; - for (const COLL_TYPE* collptr = coll_types; collptr->init_collation_name; collptr++) { STORE(REQUEST_HANDLE handle) X IN RDB$COLLATIONS USING @@ -1565,7 +1559,7 @@ static void store_intlnames(thread_db* tdbb, Database* dbb) if (collptr->init_collation_specific_attributes) { - blb* blob = BLB_create(tdbb, trans, &X.RDB$SPECIFIC_ATTRIBUTES); + blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$SPECIFIC_ATTRIBUTES); BLB_put_segment(tdbb, blob, reinterpret_cast(collptr->init_collation_specific_attributes), @@ -1735,15 +1729,13 @@ static void store_trigger(thread_db* tdbb, const jrd_trg* trigger, jrd_req** han SET_TDBB(tdbb); Database* dbb = tdbb->getDatabase(); - jrd_tra* trans = dbb->dbb_sys_trans; - /* indicate that the relation format needs revising */ dsc desc; desc.dsc_dtype = dtype_text; INTL_ASSIGN_DSC(&desc, CS_METADATA, COLLATE_NONE); desc.dsc_address = (UCHAR*) names[trigger->trg_relation]; desc.dsc_length = strlen((char*)desc.dsc_address); - DFW_post_work(trans, dfw_update_format, &desc, 0); + DFW_post_system_work(tdbb, dfw_update_format, &desc, 0); /* store the trigger */ @@ -1754,7 +1746,7 @@ static void store_trigger(thread_db* tdbb, const jrd_trg* trigger, jrd_req** han X.RDB$SYSTEM_FLAG = RDB_system; X.RDB$TRIGGER_TYPE = trigger->trg_type; X.RDB$FLAGS = trigger->trg_flags; - blb* blob = BLB_create(tdbb, trans, &X.RDB$TRIGGER_BLR); + blb* blob = BLB_create(tdbb, dbb->dbb_sys_trans, &X.RDB$TRIGGER_BLR); BLB_put_segment(tdbb, blob, trigger->trg_blr, diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index ca6fd8a20c..100d760beb 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -442,14 +442,12 @@ const int DBB_max_count = 8; // Database mutexes // const int DBB_MUTX_init_fini = 0; // During startup and shutdown -//const int DBB_MUTX_statistics = 1; // Memory size and counts -//const int DBB_MUTX_replay = 2; // Replay logging -const int DBB_MUTX_dyn = 3; // Dynamic ddl -//const int DBB_MUTX_cache = 4; // Process-private cache management -const int DBB_MUTX_clone = 5; // Request cloning -const int DBB_MUTX_cmp_clone = 6; // Compiled request cloning -const int DBB_MUTX_flush_count = 7; // flush count/time -const int DBB_MUTX_max = 8; +const int DBB_MUTX_dyn = 1; // Dynamic ddl +const int DBB_MUTX_clone = 2; // Request cloning +const int DBB_MUTX_cmp_clone = 3; // Compiled request cloning +const int DBB_MUTX_flush_count = 4; // flush count/time +const int DBB_MUTX_sys_dfw = 5; // system deferred work +const int DBB_MUTX_max = 6; // // Flags to indicate normal internal requests vs. dyn internal requests