From 7e0c287412a03b1a5d69220d99501e3a15e53ce9 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Sun, 1 May 2016 13:48:00 +0300 Subject: [PATCH] Bugfix CORE-5224: Transaction id tags for services API do not support new 48 bit transaction ids. --- src/common/classes/ClumpletReader.cpp | 9 +++ src/common/classes/ClumpletReader.h | 2 +- src/common/classes/ClumpletWriter.cpp | 6 ++ src/include/consts_pub.h | 3 + src/jrd/svc.cpp | 25 +++++--- src/jrd/svc.h | 2 +- src/utilities/fbsvcmgr/fbsvcmgr.cpp | 84 ++++++++++++++++----------- 7 files changed, 86 insertions(+), 45 deletions(-) diff --git a/src/common/classes/ClumpletReader.cpp b/src/common/classes/ClumpletReader.cpp index a027485313..467b14995e 100644 --- a/src/common/classes/ClumpletReader.cpp +++ b/src/common/classes/ClumpletReader.cpp @@ -359,6 +359,10 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const case isc_spb_rpr_rollback_trans: case isc_spb_rpr_recover_two_phase: return IntSpb; + case isc_spb_rpr_commit_trans_64: + case isc_spb_rpr_rollback_trans_64: + case isc_spb_rpr_recover_two_phase_64: + return BigIntSpb; } invalid_structure("unknown parameter for repair"); break; @@ -566,6 +570,11 @@ FB_SIZE_T ClumpletReader::getClumpletSize(bool wTag, bool wLength, bool wData) c dataSize = 4; break; + // Used in SPB for 8-byte integers + case BigIntSpb: + dataSize = 8; + break; + // Used in SPB for single byte case ByteSpb: dataSize = 1; diff --git a/src/common/classes/ClumpletReader.h b/src/common/classes/ClumpletReader.h index d366db1535..9b55c7a6e1 100644 --- a/src/common/classes/ClumpletReader.h +++ b/src/common/classes/ClumpletReader.h @@ -146,7 +146,7 @@ public: } protected: - enum ClumpletType {TraditionalDpb, SingleTpb, StringSpb, IntSpb, ByteSpb, Wide}; + enum ClumpletType {TraditionalDpb, SingleTpb, StringSpb, IntSpb, BigIntSpb, ByteSpb, Wide}; ClumpletType getClumpletType(UCHAR tag) const; FB_SIZE_T getClumpletSize(bool wTag, bool wLength, bool wData) const; void adjustSpbState(); diff --git a/src/common/classes/ClumpletWriter.cpp b/src/common/classes/ClumpletWriter.cpp index 545e5823ee..a5f6b86e9e 100644 --- a/src/common/classes/ClumpletWriter.cpp +++ b/src/common/classes/ClumpletWriter.cpp @@ -337,6 +337,12 @@ void ClumpletWriter::insertBytesLengthCheck(UCHAR tag, const void* bytes, const m.printf("attempt to store %d bytes in a clumplet, need 4", length); } break; + case BigIntSpb: + if (length != 8) + { + m.printf("attempt to store %d bytes in a clumplet, need 8", length); + } + break; case ByteSpb: if (length != 1) { diff --git a/src/include/consts_pub.h b/src/include/consts_pub.h index 806259a138..0c7731ae4b 100644 --- a/src/include/consts_pub.h +++ b/src/include/consts_pub.h @@ -471,6 +471,9 @@ #define isc_spb_tra_id_64 46 #define isc_spb_single_tra_id_64 47 #define isc_spb_multi_tra_id_64 48 +#define isc_spb_rpr_commit_trans_64 49 +#define isc_spb_rpr_rollback_trans_64 50 +#define isc_spb_rpr_recover_two_phase_64 51 #define isc_spb_rpr_validate_db 0x01 #define isc_spb_rpr_sweep_db 0x02 diff --git a/src/jrd/svc.cpp b/src/jrd/svc.cpp index 3930082a26..21b2fbbe9f 100644 --- a/src/jrd/svc.cpp +++ b/src/jrd/svc.cpp @@ -2550,6 +2550,8 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) do { + bool bigint = false; + switch (svc_action) { case isc_action_svc_nbak: @@ -2709,7 +2711,7 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) { return false; } - get_action_svc_data(spb, switches); + get_action_svc_data(spb, switches, bigint); break; case isc_spb_sec_admin: @@ -2796,10 +2798,10 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) } break; case isc_spb_bkp_length: - get_action_svc_data(spb, burp_backup); + get_action_svc_data(spb, burp_backup, bigint); break; case isc_spb_res_length: - get_action_svc_data(spb, burp_database); + get_action_svc_data(spb, burp_database, bigint); break; case isc_spb_bkp_factor: case isc_spb_res_buffers: @@ -2809,7 +2811,7 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) { return false; } - get_action_svc_data(spb, switches); + get_action_svc_data(spb, switches, bigint); break; case isc_spb_res_access_mode: if (!get_action_svc_parameter(*(spb.getBytes()), reference_burp_in_sw_table, switches)) @@ -2850,6 +2852,11 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) return false; } break; + case isc_spb_rpr_commit_trans_64: + case isc_spb_rpr_rollback_trans_64: + case isc_spb_rpr_recover_two_phase_64: + bigint = true; + // fall into case isc_spb_prp_page_buffers: case isc_spb_prp_sweep_interval: case isc_spb_prp_shutdown_db: @@ -2866,7 +2873,7 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) { return false; } - get_action_svc_data(spb, switches); + get_action_svc_data(spb, switches, bigint); break; case isc_spb_prp_write_mode: case isc_spb_prp_access_mode: @@ -2922,7 +2929,7 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) get_action_svc_string(spb, switches); break; case isc_spb_trc_id: - get_action_svc_data(spb, switches); + get_action_svc_data(spb, switches, bigint); break; default: return false; @@ -2949,7 +2956,7 @@ bool Service::process_switches(ClumpletReader& spb, string& switches) get_action_svc_string(spb, switches); break; case isc_spb_val_lock_timeout: - get_action_svc_data(spb, switches); + get_action_svc_data(spb, switches, bigint); break; } break; @@ -3077,10 +3084,10 @@ void Service::get_action_svc_string_pos(const ClumpletReader& spb, string& switc } -void Service::get_action_svc_data(const ClumpletReader& spb, string& switches) +void Service::get_action_svc_data(const ClumpletReader& spb, string& switches, bool bigint) { string s; - s.printf("%" SLONGFORMAT" ", spb.getInt()); + s.printf("%" SQUADFORMAT" ", bigint ? spb.getBigInt() : (SINT64) spb.getInt()); switches += s; } diff --git a/src/jrd/svc.h b/src/jrd/svc.h index 76b2764158..9690407094 100644 --- a/src/jrd/svc.h +++ b/src/jrd/svc.h @@ -254,7 +254,7 @@ private: static void get_action_svc_string_pos(const Firebird::ClumpletReader& spb, Firebird::string& switches, Firebird::string::size_type p = Firebird::string::npos); // Get integer from within spb buffer, add it to the command line - static void get_action_svc_data(const Firebird::ClumpletReader& spb, Firebird::string& sw); + static void get_action_svc_data(const Firebird::ClumpletReader& spb, Firebird::string& sw, bool bigint); // Get parameter from within spb buffer, find corresponding switch within specified table, // add it to the command line static bool get_action_svc_parameter(UCHAR tag, const Switches::in_sw_tab_t* table, diff --git a/src/utilities/fbsvcmgr/fbsvcmgr.cpp b/src/utilities/fbsvcmgr/fbsvcmgr.cpp index eca946f13b..d3f2532818 100644 --- a/src/utilities/fbsvcmgr/fbsvcmgr.cpp +++ b/src/utilities/fbsvcmgr/fbsvcmgr.cpp @@ -244,26 +244,38 @@ bool putShutdownMode(char**& av, ClumpletWriter& spb, unsigned int tag) return putSpecTag(av, spb, tag, shutSwitch, isc_fbsvcmgr_bad_sm); } -// add numeric (int32) tag to spb +// add integer (int32) tag to spb -bool putNumericArgument(char**& av, ClumpletWriter& spb, unsigned int tag) +bool putIntArgument(char**& av, ClumpletWriter& spb, unsigned int tag) { if (! *av) return false; - char* err = NULL; - SLONG n = strtol(*av++, &err, 10); - - if (err && *err) - { + SLONG n; + if (sscanf(*av++, "%" SLONGFORMAT, &n) != 1) (Arg::Gds(isc_fbsvcmgr_bad_arg) << av[-2]).raise(); - } spb.insertInt(tag, n); return true; } +// add big integer (int64) tag to spb + +bool putBigIntArgument(char**& av, ClumpletWriter& spb, unsigned int tag) +{ + if (! *av) + return false; + + SINT64 n; + if (sscanf(*av++, "%" SQUADFORMAT, &n) != 1) + (Arg::Gds(isc_fbsvcmgr_bad_arg) << av[-2]).raise(); + + spb.insertBigInt(tag, n); + + return true; +} + // add boolean option to spb bool putOption(char**&, ClumpletWriter& spb, unsigned int tag) @@ -351,8 +363,8 @@ const SvcSwitches backupOptions[] = {"dbname", putStringArgument, 0, isc_spb_dbname, 0}, {"verbose", putSingleTag, 0, isc_spb_verbose, 0}, {"bkp_file", putStringArgument, 0, isc_spb_bkp_file, 0}, - {"bkp_length", putNumericArgument, 0, isc_spb_bkp_length, 0}, - {"bkp_factor", putNumericArgument, 0, isc_spb_bkp_factor, 0}, + {"bkp_length", putIntArgument, 0, isc_spb_bkp_length, 0}, + {"bkp_factor", putIntArgument, 0, isc_spb_bkp_factor, 0}, {"bkp_ignore_checksums", putOption, 0, isc_spb_bkp_ignore_checksums, 0}, {"bkp_ignore_limbo", putOption, 0, isc_spb_bkp_ignore_limbo, 0}, {"bkp_metadata_only", putOption, 0, isc_spb_bkp_metadata_only, 0}, @@ -361,7 +373,7 @@ const SvcSwitches backupOptions[] = {"bkp_non_transportable", putOption, 0, isc_spb_bkp_non_transportable, 0}, {"bkp_convert", putOption, 0, isc_spb_bkp_convert, 0}, {"bkp_no_triggers", putOption, 0, isc_spb_bkp_no_triggers, 0}, - {"verbint", putNumericArgument, 0, isc_spb_verbint, 0}, + {"verbint", putIntArgument, 0, isc_spb_verbint, 0}, {"bkp_skip_data", putStringArgument, 0, isc_spb_bkp_skip_data, 0}, {"bkp_stat", putStringArgument, 0, isc_spb_bkp_stat, 0 }, {0, 0, 0, 0, 0} @@ -371,10 +383,10 @@ const SvcSwitches restoreOptions[] = { {"bkp_file", putStringArgument, 0, isc_spb_bkp_file, 0}, {"dbname", putStringArgument, 0, isc_spb_dbname, 0}, - {"res_length", putNumericArgument, 0, isc_spb_res_length, 0}, + {"res_length", putIntArgument, 0, isc_spb_res_length, 0}, {"verbose", putSingleTag, 0, isc_spb_verbose, 0}, - {"res_buffers", putNumericArgument, 0, isc_spb_res_buffers, 0}, - {"res_page_size", putNumericArgument, 0, isc_spb_res_page_size, 0}, + {"res_buffers", putIntArgument, 0, isc_spb_res_buffers, 0}, + {"res_page_size", putIntArgument, 0, isc_spb_res_page_size, 0}, {"res_access_mode", putAccessMode, 0, isc_spb_res_access_mode, 0}, {"res_deactivate_idx", putOption, 0, isc_spb_res_deactivate_idx, 0}, {"res_no_shadow", putOption, 0, isc_spb_res_no_shadow, 0}, @@ -386,7 +398,7 @@ const SvcSwitches restoreOptions[] = {"res_fix_fss_data", putStringArgument, 0, isc_spb_res_fix_fss_data, 0}, {"res_fix_fss_metadata", putStringArgument, 0, isc_spb_res_fix_fss_metadata, 0}, {"res_metadata_only", putOption, 0, isc_spb_res_metadata_only, 0}, - {"verbint", putNumericArgument, 0, isc_spb_verbint, 0}, + {"verbint", putIntArgument, 0, isc_spb_verbint, 0}, {"res_skip_data", putStringArgument, 0, isc_spb_res_skip_data, 0}, {"res_stat", putStringArgument, 0, isc_spb_res_stat, 0 }, {0, 0, 0, 0, 0} @@ -395,20 +407,20 @@ const SvcSwitches restoreOptions[] = const SvcSwitches propertiesOptions[] = { {"dbname", putStringArgument, 0, isc_spb_dbname, 0}, - {"prp_page_buffers", putNumericArgument, 0, isc_spb_prp_page_buffers, 0}, - {"prp_sweep_interval", putNumericArgument, 0, isc_spb_prp_sweep_interval, 0}, - {"prp_shutdown_db", putNumericArgument, 0, isc_spb_prp_shutdown_db, 0}, - {"prp_deny_new_transactions", putNumericArgument, 0, isc_spb_prp_deny_new_transactions, 0}, - {"prp_deny_new_attachments", putNumericArgument, 0, isc_spb_prp_deny_new_attachments, 0}, - {"prp_set_sql_dialect", putNumericArgument, 0, isc_spb_prp_set_sql_dialect, 0}, + {"prp_page_buffers", putIntArgument, 0, isc_spb_prp_page_buffers, 0}, + {"prp_sweep_interval", putIntArgument, 0, isc_spb_prp_sweep_interval, 0}, + {"prp_shutdown_db", putIntArgument, 0, isc_spb_prp_shutdown_db, 0}, + {"prp_deny_new_transactions", putIntArgument, 0, isc_spb_prp_deny_new_transactions, 0}, + {"prp_deny_new_attachments", putIntArgument, 0, isc_spb_prp_deny_new_attachments, 0}, + {"prp_set_sql_dialect", putIntArgument, 0, isc_spb_prp_set_sql_dialect, 0}, {"prp_access_mode", putAccessMode, 0, isc_spb_prp_access_mode, 0}, {"prp_reserve_space", putReserveSpace, 0, isc_spb_prp_reserve_space, 0}, {"prp_write_mode", putWriteMode, 0, isc_spb_prp_write_mode, 0}, {"prp_activate", putOption, 0, isc_spb_prp_activate, 0}, {"prp_db_online", putOption, 0, isc_spb_prp_db_online, 0}, - {"prp_force_shutdown", putNumericArgument, 0, isc_spb_prp_force_shutdown, 0}, - {"prp_attachments_shutdown", putNumericArgument, 0, isc_spb_prp_attachments_shutdown, 0}, - {"prp_transactions_shutdown", putNumericArgument, 0, isc_spb_prp_transactions_shutdown, 0}, + {"prp_force_shutdown", putIntArgument, 0, isc_spb_prp_force_shutdown, 0}, + {"prp_attachments_shutdown", putIntArgument, 0, isc_spb_prp_attachments_shutdown, 0}, + {"prp_transactions_shutdown", putIntArgument, 0, isc_spb_prp_transactions_shutdown, 0}, {"prp_shutdown_mode", putShutdownMode, 0, isc_spb_prp_shutdown_mode, 0}, {"prp_online_mode", putShutdownMode, 0, isc_spb_prp_online_mode, 0}, {"prp_nolinger", putOption, 0, isc_spb_prp_nolinger, 0}, @@ -418,9 +430,12 @@ const SvcSwitches propertiesOptions[] = const SvcSwitches repairOptions[] = { {"dbname", putStringArgument, 0, isc_spb_dbname, 0}, - {"rpr_commit_trans", putNumericArgument, 0, isc_spb_rpr_commit_trans, 0}, - {"rpr_rollback_trans", putNumericArgument, 0, isc_spb_rpr_rollback_trans, 0}, - {"rpr_recover_two_phase", putNumericArgument, 0, isc_spb_rpr_recover_two_phase, 0}, + {"rpr_commit_trans", putIntArgument, 0, isc_spb_rpr_commit_trans, 0}, + {"rpr_rollback_trans", putIntArgument, 0, isc_spb_rpr_rollback_trans, 0}, + {"rpr_recover_two_phase", putIntArgument, 0, isc_spb_rpr_recover_two_phase, 0}, + {"rpr_commit_trans_64", putBigIntArgument, 0, isc_spb_rpr_commit_trans_64, 0}, + {"rpr_rollback_trans_64", putBigIntArgument, 0, isc_spb_rpr_rollback_trans_64, 0}, + {"rpr_recover_two_phase_64", putBigIntArgument, 0, isc_spb_rpr_recover_two_phase_64, 0}, {"rpr_check_db", putOption, 0, isc_spb_rpr_check_db, 0}, {"rpr_ignore_checksum", putOption, 0, isc_spb_rpr_ignore_checksum, 0}, {"rpr_kill_shadows", putOption, 0, isc_spb_rpr_kill_shadows, 0}, @@ -472,9 +487,9 @@ const SvcSwitches addmodOptions[] = {"sec_firstname", putStringArgument, 0, isc_spb_sec_firstname, 0}, {"sec_middlename", putStringArgument, 0, isc_spb_sec_middlename, 0}, {"sec_lastname", putStringArgument, 0, isc_spb_sec_lastname, 0}, - {"sec_userid", putNumericArgument, 0, isc_spb_sec_userid, 0}, - {"sec_groupid", putNumericArgument, 0, isc_spb_sec_groupid, 0}, - {"sec_admin", putNumericArgument, 0, isc_spb_sec_admin, 0}, + {"sec_userid", putIntArgument, 0, isc_spb_sec_userid, 0}, + {"sec_groupid", putIntArgument, 0, isc_spb_sec_groupid, 0}, + {"sec_admin", putIntArgument, 0, isc_spb_sec_admin, 0}, {0, 0, 0, 0, 0} }; @@ -482,7 +497,7 @@ const SvcSwitches nbackOptions[] = { {"dbname", putStringArgument, 0, isc_spb_dbname, 0}, {"nbk_file", putStringArgument, 0, isc_spb_nbk_file, 0}, - {"nbk_level", putNumericArgument, 0, isc_spb_nbk_level, 0}, + {"nbk_level", putIntArgument, 0, isc_spb_nbk_level, 0}, {"nbk_guid", putStringArgument, 0, isc_spb_nbk_guid, 0}, {"nbk_no_triggers", putOption, 0, isc_spb_nbk_no_triggers, 0}, {"nbk_direct", putStringArgument, 0, isc_spb_nbk_direct, 0}, @@ -506,7 +521,7 @@ const SvcSwitches traceStartOptions[] = const SvcSwitches traceChgStateOptions[] = { - {"trc_id", putNumericArgument, 0, isc_spb_trc_id, 0}, + {"trc_id", putIntArgument, 0, isc_spb_trc_id, 0}, {0, 0, 0, 0, 0} }; @@ -517,7 +532,7 @@ const SvcSwitches validateOptions[] = {"val_tab_excl", putStringArgument, 0, isc_spb_val_tab_excl, 0}, {"val_idx_incl", putStringArgument, 0, isc_spb_val_idx_incl, 0}, {"val_idx_excl", putStringArgument, 0, isc_spb_val_idx_excl, 0}, - {"val_lock_timeout", putNumericArgument, 0, isc_spb_val_lock_timeout, 0}, + {"val_lock_timeout", putIntArgument, 0, isc_spb_val_lock_timeout, 0}, {0, 0, 0, 0, 0} }; @@ -939,7 +954,8 @@ struct TypeText { putWriteMode, "prp_wm_async | prp_wm_sync" }, { putReserveSpace, "prp_res_use_full | prp_res" }, { putShutdownMode, "prp_sm_normal | prp_sm_multi | prp_sm_single | prp_sm_full" }, - { putNumericArgument, "numeric value" }, + { putIntArgument, "int32 value" }, + { putBigIntArgument, "int64 value" }, { putOption, NULL }, { putSingleTag, NULL }, { NULL, NULL }