1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
|
/****************************************************************
* *
* Copyright (c) 2001-2019 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "gdsblk.h"
#include "gdsbml.h"
#include "mupint.h"
#include "gtmmsg.h"
#include "gtmcrypt.h"
#include "db_snapshot.h"
GBLDEF unsigned char *mu_int_locals;
GBLDEF int4 mu_int_ovrhd;
GBLREF gd_region *gv_cur_region;
GBLREF sgmnt_data mu_int_data;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF uint4 mu_int_errknt;
GBLREF boolean_t tn_reset_specified;
error_def(ERR_DBNOTDB);
error_def(ERR_DBINCRVER);
error_def(ERR_DBSVBNMIN);
error_def(ERR_DBFLCORRP);
error_def(ERR_DBCREINCOMP);
error_def(ERR_DBBSIZZRO);
error_def(ERR_DBSZGT64K);
error_def(ERR_DBNOTMLTP);
error_def(ERR_DBBPLMLT512);
error_def(ERR_DBBPLMGT2K);
error_def(ERR_DBBPLNOT512);
error_def(ERR_DBTTLBLK0);
error_def(ERR_DBTNNEQ);
error_def(ERR_DBMAXKEYEXC);
error_def(ERR_DBMXRSEXCMIN);
error_def(ERR_DBUNDACCMT);
error_def(ERR_DBHEADINV);
error_def(ERR_DBFGTBC);
error_def(ERR_DBFSTBC);
error_def(ERR_DBTOTBLK);
error_def(ERR_DBMISALIGN);
error_def(ERR_KILLABANDONED);
error_def(ERR_MUKILLIP);
error_def(ERR_MUTNWARN);
#define SET_NATIVE_SIZE(native_size) \
MBSTART { \
GBLREF util_snapshot_ptr_t util_ss_ptr; \
GBLREF boolean_t ointeg_this_reg; \
if (ointeg_this_reg) \
{ \
assert(NULL != util_ss_ptr); \
native_size = util_ss_ptr->native_size; \
assert(0 != native_size); /* Ensure native_size is updated properly in ss_initiate */ \
} else \
native_size = gds_file_size(gv_cur_region->dyn.addr->file_cntl); \
} MBEND
boolean_t mu_int_fhead(void)
{
unsigned char *p1;
unsigned int block_factor;
gtm_uint64_t size, native_size, delta_size;
trans_num temp_tn, max_tn_warn;
sgmnt_data_ptr_t mu_data;
gd_segment *seg;
block_id actual_tot_blks, should_be_tot_blks, maps;
int gtmcrypt_errno;
mu_data = &mu_int_data;
if (MEMCMP_LIT(mu_data->label, GDS_LABEL))
{
if (memcmp(mu_data->label, GDS_LABEL, SIZEOF(GDS_LABEL) - 2))
mu_int_err(ERR_DBNOTDB, 0, 0, 0, 0, 0, 0, 0);
else
mu_int_err(ERR_DBINCRVER, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
UNIX_ONLY(CHECK_DB_ENDIAN(mu_data, gv_cur_region->dyn.addr->fname_len, gv_cur_region->dyn.addr->fname)); /* BYPASSOK */
if (mu_data->start_vbn < DIVIDE_ROUND_UP(SIZEOF_FILE_HDR(mu_data), DISK_BLOCK_SIZE))
{
mu_int_err(ERR_DBSVBNMIN, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
if (mu_data->file_corrupt)
mu_int_err(ERR_DBFLCORRP, 0, 0, 0, 0, 0, 0, 0);
if (mu_data->createinprogress)
{
mu_int_err(ERR_DBCREINCOMP, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
/* CHECK: 0 < blk_size <= 64K; blk_size is a multiple of DISK_BLOCK_SIZE */
if (0 == mu_data->blk_size)
{
mu_int_err(ERR_DBBSIZZRO, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
if (mu_data->blk_size > 1 << 16)
{
mu_int_err(ERR_DBSZGT64K, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
if (mu_data->blk_size % DISK_BLOCK_SIZE)
{ /* these messages should use rts_error and parameters */
assert(512 == DISK_BLOCK_SIZE); /* but in lieu of that, check that message is accurate */
mu_int_err(ERR_DBNOTMLTP, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
/* CHECK: BLKS_PER_LMAP <= bplmap <= 2K; bplmap is a multiple of BLKS_PER_LMAP */
if (mu_data->bplmap < BLKS_PER_LMAP)
{
mu_int_err(ERR_DBBPLMLT512, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
if (mu_data->bplmap > 1 << 11)
{
mu_int_err(ERR_DBBPLMGT2K, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
if (BLKS_PER_LMAP != mu_data->bplmap)
{
mu_int_err(ERR_DBBPLNOT512, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
/* CHECK: total_blks <> 0 */
actual_tot_blks = mu_data->trans_hist.total_blks;
if (0 == actual_tot_blks)
{
mu_int_err(ERR_DBTTLBLK0, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
if (mu_data->trans_hist.curr_tn != mu_data->trans_hist.early_tn)
mu_int_err(ERR_DBTNNEQ, 0, 0, 0, 0, 0, 0, 0);
if (0 != mu_data->kill_in_prog)
{
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUKILLIP, 4, DB_LEN_STR(gv_cur_region), LEN_AND_LIT("MUPIP INTEG"));
mu_int_errknt++;
}
if (0 != mu_data->abandoned_kills)
{
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_KILLABANDONED, 4, DB_LEN_STR(gv_cur_region),
LEN_AND_LIT("database could have incorrectly marked busy integrity errors"));
mu_int_errknt++;
}
if (MAX_KEY_SZ < mu_data->max_key_size)
mu_int_err(ERR_DBMAXKEYEXC, 0, 0, 0, 0, 0, 0, 0);
gtmcrypt_errno = 0;
seg = gv_cur_region->dyn.addr;
if (IS_ENCRYPTED(mu_data->is_encrypted))
{
GTMCRYPT_HASH_CHK(cs_addrs, mu_data->encryption_hash, seg->fname_len, (char *)seg->fname, gtmcrypt_errno);
}
if ((0 == gtmcrypt_errno) && USES_NEW_KEY(mu_data))
{
GTMCRYPT_HASH_CHK(cs_addrs, mu_data->encryption_hash2, seg->fname_len, (char *)seg->fname, gtmcrypt_errno);
}
if (0 != gtmcrypt_errno)
{
GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, gtm_putmsg, seg->fname_len, seg->fname);
return FALSE;
}
/* !tn_reset_this_reg should ideally be used here instead of (!tn_reset_specified || gv_cur_region->read_only).
* But at this point, tn_reset_this_reg has not yet been set for this region and to avoid taking a risk in
* changing the code flow, we redo the computation ot tn_reset_this_reg here. This is not as much a performance concern.
*/
if (!tn_reset_specified || gv_cur_region->read_only)
{
SET_TN_WARN(mu_data, max_tn_warn);
if (max_tn_warn == mu_data->trans_hist.curr_tn)
{ /* implies there is not enough transactions to go before reaching MAX_TN (see SET_TN_WARN macro) */
temp_tn = mu_data->max_tn - mu_data->trans_hist.curr_tn;
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_MUTNWARN, 4,
DB_LEN_STR(gv_cur_region), &temp_tn, &mu_data->max_tn);
mu_int_errknt++;
}
}
/* Note - ovrhd is incremented once in order to achieve a zero-based
* index of the GDS 'data' blocks (those other than the file header
* and the block table).
*/
switch (mu_data->acc_meth)
{
default:
mu_int_err(ERR_DBUNDACCMT, 0, 0, 0, 0, 0, 0, 0);
/*** WARNING: Drop thru ***/
case dba_bg:
/*** WARNING: Drop thru ***/
case dba_mm:
mu_int_ovrhd = (int4)DIVIDE_ROUND_UP(SIZEOF_FILE_HDR(mu_data) + mu_data->free_space, DISK_BLOCK_SIZE);
}
assert(mu_data->blk_size == ROUND_UP(mu_data->blk_size, DISK_BLOCK_SIZE));
block_factor = mu_data->blk_size / DISK_BLOCK_SIZE;
mu_int_ovrhd += 1;
if (mu_int_ovrhd != mu_data->start_vbn)
{
mu_int_err(ERR_DBHEADINV, 0, 0, 0, 0, 0, 0, 0);
return FALSE;
}
size = (mu_int_ovrhd - 1) + (off_t)block_factor * (actual_tot_blks + 1);
/* If ONLINE INTEG for this region is in progress, then native_size would have been calculated in ss_initiate. */
SET_NATIVE_SIZE(native_size);
ALIGN_DBFILE_SIZE_IF_NEEDED(size, native_size);
if (native_size && (size != native_size))
{
if (size < native_size)
mu_int_err(ERR_DBFGTBC, 0, 0, 0, 0, 0, 0, 0);
else
mu_int_err(ERR_DBFSTBC, 0, 0, 0, 0, 0, 0, 0);
should_be_tot_blks = (native_size - (mu_data->start_vbn - 1)) / block_factor - 1;
if ((((should_be_tot_blks + 1) * block_factor) + (mu_data->start_vbn - 1)) == native_size)
{ /* The database file size is off but is off by N GDS blocks where N is an integer */
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBTOTBLK, 2, actual_tot_blks, should_be_tot_blks);
} else
{ /* The database file size is off but is off by a fractional GDS block. Issue different error (alignment) */
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_DBMISALIGN, 4, actual_tot_blks,
should_be_tot_blks, should_be_tot_blks + 1,
((should_be_tot_blks + 1 - actual_tot_blks) <= 0) ? 1 : (should_be_tot_blks + 1 - actual_tot_blks));
}
}
/* make working space for all local bitmaps */
maps = (actual_tot_blks + mu_data->bplmap - 1) / mu_data->bplmap;
size = (gtm_uint64_t)(BM_SIZE(mu_data->bplmap) - SIZEOF(blk_hdr));
size *= maps;
mu_int_locals = (unsigned char *)malloc(size);
memset(mu_int_locals, FOUR_BLKS_FREE, size);
return TRUE;
}
|