mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 17:23:03 +01:00
Implement new shutdown modes (single-user and full shutdown). Tested on Linux/AMD64 CS and SS
This commit is contained in:
parent
5ede51a093
commit
2c4fe73bd4
Binary file not shown.
@ -1080,6 +1080,8 @@ C --
|
||||
PARAMETER (GDS__wal_backup_err = 335544833)
|
||||
INTEGER*4 GDS__invalid_cursor_state
|
||||
PARAMETER (GDS__invalid_cursor_state = 335544834)
|
||||
INTEGER*4 GDS__bad_shutdown_mode
|
||||
PARAMETER (GDS__bad_shutdown_mode = 335544835)
|
||||
INTEGER*4 GDS__gfix_db_name
|
||||
PARAMETER (GDS__gfix_db_name = 335740929)
|
||||
INTEGER*4 GDS__gfix_invalid_sw
|
||||
|
@ -547,6 +547,7 @@ const
|
||||
gds_wrong_backup_state = 335544832;
|
||||
gds_wal_backup_err = 335544833;
|
||||
gds_invalid_cursor_state = 335544834;
|
||||
gds_bad_shutdown_mode = 335544835;
|
||||
gds_gfix_db_name = 335740929;
|
||||
gds_gfix_invalid_sw = 335740930;
|
||||
gds_gfix_incmp_sw = 335740932;
|
||||
|
@ -24,7 +24,7 @@
|
||||
//
|
||||
//____________________________________________________________
|
||||
//
|
||||
// $Id: alice.cpp,v 1.50 2004-02-20 06:42:27 robocop Exp $
|
||||
// $Id: alice.cpp,v 1.51 2004-02-25 01:50:10 skidder Exp $
|
||||
//
|
||||
// 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
// conditionals, as the engine now fully supports
|
||||
@ -345,6 +345,28 @@ int common_main(int argc,
|
||||
}
|
||||
switches |= table->in_sw_value;
|
||||
|
||||
if ((table->in_sw_value & (sw_shut | sw_online)) && (argc > 1)) {
|
||||
ALICE_down_case(*argv, string, sizeof(string));
|
||||
bool found = false;
|
||||
if ((found = (strcmp(string, "normal") == 0)))
|
||||
tdgbl->ALICE_data.ua_shutdown_mode = SHUT_NORMAL;
|
||||
else
|
||||
if ((found = (strcmp(string, "multi") == 0)))
|
||||
tdgbl->ALICE_data.ua_shutdown_mode = SHUT_MULTI;
|
||||
else
|
||||
if ((found = (strcmp(string, "single") == 0)))
|
||||
tdgbl->ALICE_data.ua_shutdown_mode = SHUT_SINGLE;
|
||||
else
|
||||
if ((found = (strcmp(string, "full") == 0)))
|
||||
tdgbl->ALICE_data.ua_shutdown_mode = SHUT_FULL;
|
||||
// Consume argument only if we identified mode
|
||||
// Let's hope that database with names of modes above are unusual
|
||||
if (found) {
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
}
|
||||
|
||||
if (table->in_sw_value & sw_begin_log) {
|
||||
if (--argc <= 0) {
|
||||
ALICE_error(5); // msg 5: replay log pathname required
|
||||
|
@ -49,6 +49,14 @@ enum val_errors {
|
||||
MAX_VAL_ERRORS = 8
|
||||
};
|
||||
|
||||
enum alice_shut_mode {
|
||||
SHUT_DEFAULT = 0,
|
||||
SHUT_NORMAL = 1,
|
||||
SHUT_MULTI = 2,
|
||||
SHUT_SINGLE = 3,
|
||||
SHUT_FULL = 4
|
||||
};
|
||||
|
||||
typedef struct user_action
|
||||
{
|
||||
ULONG ua_switches;
|
||||
@ -65,6 +73,7 @@ typedef struct user_action
|
||||
SLONG ua_val_errors[MAX_VAL_ERRORS];
|
||||
TEXT ua_log_file[MAXPATHLEN];
|
||||
USHORT ua_db_SQL_dialect;
|
||||
alice_shut_mode ua_shutdown_mode;
|
||||
} *USER_ACTION;
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
//
|
||||
//____________________________________________________________
|
||||
//
|
||||
// $Id: exe.cpp,v 1.28 2004-02-20 06:42:27 robocop Exp $
|
||||
// $Id: exe.cpp,v 1.29 2004-02-25 01:50:10 skidder Exp $
|
||||
//
|
||||
// 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
// conditionals, as the engine now fully supports
|
||||
@ -104,9 +104,14 @@ int EXE_action(const TEXT* database, const ULONG switches)
|
||||
|
||||
tdgbl->service_blk->svc_started();
|
||||
|
||||
if (tdgbl->status[1])
|
||||
if (tdgbl->status[1] &&
|
||||
// Ignore isc_shutdown error produced when we switch to full shutdown mode. It is expected.
|
||||
(tdgbl->status[1] != isc_shutdown || !(switches & sw_shut) || tdgbl->ALICE_data.ua_shutdown_mode != SHUT_FULL)
|
||||
)
|
||||
{
|
||||
error = true;
|
||||
|
||||
}
|
||||
|
||||
if (tdgbl->status[2] == isc_arg_warning)
|
||||
ALICE_print_status(tdgbl->status);
|
||||
|
||||
@ -276,6 +281,22 @@ static USHORT build_dpb(UCHAR* dpb, const ULONG switches)
|
||||
*dpb2 |= isc_dpb_shut_force;
|
||||
else if (switches & sw_tran)
|
||||
*dpb2 |= isc_dpb_shut_transaction;
|
||||
switch(tdgbl->ALICE_data.ua_shutdown_mode) {
|
||||
case SHUT_NORMAL:
|
||||
*dpb2 |= isc_dpb_shut_normal;
|
||||
break;
|
||||
case SHUT_SINGLE:
|
||||
*dpb2 |= isc_dpb_shut_single;
|
||||
break;
|
||||
case SHUT_MULTI:
|
||||
*dpb2 |= isc_dpb_shut_multi;
|
||||
break;
|
||||
case SHUT_FULL:
|
||||
*dpb2 |= isc_dpb_shut_full;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dpb2++;
|
||||
*dpb2++ = isc_dpb_shutdown_delay;
|
||||
*dpb2++ = 2; // Build room for shutdown delay
|
||||
@ -287,7 +308,25 @@ static USHORT build_dpb(UCHAR* dpb, const ULONG switches)
|
||||
}
|
||||
else if (switches & sw_online) {
|
||||
*dpb2++ = isc_dpb_online;
|
||||
*dpb2++ = 0;
|
||||
*dpb2++ = 1;
|
||||
*dpb2 = 0;
|
||||
switch(tdgbl->ALICE_data.ua_shutdown_mode) {
|
||||
case SHUT_NORMAL:
|
||||
*dpb2 |= isc_dpb_shut_normal;
|
||||
break;
|
||||
case SHUT_SINGLE:
|
||||
*dpb2 |= isc_dpb_shut_single;
|
||||
break;
|
||||
case SHUT_MULTI:
|
||||
*dpb2 |= isc_dpb_shut_multi;
|
||||
break;
|
||||
case SHUT_FULL:
|
||||
*dpb2 |= isc_dpb_shut_full;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dpb2++;
|
||||
}
|
||||
else if (switches & sw_disable) {
|
||||
*dpb2++ = isc_dpb_disable_wal;
|
||||
|
@ -24,7 +24,7 @@
|
||||
* 2003.08.17 Claudio Valderrama: Fix SF Bug #750659.
|
||||
*/
|
||||
/*
|
||||
$Id: restore.epp,v 1.68 2004-02-24 05:34:26 robocop Exp $
|
||||
$Id: restore.epp,v 1.69 2004-02-25 01:50:12 skidder Exp $
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
@ -1002,10 +1002,11 @@ void create_database (const TEXT* file_name)
|
||||
else
|
||||
*d++ = (UCHAR) SQL_DIALECT_V5;
|
||||
|
||||
// start database up shut down
|
||||
// start database up shut down,
|
||||
// use single-user mode to avoid conflicts during restore process
|
||||
*d++ = (UCHAR) isc_dpb_shutdown;
|
||||
*d++ = 1;
|
||||
*d++ = (UCHAR) isc_dpb_shut_attachment;
|
||||
*d++ = 1;
|
||||
*d++ = (UCHAR) isc_dpb_shut_attachment | isc_dpb_shut_single;
|
||||
*d++ = (UCHAR) isc_dpb_shutdown_delay;
|
||||
*d++ = 2;
|
||||
*d++ = 0;
|
||||
|
@ -557,6 +557,7 @@ const SLONG gds_conf_access_denied = 335544831L;
|
||||
const SLONG gds_wrong_backup_state = 335544832L;
|
||||
const SLONG gds_wal_backup_err = 335544833L;
|
||||
const SLONG gds_invalid_cursor_state = 335544834L;
|
||||
const SLONG gds_bad_shutdown_mode = 335544835L;
|
||||
const SLONG gds_gfix_db_name = 335740929L;
|
||||
const SLONG gds_gfix_invalid_sw = 335740930L;
|
||||
const SLONG gds_gfix_incmp_sw = 335740932L;
|
||||
@ -759,7 +760,7 @@ const SLONG gds_gstat_unexpected_eof = 336920580L;
|
||||
const SLONG gds_gstat_open_err = 336920605L;
|
||||
const SLONG gds_gstat_read_err = 336920606L;
|
||||
const SLONG gds_gstat_sysmemex = 336920607L;
|
||||
const SLONG gds_err_max = 716L;
|
||||
const SLONG gds_err_max = 717L;
|
||||
|
||||
#else /* c definitions */
|
||||
|
||||
@ -1297,6 +1298,7 @@ const SLONG gds_err_max = 716L;
|
||||
#define gds__wrong_backup_state 335544832L
|
||||
#define gds__wal_backup_err 335544833L
|
||||
#define gds__invalid_cursor_state 335544834L
|
||||
#define gds__bad_shutdown_mode 335544835L
|
||||
#define gds__gfix_db_name 335740929L
|
||||
#define gds__gfix_invalid_sw 335740930L
|
||||
#define gds__gfix_incmp_sw 335740932L
|
||||
@ -1499,7 +1501,7 @@ const SLONG gds_err_max = 716L;
|
||||
#define gds__gstat_open_err 336920605L
|
||||
#define gds__gstat_read_err 336920606L
|
||||
#define gds__gstat_sysmemex 336920607L
|
||||
#define gds_err_max 716
|
||||
#define gds_err_max 717
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -536,6 +536,7 @@ static const struct {
|
||||
{"wrong_backup_state", 335544832},
|
||||
{"wal_backup_err", 335544833},
|
||||
{"invalid_cursor_state", 335544834},
|
||||
{"bad_shutdown_mode", 335544835},
|
||||
{"gfix_db_name", 335740929},
|
||||
{"gfix_invalid_sw", 335740930},
|
||||
{"gfix_incmp_sw", 335740932},
|
||||
|
@ -569,6 +569,7 @@ const SLONG isc_conf_access_denied = 335544831L;
|
||||
const SLONG isc_wrong_backup_state = 335544832L;
|
||||
const SLONG isc_wal_backup_err = 335544833L;
|
||||
const SLONG isc_invalid_cursor_state = 335544834L;
|
||||
const SLONG isc_bad_shutdown_mode = 335544835L;
|
||||
const SLONG isc_gfix_db_name = 335740929L;
|
||||
const SLONG isc_gfix_invalid_sw = 335740930L;
|
||||
const SLONG isc_gfix_incmp_sw = 335740932L;
|
||||
@ -771,7 +772,7 @@ const SLONG isc_gstat_unexpected_eof = 336920580L;
|
||||
const SLONG isc_gstat_open_err = 336920605L;
|
||||
const SLONG isc_gstat_read_err = 336920606L;
|
||||
const SLONG isc_gstat_sysmemex = 336920607L;
|
||||
const SLONG isc_err_max = 716;
|
||||
const SLONG isc_err_max = 717;
|
||||
|
||||
#else /* c definitions */
|
||||
|
||||
@ -1310,6 +1311,7 @@ const SLONG isc_err_max = 716;
|
||||
#define isc_wrong_backup_state 335544832L
|
||||
#define isc_wal_backup_err 335544833L
|
||||
#define isc_invalid_cursor_state 335544834L
|
||||
#define isc_bad_shutdown_mode 335544835L
|
||||
#define isc_gfix_db_name 335740929L
|
||||
#define isc_gfix_invalid_sw 335740930L
|
||||
#define isc_gfix_incmp_sw 335740932L
|
||||
@ -1512,7 +1514,7 @@ const SLONG isc_err_max = 716;
|
||||
#define isc_gstat_open_err 336920605L
|
||||
#define isc_gstat_read_err 336920606L
|
||||
#define isc_gstat_sysmemex 336920607L
|
||||
#define isc_err_max 716
|
||||
#define isc_err_max 717
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -534,207 +534,208 @@ static const SCHAR * const messages[] = {
|
||||
"Cannot change difference file name while database is in backup mode", /* 512, wrong_backup_state */
|
||||
"Physical backup is not allowed while Write-Ahead Log is in use", /* 513, wal_backup_err */
|
||||
"Invalid cursor state: %s", /* 514, invalid_cursor_state */
|
||||
"data base file name (%s) already given", /* 515, gfix_db_name */
|
||||
"invalid switch %s", /* 516, gfix_invalid_sw */
|
||||
"incompatible switch combination", /* 517, gfix_incmp_sw */
|
||||
"replay log pathname required", /* 518, gfix_replay_req */
|
||||
"number of page buffers for cache required", /* 519, gfix_pgbuf_req */
|
||||
"numeric value required", /* 520, gfix_val_req */
|
||||
"positive numeric value required", /* 521, gfix_pval_req */
|
||||
"number of transactions per sweep required", /* 522, gfix_trn_req */
|
||||
"\"full\" or \"reserve\" required", /* 523, gfix_full_req */
|
||||
"user name required", /* 524, gfix_usrname_req */
|
||||
"password required", /* 525, gfix_pass_req */
|
||||
"subsystem name", /* 526, gfix_subs_name */
|
||||
"\"wal\" required", /* 527, gfix_wal_req */
|
||||
"number of seconds required", /* 528, gfix_sec_req */
|
||||
"numeric value between 0 and 32767 inclusive required", /* 529, gfix_nval_req */
|
||||
"must specify type of shutdown", /* 530, gfix_type_shut */
|
||||
"please retry, specifying an option", /* 531, gfix_retry */
|
||||
"please retry, giving a database name", /* 532, gfix_retry_db */
|
||||
"internal block exceeds maximum size", /* 533, gfix_exceed_max */
|
||||
"corrupt pool", /* 534, gfix_corrupt_pool */
|
||||
"virtual memory exhausted", /* 535, gfix_mem_exhausted */
|
||||
"bad pool id", /* 536, gfix_bad_pool */
|
||||
"Transaction state %d not in valid range.", /* 537, gfix_trn_not_valid */
|
||||
"unexpected end of input", /* 538, gfix_unexp_eoi */
|
||||
"failed to reconnect to a transaction in database %s", /* 539, gfix_recon_fail */
|
||||
"Transaction description item unknown", /* 540, gfix_trn_unknown */
|
||||
"\"read_only\" or \"read_write\" required", /* 541, gfix_mode_req */
|
||||
" -sql_dialect set database dialect n", /* 542, gfix_opt_SQL_dialect */
|
||||
"Cannot SELECT RDB$DB_KEY from a stored procedure.", /* 543, dsql_dbkey_from_non_table */
|
||||
"Precision 10 to 18 changed from DOUBLE PRECISION in SQL dialect 1 to 64-bit scaled integer in SQL dialect 3", /* 544, dsql_transitional_numeric */
|
||||
"Use of %s expression that returns different results in dialect 1 and dialect 3", /* 545, dsql_dialect_warning_expr */
|
||||
"Database SQL dialect %d does not support reference to %s datatype", /* 546, sql_db_dialect_dtype_unsupport */
|
||||
"DB dialect %d and client dialect %d conflict with respect to numeric precision %d.", /* 547, isc_sql_dialect_conflict_num */
|
||||
"WARNING: Numeric literal %s is interpreted as a floating-point", /* 548, dsql_warning_number_ambiguous */
|
||||
"value in SQL dialect 1, but as an exact numeric value in SQL dialect 3.", /* 549, dsql_warning_number_ambiguous1 */
|
||||
"WARNING: NUMERIC and DECIMAL fields with precision 10 or greater are stored", /* 550, dsql_warn_precision_ambiguous */
|
||||
"as approximate floating-point values in SQL dialect 1, but as 64-bit", /* 551, dsql_warn_precision_ambiguous1 */
|
||||
"integers in SQL dialect 3.", /* 552, dsql_warn_precision_ambiguous2 */
|
||||
"Ambiguous field name between %s and %s", /* 553, dsql_ambiguous_field_name */
|
||||
"External function should have return position between 1 and %d", /* 554, dsql_udf_return_pos_err */
|
||||
"Label %s %s in the current scope", /* 555, dsql_invalid_label */
|
||||
"Datatypes %sare not comparable in expression %s", /* 556, dsql_datatypes_not_comparable */
|
||||
"SQL role %s does not exist", /* 557, dyn_role_does_not_exist */
|
||||
"user %s has no grant admin option on SQL role %s", /* 558, dyn_no_grant_admin_opt */
|
||||
"user %s is not a member of SQL role %s", /* 559, dyn_user_not_role_member */
|
||||
"%s is not the owner of SQL role %s", /* 560, dyn_delete_role_failed */
|
||||
"%s is a SQL role and not a user", /* 561, dyn_grant_role_to_user */
|
||||
"user name %s could not be used for SQL role", /* 562, dyn_inv_sql_role_name */
|
||||
"SQL role %s already exists", /* 563, dyn_dup_sql_role */
|
||||
"keyword %s can not be used as a SQL role name", /* 564, dyn_kywd_spec_for_role */
|
||||
"SQL roles are not supported in on older versions of the database. A backup and restore of the database is required.", /* 565, dyn_roles_not_supported */
|
||||
"Cannot rename domain %s to %s. A domain with that name already exists.", /* 566, dyn_domain_name_exists */
|
||||
"Cannot rename column %s to %s. A column with that name already exists in table %s.", /* 567, dyn_field_name_exists */
|
||||
"Column %s from table %s is referenced in %s", /* 568, dyn_dependency_exists */
|
||||
"Cannot change datatype for column %s. Changing datatype is not supported for BLOB or ARRAY columns.", /* 569, dyn_dtype_invalid */
|
||||
"New size specified for column %s must be at least %d characters.", /* 570, dyn_char_fld_too_small */
|
||||
"Cannot change datatype for %s. Conversion from base type %s to %s is not supported.", /* 571, dyn_invalid_dtype_conversion */
|
||||
"Cannot change datatype for column %s from a character type to a non-character type.", /* 572, dyn_dtype_conv_invalid */
|
||||
"Zero length identifiers are not allowed", /* 573, dyn_zero_len_id */
|
||||
"found unknown switch", /* 574, gbak_unknown_switch */
|
||||
"page size parameter missing", /* 575, gbak_page_size_missing */
|
||||
"Page size specified (%ld) greater than limit (8192 bytes)", /* 576, gbak_page_size_toobig */
|
||||
"redirect location for output is not specified", /* 577, gbak_redir_ouput_missing */
|
||||
"conflicting switches for backup/restore", /* 578, gbak_switches_conflict */
|
||||
"device type %s not known", /* 579, gbak_unknown_device */
|
||||
"protection is not there yet", /* 580, gbak_no_protection */
|
||||
"page size is allowed only on restore or create", /* 581, gbak_page_size_not_allowed */
|
||||
"multiple sources or destinations specified", /* 582, gbak_multi_source_dest */
|
||||
"requires both input and output filenames", /* 583, gbak_filename_missing */
|
||||
"input and output have the same name. Disallowed.", /* 584, gbak_dup_inout_names */
|
||||
"expected page size, encountered \"%s\"", /* 585, gbak_inv_page_size */
|
||||
"REPLACE specified, but the first file %s is a database", /* 586, gbak_db_specified */
|
||||
"database %s already exists. To replace it, use the -R switch", /* 587, gbak_db_exists */
|
||||
"device type not specified", /* 588, gbak_unk_device */
|
||||
"gds_$blob_info failed", /* 589, gbak_blob_info_failed */
|
||||
"do not understand BLOB INFO item %ld", /* 590, gbak_unk_blob_item */
|
||||
"gds_$get_segment failed", /* 591, gbak_get_seg_failed */
|
||||
"gds_$close_blob failed", /* 592, gbak_close_blob_failed */
|
||||
"gds_$open_blob failed", /* 593, gbak_open_blob_failed */
|
||||
"Failed in put_blr_gen_id", /* 594, gbak_put_blr_gen_id_failed */
|
||||
"data type %ld not understood", /* 595, gbak_unk_type */
|
||||
"gds_$compile_request failed", /* 596, gbak_comp_req_failed */
|
||||
"gds_$start_request failed", /* 597, gbak_start_req_failed */
|
||||
" gds_$receive failed", /* 598, gbak_rec_failed */
|
||||
"gds_$release_request failed", /* 599, gbak_rel_req_failed */
|
||||
" gds_$database_info failed", /* 600, gbak_db_info_failed */
|
||||
"Expected database description record", /* 601, gbak_no_db_desc */
|
||||
"failed to create database %s", /* 602, gbak_db_create_failed */
|
||||
"RESTORE: decompression length error", /* 603, gbak_decomp_len_error */
|
||||
"cannot find table %s", /* 604, gbak_tbl_missing */
|
||||
"Cannot find column for BLOB", /* 605, gbak_blob_col_missing */
|
||||
"gds_$create_blob failed", /* 606, gbak_create_blob_failed */
|
||||
"gds_$put_segment failed", /* 607, gbak_put_seg_failed */
|
||||
"expected record length", /* 608, gbak_rec_len_exp */
|
||||
"wrong length record, expected %ld encountered %ld", /* 609, gbak_inv_rec_len */
|
||||
"expected data attribute", /* 610, gbak_exp_data_type */
|
||||
"Failed in store_blr_gen_id", /* 611, gbak_gen_id_failed */
|
||||
"do not recognize record type %ld", /* 612, gbak_unk_rec_type */
|
||||
"Expected backup version 1, 2, or 3. Found %ld", /* 613, gbak_inv_bkup_ver */
|
||||
"expected backup description record", /* 614, gbak_missing_bkup_desc */
|
||||
"string truncated", /* 615, gbak_string_trunc */
|
||||
" warning -- record could not be restored", /* 616, gbak_cant_rest_record */
|
||||
"gds_$send failed", /* 617, gbak_send_failed */
|
||||
"no table name for data", /* 618, gbak_no_tbl_name */
|
||||
"unexpected end of file on backup file", /* 619, gbak_unexp_eof */
|
||||
"database format %ld is too old to restore to", /* 620, gbak_db_format_too_old */
|
||||
"array dimension for column %s is invalid", /* 621, gbak_inv_array_dim */
|
||||
"Expected XDR record length", /* 622, gbak_xdr_len_expected */
|
||||
"cannot open backup file %s", /* 623, gbak_open_bkup_error */
|
||||
"cannot open status and error output file %s", /* 624, gbak_open_error */
|
||||
"blocking factor parameter missing", /* 625, gbak_missing_block_fac */
|
||||
"expected blocking factor, encountered \"%s\"", /* 626, gbak_inv_block_fac */
|
||||
"a blocking factor may not be used in conjunction with device CT", /* 627, gbak_block_fac_specified */
|
||||
"user name parameter missing", /* 628, gbak_missing_username */
|
||||
"password parameter missing", /* 629, gbak_missing_password */
|
||||
" missing parameter for the number of bytes to be skipped", /* 630, gbak_missing_skipped_bytes */
|
||||
"expected number of bytes to be skipped, encountered \"%s\"", /* 631, gbak_inv_skipped_bytes */
|
||||
"Bad attribute for RDB$CHARACTER_SETS", /* 632, gbak_err_restore_charset */
|
||||
"Bad attribute for RDB$COLLATIONS", /* 633, gbak_err_restore_collation */
|
||||
"Unexpected I/O error while reading from backup file", /* 634, gbak_read_error */
|
||||
"Unexpected I/O error while writing to backup file", /* 635, gbak_write_error */
|
||||
"could not drop database %s (database might be in use)", /* 636, gbak_db_in_use */
|
||||
"System memory exhausted", /* 637, gbak_sysmemex */
|
||||
"Bad attributes for restoring SQL role", /* 638, gbak_restore_role_failed */
|
||||
"SQL role parameter missing", /* 639, gbak_role_op_missing */
|
||||
"page buffers parameter missing", /* 640, gbak_page_buffers_missing */
|
||||
"expected page buffers, encountered \"%s\"", /* 641, gbak_page_buffers_wrong_param */
|
||||
"page buffers is allowed only on restore or create", /* 642, gbak_page_buffers_restore */
|
||||
"size specification either missing or incorrect for file %s", /* 643, gbak_inv_size */
|
||||
"file %s out of sequence", /* 644, gbak_file_outof_sequence */
|
||||
"can't join -- one of the files missing", /* 645, gbak_join_file_missing */
|
||||
" standard input is not supported when using join operation", /* 646, gbak_stdin_not_supptd */
|
||||
"standard output is not supported when using split operation", /* 647, gbak_stdout_not_supptd */
|
||||
"backup file %s might be corrupt", /* 648, gbak_bkup_corrupt */
|
||||
"database file specification missing", /* 649, gbak_unk_db_file_spec */
|
||||
"can't write a header record to file %s", /* 650, gbak_hdr_write_failed */
|
||||
"free disk space exhausted", /* 651, gbak_disk_space_ex */
|
||||
"file size given (%d) is less than minimum allowed (%d)", /* 652, gbak_size_lt_min */
|
||||
"service name parameter missing", /* 653, gbak_svc_name_missing */
|
||||
"Cannot restore over current database, must be SYSDBA or owner of the existing database.", /* 654, gbak_not_ownr */
|
||||
"\"read_only\" or \"read_write\" required", /* 655, gbak_mode_req */
|
||||
"just data ignore all constraints etc.", /* 656, gbak_just_data */
|
||||
"restoring data only ignoring foreign key, unique, not null & other constraints", /* 657, gbak_data_only */
|
||||
"unable to open database", /* 658, gsec_cant_open_db */
|
||||
"error in switch specifications", /* 659, gsec_switches_error */
|
||||
"no operation specified", /* 660, gsec_no_op_spec */
|
||||
"no user name specified", /* 661, gsec_no_usr_name */
|
||||
"add record error", /* 662, gsec_err_add */
|
||||
"modify record error", /* 663, gsec_err_modify */
|
||||
"find/modify record error", /* 664, gsec_err_find_mod */
|
||||
"record not found for user: %s", /* 665, gsec_err_rec_not_found */
|
||||
"delete record error", /* 666, gsec_err_delete */
|
||||
"find/delete record error", /* 667, gsec_err_find_del */
|
||||
"find/display record error", /* 668, gsec_err_find_disp */
|
||||
"invalid parameter, no switch defined", /* 669, gsec_inv_param */
|
||||
"operation already specified", /* 670, gsec_op_specified */
|
||||
"password already specified", /* 671, gsec_pw_specified */
|
||||
"uid already specified", /* 672, gsec_uid_specified */
|
||||
"gid already specified", /* 673, gsec_gid_specified */
|
||||
"project already specified", /* 674, gsec_proj_specified */
|
||||
"organization already specified", /* 675, gsec_org_specified */
|
||||
"first name already specified", /* 676, gsec_fname_specified */
|
||||
"middle name already specified", /* 677, gsec_mname_specified */
|
||||
"last name already specified", /* 678, gsec_lname_specified */
|
||||
"invalid switch specified", /* 679, gsec_inv_switch */
|
||||
"ambiguous switch specified", /* 680, gsec_amb_switch */
|
||||
"no operation specified for parameters", /* 681, gsec_no_op_specified */
|
||||
"no parameters allowed for this operation", /* 682, gsec_params_not_allowed */
|
||||
"incompatible switches specified", /* 683, gsec_incompat_switch */
|
||||
"Invalid user name (maximum 31 bytes allowed)", /* 684, gsec_inv_username */
|
||||
"Warning - maximum 8 significant bytes of password used", /* 685, gsec_inv_pw_length */
|
||||
"database already specified", /* 686, gsec_db_specified */
|
||||
"database administrator name already specified", /* 687, gsec_db_admin_specified */
|
||||
"database administrator password already specified", /* 688, gsec_db_admin_pw_specified */
|
||||
"SQL role name already specified", /* 689, gsec_sql_role_specified */
|
||||
"The license file does not exist or could not be opened for read", /* 690, license_no_file */
|
||||
"operation already specified", /* 691, license_op_specified */
|
||||
"no operation specified", /* 692, license_op_missing */
|
||||
"invalid switch", /* 693, license_inv_switch */
|
||||
"invalid switch combination", /* 694, license_inv_switch_combo */
|
||||
"illegal operation/switch combination", /* 695, license_inv_op_combo */
|
||||
"ambiguous switch", /* 696, license_amb_switch */
|
||||
"invalid parameter, no switch specified", /* 697, license_inv_parameter */
|
||||
"switch does not take any parameter", /* 698, license_param_specified */
|
||||
"switch requires a parameter", /* 699, license_param_req */
|
||||
"syntax error in command line", /* 700, license_syntx_error */
|
||||
"The certificate was not added. A duplicate ID exists in the license file.", /* 701, license_dup_id */
|
||||
"The certificate was not added. Invalid certificate ID / Key combination.", /* 702, license_inv_id_key */
|
||||
"The certificate was not removed. The key does not exist or corresponds to a temporary evaluation license.", /* 703, license_err_remove */
|
||||
"An error occurred updating the license file. Operation cancelled.", /* 704, license_err_update */
|
||||
"The certificate could not be validated based on the information given. Please recheck the ID and key information.", /* 705, license_err_convert */
|
||||
"Operation failed. An unknown error occurred.", /* 706, license_err_unk */
|
||||
"Add license operation failed, KEY: %s ID: %s", /* 707, license_svc_err_add */
|
||||
"Remove license operation failed, KEY: %s", /* 708, license_svc_err_remove */
|
||||
"The evaluation license has already been used on this server. You need to purchase a non-evaluation license.", /* 709, license_eval_exists */
|
||||
"found unknown switch", /* 710, gstat_unknown_switch */
|
||||
"please retry, giving a database name", /* 711, gstat_retry */
|
||||
"Wrong ODS version, expected %d, encountered %d", /* 712, gstat_wrong_ods */
|
||||
"Unexpected end of database file.", /* 713, gstat_unexpected_eof */
|
||||
"Can't open database file %s", /* 714, gstat_open_err */
|
||||
"Can't read a database page", /* 715, gstat_read_err */
|
||||
"System memory exhausted", /* 716, gstat_sysmemex */
|
||||
"Target shutdown mode is invalid for database \"%s\"", /* 515, bad_shutdown_mode */
|
||||
"data base file name (%s) already given", /* 516, gfix_db_name */
|
||||
"invalid switch %s", /* 517, gfix_invalid_sw */
|
||||
"incompatible switch combination", /* 518, gfix_incmp_sw */
|
||||
"replay log pathname required", /* 519, gfix_replay_req */
|
||||
"number of page buffers for cache required", /* 520, gfix_pgbuf_req */
|
||||
"numeric value required", /* 521, gfix_val_req */
|
||||
"positive numeric value required", /* 522, gfix_pval_req */
|
||||
"number of transactions per sweep required", /* 523, gfix_trn_req */
|
||||
"\"full\" or \"reserve\" required", /* 524, gfix_full_req */
|
||||
"user name required", /* 525, gfix_usrname_req */
|
||||
"password required", /* 526, gfix_pass_req */
|
||||
"subsystem name", /* 527, gfix_subs_name */
|
||||
"\"wal\" required", /* 528, gfix_wal_req */
|
||||
"number of seconds required", /* 529, gfix_sec_req */
|
||||
"numeric value between 0 and 32767 inclusive required", /* 530, gfix_nval_req */
|
||||
"must specify type of shutdown", /* 531, gfix_type_shut */
|
||||
"please retry, specifying an option", /* 532, gfix_retry */
|
||||
"please retry, giving a database name", /* 533, gfix_retry_db */
|
||||
"internal block exceeds maximum size", /* 534, gfix_exceed_max */
|
||||
"corrupt pool", /* 535, gfix_corrupt_pool */
|
||||
"virtual memory exhausted", /* 536, gfix_mem_exhausted */
|
||||
"bad pool id", /* 537, gfix_bad_pool */
|
||||
"Transaction state %d not in valid range.", /* 538, gfix_trn_not_valid */
|
||||
"unexpected end of input", /* 539, gfix_unexp_eoi */
|
||||
"failed to reconnect to a transaction in database %s", /* 540, gfix_recon_fail */
|
||||
"Transaction description item unknown", /* 541, gfix_trn_unknown */
|
||||
"\"read_only\" or \"read_write\" required", /* 542, gfix_mode_req */
|
||||
" -sql_dialect set database dialect n", /* 543, gfix_opt_SQL_dialect */
|
||||
"Cannot SELECT RDB$DB_KEY from a stored procedure.", /* 544, dsql_dbkey_from_non_table */
|
||||
"Precision 10 to 18 changed from DOUBLE PRECISION in SQL dialect 1 to 64-bit scaled integer in SQL dialect 3", /* 545, dsql_transitional_numeric */
|
||||
"Use of %s expression that returns different results in dialect 1 and dialect 3", /* 546, dsql_dialect_warning_expr */
|
||||
"Database SQL dialect %d does not support reference to %s datatype", /* 547, sql_db_dialect_dtype_unsupport */
|
||||
"DB dialect %d and client dialect %d conflict with respect to numeric precision %d.", /* 548, isc_sql_dialect_conflict_num */
|
||||
"WARNING: Numeric literal %s is interpreted as a floating-point", /* 549, dsql_warning_number_ambiguous */
|
||||
"value in SQL dialect 1, but as an exact numeric value in SQL dialect 3.", /* 550, dsql_warning_number_ambiguous1 */
|
||||
"WARNING: NUMERIC and DECIMAL fields with precision 10 or greater are stored", /* 551, dsql_warn_precision_ambiguous */
|
||||
"as approximate floating-point values in SQL dialect 1, but as 64-bit", /* 552, dsql_warn_precision_ambiguous1 */
|
||||
"integers in SQL dialect 3.", /* 553, dsql_warn_precision_ambiguous2 */
|
||||
"Ambiguous field name between %s and %s", /* 554, dsql_ambiguous_field_name */
|
||||
"External function should have return position between 1 and %d", /* 555, dsql_udf_return_pos_err */
|
||||
"Label %s %s in the current scope", /* 556, dsql_invalid_label */
|
||||
"Datatypes %sare not comparable in expression %s", /* 557, dsql_datatypes_not_comparable */
|
||||
"SQL role %s does not exist", /* 558, dyn_role_does_not_exist */
|
||||
"user %s has no grant admin option on SQL role %s", /* 559, dyn_no_grant_admin_opt */
|
||||
"user %s is not a member of SQL role %s", /* 560, dyn_user_not_role_member */
|
||||
"%s is not the owner of SQL role %s", /* 561, dyn_delete_role_failed */
|
||||
"%s is a SQL role and not a user", /* 562, dyn_grant_role_to_user */
|
||||
"user name %s could not be used for SQL role", /* 563, dyn_inv_sql_role_name */
|
||||
"SQL role %s already exists", /* 564, dyn_dup_sql_role */
|
||||
"keyword %s can not be used as a SQL role name", /* 565, dyn_kywd_spec_for_role */
|
||||
"SQL roles are not supported in on older versions of the database. A backup and restore of the database is required.", /* 566, dyn_roles_not_supported */
|
||||
"Cannot rename domain %s to %s. A domain with that name already exists.", /* 567, dyn_domain_name_exists */
|
||||
"Cannot rename column %s to %s. A column with that name already exists in table %s.", /* 568, dyn_field_name_exists */
|
||||
"Column %s from table %s is referenced in %s", /* 569, dyn_dependency_exists */
|
||||
"Cannot change datatype for column %s. Changing datatype is not supported for BLOB or ARRAY columns.", /* 570, dyn_dtype_invalid */
|
||||
"New size specified for column %s must be at least %d characters.", /* 571, dyn_char_fld_too_small */
|
||||
"Cannot change datatype for %s. Conversion from base type %s to %s is not supported.", /* 572, dyn_invalid_dtype_conversion */
|
||||
"Cannot change datatype for column %s from a character type to a non-character type.", /* 573, dyn_dtype_conv_invalid */
|
||||
"Zero length identifiers are not allowed", /* 574, dyn_zero_len_id */
|
||||
"found unknown switch", /* 575, gbak_unknown_switch */
|
||||
"page size parameter missing", /* 576, gbak_page_size_missing */
|
||||
"Page size specified (%ld) greater than limit (8192 bytes)", /* 577, gbak_page_size_toobig */
|
||||
"redirect location for output is not specified", /* 578, gbak_redir_ouput_missing */
|
||||
"conflicting switches for backup/restore", /* 579, gbak_switches_conflict */
|
||||
"device type %s not known", /* 580, gbak_unknown_device */
|
||||
"protection is not there yet", /* 581, gbak_no_protection */
|
||||
"page size is allowed only on restore or create", /* 582, gbak_page_size_not_allowed */
|
||||
"multiple sources or destinations specified", /* 583, gbak_multi_source_dest */
|
||||
"requires both input and output filenames", /* 584, gbak_filename_missing */
|
||||
"input and output have the same name. Disallowed.", /* 585, gbak_dup_inout_names */
|
||||
"expected page size, encountered \"%s\"", /* 586, gbak_inv_page_size */
|
||||
"REPLACE specified, but the first file %s is a database", /* 587, gbak_db_specified */
|
||||
"database %s already exists. To replace it, use the -R switch", /* 588, gbak_db_exists */
|
||||
"device type not specified", /* 589, gbak_unk_device */
|
||||
"gds_$blob_info failed", /* 590, gbak_blob_info_failed */
|
||||
"do not understand BLOB INFO item %ld", /* 591, gbak_unk_blob_item */
|
||||
"gds_$get_segment failed", /* 592, gbak_get_seg_failed */
|
||||
"gds_$close_blob failed", /* 593, gbak_close_blob_failed */
|
||||
"gds_$open_blob failed", /* 594, gbak_open_blob_failed */
|
||||
"Failed in put_blr_gen_id", /* 595, gbak_put_blr_gen_id_failed */
|
||||
"data type %ld not understood", /* 596, gbak_unk_type */
|
||||
"gds_$compile_request failed", /* 597, gbak_comp_req_failed */
|
||||
"gds_$start_request failed", /* 598, gbak_start_req_failed */
|
||||
" gds_$receive failed", /* 599, gbak_rec_failed */
|
||||
"gds_$release_request failed", /* 600, gbak_rel_req_failed */
|
||||
" gds_$database_info failed", /* 601, gbak_db_info_failed */
|
||||
"Expected database description record", /* 602, gbak_no_db_desc */
|
||||
"failed to create database %s", /* 603, gbak_db_create_failed */
|
||||
"RESTORE: decompression length error", /* 604, gbak_decomp_len_error */
|
||||
"cannot find table %s", /* 605, gbak_tbl_missing */
|
||||
"Cannot find column for BLOB", /* 606, gbak_blob_col_missing */
|
||||
"gds_$create_blob failed", /* 607, gbak_create_blob_failed */
|
||||
"gds_$put_segment failed", /* 608, gbak_put_seg_failed */
|
||||
"expected record length", /* 609, gbak_rec_len_exp */
|
||||
"wrong length record, expected %ld encountered %ld", /* 610, gbak_inv_rec_len */
|
||||
"expected data attribute", /* 611, gbak_exp_data_type */
|
||||
"Failed in store_blr_gen_id", /* 612, gbak_gen_id_failed */
|
||||
"do not recognize record type %ld", /* 613, gbak_unk_rec_type */
|
||||
"Expected backup version 1, 2, or 3. Found %ld", /* 614, gbak_inv_bkup_ver */
|
||||
"expected backup description record", /* 615, gbak_missing_bkup_desc */
|
||||
"string truncated", /* 616, gbak_string_trunc */
|
||||
" warning -- record could not be restored", /* 617, gbak_cant_rest_record */
|
||||
"gds_$send failed", /* 618, gbak_send_failed */
|
||||
"no table name for data", /* 619, gbak_no_tbl_name */
|
||||
"unexpected end of file on backup file", /* 620, gbak_unexp_eof */
|
||||
"database format %ld is too old to restore to", /* 621, gbak_db_format_too_old */
|
||||
"array dimension for column %s is invalid", /* 622, gbak_inv_array_dim */
|
||||
"Expected XDR record length", /* 623, gbak_xdr_len_expected */
|
||||
"cannot open backup file %s", /* 624, gbak_open_bkup_error */
|
||||
"cannot open status and error output file %s", /* 625, gbak_open_error */
|
||||
"blocking factor parameter missing", /* 626, gbak_missing_block_fac */
|
||||
"expected blocking factor, encountered \"%s\"", /* 627, gbak_inv_block_fac */
|
||||
"a blocking factor may not be used in conjunction with device CT", /* 628, gbak_block_fac_specified */
|
||||
"user name parameter missing", /* 629, gbak_missing_username */
|
||||
"password parameter missing", /* 630, gbak_missing_password */
|
||||
" missing parameter for the number of bytes to be skipped", /* 631, gbak_missing_skipped_bytes */
|
||||
"expected number of bytes to be skipped, encountered \"%s\"", /* 632, gbak_inv_skipped_bytes */
|
||||
"Bad attribute for RDB$CHARACTER_SETS", /* 633, gbak_err_restore_charset */
|
||||
"Bad attribute for RDB$COLLATIONS", /* 634, gbak_err_restore_collation */
|
||||
"Unexpected I/O error while reading from backup file", /* 635, gbak_read_error */
|
||||
"Unexpected I/O error while writing to backup file", /* 636, gbak_write_error */
|
||||
"could not drop database %s (database might be in use)", /* 637, gbak_db_in_use */
|
||||
"System memory exhausted", /* 638, gbak_sysmemex */
|
||||
"Bad attributes for restoring SQL role", /* 639, gbak_restore_role_failed */
|
||||
"SQL role parameter missing", /* 640, gbak_role_op_missing */
|
||||
"page buffers parameter missing", /* 641, gbak_page_buffers_missing */
|
||||
"expected page buffers, encountered \"%s\"", /* 642, gbak_page_buffers_wrong_param */
|
||||
"page buffers is allowed only on restore or create", /* 643, gbak_page_buffers_restore */
|
||||
"size specification either missing or incorrect for file %s", /* 644, gbak_inv_size */
|
||||
"file %s out of sequence", /* 645, gbak_file_outof_sequence */
|
||||
"can't join -- one of the files missing", /* 646, gbak_join_file_missing */
|
||||
" standard input is not supported when using join operation", /* 647, gbak_stdin_not_supptd */
|
||||
"standard output is not supported when using split operation", /* 648, gbak_stdout_not_supptd */
|
||||
"backup file %s might be corrupt", /* 649, gbak_bkup_corrupt */
|
||||
"database file specification missing", /* 650, gbak_unk_db_file_spec */
|
||||
"can't write a header record to file %s", /* 651, gbak_hdr_write_failed */
|
||||
"free disk space exhausted", /* 652, gbak_disk_space_ex */
|
||||
"file size given (%d) is less than minimum allowed (%d)", /* 653, gbak_size_lt_min */
|
||||
"service name parameter missing", /* 654, gbak_svc_name_missing */
|
||||
"Cannot restore over current database, must be SYSDBA or owner of the existing database.", /* 655, gbak_not_ownr */
|
||||
"\"read_only\" or \"read_write\" required", /* 656, gbak_mode_req */
|
||||
"just data ignore all constraints etc.", /* 657, gbak_just_data */
|
||||
"restoring data only ignoring foreign key, unique, not null & other constraints", /* 658, gbak_data_only */
|
||||
"unable to open database", /* 659, gsec_cant_open_db */
|
||||
"error in switch specifications", /* 660, gsec_switches_error */
|
||||
"no operation specified", /* 661, gsec_no_op_spec */
|
||||
"no user name specified", /* 662, gsec_no_usr_name */
|
||||
"add record error", /* 663, gsec_err_add */
|
||||
"modify record error", /* 664, gsec_err_modify */
|
||||
"find/modify record error", /* 665, gsec_err_find_mod */
|
||||
"record not found for user: %s", /* 666, gsec_err_rec_not_found */
|
||||
"delete record error", /* 667, gsec_err_delete */
|
||||
"find/delete record error", /* 668, gsec_err_find_del */
|
||||
"find/display record error", /* 669, gsec_err_find_disp */
|
||||
"invalid parameter, no switch defined", /* 670, gsec_inv_param */
|
||||
"operation already specified", /* 671, gsec_op_specified */
|
||||
"password already specified", /* 672, gsec_pw_specified */
|
||||
"uid already specified", /* 673, gsec_uid_specified */
|
||||
"gid already specified", /* 674, gsec_gid_specified */
|
||||
"project already specified", /* 675, gsec_proj_specified */
|
||||
"organization already specified", /* 676, gsec_org_specified */
|
||||
"first name already specified", /* 677, gsec_fname_specified */
|
||||
"middle name already specified", /* 678, gsec_mname_specified */
|
||||
"last name already specified", /* 679, gsec_lname_specified */
|
||||
"invalid switch specified", /* 680, gsec_inv_switch */
|
||||
"ambiguous switch specified", /* 681, gsec_amb_switch */
|
||||
"no operation specified for parameters", /* 682, gsec_no_op_specified */
|
||||
"no parameters allowed for this operation", /* 683, gsec_params_not_allowed */
|
||||
"incompatible switches specified", /* 684, gsec_incompat_switch */
|
||||
"Invalid user name (maximum 31 bytes allowed)", /* 685, gsec_inv_username */
|
||||
"Warning - maximum 8 significant bytes of password used", /* 686, gsec_inv_pw_length */
|
||||
"database already specified", /* 687, gsec_db_specified */
|
||||
"database administrator name already specified", /* 688, gsec_db_admin_specified */
|
||||
"database administrator password already specified", /* 689, gsec_db_admin_pw_specified */
|
||||
"SQL role name already specified", /* 690, gsec_sql_role_specified */
|
||||
"The license file does not exist or could not be opened for read", /* 691, license_no_file */
|
||||
"operation already specified", /* 692, license_op_specified */
|
||||
"no operation specified", /* 693, license_op_missing */
|
||||
"invalid switch", /* 694, license_inv_switch */
|
||||
"invalid switch combination", /* 695, license_inv_switch_combo */
|
||||
"illegal operation/switch combination", /* 696, license_inv_op_combo */
|
||||
"ambiguous switch", /* 697, license_amb_switch */
|
||||
"invalid parameter, no switch specified", /* 698, license_inv_parameter */
|
||||
"switch does not take any parameter", /* 699, license_param_specified */
|
||||
"switch requires a parameter", /* 700, license_param_req */
|
||||
"syntax error in command line", /* 701, license_syntx_error */
|
||||
"The certificate was not added. A duplicate ID exists in the license file.", /* 702, license_dup_id */
|
||||
"The certificate was not added. Invalid certificate ID / Key combination.", /* 703, license_inv_id_key */
|
||||
"The certificate was not removed. The key does not exist or corresponds to a temporary evaluation license.", /* 704, license_err_remove */
|
||||
"An error occurred updating the license file. Operation cancelled.", /* 705, license_err_update */
|
||||
"The certificate could not be validated based on the information given. Please recheck the ID and key information.", /* 706, license_err_convert */
|
||||
"Operation failed. An unknown error occurred.", /* 707, license_err_unk */
|
||||
"Add license operation failed, KEY: %s ID: %s", /* 708, license_svc_err_add */
|
||||
"Remove license operation failed, KEY: %s", /* 709, license_svc_err_remove */
|
||||
"The evaluation license has already been used on this server. You need to purchase a non-evaluation license.", /* 710, license_eval_exists */
|
||||
"found unknown switch", /* 711, gstat_unknown_switch */
|
||||
"please retry, giving a database name", /* 712, gstat_retry */
|
||||
"Wrong ODS version, expected %d, encountered %d", /* 713, gstat_wrong_ods */
|
||||
"Unexpected end of database file.", /* 714, gstat_unexpected_eof */
|
||||
"Can't open database file %s", /* 715, gstat_open_err */
|
||||
"Can't read a database page", /* 716, gstat_read_err */
|
||||
"System memory exhausted", /* 717, gstat_sysmemex */
|
||||
0 /* Null entry to terminate list */
|
||||
};
|
||||
|
@ -735,4 +735,5 @@ static SLONG user_codes[] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
@ -533,6 +533,7 @@ static const SSHORT gds__sql_code [] = {
|
||||
-904 /* 512 wrong_backup_state */,
|
||||
-904 /* 513 wal_backup_err */,
|
||||
-902 /* 514 invalid_cursor_state */,
|
||||
-901 /* 515 bad_shutdown_mode */,
|
||||
-901 /* 1 gfix_db_name */,
|
||||
-901 /* 2 gfix_invalid_sw */,
|
||||
-901 /* 4 gfix_incmp_sw */,
|
||||
|
@ -452,7 +452,7 @@ if (dbb->dbb_use_count)
|
||||
|
||||
/* If we are supposed to be exclusive, stay exclusive */
|
||||
|
||||
if (dbb->dbb_flags & DBB_exclusive) {
|
||||
if ((dbb->dbb_flags & DBB_exclusive) || (dbb->dbb_ast_flags & DBB_shutdown_single)) {
|
||||
RESTORE_THREAD_DATA;
|
||||
return 0;
|
||||
}
|
||||
@ -787,7 +787,7 @@ PAG CCH_fetch(TDBB tdbb,
|
||||
WIN* window,
|
||||
USHORT lock_type,
|
||||
SSHORT page_type,
|
||||
SHORT checksum, SSHORT latch_wait, bool read_shadow)
|
||||
SSHORT checksum, SSHORT latch_wait, bool read_shadow)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -2263,7 +2263,7 @@ void CCH_release_exclusive(TDBB tdbb)
|
||||
* Release exclusive access to database.
|
||||
*
|
||||
**************************************/
|
||||
SET_TDBB(tdbb);
|
||||
SET_TDBB(tdbb);
|
||||
DBB dbb = tdbb->tdbb_database;
|
||||
dbb->dbb_flags &= ~DBB_exclusive;
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
$Id: ibase.h,v 1.68 2004-02-02 11:01:34 robocop Exp $
|
||||
$Id: ibase.h,v 1.69 2004-02-25 01:50:34 skidder Exp $
|
||||
*/
|
||||
|
||||
#ifndef JRD_IBASE_H
|
||||
@ -1341,10 +1341,17 @@ int ISC_EXPORT isc_get_client_minor_version ();
|
||||
/* isc_dpb_shutdown specific flags */
|
||||
/***********************************/
|
||||
|
||||
#define isc_dpb_shut_cache 1
|
||||
#define isc_dpb_shut_attachment 2
|
||||
#define isc_dpb_shut_transaction 4
|
||||
#define isc_dpb_shut_force 8
|
||||
#define isc_dpb_shut_cache 0x1
|
||||
#define isc_dpb_shut_attachment 0x2
|
||||
#define isc_dpb_shut_transaction 0x4
|
||||
#define isc_dpb_shut_force 0x8
|
||||
#define isc_dpb_shut_mode_mask 0x70
|
||||
|
||||
#define isc_dpb_shut_default 0x0
|
||||
#define isc_dpb_shut_normal 0x10
|
||||
#define isc_dpb_shut_multi 0x20
|
||||
#define isc_dpb_shut_single 0x30
|
||||
#define isc_dpb_shut_full 0x40
|
||||
|
||||
/**************************************/
|
||||
/* Bit assignments in RDB$SYSTEM_FLAG */
|
||||
|
@ -989,7 +989,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
V4_JRD_MUTEX_LOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
#endif
|
||||
|
||||
if (options.dpb_shutdown || options.dpb_online)
|
||||
if (options.dpb_shutdown)
|
||||
{
|
||||
/* By releasing the DBB_MUTX_init_fini mutex here, we would be allowing
|
||||
other threads to proceed with their detachments, so that shutdown does
|
||||
@ -1001,7 +1001,41 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
#endif
|
||||
JRD_SS_MUTEX_UNLOCK;
|
||||
if (!SHUT_database
|
||||
(dbb, options.dpb_shutdown, options.dpb_shutdown_delay)) {
|
||||
(dbb, options.dpb_shutdown, options.dpb_shutdown_delay))
|
||||
{
|
||||
JRD_SS_MUTEX_LOCK;
|
||||
#if defined(V4_THREADING) && !defined(SUPERSERVER)
|
||||
V4_JRD_MUTEX_LOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
#endif
|
||||
if (user_status[1] != FB_SUCCESS)
|
||||
ERR_punt();
|
||||
else
|
||||
ERR_post(isc_no_priv,
|
||||
isc_arg_string, "shutdown or online",
|
||||
isc_arg_string, "database",
|
||||
isc_arg_string,
|
||||
ERR_string(file_name, file_length),
|
||||
0);
|
||||
}
|
||||
JRD_SS_MUTEX_LOCK;
|
||||
#if defined(V4_THREADING) && !defined(SUPERSERVER)
|
||||
V4_JRD_MUTEX_LOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (options.dpb_online)
|
||||
{
|
||||
/* By releasing the DBB_MUTX_init_fini mutex here, we would be allowing
|
||||
other threads to proceed with their detachments, so that shutdown does
|
||||
not timeout for exclusive access and other threads don't have to wait
|
||||
behind shutdown */
|
||||
|
||||
#if defined(V4_THREADING) && !defined(SUPERSERVER)
|
||||
V4_JRD_MUTEX_UNLOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
#endif
|
||||
JRD_SS_MUTEX_UNLOCK;
|
||||
if (!SHUT_online(dbb, options.dpb_online))
|
||||
{
|
||||
JRD_SS_MUTEX_LOCK;
|
||||
#if defined(V4_THREADING) && !defined(SUPERSERVER)
|
||||
V4_JRD_MUTEX_LOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
@ -1052,11 +1086,30 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
ERR_string(file_name, file_length), 0);
|
||||
}
|
||||
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown &&
|
||||
!(attachment->att_user->usr_flags & (USR_locksmith | USR_owner)))
|
||||
{
|
||||
ERR_post(isc_shutdown, isc_arg_string,
|
||||
ERR_string(file_name, file_length), 0);
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown) {
|
||||
// Allow only SYSDBA/owner to access database that is shut down
|
||||
bool allow_access = attachment->att_user->usr_flags & (USR_locksmith | USR_owner);
|
||||
// Handle special shutdown modes
|
||||
if (allow_access) {
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown_full) {
|
||||
// Full shutdown. Deny access always
|
||||
allow_access = false;
|
||||
}
|
||||
else if (dbb->dbb_ast_flags & DBB_shutdown_single) {
|
||||
// Single user maintenance. Allow access only if we were able to take exclusive lock
|
||||
// Note that logic below this exclusive lock differs for SS and CS builds:
|
||||
// - CS keeps PW database lock from releasing in AST in single-user maintenance mode
|
||||
// - for SS this code effectively checks that no other attachments are present
|
||||
// at call point, ATT_exclusive bit is released just before this procedure exits
|
||||
// Things are done this way to handle return to online mode nicely.
|
||||
allow_access = CCH_exclusive(tdbb, LCK_PW, WAIT_PERIOD);
|
||||
}
|
||||
}
|
||||
if (!allow_access) {
|
||||
// Note we throw exception here when entering full-shutdown mode
|
||||
ERR_post(isc_shutdown, isc_arg_string,
|
||||
ERR_string(file_name, file_length), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef REPLAY_OSRI_API_CALLS_SUBSYSTEM
|
||||
@ -1917,7 +1970,12 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
|
||||
INI_format(attachment->att_user->usr_user_name, options.dpb_set_db_charset);
|
||||
|
||||
if (options.dpb_shutdown || options.dpb_online) {
|
||||
// There is no point to move database online at database creation since it is online by default.
|
||||
// We do not allow to create database that is fully shut down.
|
||||
if (options.dpb_online || (options.dpb_shutdown & isc_dpb_shut_mode_mask) == isc_dpb_shut_full)
|
||||
ERR_post(isc_bad_shutdown_mode, isc_arg_string, ERR_string(file_name, file_length), 0);
|
||||
|
||||
if (options.dpb_shutdown) {
|
||||
/* By releasing the DBB_MUTX_init_fini mutex here, we would be allowing
|
||||
other threads to proceed with their detachments, so that shutdown does
|
||||
not timeout for exclusive access and other threads don't have to wait
|
||||
@ -1941,7 +1999,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
V4_JRD_MUTEX_LOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (options.dpb_sweep_interval != -1) {
|
||||
PAG_sweep_interval(options.dpb_sweep_interval);
|
||||
dbb->dbb_sweep_interval = options.dpb_sweep_interval;
|
||||
@ -4587,8 +4645,9 @@ static ISC_STATUS check_database(TDBB tdbb, ATT attachment, ISC_STATUS * user_st
|
||||
}
|
||||
|
||||
if (attachment->att_flags & ATT_shutdown ||
|
||||
(dbb->dbb_ast_flags & DBB_shutdown &&
|
||||
!(attachment->att_user->usr_flags & (USR_locksmith | USR_owner))))
|
||||
((dbb->dbb_ast_flags & DBB_shutdown) &&
|
||||
((dbb->dbb_ast_flags & DBB_shutdown_full) ||
|
||||
!(attachment->att_user->usr_flags & (USR_locksmith | USR_owner)))))
|
||||
{
|
||||
tdbb->tdbb_status_vector = ptr = user_status;
|
||||
*ptr++ = isc_arg_gds;
|
||||
@ -5187,6 +5246,9 @@ static void get_options(const UCHAR* dpb,
|
||||
|
||||
case isc_dpb_shutdown:
|
||||
options->dpb_shutdown = (USHORT) get_parameter(&p);
|
||||
// Enforce default
|
||||
if ((options->dpb_shutdown & isc_dpb_shut_mode_mask) == isc_dpb_shut_default)
|
||||
options->dpb_shutdown |= isc_dpb_shut_multi;
|
||||
break;
|
||||
|
||||
case isc_dpb_shutdown_delay:
|
||||
@ -5194,9 +5256,10 @@ static void get_options(const UCHAR* dpb,
|
||||
break;
|
||||
|
||||
case isc_dpb_online:
|
||||
options->dpb_online = TRUE;
|
||||
l = *p++;
|
||||
p += l;
|
||||
options->dpb_online = (USHORT) get_parameter(&p);
|
||||
// Enforce default
|
||||
if ((options->dpb_online & isc_dpb_shut_mode_mask) == isc_dpb_shut_default)
|
||||
options->dpb_online |= isc_dpb_shut_normal;
|
||||
break;
|
||||
|
||||
case isc_dpb_reserved:
|
||||
|
@ -88,6 +88,16 @@
|
||||
#include "../include/fb_blk.h"
|
||||
|
||||
|
||||
/* Shutdown lock data */
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
SSHORT flag;
|
||||
SSHORT delay;
|
||||
} data_items;
|
||||
SLONG data_long;
|
||||
} SDATA;
|
||||
|
||||
/* the database block, the topmost block in the metadata
|
||||
cache for a database */
|
||||
|
||||
@ -305,6 +315,8 @@ typedef dbb* DBB;
|
||||
#define DBB_shut_tran 0x20L // no new transactions accepted
|
||||
#define DBB_shut_force 0x40L // forced shutdown in progress
|
||||
#define DBB_shutdown_locks 0x80L // Database locks release by shutdown
|
||||
#define DBB_shutdown_full 0x100L // Database fully shut down
|
||||
#define DBB_shutdown_single 0x200L // Database is in single-user maintenance mode
|
||||
|
||||
//
|
||||
// Database attachments
|
||||
|
@ -365,11 +365,18 @@ struct header_page {
|
||||
#define hdr_no_checksums 0x10 /* 16 don't calculate checksums */
|
||||
#define hdr_no_reserve 0x20 /* 32 don't reserve space for versions */
|
||||
#define hdr_disable_cache 0x40 /* 64 disable using shared cache file */
|
||||
#define hdr_shutdown 0x80 /* 128 database is shutdown */
|
||||
//#define hdr_shutdown 0x80 /* 128 database is shutdown */
|
||||
#define hdr_SQL_dialect_3 0x100 /* 256 database SQL dialect 3 */
|
||||
#define hdr_read_only 0x200 /* 512 Database in ReadOnly. If not set, DB is RW */
|
||||
/* backup status mask */
|
||||
#define hdr_backup_mask 0xC00
|
||||
/* backup status mask - see bit values in nbak.h */
|
||||
#define hdr_backup_mask 0xC00
|
||||
#define hdr_shutdown_mask 0x1080
|
||||
|
||||
// Values for shutdown mask
|
||||
#define hdr_shutdown_none 0x0
|
||||
#define hdr_shutdown_multi 0x80
|
||||
#define hdr_shutdown_full 0x1000
|
||||
#define hdr_shutdown_single 0x1080
|
||||
|
||||
/*
|
||||
typedef struct sfd {
|
||||
|
@ -290,7 +290,13 @@ jrd_file* PIO_create(DBB dbb, const TEXT* string, SSHORT length, bool overwrite)
|
||||
|
||||
TEXT expanded_name[256]; // Shouldn't it be MAXPATHLEN?
|
||||
length = PIO_expand(string, length, expanded_name);
|
||||
jrd_file* file = setup_file(dbb, expanded_name, length, desc);
|
||||
jrd_file *file;
|
||||
try {
|
||||
file = setup_file(dbb, expanded_name, length, desc);
|
||||
} catch(const std::exception&) {
|
||||
close(desc);
|
||||
throw;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -661,7 +667,14 @@ jrd_file* PIO_open(DBB dbb,
|
||||
}
|
||||
#endif /* SUPPORT_RAW_DEVICES */
|
||||
|
||||
return setup_file(dbb, string, length, desc);
|
||||
jrd_file *file;
|
||||
try {
|
||||
file = setup_file(dbb, string, length, desc);
|
||||
} catch(const std::exception&) {
|
||||
close(desc);
|
||||
throw;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@ -1012,7 +1025,35 @@ static jrd_file* setup_file(DBB dbb, const TEXT* file_name, USHORT file_length,
|
||||
dbb->dbb_flags |= DBB_exclusive;
|
||||
if (!LCK_lock(NULL, lock, LCK_EX, LCK_NO_WAIT)) {
|
||||
dbb->dbb_flags &= ~DBB_exclusive;
|
||||
LCK_lock(NULL, lock, LCK_SW, LCK_WAIT);
|
||||
TDBB tdbb = GET_THREAD_DATA;
|
||||
|
||||
while (!LCK_lock(tdbb, lock, LCK_SW, -1)) {
|
||||
tdbb->tdbb_status_vector[0] = 0; // Clean status vector from lock manager error code
|
||||
// If we are in a single-threaded maintenance mode then clean up and stop waiting
|
||||
SCHAR spare_memory[MIN_PAGE_SIZE*2];
|
||||
SCHAR *header_page_buffer = (SCHAR*) FB_ALIGN((IPTR)spare_memory, MIN_PAGE_SIZE);
|
||||
|
||||
try {
|
||||
dbb->dbb_file = file;
|
||||
PIO_header(dbb, header_page_buffer, MIN_PAGE_SIZE);
|
||||
/* Rewind file pointer */
|
||||
if (lseek (file->fil_desc, LSEEK_OFFSET_CAST 0, 0) == (off_t)-1)
|
||||
ERR_post (isc_io_error,
|
||||
isc_arg_string, "lseek",
|
||||
isc_arg_string, ERR_string (file_name, file_length),
|
||||
isc_arg_gds, isc_io_read_err,
|
||||
isc_arg_unix, errno, 0);
|
||||
if ((reinterpret_cast<header_page*>(header_page_buffer)->hdr_flags & hdr_shutdown_mask) == hdr_shutdown_single)
|
||||
ERR_post(isc_shutdown, isc_arg_string, ERR_string(file_name, file_length), 0);
|
||||
dbb->dbb_file = NULL; // Will be set again later by the caller
|
||||
} catch(const std::exception&) {
|
||||
delete dbb->dbb_lock;
|
||||
dbb->dbb_lock = NULL;
|
||||
delete file;
|
||||
dbb->dbb_file = NULL; // Will be set again later by the caller
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
@ -1317,8 +1358,8 @@ raw_devices_unlink_database (
|
||||
|
||||
for (i = 0; i < IO_RETRY; i++)
|
||||
{
|
||||
const ssize_t bytes = write (desc, header, sizeof(header);
|
||||
if (bytes) == sizeof(header))
|
||||
const ssize_t bytes = write (desc, header, sizeof(header));
|
||||
if (bytes == sizeof(header))
|
||||
break;
|
||||
if (bytes == -1 && SYSCALL_INTERRUPTED(errno))
|
||||
continue;
|
||||
|
@ -1102,8 +1102,13 @@ if (header->hdr_implementation && header->hdr_implementation != CLASS)
|
||||
if (header->hdr_flags & hdr_no_reserve)
|
||||
dbb->dbb_flags |= DBB_no_reserve;
|
||||
|
||||
if (header->hdr_flags & hdr_shutdown)
|
||||
if (header->hdr_flags & hdr_shutdown_mask) {
|
||||
dbb->dbb_ast_flags |= DBB_shutdown;
|
||||
if ((header->hdr_flags & hdr_shutdown_mask) == hdr_shutdown_full)
|
||||
dbb->dbb_ast_flags |= DBB_shutdown_full;
|
||||
else if ((header->hdr_flags & hdr_shutdown_mask) == hdr_shutdown_single)
|
||||
dbb->dbb_ast_flags |= DBB_shutdown_single;
|
||||
}
|
||||
|
||||
if (temp_buffer)
|
||||
gds__free(temp_buffer);
|
||||
|
277
src/jrd/shut.cpp
277
src/jrd/shut.cpp
@ -39,23 +39,17 @@
|
||||
#include "../jrd/thd_proto.h"
|
||||
#include "../jrd/tra_proto.h"
|
||||
|
||||
/* Shutdown lock data */
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
SSHORT flag;
|
||||
SSHORT delay;
|
||||
} data_items;
|
||||
SLONG data_long;
|
||||
} SDATA;
|
||||
|
||||
#define SHUT_WAIT_TIME 5
|
||||
|
||||
// Define this to true if you need to allow no-op behavior when requested shutdown mode
|
||||
// matches current. Logic of jrd8_create_database may need attention in this case too
|
||||
#define IGNORE_SAME_MODE false
|
||||
|
||||
static bool notify_shutdown(DBB, SSHORT, SSHORT);
|
||||
static bool shutdown_locks(DBB);
|
||||
static bool shutdown_locks(DBB, SSHORT);
|
||||
|
||||
|
||||
BOOLEAN SHUT_blocking_ast(DBB dbb)
|
||||
bool SHUT_blocking_ast(DBB dbb)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -75,21 +69,36 @@ BOOLEAN SHUT_blocking_ast(DBB dbb)
|
||||
|
||||
/* Database shutdown has been cancelled. */
|
||||
|
||||
if (!flag) {
|
||||
// Delay of -1 means we're going online
|
||||
if (delay == -1) {
|
||||
dbb->dbb_ast_flags &=
|
||||
~(DBB_shut_attach | DBB_shut_tran | DBB_shut_force |
|
||||
DBB_shutdown);
|
||||
DBB_shutdown | DBB_shutdown_single | DBB_shutdown_full);
|
||||
switch (flag & isc_dpb_shut_mode_mask) {
|
||||
case isc_dpb_shut_normal:
|
||||
break;
|
||||
case isc_dpb_shut_multi:
|
||||
dbb->dbb_ast_flags |= DBB_shutdown;
|
||||
break;
|
||||
case isc_dpb_shut_single:
|
||||
dbb->dbb_ast_flags |= DBB_shutdown | DBB_shutdown_single;
|
||||
break;
|
||||
case isc_dpb_shut_full:
|
||||
dbb->dbb_ast_flags |= DBB_shutdown | DBB_shutdown_full;
|
||||
break;
|
||||
}
|
||||
|
||||
dbb->dbb_shutdown_delay = 0;
|
||||
for (att* attachment = dbb->dbb_attachments; attachment;
|
||||
attachment = attachment->att_next)
|
||||
{
|
||||
attachment->att_flags &= ~ATT_shutdown_notify;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flag & isc_dpb_shut_force && !delay)
|
||||
return shutdown_locks(dbb);
|
||||
if ((flag & isc_dpb_shut_force) && !delay)
|
||||
return shutdown_locks(dbb, flag);
|
||||
else {
|
||||
if (flag & isc_dpb_shut_attachment)
|
||||
dbb->dbb_ast_flags |= DBB_shut_attach;
|
||||
@ -98,12 +107,124 @@ BOOLEAN SHUT_blocking_ast(DBB dbb)
|
||||
if (flag & isc_dpb_shut_transaction)
|
||||
dbb->dbb_ast_flags |= DBB_shut_tran;
|
||||
dbb->dbb_shutdown_delay = delay;
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool bad_mode(bool ignore) {
|
||||
if (!ignore) {
|
||||
TDBB tdbb = GET_THREAD_DATA;
|
||||
|
||||
ISC_STATUS* status = tdbb->tdbb_status_vector;
|
||||
*status++ = isc_arg_gds;
|
||||
*status++ = isc_bad_shutdown_mode;
|
||||
*status++ = isc_arg_string;
|
||||
*status++ = (ISC_STATUS) ERR_cstring(reinterpret_cast<TEXT*>(tdbb->tdbb_database->dbb_filename->str_data));
|
||||
*status++ = isc_arg_end;
|
||||
}
|
||||
return ignore;
|
||||
}
|
||||
|
||||
BOOLEAN SHUT_database(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
|
||||
bool SHUT_online(DBB dbb, SSHORT flag)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* S H U T _ o n l i n e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Move database to "more online" state
|
||||
*
|
||||
**************************************/
|
||||
|
||||
TDBB tdbb = GET_THREAD_DATA;
|
||||
att* attachment = tdbb->tdbb_attachment;
|
||||
|
||||
/* Only platform's user locksmith can shutdown or bring online
|
||||
a database. */
|
||||
|
||||
if (!(attachment->att_user->usr_flags & (USR_locksmith | USR_owner))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if requested shutdown mode is valid
|
||||
int shut_mode = flag & isc_dpb_shut_mode_mask;
|
||||
switch(shut_mode) {
|
||||
case isc_dpb_shut_normal:
|
||||
if (!(dbb->dbb_ast_flags & DBB_shutdown))
|
||||
return bad_mode(IGNORE_SAME_MODE); // normal -> normal
|
||||
break;
|
||||
case isc_dpb_shut_multi:
|
||||
if (!(dbb->dbb_ast_flags & DBB_shutdown))
|
||||
return bad_mode(false); // normal -> multi
|
||||
if (!(dbb->dbb_ast_flags & DBB_shutdown_full) &&
|
||||
!(dbb->dbb_ast_flags & DBB_shutdown_single))
|
||||
{
|
||||
return bad_mode(IGNORE_SAME_MODE); // multi -> multi
|
||||
}
|
||||
break;
|
||||
case isc_dpb_shut_single:
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown_single)
|
||||
return bad_mode(IGNORE_SAME_MODE); //single -> single
|
||||
if (!(dbb->dbb_ast_flags & DBB_shutdown_full))
|
||||
return bad_mode(false); // !full -> single
|
||||
break;
|
||||
case isc_dpb_shut_full:
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown_full)
|
||||
{
|
||||
return bad_mode(IGNORE_SAME_MODE); // full -> full
|
||||
}
|
||||
return bad_mode(false);
|
||||
default: // isc_dpb_shut_full
|
||||
return bad_mode(false); // unexpected mode
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
/* Clear shutdown flag on database header page */
|
||||
|
||||
WIN window(HEADER_PAGE);
|
||||
header_page* header = (header_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_header);
|
||||
CCH_MARK_MUST_WRITE(tdbb, &window);
|
||||
// Set appropriate shutdown mode in database header
|
||||
header->hdr_flags &= ~hdr_shutdown_mask;
|
||||
switch(shut_mode) {
|
||||
case isc_dpb_shut_normal:
|
||||
break;
|
||||
case isc_dpb_shut_multi:
|
||||
header->hdr_flags |= hdr_shutdown_multi;
|
||||
break;
|
||||
case isc_dpb_shut_single:
|
||||
header->hdr_flags |= hdr_shutdown_single;
|
||||
break;
|
||||
case isc_dpb_shut_full:
|
||||
header->hdr_flags |= hdr_shutdown_full;
|
||||
break;
|
||||
}
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
|
||||
/* Notify existing database clients that a currently
|
||||
scheduled shutdown is cancelled. */
|
||||
|
||||
if (notify_shutdown(dbb, shut_mode, -1))
|
||||
CCH_release_exclusive(tdbb);
|
||||
|
||||
/* Notify local attachments */
|
||||
|
||||
SHUT_blocking_ast(dbb);
|
||||
|
||||
} // try
|
||||
catch (const std::exception&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHUT_database(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -115,45 +236,54 @@ BOOLEAN SHUT_database(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
* Schedule database for shutdown
|
||||
*
|
||||
**************************************/
|
||||
TDBB tdbb;
|
||||
ATT attachment;
|
||||
SSHORT timeout, exclusive;
|
||||
|
||||
TDBB tdbb = GET_THREAD_DATA;
|
||||
att* attachment = tdbb->tdbb_attachment;
|
||||
tdbb = GET_THREAD_DATA;
|
||||
attachment = tdbb->tdbb_attachment;
|
||||
|
||||
/* Only platform's user locksmith can shutdown or bring online
|
||||
a database. */
|
||||
|
||||
if (!(attachment->att_user->usr_flags & (USR_locksmith | USR_owner))) {
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if requested shutdown mode is valid
|
||||
// Note that if we are already in requested mode we just return true.
|
||||
// This is required to ensure backward compatible behavior (gbak relies on that,
|
||||
// user-written scripts may rely on this behaviour too)
|
||||
int shut_mode = flag & isc_dpb_shut_mode_mask;
|
||||
switch(shut_mode) {
|
||||
case isc_dpb_shut_full:
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown_full) return bad_mode(IGNORE_SAME_MODE);
|
||||
break;
|
||||
case isc_dpb_shut_multi:
|
||||
if ((dbb->dbb_ast_flags & DBB_shutdown_full) ||
|
||||
(dbb->dbb_ast_flags & DBB_shutdown_single))
|
||||
{
|
||||
return bad_mode(false);
|
||||
}
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown)
|
||||
return bad_mode(IGNORE_SAME_MODE);
|
||||
break;
|
||||
case isc_dpb_shut_single:
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown_full)
|
||||
return bad_mode(false);
|
||||
if (dbb->dbb_ast_flags & DBB_shutdown_single)
|
||||
return bad_mode(IGNORE_SAME_MODE);
|
||||
break;
|
||||
case isc_dpb_shut_normal:
|
||||
if (!(dbb->dbb_ast_flags & DBB_shutdown))
|
||||
return bad_mode(IGNORE_SAME_MODE);
|
||||
return bad_mode(false);
|
||||
default:
|
||||
return bad_mode(false); // unexpected mode
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
/* If shutdown flag is zero then bring database online */
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
/* Clear shutdown flag on database header page */
|
||||
|
||||
WIN window(HEADER_PAGE);
|
||||
header_page* header =
|
||||
(header_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_header);
|
||||
CCH_MARK_MUST_WRITE(tdbb, &window);
|
||||
header->hdr_flags &= ~hdr_shutdown;
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
|
||||
/* Notify existing database clients that a currently
|
||||
scheduled shutdown is cancelled. */
|
||||
|
||||
if (notify_shutdown(dbb, 0, 0))
|
||||
CCH_release_exclusive(tdbb);
|
||||
|
||||
/* Notify local attachments */
|
||||
|
||||
SHUT_blocking_ast(dbb);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
attachment->att_flags |= ATT_shutdown_manager;
|
||||
--dbb->dbb_use_count;
|
||||
|
||||
@ -202,8 +332,13 @@ BOOLEAN SHUT_database(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
}
|
||||
|
||||
dbb->dbb_ast_flags |= DBB_shutdown;
|
||||
dbb->dbb_ast_flags &= ~(DBB_shutdown_single | DBB_shutdown_full);
|
||||
if (flag & isc_dpb_shut_single)
|
||||
dbb->dbb_ast_flags |= DBB_shutdown_single;
|
||||
else if (flag & isc_dpb_shut_full)
|
||||
dbb->dbb_ast_flags |= DBB_shutdown_full;
|
||||
|
||||
if (!exclusive && flag & isc_dpb_shut_force) {
|
||||
if (!exclusive && (flag & isc_dpb_shut_force)) {
|
||||
// TMN: Ugly counting!
|
||||
while (!notify_shutdown(dbb, flag, 0));
|
||||
}
|
||||
@ -214,20 +349,34 @@ BOOLEAN SHUT_database(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
header_page* header =
|
||||
(header_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_header);
|
||||
CCH_MARK_MUST_WRITE(tdbb, &window);
|
||||
header->hdr_flags |= hdr_shutdown;
|
||||
// Set appropriate shutdown mode in database header
|
||||
header->hdr_flags &= ~hdr_shutdown_mask;
|
||||
switch(flag & isc_dpb_shut_mode_mask) {
|
||||
case isc_dpb_shut_normal:
|
||||
break;
|
||||
case isc_dpb_shut_multi:
|
||||
header->hdr_flags |= hdr_shutdown_multi;
|
||||
break;
|
||||
case isc_dpb_shut_single:
|
||||
header->hdr_flags |= hdr_shutdown_single;
|
||||
break;
|
||||
case isc_dpb_shut_full:
|
||||
header->hdr_flags |= hdr_shutdown_full;
|
||||
break;
|
||||
}
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
CCH_release_exclusive(tdbb);
|
||||
|
||||
} // try
|
||||
catch (const std::exception&) {
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN SHUT_init(DBB dbb)
|
||||
bool SHUT_init(DBB dbb)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -271,11 +420,11 @@ static bool notify_shutdown(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
|
||||
/* Send blocking ASTs to database users */
|
||||
|
||||
if (CCH_exclusive(tdbb, LCK_PW, ((SSHORT) - SHUT_WAIT_TIME)) && flag) {
|
||||
return shutdown_locks(dbb);
|
||||
if (CCH_exclusive(tdbb, LCK_PW, ((SSHORT) - SHUT_WAIT_TIME)) && (delay != -1)) {
|
||||
return shutdown_locks(dbb, flag);
|
||||
}
|
||||
if ((flag & isc_dpb_shut_force) && !delay) {
|
||||
return shutdown_locks(dbb);
|
||||
return shutdown_locks(dbb, flag);
|
||||
}
|
||||
if ((flag & isc_dpb_shut_transaction) &&
|
||||
!(TRA_active_transactions(tdbb, dbb)))
|
||||
@ -287,7 +436,7 @@ static bool notify_shutdown(DBB dbb, SSHORT flag, SSHORT delay)
|
||||
}
|
||||
|
||||
|
||||
static bool shutdown_locks(DBB dbb)
|
||||
static bool shutdown_locks(DBB dbb, SSHORT flag)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -304,7 +453,19 @@ static bool shutdown_locks(DBB dbb)
|
||||
|
||||
/* Mark database and all active attachments as shutdown. */
|
||||
|
||||
dbb->dbb_ast_flags |= DBB_shutdown;
|
||||
dbb->dbb_ast_flags &= ~(DBB_shutdown | DBB_shutdown_single | DBB_shutdown_full);
|
||||
|
||||
switch (flag & isc_dpb_shut_mode_mask) {
|
||||
case isc_dpb_shut_multi:
|
||||
dbb->dbb_ast_flags |= DBB_shutdown;
|
||||
break;
|
||||
case isc_dpb_shut_single:
|
||||
dbb->dbb_ast_flags |= DBB_shutdown | DBB_shutdown_single;
|
||||
break;
|
||||
case isc_dpb_shut_full:
|
||||
dbb->dbb_ast_flags |= DBB_shutdown | DBB_shutdown_full;
|
||||
break;
|
||||
}
|
||||
|
||||
att* attachment;
|
||||
|
||||
|
@ -26,9 +26,10 @@
|
||||
|
||||
class dbb;
|
||||
|
||||
BOOLEAN SHUT_blocking_ast(dbb*);
|
||||
BOOLEAN SHUT_database(dbb*, SSHORT, SSHORT);
|
||||
BOOLEAN SHUT_init(dbb*);
|
||||
bool SHUT_blocking_ast(dbb*);
|
||||
bool SHUT_online(dbb*, SSHORT);
|
||||
bool SHUT_database(dbb*, SSHORT, SSHORT);
|
||||
bool SHUT_init(dbb*);
|
||||
|
||||
#endif // JRD_SHUT_PROTO_H
|
||||
|
||||
|
@ -164,10 +164,22 @@ void PPG_print_header(const header_page* header, SLONG page,
|
||||
FPRINTF(outfile, "active shadow");
|
||||
}
|
||||
|
||||
if (flags & hdr_shutdown) {
|
||||
if ((flags & hdr_shutdown_mask) == hdr_shutdown_multi) {
|
||||
if (flag_count++)
|
||||
FPRINTF(outfile, ", ");
|
||||
FPRINTF(outfile, "database shutdown");
|
||||
FPRINTF(outfile, "multi-user maintenance");
|
||||
}
|
||||
|
||||
if ((flags & hdr_shutdown_mask) == hdr_shutdown_single) {
|
||||
if (flag_count++)
|
||||
FPRINTF(outfile, ", ");
|
||||
FPRINTF(outfile, "single-user maintenance");
|
||||
}
|
||||
|
||||
if ((flags & hdr_shutdown_mask) == hdr_shutdown_full) {
|
||||
if (flag_count++)
|
||||
FPRINTF(outfile, ", ");
|
||||
FPRINTF(outfile, "full shutdown");
|
||||
}
|
||||
|
||||
if (flags & hdr_read_only) {
|
||||
|
Loading…
Reference in New Issue
Block a user