151 lines
4.6 KiB
C
151 lines
4.6 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2012 Fidelity Information Services, Inc *
|
|
* *
|
|
* 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 "gdsroot.h"
|
|
#include "gtm_facility.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsbt.h"
|
|
#include "gdsfhead.h"
|
|
#include "filestruct.h"
|
|
#include "gdsbml.h"
|
|
#include "dbfilop.h"
|
|
#include "gdsdbver.h"
|
|
#include "gdsblk.h"
|
|
#include "iosp.h"
|
|
#include "mupint.h"
|
|
#include "gds_blk_upgrade.h"
|
|
#ifdef GTM_CRYPT
|
|
#include "gtmcrypt.h"
|
|
#endif
|
|
#include "min_max.h"
|
|
#ifdef GTM_SNAPSHOT
|
|
#include "shmpool.h" /* Needed for DBG_ENSURE_PTR_WITHIN_SS_BOUNDS */
|
|
#include "db_snapshot.h"
|
|
#endif
|
|
#include "mupip_exit.h"
|
|
|
|
GBLREF sgmnt_data mu_int_data;
|
|
GBLREF int4 mu_int_ovrhd;
|
|
GBLREF gd_region *gv_cur_region;
|
|
GTMCRYPT_ONLY(
|
|
GBLREF gtmcrypt_key_t mu_int_encrypt_key_handle;
|
|
)
|
|
GBLREF boolean_t ointeg_this_reg;
|
|
GBLREF sgmnt_addrs *cs_addrs;
|
|
GBLREF uint4 mu_int_errknt;
|
|
GBLREF bool region;
|
|
|
|
error_def(ERR_DBRDERR);
|
|
error_def(ERR_DBROLLEDBACK);
|
|
error_def(ERR_DYNUPGRDFAIL);
|
|
error_def(ERR_INTEGERRS);
|
|
error_def(ERR_REGSSFAIL);
|
|
|
|
uchar_ptr_t mu_int_read(block_id blk, enum db_ver *ondsk_blkver)
|
|
{
|
|
int4 status;
|
|
file_control *fc;
|
|
unsigned char *tmp_ptr;
|
|
GTMCRYPT_ONLY(
|
|
int req_dec_blk_size;
|
|
int crypt_status;
|
|
)
|
|
boolean_t have_blk = FALSE;
|
|
sgmnt_addrs *csa;
|
|
GTM_SNAPSHOT_ONLY(
|
|
boolean_t read_failed;
|
|
shm_snapshot_t *ss_shm_ptr;
|
|
)
|
|
|
|
csa = cs_addrs;
|
|
# ifdef UNIX
|
|
if (region && csa->nl->onln_rlbk_pid)
|
|
{
|
|
gtm_putmsg(VARLSTCNT(1) ERR_DBROLLEDBACK);
|
|
mupip_exit(ERR_INTEGERRS);
|
|
}
|
|
# endif
|
|
tmp_ptr = malloc(mu_int_data.blk_size);
|
|
# ifdef GTM_SNAPSHOT
|
|
if (ointeg_this_reg)
|
|
{
|
|
assert(NULL != csa->ss_ctx);
|
|
ss_shm_ptr = (SS_CTX_CAST(csa->ss_ctx))->ss_shm_ptr;
|
|
DBG_ENSURE_PTR_WITHIN_SS_BOUNDS(csa, (sm_uc_ptr_t)ss_shm_ptr);
|
|
if (!ss_shm_ptr->failure_errno)
|
|
have_blk = ss_get_block(csa, blk, tmp_ptr);
|
|
else
|
|
{ /* GT.M has failed initiating snapshot resources. Report error and exit so that we don't continue with
|
|
* an INTEG which is unusable. Note that, it's okay to check failure_errno (in the shared memory) outside
|
|
* crit as GT.M is the only one that sets it and INTEG (while doing snapshot cleanup) is the only one
|
|
* that resets it
|
|
*/
|
|
gtm_putmsg(VARLSTCNT(5) ERR_REGSSFAIL, 3, ss_shm_ptr->failed_pid, DB_LEN_STR(gv_cur_region));
|
|
mupip_exit(ERR_INTEGERRS);
|
|
}
|
|
}
|
|
# endif
|
|
if (!have_blk)
|
|
{
|
|
fc = gv_cur_region->dyn.addr->file_cntl;
|
|
fc->op = FC_READ;
|
|
fc->op_buff = tmp_ptr;
|
|
fc->op_len = mu_int_data.blk_size;
|
|
fc->op_pos = mu_int_ovrhd + ((gtm_int64_t)mu_int_data.blk_size / DISK_BLOCK_SIZE * blk);
|
|
dbfilop(fc); /* No return if error */
|
|
# ifdef GTM_SNAPSHOT
|
|
if (ointeg_this_reg)
|
|
{
|
|
assert(NULL != ss_shm_ptr); /* should have been initialized above */
|
|
/* Since we did not have locks up, ensure we didn't miss a before-image while we were reading
|
|
* in this block. Note we don't have to check the return status since it will either get the
|
|
* before-image or not.
|
|
*/
|
|
if (!ss_shm_ptr->failure_errno)
|
|
ss_get_block(csa, blk, tmp_ptr);
|
|
else
|
|
{
|
|
gtm_putmsg(VARLSTCNT(5) ERR_REGSSFAIL, 3, ss_shm_ptr->failed_pid, DB_LEN_STR(gv_cur_region));
|
|
mupip_exit(ERR_INTEGERRS);
|
|
}
|
|
}
|
|
# endif
|
|
}
|
|
# ifdef GTM_CRYPT
|
|
req_dec_blk_size = MIN(mu_int_data.blk_size, ((blk_hdr_ptr_t)tmp_ptr)->bsiz) - SIZEOF(blk_hdr);
|
|
if (BLOCK_REQUIRE_ENCRYPTION(mu_int_data.is_encrypted, (((blk_hdr_ptr_t)tmp_ptr)->levl), req_dec_blk_size))
|
|
{
|
|
/* The below assert cannot be moved before BLOCK_REQUIRE_ENCRYPTION check done above as tmp_ptr could
|
|
* potentially point to a V4 block in which case the assert might fail when a V4 block is casted to
|
|
* a V5 block header.
|
|
*/
|
|
assert(((blk_hdr_ptr_t)tmp_ptr)->bsiz <= mu_int_data.blk_size);
|
|
assert(((blk_hdr_ptr_t)tmp_ptr)->bsiz >= SIZEOF(blk_hdr));
|
|
GTMCRYPT_DECODE_FAST(mu_int_encrypt_key_handle,
|
|
(char *)(tmp_ptr + SIZEOF(blk_hdr)),
|
|
req_dec_blk_size,
|
|
NULL,
|
|
crypt_status);
|
|
if (0 != crypt_status)
|
|
GC_RTS_ERROR(crypt_status, gv_cur_region->dyn.addr->fname);
|
|
}
|
|
# endif
|
|
GDS_BLK_UPGRADE_IF_NEEDED(blk, tmp_ptr, tmp_ptr, &mu_int_data, ondsk_blkver, status, mu_int_data.fully_upgraded);
|
|
if (SS_NORMAL != status)
|
|
if (ERR_DYNUPGRDFAIL == status)
|
|
rts_error(VARLSTCNT(5) status, 3, blk, DB_LEN_STR(gv_cur_region));
|
|
else
|
|
rts_error(VARLSTCNT(1) status);
|
|
return tmp_ptr;
|
|
}
|