fis-gtm/sr_unix/mu_replpool_grab_sem.c

196 lines
6.1 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_ipc.h"
#include "gtm_unistd.h"
#include "gtm_string.h"
#include "gtm_inet.h"
#include "gtm_fcntl.h"
#include <sys/sem.h>
#include <errno.h>
#include <stddef.h>
#include "gdsroot.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "iosp.h"
#include "gtmrecv.h"
#include "repl_msg.h"
#include "gtmsource.h"
#include "gtm_logicals.h"
#include "jnl.h"
#include "repl_sem.h"
#include "repl_shutdcode.h"
#include "io.h"
#include "trans_log_name.h"
#include "repl_instance.h"
#include "mu_gv_cur_reg_init.h"
#include "gtmmsg.h"
#include "gtm_sem.h"
#include "mu_rndwn_replpool.h"
#include "ftok_sems.h"
GBLREF jnlpool_addrs jnlpool;
GBLREF recvpool_addrs recvpool;
GBLREF gd_region *gv_cur_region;
/*
* Description:
* Grab ftok semaphore on replication instance file
* Grab all replication semaphores for the instance (both jnlpool and recvpool)
* Release ftok semaphore
* Parameters:
* Return Value: TRUE, if succsessful
* FALSE, if fails.
*/
boolean_t mu_replpool_grab_sem(boolean_t immediate)
{
char instfilename[MAX_FN_LEN + 1];
gd_region *r_save;
static gd_region *replreg;
int status, save_errno;
union semun semarg;
struct semid_ds semstat;
repl_inst_hdr repl_instance;
unix_db_info *udi;
unsigned int full_len;
error_def(ERR_RECVPOOLSETUP);
error_def(ERR_JNLPOOLSETUP);
error_def(ERR_REPLFTOKSEM);
error_def(ERR_TEXT);
if (NULL == replreg)
{
r_save = gv_cur_region;
mu_gv_cur_reg_init();
replreg = gv_cur_region;
gv_cur_region = r_save;
}
jnlpool.jnlpool_dummy_reg = replreg;
recvpool.recvpool_dummy_reg = replreg;
if (!repl_inst_get_name(instfilename, &full_len, MAX_FN_LEN + 1, issue_rts_error))
GTMASSERT; /* rts_error should have been issued by repl_inst_get_name */
assert(full_len);
memcpy((char *)replreg->dyn.addr->fname, instfilename, full_len);
replreg->dyn.addr->fname_len = full_len;
udi = FILE_INFO(replreg);
udi->fn = (char *)replreg->dyn.addr->fname;
if (!ftok_sem_get(replreg, TRUE, REPLPOOL_ID, immediate))
rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instfilename);
repl_inst_read(instfilename, (off_t)0, (sm_uc_ptr_t)&repl_instance, SIZEOF(repl_inst_hdr));
/*
* --------------------------
* First semaphores of jnlpool
* --------------------------
*/
if (-1 == (udi->semid = init_sem_set_source(IPC_PRIVATE, NUM_SRC_SEMS, RWDALL | IPC_CREAT)))
{
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
RTS_ERROR_LITERAL("Error creating journal pool"), REPL_SEM_ERRNO);
}
semarg.val = GTM_ID;
if (-1 == semctl(udi->semid, SOURCE_ID_SEM, SETVAL, semarg))
{
save_errno = errno;
remove_sem_set(SOURCE); /* Remove what we created */
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
RTS_ERROR_LITERAL("Error with jnlpool semctl"), save_errno);
}
semarg.buf = &semstat;
if (-1 == semctl(udi->semid, 0, IPC_STAT, semarg))
{
save_errno = errno;
remove_sem_set(SOURCE); /* Remove what we created */
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(7) ERR_JNLPOOLSETUP, 0, ERR_TEXT, 2,
RTS_ERROR_LITERAL("Error with jnlpool semctl"), save_errno);
}
udi->gt_sem_ctime = semarg.buf->sem_ctime;
status = grab_sem_all_source();
if (0 != status)
{
remove_sem_set(SOURCE); /* Remove what we created */
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(1) ERR_JNLPOOLSETUP);
}
repl_instance.jnlpool_semid = udi->semid;
repl_instance.jnlpool_semid_ctime = udi->gt_sem_ctime;
/*
* --------------------------
* Now semaphores of recvpool
* --------------------------
*/
assert(NUM_SRC_SEMS == NUM_RECV_SEMS);
if (-1 == (udi->semid = init_sem_set_recvr(IPC_PRIVATE, NUM_RECV_SEMS, RWDALL | IPC_CREAT)))
{
remove_sem_set(SOURCE);
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0,
ERR_TEXT, 2,
RTS_ERROR_LITERAL("Error creating recv pool"), REPL_SEM_ERRNO);
}
semarg.val = GTM_ID;
if (-1 == semctl(udi->semid, RECV_ID_SEM, SETVAL, semarg))
{
save_errno = errno;
remove_sem_set(SOURCE);
remove_sem_set(RECV);
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
RTS_ERROR_LITERAL("Error with recvpool semctl"), save_errno);
}
semarg.buf = &semstat;
if (-1 == semctl(udi->semid, 0, IPC_STAT, semarg)) /* For creation time */
{
save_errno = errno;
remove_sem_set(SOURCE);
remove_sem_set(RECV);
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
RTS_ERROR_LITERAL("Error with recvpool semctl"), save_errno);
}
udi->gt_sem_ctime = semarg.buf->sem_ctime;
status = grab_sem_all_receive();
if (0 != status)
{
remove_sem_set(SOURCE);
remove_sem_set(RECV);
ftok_sem_release(replreg, TRUE, TRUE);
rts_error(VARLSTCNT(1) ERR_RECVPOOLSETUP);
}
repl_instance.recvpool_semid = udi->semid;
repl_instance.recvpool_semid_ctime = udi->gt_sem_ctime;
/* Initialize jnlpool.repl_inst_filehdr as it is used later by gtmrecv_fetchresync() */
assert(NULL == jnlpool.repl_inst_filehdr);
jnlpool.repl_inst_filehdr = (repl_inst_hdr_ptr_t)malloc(SIZEOF(repl_inst_hdr));
memcpy(jnlpool.repl_inst_filehdr, &repl_instance, SIZEOF(repl_inst_hdr));
/* Flush changes to the replication instance file header to disk */
repl_inst_write(instfilename, (off_t)0, (sm_uc_ptr_t)&repl_instance, SIZEOF(repl_inst_hdr));
/* Now release jnlpool/recvpool ftok semaphore */
if (!ftok_sem_release(replreg, FALSE, immediate))
{
remove_sem_set(SOURCE);
remove_sem_set(RECV);
rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instfilename);
}
return TRUE;
}