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
|
/****************************************************************
* *
* Copyright (c) 2016 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 "cdb_sc.h"
#include "gdsroot.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "process_reorg_encrypt_restart.h"
GBLREF sgmnt_addrs *reorg_encrypt_restart_csa;
GBLREF uint4 mu_reorg_encrypt_in_prog; /* non-zero if MUPIP REORG ENCRYPT is in progress */
GBLREF uint4 process_id;
#ifdef DEBUG
GBLREF uint4 dollar_tlevel;
#endif
/* This is a version of "grab_crit" that returns with crit held but also ensures
* "csa->nl->reorg_encrypt_cycle == csa->encr_ptr->reorg_encrypt_cycle" and that the encryption
* sync happens without holding crit (as that can take a lot of time involving external access to gpg).
* This should be used by
* 1) Callers of "t_qread" who expect that holding crit and doing t_qread is guaranteed to not return a NULL value
* (NULL is possible if the encryption cycles are different). Examples of such callers are
* a) All dse*.c modules
* b) mu_reorg_upgrd_dwngrd.c when it does a t_qread of a bitmap block inside crit
* c) mupip_reorg_encrypt.c when it does a t_qread of a bitmap block inside crit
* d) gvcst_expand_free_subtree.c when it does a t_qread of a killed index block to find its descendants to kill.
* 2) Functions like "t_retry" and "tp_restart" which grab_crit to enter into the final retry. It is best to do
* the heavyweight new-encryption-handle opening operation while outside of crit.
*
* Returns: TRUE if new-encryption-handles were opened (i.e. "process_reorg_encrypt_restart" was invoked) at least once.
* FALSE otherwise.
*/
boolean_t grab_crit_encr_cycle_sync(gd_region *reg)
{
boolean_t sync_needed;
enc_info_t *encr_ptr;
enum cdb_sc status;
node_local_ptr_t cnl;
sgmnt_addrs *csa;
sgmnt_data_ptr_t csd;
unix_db_info *udi;
udi = FILE_INFO(reg);
csa = &udi->s_addrs;
grab_crit(reg);
encr_ptr = csa->encr_ptr;
sync_needed = FALSE;
if (NULL != encr_ptr)
{
csd = csa->hdr;
cnl = csa->nl;
assert(NULL == reorg_encrypt_restart_csa);
while (cnl->reorg_encrypt_cycle != encr_ptr->reorg_encrypt_cycle)
{
sync_needed = TRUE;
/* Cycles mismatch. Fix the cycles. Take copy of shared memory while holding crit but do the
* "process_encrypt_restart_csa" after releasing crit as that is a heavyweight operation
* (involving access to external "gpg").
*/
SIGNAL_REORG_ENCRYPT_RESTART(mu_reorg_encrypt_in_prog, reorg_encrypt_restart_csa,
cnl, csa, csd, status, process_id);
rel_crit(reg);
assert(csa == reorg_encrypt_restart_csa);
process_reorg_encrypt_restart();
assert(NULL == reorg_encrypt_restart_csa);
grab_crit(reg);
}
}
return sync_needed;
}
|