fis-gtm/sr_port/mupip_extend.c

183 lines
5.3 KiB
C

/****************************************************************
* *
* Copyright 2001, 2013 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"
#include "gtm_string.h"
#include <errno.h>
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsbml.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "stp_parms.h"
#include "iosp.h"
#include "jnl.h"
#ifdef UNIX
#include "io.h"
#include "gtmsecshr.h"
#endif
#include "util.h"
#include "cli.h"
#include "gvcst_protos.h" /* for gvcst_init prototype */
#include "mupip_exit.h"
#include "mupip_extend.h"
#include "gtmmsg.h"
#include "gdsfilext.h"
#include "wcs_backoff.h"
#include "gt_timer.h"
#if defined(VMS) || defined(MM_FILE_EXT_OK)
#define DB_IPCS_RESET(REG)
#else
#include "mu_rndwn_file.h"
#include "db_ipcs_reset.h"
#define DB_IPCS_RESET(REG) \
{ \
if (dba_mm == REG->dyn.addr->acc_meth) \
db_ipcs_reset(REG); \
}
#endif
GBLREF gd_addr *gd_header;
GBLREF gd_region *gv_cur_region;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF sgmnt_data_ptr_t cs_data;
#ifdef UNIX
GBLREF boolean_t jnlpool_init_needed;
#endif
error_def(ERR_DBOPNERR);
error_def(ERR_DBRDONLY);
error_def(ERR_JNLFILOPN);
error_def(ERR_MUNOACTION);
error_def(ERR_MUNODBNAME);
error_def(ERR_NOREGION);
error_def(ERR_TEXT);
void mupip_extend(void)
{
unsigned short r_len;
char regionname[MAX_RN_LEN];
uint4 bplmap, bit_maps, blocks, i, old_total, total, status;
int4 tblocks;
int fd;
r_len = SIZEOF(regionname);
UNIX_ONLY(jnlpool_init_needed = TRUE);
if (cli_get_str("REG_NAME", regionname, &r_len) == FALSE)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MUNODBNAME);
if (cli_get_int("BLOCKS",&tblocks))
{
if (tblocks < 1)
{
util_out_print("!/BLOCKS too small, no extension done",TRUE);
mupip_exit(ERR_MUNOACTION);
}
blocks = tblocks;
} else
blocks = (uint4)-1;
gvinit();
for (i = 0, gv_cur_region = gd_header->regions; i < gd_header->n_regions; i++, gv_cur_region++)
{
if (memcmp(gv_cur_region->rname, regionname, r_len) == 0)
break;
}
if (i >= gd_header->n_regions)
{
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_NOREGION, 2, r_len, regionname);
mupip_exit(ERR_MUNOACTION);
}
if ((dba_bg != gv_cur_region->dyn.addr->acc_meth) && (dba_mm != gv_cur_region->dyn.addr->acc_meth))
{
util_out_print("Can only EXTEND BG and MM databases",TRUE);
mupip_exit(ERR_MUNOACTION);
}
if (reg_cmcheck(gv_cur_region))
{
util_out_print("!/Can't EXTEND region !AD across network",TRUE, REG_LEN_STR(gv_cur_region));
mupip_exit(ERR_MUNOACTION);
}
# if !defined(MM_FILE_EXT_OK) && defined(UNIX)
if (dba_mm == gv_cur_region->dyn.addr->acc_meth)
{
FILE_CNTL_INIT(gv_cur_region->dyn.addr);
if (!STANDALONE(gv_cur_region))
{
util_out_print("Can't get standalone access to database file !AD with MM access method, no extension done.",
TRUE, DB_LEN_STR(gv_cur_region));
mupip_exit(ERR_MUNOACTION);
}
assert((FILE_INFO(gv_cur_region))->grabbed_access_sem); /* we should have standalone access */
}
# endif
gvcst_init(gv_cur_region);
if (gv_cur_region->was_open)
{ /* This should not happen as extend works on only one region at a time, but handle for safety */
gtm_putmsg_csa(CSA_ARG(REG2CSA(gv_cur_region)) VARLSTCNT(4) ERR_DBOPNERR, 2, DB_LEN_STR(gv_cur_region));
DB_IPCS_RESET(gv_cur_region);
mupip_exit(ERR_MUNOACTION);
}
cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
cs_data = cs_addrs->hdr;
if ((uint4)-1 == blocks)
{
if (cs_addrs->hdr->extension_size == 0)
{
util_out_print("The extension size on file !AD is zero, no extension done.",TRUE,
DB_LEN_STR(gv_cur_region));
DB_IPCS_RESET(gv_cur_region);
mupip_exit(ERR_MUNOACTION);
}
blocks = cs_addrs->hdr->extension_size;
}
/* cannot extend for read_only database. */
if (gv_cur_region->read_only)
{
gtm_putmsg_csa(CSA_ARG(cs_addrs) VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
DB_IPCS_RESET(gv_cur_region);
mupip_exit(ERR_MUNOACTION);
}
switch(gv_cur_region->dyn.addr->acc_meth)
{
case dba_bg:
case dba_mm:
grab_crit(gv_cur_region);
GRAB_UNFROZEN_CRIT(gv_cur_region, cs_addrs, cs_data);
old_total = cs_addrs->ti->total_blks;
if ((uint4)NO_FREE_SPACE == (status = GDSFILEXT(blocks, old_total, TRANS_IN_PROG_FALSE)))
{
rel_crit(gv_cur_region);
util_out_print("The extension failed on file !AD; check disk space and permissions.", TRUE,
DB_LEN_STR(gv_cur_region));
DB_IPCS_RESET(gv_cur_region);
mupip_exit(ERR_MUNOACTION);
} else
assert(SS_NORMAL == status);
total = cs_addrs->ti->total_blks;
bplmap = cs_addrs->hdr->bplmap;
bit_maps = DIVIDE_ROUND_UP(total, bplmap) - DIVIDE_ROUND_UP(old_total, bplmap);
rel_crit(gv_cur_region);
break;
default:
GTMASSERT;
}
util_out_print("Extension successful, file !AD extended by !UL blocks. Total blocks = !UL.",TRUE,
DB_LEN_STR(gv_cur_region), total - old_total - bit_maps, total - DIVIDE_ROUND_UP(total, bplmap));
DB_IPCS_RESET(gv_cur_region); /* final cleanup (for successful case) before exit */
mupip_exit(SS_NORMAL);
}