2012-02-05 11:35:58 -05:00
|
|
|
/****************************************************************
|
|
|
|
* *
|
2012-03-24 14:06:46 -04:00
|
|
|
* Copyright 2001, 2012 Fidelity Information Services, Inc.*
|
2012-02-05 11:35:58 -05:00
|
|
|
* *
|
|
|
|
* 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_time.h"
|
|
|
|
#include "gtm_fcntl.h"
|
|
|
|
#include "gtm_unistd.h"
|
|
|
|
#include "gtm_inet.h"
|
|
|
|
#ifdef UNIX
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#elif defined(VMS)
|
|
|
|
#include <descrip.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "gdsroot.h"
|
|
|
|
#include "gdsblk.h"
|
|
|
|
#include "gtm_facility.h"
|
|
|
|
#include "fileinfo.h"
|
|
|
|
#include "gdsbt.h"
|
|
|
|
#include "gdsfhead.h"
|
|
|
|
#include "filestruct.h"
|
|
|
|
#include "gtmrecv.h"
|
|
|
|
#include "repl_dbg.h"
|
|
|
|
#include "repl_errno.h"
|
|
|
|
#include "iosp.h"
|
|
|
|
#include "gtm_stdio.h"
|
|
|
|
#include "repl_shutdcode.h"
|
|
|
|
#include "repl_sem.h"
|
|
|
|
#include "io.h"
|
|
|
|
#include "is_proc_alive.h"
|
|
|
|
#include "gtmmsg.h"
|
|
|
|
#include "trans_log_name.h"
|
|
|
|
#include "repl_log.h"
|
|
|
|
#include "eintr_wrappers.h"
|
|
|
|
|
|
|
|
#define UPDPROC_CMD_MAXLEN 1024
|
|
|
|
#define UPDPROC_CMD "$gtm_dist/mupip"
|
|
|
|
#define UPDPROC_CMD_FILE "mupip"
|
|
|
|
#define UPDPROC_CMD_ARG1 "replicate"
|
|
|
|
#define UPDPROC_CMD_ARG2 "-updateproc"
|
|
|
|
#define UPDPROC_CMD_STR "REPLICATE/UPDATEPROC"
|
|
|
|
|
|
|
|
GBLREF recvpool_addrs recvpool;
|
|
|
|
GBLREF int recvpool_shmid;
|
|
|
|
|
|
|
|
GBLREF int gtmrecv_log_fd;
|
|
|
|
GBLREF FILE *gtmrecv_log_fp;
|
|
|
|
GBLREF int updproc_log_fd;
|
|
|
|
|
|
|
|
error_def(ERR_LOGTOOLONG);
|
|
|
|
error_def(ERR_RECVPOOLSETUP);
|
|
|
|
error_def(ERR_REPLINFO);
|
|
|
|
error_def(ERR_TEXT);
|
|
|
|
|
|
|
|
int gtmrecv_upd_proc_init(boolean_t fresh_start)
|
|
|
|
{
|
|
|
|
/* Update Process initialization */
|
|
|
|
|
|
|
|
mstr upd_proc_log_cmd, upd_proc_trans_cmd;
|
|
|
|
char upd_proc_cmd[UPDPROC_CMD_MAXLEN];
|
|
|
|
int status;
|
|
|
|
int upd_status, save_upd_status;
|
|
|
|
#ifdef UNIX
|
|
|
|
pid_t upd_pid, waitpid_res;
|
|
|
|
#elif defined(VMS)
|
|
|
|
uint4 upd_pid;
|
|
|
|
uint4 cmd_channel;
|
|
|
|
$DESCRIPTOR(cmd_desc, UPDPROC_CMD_STR);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check if the update process is alive */
|
|
|
|
|
|
|
|
if ((upd_status = is_updproc_alive()) == SRV_ERR)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Receive pool semctl failure"), REPL_SEM_ERRNO);
|
|
|
|
repl_errno = EREPL_UPDSTART_SEMCTL;
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
} else if (upd_status == SRV_ALIVE && !fresh_start)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(4) ERR_TEXT, 2, RTS_ERROR_LITERAL("Update process already exists. Not starting it"));
|
|
|
|
return(UPDPROC_EXISTS);
|
|
|
|
} else if (upd_status == SRV_ALIVE)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Update process already exists. Please kill it before a fresh start"));
|
|
|
|
return(UPDPROC_EXISTS);
|
|
|
|
}
|
|
|
|
|
|
|
|
save_upd_status = recvpool.upd_proc_local->upd_proc_shutdown;
|
|
|
|
recvpool.upd_proc_local->upd_proc_shutdown = NO_SHUTDOWN;
|
|
|
|
|
|
|
|
#ifdef UNIX
|
2012-03-24 14:06:46 -04:00
|
|
|
if (0 > (upd_pid = fork())) /* BYPASSOK: we exec immediately, no FORK_CLEAN needed */
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
|
|
|
recvpool.upd_proc_local->upd_proc_shutdown = save_upd_status;
|
|
|
|
gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Could not fork update process"), errno);
|
|
|
|
repl_errno = EREPL_UPDSTART_FORK;
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|
|
|
|
if (0 == upd_pid)
|
|
|
|
{
|
|
|
|
/* Update Process */
|
|
|
|
upd_proc_log_cmd.len = SIZEOF(UPDPROC_CMD) - 1;
|
|
|
|
upd_proc_log_cmd.addr = UPDPROC_CMD;
|
|
|
|
status = TRANS_LOG_NAME(&upd_proc_log_cmd, &upd_proc_trans_cmd, upd_proc_cmd, SIZEOF(upd_proc_cmd),
|
|
|
|
dont_sendmsg_on_log2long);
|
|
|
|
if (status != SS_NORMAL)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Could not find path of Update Process. Check value of $gtm_dist"));
|
|
|
|
if (SS_LOG2LONG == status)
|
|
|
|
gtm_putmsg(VARLSTCNT(5) ERR_LOGTOOLONG, 3, LEN_AND_LIT(UPDPROC_CMD), SIZEOF(upd_proc_cmd) - 1);
|
|
|
|
repl_errno = EREPL_UPDSTART_BADPATH;
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|
|
|
|
upd_proc_cmd[upd_proc_trans_cmd.len] = '\0';
|
|
|
|
if (EXECL(upd_proc_cmd, upd_proc_cmd, UPDPROC_CMD_ARG1, UPDPROC_CMD_ARG2, NULL) < 0)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Could not exec Update Process"), errno);
|
|
|
|
repl_errno = EREPL_UPDSTART_EXEC;
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#elif defined(VMS)
|
|
|
|
/* Create detached server and write startup commands to it */
|
|
|
|
status = repl_create_server(&cmd_desc, "GTMU", "", &cmd_channel, &upd_pid, ERR_RECVPOOLSETUP);
|
|
|
|
if (SS_NORMAL != status)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Unable to spawn Update process"), status);
|
|
|
|
recvpool.upd_proc_local->upd_proc_shutdown = save_upd_status;
|
|
|
|
repl_errno = EREPL_UPDSTART_FORK;
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (recvpool.upd_proc_local->upd_proc_pid)
|
|
|
|
recvpool.upd_proc_local->upd_proc_pid_prev = recvpool.upd_proc_local->upd_proc_pid;
|
|
|
|
else
|
|
|
|
recvpool.upd_proc_local->upd_proc_pid_prev = upd_pid;
|
|
|
|
recvpool.upd_proc_local->upd_proc_pid = upd_pid;
|
|
|
|
/* Receiver Server; wait for the update process to startup */
|
|
|
|
REPL_DPRINT2("Waiting for update process %d to startup\n", upd_pid);
|
|
|
|
while (get_sem_info(RECV, UPD_PROC_COUNT_SEM, SEM_INFO_VAL) == 0 && is_proc_alive(upd_pid, 0))
|
|
|
|
{
|
|
|
|
/* To take care of reassignment of PIDs, the while condition should be && with the
|
|
|
|
* condition (PPID of pid == process_id)
|
|
|
|
*/
|
|
|
|
REPL_DPRINT2("Waiting for update process %d to startup\n", upd_pid);
|
|
|
|
UNIX_ONLY(WAITPID(upd_pid, &status, WNOHANG, waitpid_res);) /* Release defunct update process if dead */
|
|
|
|
SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START);
|
|
|
|
}
|
|
|
|
#ifdef VMS
|
|
|
|
/* Deassign the send-cmd mailbox channel */
|
|
|
|
if (SS_NORMAL != (status = sys$dassgn(cmd_channel)))
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Unable to close upd-send-cmd mbox channel"), status);
|
|
|
|
recvpool.upd_proc_local->upd_proc_shutdown = save_upd_status;
|
|
|
|
repl_errno = EREPL_UPDSTART_BADPATH; /* Just to make an auto-shutdown */
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
repl_log(gtmrecv_log_fp, TRUE, FALSE, "Update Process started. PID %d [0x%X]\n", upd_pid, upd_pid);
|
|
|
|
return(UPDPROC_STARTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
int gtmrecv_start_updonly(void)
|
|
|
|
{
|
|
|
|
int start_status, recvr_status, upd_status;
|
|
|
|
|
|
|
|
if ((upd_status = is_updproc_alive()) == SRV_ALIVE)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Update Process exists already. New process not started"));
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
} else if (upd_status == SRV_ERR)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Error in starting up update process"));
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(upd_status == SRV_DEAD);
|
|
|
|
#ifdef VMS
|
|
|
|
recvpool.upd_proc_local->changelog |= REPLIC_CHANGE_LOGFILE;
|
|
|
|
#endif
|
|
|
|
recvpool.upd_proc_local->start_upd = UPDPROC_START;
|
|
|
|
while ((start_status = recvpool.upd_proc_local->start_upd) == UPDPROC_START &&
|
|
|
|
(recvr_status = is_recv_srv_alive()) == SRV_ALIVE)
|
|
|
|
SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START);
|
|
|
|
|
|
|
|
if (start_status == UPDPROC_STARTED)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(4) ERR_REPLINFO, 2, RTS_ERROR_LITERAL("Update Process started successfully"));
|
|
|
|
return(UPDPROC_STARTED);
|
|
|
|
}
|
|
|
|
#ifdef VMS
|
|
|
|
recvpool.upd_proc_local->changelog &= ~REPLIC_CHANGE_LOGFILE;
|
|
|
|
#endif
|
|
|
|
if (start_status == UPDPROC_START)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Receiver server is not alive to start update process. Please start receiver server"));
|
|
|
|
} else if (start_status == UPDPROC_START_ERR)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Error starting update process"));
|
|
|
|
} else if (start_status == UPDPROC_EXISTS)
|
|
|
|
{
|
|
|
|
gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2,
|
|
|
|
RTS_ERROR_LITERAL("Update Process exists already. New process not started"));
|
|
|
|
}
|
|
|
|
return(UPDPROC_START_ERR);
|
|
|
|
}
|