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
|
/****************************************************************
* *
* Copyright (c) 2001-2020 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 <errno.h>
#include "gtm_inet.h" /* Required for gtmsource.h */
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "gdsblk.h"
#include "gdskill.h"
#include "gdscc.h"
#include "min_max.h" /* needed for gdsblkops.h */
#include "gdsblkops.h"
#include "filestruct.h"
#include "jnl.h"
#include "buddy_list.h" /* needed for tp.h */
#include "tp.h"
#include "ast.h"
#include "repl_msg.h"
#include "gtmsource.h"
#include "gtmrecv.h"
#include "error.h"
#include "io.h"
#include "gtmsecshr.h"
#include "mutex.h"
#include "ftok_sems.h"
#include "tp_change_reg.h"
#include "gds_rundown.h"
#include "dpgbldir.h"
#include "gvcmy_rundown.h"
#include "rc_cpt_ops.h"
#include "gv_rundown.h"
#include "targ_alloc.h"
#ifdef DEBUG
#include "anticipatory_freeze.h"
#endif
#include "aio_shim.h"
GBLREF gd_region *gv_cur_region;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF int pool_init;
GBLREF jnlpool_addrs_ptr_t jnlpool;
GBLREF jnlpool_addrs_ptr_t jnlpool_head;
GBLREF recvpool_addrs recvpool;
#ifdef DEBUG
GBLREF boolean_t is_jnlpool_creator;
error_def(ERR_TEXT);
#endif
error_def(ERR_NOTALLDBRNDWN);
void gv_rundown(void)
{
gd_region *r_top, *r_save, *r_local;
gd_addr *addr_ptr;
jnlpool_addrs_ptr_t local_jnlpool, save_jnlpool;
sgm_info *si;
int4 rundown_status = EXIT_NRM; /* if gds_rundown went smoothly */
unix_db_info *udi;
sgmnt_addrs *csa;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
r_save = gv_cur_region; /* Save for possible core dump */
save_jnlpool = jnlpool;
gvcmy_rundown();
ENABLE_AST
if (pool_init)
{
for (local_jnlpool = jnlpool_head; local_jnlpool; local_jnlpool = local_jnlpool->next)
if (local_jnlpool->pool_init)
rel_lock(local_jnlpool->jnlpool_dummy_reg);
}
for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
{
for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions; r_local < r_top; r_local++)
{
if (r_local->open && (dba_cm != r_local->dyn.addr->acc_meth))
{
/* Rundown has already occurred for GT.CM client regions through gvcmy_rundown() above.
* Hence the (dba_cm != ...) check in the if above. Note that for GT.CM client regions,
* region->open is TRUE although cs_addrs is NULL.
*/
# ifdef DEBUG
if (is_jnlpool_creator
&& INST_FREEZE_ON_NOSPC_ENABLED(REG2CSA(r_local), local_jnlpool)
&& TREF(gtm_test_fake_enospc))
{ /* Clear ENOSPC faking now that we are running down */
csa = REG2CSA(r_local);
assert((NULL == csa->jnlpool) || (jnlpool == csa->jnlpool));
if (csa->nl->fake_db_enospc || csa->nl->fake_jnl_enospc)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TEXT, 2, DB_LEN_STR(r_local), ERR_TEXT,
2, LEN_AND_LIT("Resetting fake_db_enospc and fake_jnl_enospc"));
csa->nl->fake_db_enospc = FALSE;
csa->nl->fake_jnl_enospc = FALSE;
}
}
# endif
gv_cur_region = r_local;
csa = REG2CSA(r_local);
if (csa->jnlpool && (jnlpool != csa->jnlpool))
jnlpool = csa->jnlpool;
tp_change_reg();
rundown_status |= gds_rundown(CLEANUP_UDI_TRUE);
}
r_local->open = r_local->was_open = FALSE;
}
}
rc_close_section();
gv_cur_region = r_save; /* Restore value for dumps but this region is now closed and is otherwise defunct */
jnlpool = save_jnlpool;
cs_addrs = NULL;
gtmsecshr_sock_cleanup(CLIENT);
# ifndef MUTEX_MSEM_WAKE
mutex_sock_cleanup();
# endif
for (jnlpool = jnlpool_head; jnlpool; jnlpool = jnlpool->next)
jnlpool_detach();
/* Once upon a time this used ftok_sem_reg to release a possibly still held semaphore, but attempts to do that exploded if
* the region was closed because the structures needed by FILE_INFO had been released; this could happen due to bypass. So
* this approach was relegated to the mists of time on the theory that gds_rundown did the best it could with the semaphores
* and, if bypass was involved, some required operational action will deal with them. We still check for possible remaining
* replication journal pool semaphores and deal with those.
* Note that we use FALSE for the decr_cnt parameter (2nd parameter) to "ftok_sem_release". This is to avoid incorrect
* removal of the ftok semaphore in case the counter is down to 1 but there are processes which did not bump the counter
* (due to the counter overflowing) that are still accessing the semaphore. Even though we don't decrement the counter,
* the SEM_UNDO will take care of doing the actual decrement when this process terminates. The only consequence is
* we don't remove the ftok semaphore when the last process to use it dies, requiring mupip rollback/recover/rundown to
* clean it up. But that is considered okay because these are unclean exit conditions with that documented requirement.
*/
for (jnlpool = jnlpool_head; jnlpool; jnlpool = jnlpool->next)
if (jnlpool->jnlpool_dummy_reg && jnlpool->pool_init)
{
udi = FILE_INFO(jnlpool->jnlpool_dummy_reg);
if (udi->grabbed_ftok_sem)
ftok_sem_release(jnlpool->jnlpool_dummy_reg, FALSE, TRUE);
}
if (NULL != recvpool.recvpool_dummy_reg)
{
udi = FILE_INFO(recvpool.recvpool_dummy_reg);
if (udi->grabbed_ftok_sem)
ftok_sem_release(recvpool.recvpool_dummy_reg, FALSE, TRUE);
}
if (EXIT_NRM != rundown_status)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOTALLDBRNDWN);
}
|