197 lines
5.7 KiB
C
197 lines
5.7 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2009 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 "gtm_fcntl.h"
|
||
|
#include "gtm_unistd.h"
|
||
|
|
||
|
#ifdef VMS
|
||
|
#include <rms.h>
|
||
|
#endif
|
||
|
|
||
|
#include "gtm_string.h"
|
||
|
#include "stringpool.h"
|
||
|
#include "gdsroot.h"
|
||
|
#include "gtm_facility.h"
|
||
|
#include "fileinfo.h"
|
||
|
#include "gdsbt.h"
|
||
|
#include "gdsfhead.h"
|
||
|
#include "mupipbckup.h"
|
||
|
#include "gdscc.h"
|
||
|
#include "gdskill.h"
|
||
|
#include "filestruct.h"
|
||
|
#include "jnl.h"
|
||
|
#include "buddy_list.h" /* needed for tp.h */
|
||
|
#include "hashtab_int4.h" /* needed for tp.h */
|
||
|
#include "tp.h"
|
||
|
#include "util.h"
|
||
|
#include "gtmmsg.h"
|
||
|
#include "memcoherency.h"
|
||
|
#include "shmpool.h"
|
||
|
#include "interlock.h"
|
||
|
#include "add_inter.h"
|
||
|
|
||
|
#ifdef UNIX
|
||
|
#include "ftok_sems.h"
|
||
|
#include "repl_msg.h"
|
||
|
#include "gtmsource.h"
|
||
|
#include "gtmio.h"
|
||
|
#endif
|
||
|
|
||
|
GBLREF spdesc stringpool;
|
||
|
GBLREF tp_region *grlist;
|
||
|
GBLREF tp_region *halt_ptr;
|
||
|
GBLREF bool online;
|
||
|
GBLREF bool error_mupip;
|
||
|
GBLREF boolean_t backup_interrupted;
|
||
|
|
||
|
#ifdef UNIX
|
||
|
GBLREF backup_reg_list *mu_repl_inst_reg_list;
|
||
|
GBLREF jnlpool_addrs jnlpool;
|
||
|
#endif
|
||
|
|
||
|
void mubclnup(backup_reg_list *curr_ptr, clnup_stage stage)
|
||
|
{
|
||
|
sgmnt_addrs *csa;
|
||
|
backup_reg_list *ptr, *next;
|
||
|
uint4 status;
|
||
|
boolean_t had_lock;
|
||
|
#ifdef VMS
|
||
|
struct FAB temp_fab;
|
||
|
#else
|
||
|
unix_db_info *udi;
|
||
|
int rc;
|
||
|
#endif
|
||
|
|
||
|
error_def(ERR_FORCEDHALT);
|
||
|
|
||
|
assert(stage >= need_to_free_space && stage < num_of_clnup_stage);
|
||
|
|
||
|
free(stringpool.base);
|
||
|
|
||
|
switch(stage)
|
||
|
{
|
||
|
case need_to_rel_crit:
|
||
|
for (ptr = (backup_reg_list *)grlist; ptr != NULL && ptr != curr_ptr && ptr != (backup_reg_list *)halt_ptr;)
|
||
|
{
|
||
|
if (keep_going == ptr->not_this_time)
|
||
|
{
|
||
|
csa = &FILE_INFO(ptr->reg)->s_addrs;
|
||
|
DECR_INHIBIT_KILLS(csa->nl);
|
||
|
rel_crit(ptr->reg);
|
||
|
}
|
||
|
ptr = ptr->fPtr;
|
||
|
}
|
||
|
curr_ptr = (backup_reg_list *)halt_ptr;
|
||
|
/* Intentional Fall Through */
|
||
|
case need_to_del_tempfile:
|
||
|
for (ptr = (backup_reg_list *)grlist; ptr != NULL && ptr != curr_ptr;)
|
||
|
{
|
||
|
assert(3 == num_backup_proc_status); /* Ensure there are only 3 possible values for "ptr->not_this_time".
|
||
|
* The assert below and the following if check rely on this. */
|
||
|
assert((keep_going == ptr->not_this_time)
|
||
|
|| (give_up_before_create_tempfile == ptr->not_this_time)
|
||
|
|| (give_up_after_create_tempfile == ptr->not_this_time));
|
||
|
if (give_up_before_create_tempfile != ptr->not_this_time)
|
||
|
{
|
||
|
free(ptr->backup_hdr);
|
||
|
if (online)
|
||
|
{ /* Stop temporary file from growing if we made it active */
|
||
|
if (keep_going == ptr->not_this_time)
|
||
|
{
|
||
|
csa = &FILE_INFO(ptr->reg)->s_addrs;
|
||
|
csa->nl->nbb = BACKUP_NOT_IN_PROGRESS;
|
||
|
/* Make sure all running processes have a chance to see this backup
|
||
|
state change so they won't be trying to flush when we go to delete
|
||
|
the temporary files (mostly an issue on VMS).
|
||
|
|
||
|
This operation notifies other processes by:
|
||
|
1) Using a compswap lock with builtin memory barriers so other
|
||
|
processors know the memory state change.
|
||
|
2) Processes obtaining the lock after we release it will do their
|
||
|
own memory barrier operation and see the change.
|
||
|
3) By grabbing the lock, we are assured that anyone else getting the
|
||
|
lock after us will also be checking the errno flag AFTER getting the
|
||
|
lock (see backup_buffer_flush()) and see no flush is necessary.
|
||
|
*/
|
||
|
if (!(had_lock = shmpool_lock_held_by_us(ptr->reg)))
|
||
|
shmpool_lock_hdr(ptr->reg);
|
||
|
|
||
|
if (backup_interrupted && 0 == csa->shmpool_buffer->backup_errno)
|
||
|
/* Needs a non-zero value to stop the backup */
|
||
|
csa->shmpool_buffer->backup_errno = ERR_FORCEDHALT;
|
||
|
if (!had_lock)
|
||
|
shmpool_unlock_hdr(ptr->reg);
|
||
|
}
|
||
|
/* get rid of the temporary file */
|
||
|
#if defined(UNIX)
|
||
|
if (ptr->backup_fd > 2)
|
||
|
{
|
||
|
CLOSEFILE_RESET(ptr->backup_fd, rc); /* resets "ptr" to FD_INVALID */
|
||
|
UNLINK(ptr->backup_tempfile);
|
||
|
}
|
||
|
#elif defined(VMS)
|
||
|
temp_fab = cc$rms_fab;
|
||
|
temp_fab.fab$b_fac = FAB$M_GET;
|
||
|
temp_fab.fab$l_fna = ptr->backup_tempfile;
|
||
|
temp_fab.fab$b_fns = strlen(ptr->backup_tempfile);
|
||
|
if (RMS$_NORMAL == (status = sys$open(&temp_fab, NULL, NULL)))
|
||
|
{
|
||
|
temp_fab.fab$l_fop |= FAB$M_DLT;
|
||
|
status = sys$close(&temp_fab);
|
||
|
}
|
||
|
if (RMS$_NORMAL != status)
|
||
|
{
|
||
|
util_out_print("!/Cannot delete the the temporary file !AD.",
|
||
|
TRUE, temp_fab.fab$b_fns, temp_fab.fab$l_fna);
|
||
|
gtm_putmsg(VARLSTCNT(1) status);
|
||
|
}
|
||
|
#else
|
||
|
#error UNSUPPORTED PLATFORM
|
||
|
#endif
|
||
|
} else /* defreeze the databases */
|
||
|
region_freeze(ptr->reg, FALSE, FALSE, FALSE);
|
||
|
}
|
||
|
ptr = ptr->fPtr;
|
||
|
}
|
||
|
|
||
|
/* Intentional fall through */
|
||
|
case need_to_free_space:
|
||
|
for (ptr = (backup_reg_list *)grlist; ptr != NULL;)
|
||
|
{
|
||
|
next = ptr->fPtr;
|
||
|
if (keep_going != ptr->not_this_time)
|
||
|
error_mupip = TRUE;
|
||
|
if (NULL != ptr->backup_file.addr)
|
||
|
free(ptr->backup_file.addr);
|
||
|
free(ptr);
|
||
|
ptr = next;
|
||
|
}
|
||
|
}
|
||
|
UNIX_ONLY(
|
||
|
/* Release FTOK lock on the replication instance file if holding it */
|
||
|
assert((NULL == jnlpool.jnlpool_dummy_reg) || (NULL != mu_repl_inst_reg_list));
|
||
|
if ((NULL != mu_repl_inst_reg_list) && (NULL != jnlpool.jnlpool_dummy_reg) && jnlpool.jnlpool_dummy_reg->open)
|
||
|
{
|
||
|
udi = FILE_INFO(jnlpool.jnlpool_dummy_reg);
|
||
|
assert(NULL != udi);
|
||
|
if (NULL != udi)
|
||
|
{
|
||
|
if (udi->grabbed_ftok_sem)
|
||
|
ftok_sem_release(jnlpool.jnlpool_dummy_reg, TRUE, TRUE);
|
||
|
assert(!udi->grabbed_ftok_sem);
|
||
|
}
|
||
|
}
|
||
|
)
|
||
|
return;
|
||
|
}
|