Beispiel #1
0
int gtmrecv_changelog(void)
{
	uint4	changelog_desired = 0, changelog_accepted = 0;

	/* Grab the recvpool jnlpool option write lock */
	if (0 > grab_sem(RECV, RECV_SERV_OPTIONS_SEM))
	{
		util_out_print("Error grabbing recvpool option write lock. Could not initiate change log", TRUE);
		return (ABNORMAL_SHUTDOWN);
	}
	if (0 != recvpool.gtmrecv_local->changelog || 0 != recvpool.upd_proc_local->changelog)
	{
		util_out_print("Change log is already in progress. Not initiating change in log file or log interval", TRUE);
		rel_sem(RECV, RECV_SERV_OPTIONS_SEM);
		return (ABNORMAL_SHUTDOWN);
	}
	if ('\0' != gtmrecv_options.log_file[0]) /* trigger change in log file (for both receiver and update process) */
	{
		changelog_desired |= REPLIC_CHANGE_LOGFILE;
		if (0 != strcmp(recvpool.gtmrecv_local->log_file, gtmrecv_options.log_file))
		{
			changelog_accepted |= REPLIC_CHANGE_LOGFILE;
			strcpy(recvpool.gtmrecv_local->log_file, gtmrecv_options.log_file);
			util_out_print("Change log initiated with file !AD", TRUE, LEN_AND_STR(gtmrecv_options.log_file));
		} else
			util_out_print("Log file is already !AD. Not initiating change in log file", TRUE,
					LEN_AND_STR(gtmrecv_options.log_file));
	}
	if (0 != gtmrecv_options.rcvr_log_interval) /* trigger change in receiver log interval */
	{
		changelog_desired |= REPLIC_CHANGE_LOGINTERVAL;
		if (gtmrecv_options.rcvr_log_interval != recvpool.gtmrecv_local->log_interval)
		{
			changelog_accepted |= REPLIC_CHANGE_LOGINTERVAL;
			recvpool.gtmrecv_local->log_interval = gtmrecv_options.rcvr_log_interval;
			util_out_print("Change initiated with receiver log interval !UL", TRUE, gtmrecv_options.rcvr_log_interval);
		} else
			util_out_print("Receiver log interval is already !UL. Not initiating change in log interval", TRUE,
					gtmrecv_options.rcvr_log_interval);
	}
	if (0 != gtmrecv_options.upd_log_interval) /* trigger change in update process log interval */
	{
		changelog_desired |= REPLIC_CHANGE_UPD_LOGINTERVAL;
		if (gtmrecv_options.upd_log_interval != recvpool.upd_proc_local->log_interval)
		{
			changelog_accepted |= REPLIC_CHANGE_UPD_LOGINTERVAL;
			recvpool.upd_proc_local->log_interval = gtmrecv_options.upd_log_interval;
			util_out_print("Change initiated with update process log interval !UL", TRUE,
					gtmrecv_options.upd_log_interval);
		} else
			util_out_print("Update process log interval is already !UL. Not initiating change in log interval", TRUE,
					gtmrecv_options.upd_log_interval);
	}
	if (0 != changelog_accepted)
		recvpool.gtmrecv_local->changelog = changelog_accepted;
	else
		util_out_print("No change to log file or log interval", TRUE);
	rel_sem(RECV, RECV_SERV_OPTIONS_SEM);
	return ((0 != changelog_accepted && changelog_accepted == changelog_desired) ? NORMAL_SHUTDOWN : ABNORMAL_SHUTDOWN);
}
Beispiel #2
0
/* Lookup an external function. Return function address if success, NULL otherwise.
 * package_handle - DLL handle returned by fgn_getpak
 * entry_name - symbol name to be looked up
 * msgtype - message severity of the errors reported if any.
 * Note: If msgtype is SUCCESS, errors are not issued. It is useful if the callers are not
 * interested in message report and not willing to have condition handler overhead (eg. zro_search).
 */
fgnfnc fgn_getrtn(void_ptr_t package_handle, mstr *entry_name, int msgtype)
{
	void_ptr_t	sym_addr;
	char_ptr_t	dummy_err_str;
	void		*short_sym_addr;
	char		err_str[MAX_ERRSTR_LEN]; /* needed as util_out_print doesn't handle 64bit pointers */
	error_def(ERR_DLLNORTN);
	error_def(ERR_TEXT);

	if (!(sym_addr = dlsym(package_handle, entry_name->addr)))
	{
		if (SUCCESS != msgtype)
		{
			assert(!(msgtype & ~SEV_MSK));
			COPY_DLLERR_MSG;
			rts_error(VARLSTCNT(8) MAKE_MSG_TYPE(ERR_DLLNORTN, msgtype), 2, LEN_AND_STR(entry_name->addr),
				ERR_TEXT, 2, LEN_AND_STR(err_str));
		}
	} else
	{  /* Tru64 - dlsym() is bound to return short pointer because of ld -taso flag used for GT.M */
#ifdef	__osf__
		short_sym_addr = sym_addr;
		if (short_sym_addr != sym_addr)
		{
			sym_addr = NULL;
			/* always report an error irrespective of msgtype - since this code should never
			 * have executed and/or the DLL might need to be rebuilt with 32-bit options */
			rts_error(VARLSTCNT(8) ERR_DLLNORTN, 2, LEN_AND_STR(entry_name->addr),
				ERR_TEXT, 2, LEN_AND_LIT("Symbol is loaded above the lower 31-bit address space"));
		}
#endif
	}
	return (fgnfnc)sym_addr;
}
Beispiel #3
0
int gtmsource_changelog(void)
{
	uint4	changelog_desired = 0, changelog_accepted = 0;
	int     log_fd = 0; /*used to indicate whether the new specified log file is writable*/
	int     close_status = 0; /*used to indicate if log file is successfully closed*/
	char*   err_code;
	int	save_errno;

	assert(holds_sem[SOURCE][JNL_POOL_ACCESS_SEM]);
	repl_log(stderr, TRUE, TRUE, "Initiating CHANGELOG operation on source server pid [%d] for secondary instance [%s]\n",
		jnlpool.gtmsource_local->gtmsource_pid, jnlpool.gtmsource_local->secondary_instname);
	if (0 != jnlpool.gtmsource_local->changelog)
	{
		util_out_print("Change log is already in progress. Not initiating change in log file or log interval", TRUE);
		return (ABNORMAL_SHUTDOWN);
	}
	if ('\0' != gtmsource_options.log_file[0]) /* trigger change in log file */
	{
		changelog_desired |= REPLIC_CHANGE_LOGFILE;
		if (0 != STRCMP(jnlpool.gtmsource_local->log_file, gtmsource_options.log_file))
		{	/*check if the new log file is writable*/
			OPENFILE3_CLOEXEC(gtmsource_options.log_file,
				      O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, log_fd);
			if (log_fd < 0)
			{
				save_errno = ERRNO;
				err_code = STRERROR(save_errno);
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLLOGOPN, 6,
						   LEN_AND_STR(gtmsource_options.log_file),
						   LEN_AND_STR(err_code),
						   LEN_AND_STR(NULL_DEVICE));
			} else {
				CLOSEFILE_IF_OPEN(log_fd, close_status);
				assert(close_status==0);
				changelog_accepted |= REPLIC_CHANGE_LOGFILE;
				STRCPY(jnlpool.gtmsource_local->log_file, gtmsource_options.log_file);
				util_out_print("Change log initiated with file !AD", TRUE, LEN_AND_STR(gtmsource_options.log_file));
			}
		} else
			util_out_print("Log file is already !AD. Not initiating change in log file", TRUE,
					LEN_AND_STR(gtmsource_options.log_file));
	}
	if (0 != gtmsource_options.src_log_interval) /* trigger change in log interval */
	{
		changelog_desired |= REPLIC_CHANGE_LOGINTERVAL;
		if (gtmsource_options.src_log_interval != jnlpool.gtmsource_local->log_interval)
		{
			changelog_accepted |= REPLIC_CHANGE_LOGINTERVAL;
			jnlpool.gtmsource_local->log_interval = gtmsource_options.src_log_interval;
			util_out_print("Change log initiated with interval !UL", TRUE, gtmsource_options.src_log_interval);
		} else
			util_out_print("Log interval is already !UL. Not initiating change in log interval", TRUE,
					gtmsource_options.src_log_interval);
	}
	if (0 != changelog_accepted)
		jnlpool.gtmsource_local->changelog = changelog_accepted;
	else
		util_out_print("No change to log file or log interval", TRUE);
	return ((0 != changelog_accepted && changelog_accepted == changelog_desired) ? NORMAL_SHUTDOWN : ABNORMAL_SHUTDOWN);
}
int gtmsource_mode_change(int to_mode)
{
	uint4		savepid;
	int		exit_status;
	int		status, detach_status, remove_status;
	int 	        log_fd = 0, close_status = 0;
	char*           err_code;
	int	        save_errno;
	sgmnt_addrs	*repl_csa;

	assert(holds_sem[SOURCE][JNL_POOL_ACCESS_SEM]);
	repl_log(stdout, TRUE, TRUE, "Initiating %s operation on source server pid [%d] for secondary instance [%s]\n",
		(GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode) ? "ACTIVATE" : "DEACTIVATE",
		jnlpool.gtmsource_local->gtmsource_pid, jnlpool.gtmsource_local->secondary_instname);
	if ((jnlpool.gtmsource_local->mode == GTMSOURCE_MODE_ACTIVE_REQUESTED)
		|| (jnlpool.gtmsource_local->mode == GTMSOURCE_MODE_PASSIVE_REQUESTED))
	{
		repl_log(stderr, FALSE, TRUE, "Source Server %s already requested, not changing mode\n",
				(to_mode == GTMSOURCE_MODE_ACTIVE_REQUESTED) ? "ACTIVATE" : "DEACTIVATE");
		return (ABNORMAL_SHUTDOWN);
	}
	if (((GTMSOURCE_MODE_ACTIVE == jnlpool.gtmsource_local->mode) && (GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode))
		|| ((GTMSOURCE_MODE_PASSIVE == jnlpool.gtmsource_local->mode) && (GTMSOURCE_MODE_PASSIVE_REQUESTED == to_mode)))
	{
		repl_log(stderr, FALSE, TRUE, "Source Server already %s, not changing mode\n",
				(to_mode == GTMSOURCE_MODE_ACTIVE_REQUESTED) ? "ACTIVE" : "PASSIVE");
		return (ABNORMAL_SHUTDOWN);
	}
	assert(ROOTPRIMARY_UNSPECIFIED != gtmsource_options.rootprimary);
	/*check if the new log file is writable*/
	if ('\0' != gtmsource_options.log_file[0] && 0 != STRCMP(jnlpool.gtmsource_local->log_file, gtmsource_options.log_file))
	{
		OPENFILE3(gtmsource_options.log_file,
			      O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, log_fd);
		if (log_fd < 0) {
			save_errno = ERRNO;
			err_code = STRERROR(save_errno);
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_REPLLOGOPN, 6,
					   LEN_AND_STR(gtmsource_options.log_file),
					   LEN_AND_STR(err_code),
					   LEN_AND_STR(NULL_DEVICE));
			return (ABNORMAL_SHUTDOWN);
		}
		CLOSEFILE_IF_OPEN(log_fd, close_status);
		assert(close_status==0);
	}
	if ((GTMSOURCE_MODE_ACTIVE_REQUESTED == to_mode)
			&& (ROOTPRIMARY_SPECIFIED == gtmsource_options.rootprimary) && jnlpool.jnlpool_ctl->upd_disabled)
	{	/* ACTIVATE is specified with ROOTPRIMARY on a journal pool that was created with PROPAGATEPRIMARY. This is a
		 * case of transition from propagating primary to root primary. Enable updates in this journal pool and append
		 * a histinfo record to the replication instance file. The function "gtmsource_rootprimary_init" does just that.
		 */
		gtmsource_rootprimary_init(jnlpool.jnlpool_ctl->jnl_seqno);
	}
	DEBUG_ONLY(repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;)
Beispiel #5
0
void	dse_dmp(void)
{
	boolean_t	dmp_res, glo_present, zwr_present;

	patch_fdmp_recs = 0;
	glo_present = (CLI_PRESENT == cli_present("GLO"));
	zwr_present = (CLI_PRESENT == cli_present("ZWR"));
	if (glo_present || zwr_present)
	{
		if (CLOSED_FMT == dse_dmp_format)
		{
			util_out_print("Error:  must open an output file before dump.", TRUE);
			return;
		}
		if (gtm_utf8_mode && (GLO_FMT == glo_present))
		{
			util_out_print("Error:  GLO format is not supported in UTF-8 mode. Use ZWR format.", TRUE);
			return;
		}
		if (OPEN_FMT == dse_dmp_format)
		{
			dse_dmp_format = (glo_present ? GLO_FMT : ZWR_FMT);
			if (!gtm_utf8_mode)
				dse_fdmp_output(LIT_AND_LEN("; DSE EXTRACT"));
			else
				dse_fdmp_output(LIT_AND_LEN("; DSE EXTRACT UTF-8"));
			dse_fdmp_output(STR_AND_LEN(format_label[dse_dmp_format]));
		} else if ((glo_present ? GLO_FMT : ZWR_FMT) != dse_dmp_format)
		{
			util_out_print("Error:  current output file already contains !AD records.", TRUE,
					LEN_AND_STR(&format_label[dse_dmp_format][MESS_OFF]));
			return;
		}
		patch_is_fdmp = TRUE;
		ESTABLISH(dse_dmp_handler);
	} else
		patch_is_fdmp = FALSE;
	if (CLI_PRESENT == cli_present("RECORD") || CLI_PRESENT == cli_present("OFFSET"))
		dmp_res = dse_r_dmp();
	else
		dmp_res = dse_b_dmp();
	if (patch_is_fdmp)
	{
		REVERT;
		if (dmp_res)
			util_out_print("!UL !AD records written.!/", TRUE, patch_fdmp_recs,
					LEN_AND_STR(&format_label[dse_dmp_format][MESS_OFF]));
	}
	return;
}
Beispiel #6
0
STATICFNDEF void mu_rndwn_all_helper(shm_parms *parm_buff, char *fname, int *exit_status, int *tmp_exit_status)
{
	replpool_identifier	replpool_id;
	boolean_t 		ret_status, jnlpool_sem_created;
	unsigned char		ipcs_buff[MAX_IPCS_ID_BUF], *ipcs_ptr;

	ESTABLISH(mu_rndwn_all_helper_ch);
	if (validate_db_shm_entry(parm_buff, fname, tmp_exit_status))
	{
		if (SS_NORMAL == *tmp_exit_status)
		{	/* shm still exists */
			mu_gv_cur_reg_init();
			gv_cur_region->dyn.addr->fname_len = strlen(fname);
			STRNCPY_STR(gv_cur_region->dyn.addr->fname, fname, gv_cur_region->dyn.addr->fname_len);
			if (mu_rndwn_file(gv_cur_region, FALSE))
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
			else
			{	/* Save semid so that it will not be removed by mu_rndwn_sem_all() */
				add_to_semids_list(FILE_INFO(gv_cur_region)->semid);
				*exit_status = ERR_MUNOTALLSEC;
			}
			mu_gv_cur_reg_free();
		} else
		{	/* shm has been cleaned up by "validate_db_shm_entry" so no need of any more cleanup here */
			assert(ERR_SHMREMOVED == *tmp_exit_status);
			*tmp_exit_status = SS_NORMAL;	/* reset tmp_exit_status for below logic to treat this as normal */
		}
	} else if ((SS_NORMAL == *tmp_exit_status)
		&& validate_replpool_shm_entry(parm_buff, (replpool_id_ptr_t)&replpool_id, tmp_exit_status))
	{
		if (SS_NORMAL == *tmp_exit_status)
		{
			assert(JNLPOOL_SEGMENT == replpool_id.pool_type || RECVPOOL_SEGMENT == replpool_id.pool_type);
			ret_status = mu_rndwn_repl_instance(&replpool_id, TRUE, FALSE, &jnlpool_sem_created);
			ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, parm_buff->shmid);
			*ipcs_ptr = '\0';
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) (JNLPOOL_SEGMENT == replpool_id.pool_type) ?
				(ret_status ? ERR_MUJPOOLRNDWNSUC : ERR_MUJPOOLRNDWNFL) :
				(ret_status ? ERR_MURPOOLRNDWNSUC : ERR_MURPOOLRNDWNFL),
				4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(replpool_id.instfilename));
			if (!ret_status)
				*exit_status = ERR_MUNOTALLSEC;
		} else
		{	/* shm has been cleaned up by "validate_replpool_shm_entry" so no need of any more cleanup here */
			assert(ERR_SHMREMOVED == *tmp_exit_status);
			*tmp_exit_status = SS_NORMAL;	/* reset tmp_exit_status for below logic to treat this as normal */
		}
	}
	REVERT;
}
Beispiel #7
0
static bool lke_process(int argc)
{
    bool		flag = FALSE;
    int		res;
    static int	save_stderr = SYS_STDERR;

    ESTABLISH_RET(util_ch, TRUE);
    if (util_interrupt)
        rts_error(VARLSTCNT(1) ERR_CTRLC);
    if (SYS_STDERR != save_stderr)  /* necesary in case of rts_error */
        close_fileio(&save_stderr);
    assert(SYS_STDERR == save_stderr);

    func = 0;
    util_interrupt = 0;
    if (argc < 2)
        display_prompt();
    if ( EOF == (res = parse_cmd()))
    {
        if (util_interrupt)
        {
            rts_error(VARLSTCNT(1) ERR_CTRLC);
            REVERT;
            return TRUE;
        }
        else
        {
            REVERT;
            return FALSE;
        }
    } else if (res)
    {
        if (1 < argc)
        {
            REVERT;
            rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
        } else
            gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
    }
    if (func)
    {
        flag = open_fileio(&save_stderr); /* save_stderr = SYS_STDERR if -output option not present */
        func();
        if (flag)
            close_fileio(&save_stderr);
        assert(SYS_STDERR == save_stderr);
    }
    REVERT;
    return(1 >= argc);
}
Beispiel #8
0
void	repl_inst_dump_triplehist(char *inst_fn, int4 num_triples)
{
	int4		idx;
	off_t		offset;
	repl_triple	curtriple;
	jnl_proc_time	whole_time;
	int		time_len;
	char		time_str[LENGTH_OF_TIME + 1];
	boolean_t	first_time = TRUE;

	for (idx = 0; idx < num_triples; idx++, offset += SIZEOF(repl_triple))
	{
		if (first_time)
		{
			util_out_print("", TRUE);
			first_time = FALSE;
			PRINT_DASHES;
			util_out_print(TRIPLEHIST_TITLE_STRING, TRUE);
			PRINT_DASHES;
			offset = REPL_INST_TRIPLE_OFFSET;
		} else
			PRINT_DASHES;
		repl_inst_read(inst_fn, (off_t)offset, (sm_uc_ptr_t)&curtriple, SIZEOF(repl_triple));
		PRINT_OFFSET_HEADER;

		PRINT_OFFSET_PREFIX(offsetof(repl_triple, root_primary_instname[0]), SIZEOF(curtriple.root_primary_instname));
		util_out_print(PREFIX_TRIPLEHIST "Root Primary Instance Name  !R15AD", TRUE, idx,
			LEN_AND_STR((char *)curtriple.root_primary_instname));

		PRINT_OFFSET_PREFIX(offsetof(repl_triple, start_seqno), SIZEOF(curtriple.start_seqno));
		util_out_print(PREFIX_TRIPLEHIST "Start Sequence Number  !20@UQ [0x!16@XQ]", TRUE, idx,
			&curtriple.start_seqno, &curtriple.start_seqno);

		PRINT_OFFSET_PREFIX(offsetof(repl_triple, root_primary_cycle), SIZEOF(curtriple.root_primary_cycle));
		util_out_print(PREFIX_TRIPLEHIST "Root Primary Cycle               !10UL [0x!XL]", TRUE, idx,
			curtriple.root_primary_cycle, curtriple.root_primary_cycle);

		PRINT_OFFSET_PREFIX(offsetof(repl_triple, created_time), SIZEOF(curtriple.created_time));
		JNL_WHOLE_FROM_SHORT_TIME(whole_time, curtriple.created_time);
		time_len = format_time(whole_time, time_str, SIZEOF(time_str), SHORT_TIME_FORMAT);
		util_out_print(PREFIX_TRIPLEHIST "Creation Time          "TIME_DISPLAY_FAO, TRUE, idx,
			time_len, time_str);

		PRINT_OFFSET_PREFIX(offsetof(repl_triple, rcvd_from_instname[0]), SIZEOF(curtriple.rcvd_from_instname));
		util_out_print(PREFIX_TRIPLEHIST "Received from Instance      !R15AD", TRUE, idx,
			LEN_AND_STR((char *)curtriple.rcvd_from_instname));
		section_offset += SIZEOF(repl_triple);
	}
}
void mu_signal_process(char *command, int signal)
{
	boolean_t	pid_present, name_present;
	int4		pid, length, status, item, outv;
	char		prc_nam[20];
	unsigned short	name_len;
	$DESCRIPTOR(d_prc_nam,"");

	memset(prc_nam, 0, SIZEOF(prc_nam));
	pid_present = name_present = FALSE;
	if (cli_present("id") == CLI_PRESENT)
	{
		if(!cli_get_hex("id", &pid))
			return;
		pid_present = TRUE;
	}
	if (cli_present("name") == CLI_PRESENT)
	{
		name_len = 20;
		if (!cli_get_str("name", prc_nam, &name_len))
			return;
		if (prc_nam[name_len-1] == '"')
			name_len--;
		if (prc_nam[0] == '"')
		{
			d_prc_nam.dsc$a_pointer = &prc_nam[1];
			name_len--;
		} else
			d_prc_nam.dsc$a_pointer = &prc_nam;
		d_prc_nam.dsc$w_length = name_len;
		name_present = TRUE;
	}
	if (!name_present)
	{
		if (SS$_NORMAL == send_signal(pid, signal))
			SENDMSG_OUTPUT("", pid);
		return;
	}
	item = JPI$_PID;
	status = lib$getjpi(&item, 0, &d_prc_nam, &outv, 0, 0);
	if (SS$_NORMAL != status)
	{
		rts_error(VARLSTCNT(1) status);
		return;
	}
	if (!pid_present)
	{
		if (SS$_NORMAL == send_signal(outv, signal))
			SENDMSG_OUTPUT(&prc_nam, outv);
		return;
	}
	if (outv != pid)
	{
		util_out_print("ID !XL and NAME !AD are not the same process", FLUSH, pid, LEN_AND_STR(&prc_nam));
		return;
	}
	if (SS$_NORMAL == send_signal(pid, signal))
		SENDMSG_OUTPUT(&prc_nam, pid);
	return;
}
STATICFNDEF void ext_stx_error(int in_error, ...)
{
	va_list	args;
	char	*ext_table_name;
	char	buf[MAX_SRC_LINE], *b;
	int	num_tabs, num_spaces;

	va_start(args, in_error);
	ext_table_name = va_arg(args, char *);
	va_end(args);

	num_tabs = ext_source_column/TABLEN;
	num_spaces = ext_source_column%TABLEN;

	b = &buf[0];
	memset(buf, '\t', num_tabs+2);
	b += num_tabs+NUM_TABS_FOR_GTMERRSTR;
	memset(b, ' ', num_spaces);
	b += num_spaces;
	memcpy(b, "^-----", POINTER_SIZE);
	b += POINTER_SIZE;
	*b = 0;

	dec_err(VARLSTCNT(6) ERR_EXTSRCLIN, 4, ext_source_line_len, ext_source_line, b - &buf[0], &buf[0]);
	dec_err(VARLSTCNT(6) ERR_EXTSRCLOC, 4, ext_source_column, ext_source_line_num, LEN_AND_STR(ext_table_name));
	rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) in_error);
}
Beispiel #11
0
/* We made this a error seperate function because we did not wanted to do the MAXSTR_BUFF_DECL(buff) declartion in op_lock2,
 * because  MAXSTR_BUFF_DECL macro would allocate a huge stack every time op_lock2 is called.
 */
STATICFNDCL void level_err(mlk_pvtblk *pvt_ptr); /* This definition is made here because there is no appropriate place to
						  * put this prototype. This will not be used anywhere else so we did not
						  * wanted to create a op_lock2.h just for this function.
						  */
STATICFNDCL void level_err(mlk_pvtblk *pvt_ptr)
{
	MAXSTR_BUFF_DECL(buff);
	MAXSTR_BUFF_INIT;
	lock_str_to_buff(pvt_ptr, buff, MAX_STRBUFF_INIT);
	rts_error(VARLSTCNT(7) ERR_LOCKINCR2HIGH, 1, pvt_ptr->level, ERR_LOCKIS, 2, LEN_AND_STR(buff));
}
Beispiel #12
0
int main (int argc, char **argv)
{
	int		res;
	DCL_THREADGBL_ACCESS;

	GTM_THREADGBL_INIT;
	set_blocksig();
	gtm_imagetype_init(MUPIP_IMAGE);
	invocation_mode = MUMPS_UTILTRIGR;
	gtm_wcswidth_fnptr = gtm_wcswidth;
	gtm_env_init();	/* read in all environment variables */
	err_init(util_base_ch);
	UNICODE_ONLY(gtm_strToTitle_ptr = &gtm_strToTitle);
	GTM_ICU_INIT_IF_NEEDED;	/* Note: should be invoked after err_init (since it may error out) and before CLI parsing */
	sig_init(generic_signal_handler, NULL, suspsigs_handler, continue_handler);	/* Note: no ^C handler is defined (yet) */
	atexit(mupip_exit_handler);
	licensed = TRUE;
	in_backup = FALSE;
	op_open_ptr = mu_op_open;
	mu_get_term_characterstics();
	cli_lex_setup(argc,argv);
	if (argc < 2)			/* Interactive mode */
		display_prompt();
	/*      this call should be after cli_lex_setup() due to S390 A/E conversion    */
	gtm_chk_dist(argv[0]);
	INIT_GBL_ROOT(); /* Needed for GVT initialization */
	init_gtm();
	while (TRUE)
	{	func = 0;
		if ((res = parse_cmd()) == EOF)
			break;
		else if (res)
		{
			if (1 < argc)
				rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
			else
				gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
		}
		if (func)
			func();
		if (argc > 1)		/* Non-interactive mode, exit after command */
			break;
		display_prompt();
	}
	mupip_exit(SS_NORMAL);
}
Beispiel #13
0
/* mupfndfil.c
 * Description:
 *	For a region find if the corresponding database is present.
 * Arguments:
 *	reg: Region's pointer
 *	filestr: Sent as allocated memory, if returned full path is needed in this mstr
 *	Returns: TRUE if region's database file is found
 *		 FALSE, otherwise
 * Side Effects:
 *	reg->dyn.addr->fname_len and reg->dyn.addr->fname are updated
 */
boolean_t mupfndfil(gd_region *reg, mstr *filestr)
{
	char 	filename[MAX_FN_LEN];
	mstr 	file, def, ret, *retptr;
	uint4	ustatus;

	switch(reg->dyn.addr->acc_meth)
	{
	case dba_mm:
	case dba_bg:
		break;
#	ifdef VMS
	case dba_usr:
		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_NOUSERDB, 4, LEN_AND_LIT("specified function"), REG_LEN_STR(reg));
		return FALSE;		/* This is currently a VMS only possibility and has no corresponding test case */
#	endif
	default:
		util_out_print("REGION !AD has an unrecognized access method.", TRUE, REG_LEN_STR(reg));
		return FALSE;
	}
	file.addr = (char *)reg->dyn.addr->fname;
	file.len = reg->dyn.addr->fname_len;
#if defined(UNIX)
	file.addr[file.len] = 0;
	if (is_raw_dev(file.addr))
	{
		def.addr = DEF_NODBEXT;
		def.len = SIZEOF(DEF_NODBEXT) - 1;
	} else
	{
		def.addr = DEF_DBEXT;	/* UNIX need to pass "*.dat" but reg->dyn.addr->defext has "DAT" */
		def.len = SIZEOF(DEF_DBEXT) - 1;
	}
#elif defined(VMS)
	def.addr = (char *)reg->dyn.addr->defext;
	def.len = SIZEOF(reg->dyn.addr->defext);
#endif
	if (NULL == filestr)
	{
		ret.len = SIZEOF(filename);
		ret.addr = filename;
		retptr = &ret;
	} else
		retptr = filestr;
	if (FILE_PRESENT != gtm_file_stat(&file, &def, retptr, FALSE, &ustatus))
	{
		if (!jgbl.mupip_journal)
		{	/* Do not print error messages in case of call from mur_open_files().
			 * Currently we use "jgbl.mupip_journal" to identify a call from mupip_recover code */
			util_out_print("REGION !AD's file !AD cannot be found.", TRUE, REG_LEN_STR(reg), LEN_AND_STR(file.addr));
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ustatus);
		}
		return FALSE;
	}
	reg->dyn.addr->fname_len = retptr->len;
	memcpy(reg->dyn.addr->fname, retptr->addr, retptr->len + 1);
	return TRUE;
}
uint4 mupip_set_journal_newstate(set_jnl_options *jnl_options, jnl_create_info *jnl_info, mu_set_rlist *rptr)
{
	enum jnl_state_codes	jnl_curr_state;
	enum repl_state_codes	repl_curr_state;
	boolean_t 		current_image;
	enum db_acc_method	acc_meth;

	error_def(ERR_REPLNOBEFORE);
	error_def(ERR_REPLJNLCNFLCT);
	error_def(ERR_JNLDISABLE);
	error_def(ERR_MMBEFOREJNL);
	error_def(ERR_MMNOBFORRPL);

	jnl_curr_state = (enum jnl_state_codes)rptr->sd->jnl_state;
	repl_curr_state = (enum repl_state_codes)rptr->sd->repl_state;
	acc_meth = rptr->sd->acc_meth;
	current_image = rptr->sd->jnl_before_image;
	if (CLI_ABSENT == jnl_options->cli_journal)
		rptr->jnl_new_state = jnl_curr_state;
	else if ((CLI_NEGATED == jnl_options->cli_journal) || (CLI_NEGATED == jnl_options->cli_enable))
		rptr->jnl_new_state = jnl_notallowed; /* DISABLE specified */
	else if ((jnl_notallowed != jnl_curr_state) || (CLI_PRESENT == jnl_options->cli_enable))
	{	/* journaling is already ENABLED or ENABLE is explicitly specified */
		if (CLI_NEGATED == jnl_options->cli_on)	/* OFF specified */
			rptr->jnl_new_state = jnl_closed;
		else if (repl_curr_state == repl_was_open && CLI_PRESENT != jnl_options->cli_replic_on)
		{ /* Journaling was turned OFF by jnl_file_lost(). Do not allow turning journaling ON without also
		     turning replication ON */
			gtm_putmsg(VARLSTCNT(10) ERR_REPLJNLCNFLCT, 8, LEN_AND_STR(jnl_state_lit[jnl_open]),
					DB_LEN_STR(gv_cur_region), LEN_AND_STR(repl_state_lit[repl_closed]),
					LEN_AND_STR(jnl_state_lit[jnl_open]));
			return EXIT_WRN;
		}
		else /* ON explicitly specified or present by default */
			rptr->jnl_new_state = jnl_open;
	} else	/* jnl_notallowed == jnl_curr_state && CLI_ABSENT == jnl_options->cli_enable */
	{
		if (CLI_PRESENT != jnl_options->cli_replic_on)
		{
			gtm_putmsg(VARLSTCNT(4) ERR_JNLDISABLE, 2, DB_LEN_STR(gv_cur_region));
			return EXIT_WRN;
		} else
			rptr->jnl_new_state = jnl_open;	/* turn journaling on for REPLICATION=ON */
	}
	VMS_ONLY(rptr->before_images = (jnl_options->image_type_specified ?  jnl_info->before_images : current_image);)
Beispiel #15
0
/* Lookup package. Return package handle if success, NULL otherwise.
 * package_name - DLL name
 * msgtype - message severity of the errors reported if any.
 * Note - Errors are not issued if msgtype is SUCCESS, which is to be used if the callers are not
 * interested in message report and not willing to have condition handler overhead.
 */
void_ptr_t fgn_getpak(char *package_name, int msgtype)
{
	void_ptr_t 	ret_handle;
	char_ptr_t	dummy_err_str;
	char		err_str[MAX_ERRSTR_LEN]; /* needed as util_out_print doesn't handle 64bit pointers */
	error_def(ERR_TEXT);
	error_def(ERR_DLLNOOPEN);

	if (!(ret_handle = dlopen(package_name, RTLD_LAZY)))
	{
		if (SUCCESS != msgtype)
		{
			assert(!(msgtype & ~SEV_MSK));
			COPY_DLLERR_MSG;
			rts_error(VARLSTCNT(8) MAKE_MSG_TYPE(ERR_DLLNOOPEN, msgtype), 2, LEN_AND_STR(package_name),
				ERR_TEXT, 2, LEN_AND_STR(err_str));
		}
	}
	return ret_handle;
}
Beispiel #16
0
void log_detailed_log(char *X, srch_hist *Y, srch_hist *Z, int level, kill_set *kill_set_list, trans_num tn)
{
	int 		i;
	block_id	bitmap = 1, temp_bitmap;	/* bitmap is initialized to 1, which is not a bitmap block id */

	assert(NULL != (char *)(Y));
	assert(0 < (Y)->depth);
	assert((NULL == (char *)(Z)) || (0 < (Z)->depth));
	util_out_print("!AD::!16@XQ::", FALSE, LEN_AND_STR(X), &tn);
	for (i = 0; i <= (Y)->depth; i++)
		util_out_print("!SL|", FALSE, (Y)->h[i].blk_num);
	if (NULL != (char *)(Z))
	{
		util_out_print("-", FALSE);
		for (i = 0; i <= (Z)->depth; i++)
			util_out_print("!SL|", FALSE, (Z)->h[i].blk_num);
	}
	if (cw_set_depth)
	{
		util_out_print("::", FALSE);
		for (i = 0; i < cw_set_depth; i++)
			util_out_print("!SL|", FALSE, cw_set[i].blk);
	}
	if ((0 == memcmp((X), "SPL", 3))
		|| (0 == memcmp((X), "CLS", 3))
		|| (0 == memcmp((X), "SWA", 3)))
	{
		if (NULL != (char *)(Z))
			util_out_print("::!SL|!SL", TRUE,
				(Y)->h[level].blk_num, (Z)->h[level].blk_num);
		else
			util_out_print("::!SL", TRUE, (Y)->h[level].blk_num);
	} else
	{
		if ((0 == memcmp((X), "KIL", 3)) && (NULL != kill_set_list))
		{
			util_out_print("::", FALSE);
			for (i = 0; i < kill_set_list->used; i++)
			{
				temp_bitmap = kill_set_list->blk[i].block & (~(BLKS_PER_LMAP - 1));
				if (bitmap != temp_bitmap)
				{
					if (1 != bitmap)
						util_out_print("]", FALSE);
					bitmap = temp_bitmap;
					util_out_print("[!SL:", FALSE, bitmap);
				}
				util_out_print("!SL,", FALSE, kill_set_list->blk[i].block);
			}
			util_out_print("]", TRUE);
		}
	}
}
gtm_uint64_t gds_file_size(file_control *fc)
{
	unix_db_info	*udi;
	int		fstat_res;
	struct stat	stat_buf;

	udi = (unix_db_info *)fc->file_info;
	FSTAT_FILE(udi->fd, &stat_buf, fstat_res);
	if (-1 == fstat_res)
		rts_error(VARLSTCNT(5) ERR_DBFILOPERR, 2, LEN_AND_STR(udi->fn), errno);
	assert(0 == stat_buf.st_size % DISK_BLOCK_SIZE);
	return (gtm_uint64_t)(stat_buf.st_size / DISK_BLOCK_SIZE);
}
Beispiel #18
0
void set_enospc_flags(gd_addr *addr_ptr, char enospc_enable_list[], boolean_t ok_to_interrupt)
{
	gd_region	*r_local, *r_top;
	int		i;
	sgmnt_addrs	*csa;
	const char	*syslog_msg;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;

	for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions, i = 0;
	     r_local < r_top; r_local++, i++)
	{
		if (!r_local->open || r_local->was_open)
			continue;
		if ((dba_bg != r_local->dyn.addr->acc_meth) && (dba_mm != r_local->dyn.addr->acc_meth))
			continue;
		csa = &FILE_INFO(r_local)->s_addrs;
		if (ANTICIPATORY_FREEZE_ENABLED(csa))
		{
			switch(enospc_enable_list[i])
			{
			case NONE:
				syslog_msg = "Turning off fake ENOSPC for both database and journal file.";
				csa->nl->fake_db_enospc = FALSE;
				csa->nl->fake_jnl_enospc = FALSE;
				break;
			case DB_ON:
				syslog_msg = "Turning on fake ENOSPC only for database file.";
				csa->nl->fake_db_enospc = TRUE;
				csa->nl->fake_jnl_enospc = FALSE;
				break;
			case JNL_ON:
				syslog_msg = "Turning on fake ENOSPC only for journal file.";
				csa->nl->fake_db_enospc = FALSE;
				csa->nl->fake_jnl_enospc = TRUE;
				break;
			case DB_AND_JNL_ON:
				syslog_msg = "Turning on fake ENOSPC for both database and journal file.";
				csa->nl->fake_db_enospc = TRUE;
				csa->nl->fake_jnl_enospc = TRUE;
				break;
			default:
				assert(FALSE);
			}
			if (ok_to_interrupt)
				send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_TEXT, 2, DB_LEN_STR(r_local), ERR_TEXT, 2,
					     LEN_AND_STR(syslog_msg));
		}
	}
}
Beispiel #19
0
static bool	dse_process(int argc)
{
	int	res;

	ESTABLISH_RET(util_ch, TRUE);
	func = 0;
	util_interrupt = 0;
	if (EOF == (res = parse_cmd()))
	{
		if (util_interrupt)
		{
			rts_error(VARLSTCNT(1) ERR_CTRLC);
			REVERT;
			return TRUE;
		} else
		{
			REVERT;
			return FALSE;
		}
	} else if (res)
	{
		if (1 < argc)
		{
			/* Here we need to REVERT since otherwise we stay in dse in a loop
			 * The design of dse needs to be changed to act like VMS (which is:
			 * if there is an error in the dse command (dse dumpoa), go to command
			 * prompt, but UNIX exits
			 */
			REVERT;
			rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
		} else
			gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
	}
	if (func)
		func();
	REVERT;
	return(1 >= argc);
}
Beispiel #20
0
void mu_signal_process(char *command, int signal)
{
	unsigned short	slen;
	int		len, toprocess_id, save_errno;
	char		buff[256];
	error_def(ERR_MUPCLIERR);
	error_def(ERR_MUPIPSIG);

	slen = sizeof(buff);
	if (!cli_get_str("ID", buff, &slen))
		mupip_exit(ERR_MUPCLIERR);
	len = slen;
	toprocess_id = asc2i((uchar_ptr_t)buff, len);
	if (toprocess_id < 0)
	{
		util_out_print("Error converting !AD to a number", FLUSH, len, buff);
		mupip_exit(ERR_MUPCLIERR);
	} else
	{
		if (-1 == kill(toprocess_id, signal))
		{
			save_errno = errno;
			util_out_print("Error issuing !AD to process !UL: !AZ", FLUSH,
				       LEN_AND_STR(command), toprocess_id, STRERROR(errno));
		} else
		{
			util_out_print("!AD issued to process !UL", FLUSH, LEN_AND_STR(command), toprocess_id);
			if (!MEMCMP_LIT(command, STOP_STR))
			{
				send_msg(VARLSTCNT(9) ERR_MUPIPSIG, 7, LEN_AND_STR(command), signal, process_id, process_id,
					 toprocess_id, toprocess_id);
			}
		}
	}
	return;
}
Beispiel #21
0
void fgn_closepak(void_ptr_t package_handle, int msgtype)
{
	char_ptr_t      dummy_err_str;
  	int 		status;
	char		err_str[MAX_ERRSTR_LEN];
	error_def(ERR_TEXT);
	error_def(ERR_DLLNOCLOSE);

	status = dlclose(package_handle);
	if (0 != status && SUCCESS != msgtype)
	{
		assert(!(msgtype & ~SEV_MSK));
		COPY_DLLERR_MSG;
		rts_error(VARLSTCNT(6) MAKE_MSG_TYPE(ERR_DLLNOCLOSE, msgtype), 0, ERR_TEXT, 2, LEN_AND_STR(err_str));
	}
}
Beispiel #22
0
void show_source_line(char* buf, boolean_t warn)
{
	char 	*b, *c, *c_top;
	int	chlen, chwidth;
	unsigned int ch;
	error_def(ERR_SRCLIN);
	error_def(ERR_SRCLOC);

	for (c = (char *)source_buffer, b = buf, c_top = c + last_source_column - 1; c < c_top; )
	{
		if (*c == '\t')
			*b++ = *c++;
		else if (!gtm_utf8_mode || *(uchar_ptr_t)c <= ASCII_MAX)
		{
			*b++ = ' ';
			c++;
		}
#ifdef UNICODE_SUPPORTED
		else
		{
			chlen = (int)(UTF8_MBTOWC(c, c_top, ch) - (uchar_ptr_t)c);
			if (WEOF != ch && 0 < (chwidth = UTF8_WCWIDTH(ch)))
			{
				memset(b, ' ', chwidth);
				b += chwidth;
			}
			c += chlen;
		}
#endif
	}
	memcpy(b, ARROW, STR_LIT_LEN(ARROW));
	b += STR_LIT_LEN(ARROW);
	*b = '\0';
	if (warn)
	{
		dec_nofac = TRUE;
		dec_err(VARLSTCNT (6) ERR_SRCLIN, 4, LEN_AND_STR((char *)source_buffer), b - buf, buf);
		if (!run_time)
			dec_err(VARLSTCNT(6) ERR_SRCLOC, 4, last_source_column, source_line, source_name_len, source_file_name);
		dec_nofac = FALSE;
	}
}
Beispiel #23
0
void zl_cmd_qlf (mstr *quals, command_qualifier *qualif)
{
	char		cbuf[MAX_LINE];
	error_def	(ERR_COMPILEQUALS);
	int		parse_ret;

	if (quals->len + sizeof(COMMAND) > MAX_LINE)
		rts_error(VARLSTCNT(4) ERR_COMPILEQUALS, 2, quals->len, quals->addr);

	memcpy(cbuf, COMMAND, sizeof(COMMAND) - 1);
	memcpy(cbuf + sizeof(COMMAND) -1, quals->addr, quals->len);
	cbuf[sizeof(COMMAND) - 1 + quals->len] = 0;
	cli_str_setup(sizeof(COMMAND) + quals->len, cbuf);
	parse_ret = parse_cmd();
	if (parse_ret)
		rts_error(VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str));

	qualif->object_file.mvtype = qualif->list_file.mvtype = qualif->ceprep_file.mvtype = 0;
	get_cmd_qlf (qualif);
}
Beispiel #24
0
void	dse_close(void)
{
	mval		val;
	mval		pars;
	unsigned char	no_param = (unsigned char)iop_eol;

	if (CLOSED_FMT != dse_dmp_format)
	{
		util_out_print("Closing output file:  !AD",TRUE,LEN_AND_STR(patch_ofile));
		val.mvtype = pars.mvtype = MV_STR;
		val.str.addr = (char *)patch_ofile;
		val.str.len = patch_len;
		pars.str.len = SIZEOF(iop_eol);
		pars.str.addr = (char *)&no_param;
		op_close(&val, &pars);
		dse_dmp_format = CLOSED_FMT;
	} else
		util_out_print("Error:  no current output file.",TRUE);
	return;
}
Beispiel #25
0
boolean_t mur_fopen_sp(jnl_ctl_list *jctl)
{
	struct stat		stat_buf;
	int			status, perms;

	error_def(ERR_JNLFILEOPNERR);
	error_def(ERR_SYSCALL);

	perms = O_RDONLY;
	jctl->read_only = TRUE;
	/* Both for recover and rollback open in read/write mode. We do not need to write in journal file
	 * for mupip journal extract/show/verify or recover -forward.  So open it as read-only
	 */
	if (mur_options.update && !mur_options.forward)
	{
		perms = O_RDWR;
		jctl->read_only = FALSE;
	}
	jctl->channel = OPEN((char *)jctl->jnl_fn, perms);
	if (-1 != jctl->channel)
	{
		FSTAT_FILE(jctl->channel, &stat_buf, status);
		if (-1 != status)
		{
			jctl->os_filesize = (off_jnl_t)stat_buf.st_size;
			return TRUE;
		}
		jctl->status = errno;
		CLOSEFILE(jctl->channel, status);
	} else
		jctl->status = errno;
	if (ENOENT == jctl->status)	/* File Not Found is a common error, so no need for SYSCALL */
		gtm_putmsg(VARLSTCNT(5) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn, jctl->status);
	else
		gtm_putmsg(VARLSTCNT(12) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn, ERR_SYSCALL, 5,
			LEN_AND_STR((-1 == jctl->channel) ? "open" : "fstat"), CALLFROM, jctl->status);
	jctl->channel = NOJNL;
	return FALSE;
}
Beispiel #26
0
static	void	gvcst_search_fail(srch_blk_status *pStat)
{
	char	buff[1024], crbuff[256], regbuff[512];

	error_def(ERR_TEXT);

	assert(CDB_STAGNATE <= t_tries);
	assert((NULL != pStat) && (NULL != pStat->cr) && (NULL != cs_addrs));
	if (NULL != pStat)
	{
		if (NULL != pStat->cr)
			SPRINTF(crbuff, ": crbuff = 0x%X", pStat->cr->buffaddr);
		else
			crbuff[0] = '\0';
		memcpy(regbuff, REG_STR_LEN(gv_cur_region));
		regbuff[gv_cur_region->rname_len] = '\0';
		SPRINTF(buff, "Possible data corruption in region %s : blk = 0x%X : buff = 0x%X : cr = 0x%X %s : "
				"csa = 0x%X : csalock = 0x%X", regbuff, pStat->blk_num, pStat->buffaddr,
				pStat->cr, crbuff, cs_addrs, cs_addrs->lock_addrs[0]);
		send_msg(VARLSTCNT(4) ERR_TEXT, 2, LEN_AND_STR(buff));
	}
}
Beispiel #27
0
void setzdir(mval *newdir, mval *full_path_of_newdir)
{   /* newdir is the directory to change to; NULL to set full_path_of_newdir to current working directory.
     * If full_path_of_newdir is non NULL, return the full path of the new directory in full_path_of_newdir.
     * NOTE : the full path of directory is stored in a static buffer which might get overwritten by the next call to setzdir.
     * Callers should save return value if needed.
     */
    char 		directory[GTM_MAX_DIR_LEN], *getcwd_res, *err_str;
    uint4		length, status;

    assert(NULL != newdir || NULL != full_path_of_newdir);
    if (NULL != newdir)
    {
        MV_FORCE_STR(newdir);
        assert(SIZEOF(directory) > newdir->str.len);
        memcpy(directory, newdir->str.addr, newdir->str.len);
        directory[newdir->str.len] = '\0';
        if (-1 == CHDIR(directory))
        {   /* On VMS, chdir(directory, 0) [actually, any non 1 value] is supposed to restore the process startup cwd at
             * exit (see help cc run). We've noticed that it doesn't behave the way it has been documented in the mumps
             * executable. Vinaya, 08/22/2001.
             */
            err_str = STRERROR(errno);
            rts_error(VARLSTCNT(8) ERR_SETZDIR, 2, newdir->str.len, newdir->str.addr, ERR_TEXT, 2,
                      LEN_AND_STR(err_str));
        }
    }
    /* We need to find the full path of the current working directory because newdir might be a relative path, in which case
     * $ZDIR will show up as a relative path.
     */
    if (NULL != full_path_of_newdir)
    {
        GETCWD(directory_buffer, SIZEOF(directory_buffer), getcwd_res);
        if (NULL != getcwd_res)
        {
            length = USTRLEN(directory_buffer);
            UNIX_ONLY(directory_buffer[length++] = '/';)
        } else
Beispiel #28
0
void	repl_inst_dump_gtmsrclcl(gtmsrc_lcl_ptr_t gtmsrclcl_ptr)
{
	int		idx;
	boolean_t	first_time = TRUE;

	for (idx = 0; idx < NUM_GTMSRC_LCL; idx++, gtmsrclcl_ptr++)
	{
		if (('\0' == gtmsrclcl_ptr->secondary_instname[0])
				&& (0 == gtmsrclcl_ptr->resync_seqno)
				&& (0 == gtmsrclcl_ptr->connect_jnl_seqno))
			continue;
		if (first_time)
		{
			util_out_print("", TRUE);
			first_time = FALSE;
			PRINT_DASHES;
			util_out_print(SRCLCL_TITLE_STRING, TRUE);
			PRINT_DASHES;
		} else
			PRINT_DASHES;
		PRINT_OFFSET_HEADER;

		PRINT_OFFSET_PREFIX(offsetof(gtmsrc_lcl, secondary_instname[0]), SIZEOF(gtmsrclcl_ptr->secondary_instname));
		util_out_print( PREFIX_SRCLCL "Secondary Instance Name          !R15AD", TRUE, idx,
			LEN_AND_STR((char *)gtmsrclcl_ptr->secondary_instname));

		PRINT_OFFSET_PREFIX(offsetof(gtmsrc_lcl, resync_seqno), SIZEOF(gtmsrclcl_ptr->resync_seqno));
		util_out_print( PREFIX_SRCLCL "Resync Sequence Number      !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsrclcl_ptr->resync_seqno, &gtmsrclcl_ptr->resync_seqno);

		PRINT_OFFSET_PREFIX(offsetof(gtmsrc_lcl, connect_jnl_seqno), SIZEOF(gtmsrclcl_ptr->connect_jnl_seqno));
		util_out_print( PREFIX_SRCLCL "Connect Sequence Number     !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsrclcl_ptr->connect_jnl_seqno, &gtmsrclcl_ptr->connect_jnl_seqno);
		section_offset += SIZEOF(gtmsrc_lcl);
	}
}
int gtmrecv_start_helpers(int n_readers, int n_writers)
{ /* Set flag in recvpool telling the receiver server to start n_readers and n_writers helper processes.
   * Wait for receiver server to complete the process - completed successfully, or terminated with error
   */
	upd_helper_ctl_ptr_t	upd_helper_ctl;
	upd_helper_entry_ptr_t	helper, helper_top;
	char			err_str[BUFSIZ];
	int			avail_slots, started_readers, started_writers;

	error_def(ERR_REPLERR);
	error_def(ERR_REPLINFO);
	error_def(ERR_REPLWARN);

	assert(0 != n_readers || 0 != n_writers);
	upd_helper_ctl = recvpool.upd_helper_ctl;

	/* let's clean up dead helpers first so we get an accurate count of available slots */
	upd_helper_ctl->reap_helpers = HELPER_REAP_NOWAIT;
	while (HELPER_REAP_NONE != upd_helper_ctl->reap_helpers && SRV_ALIVE == is_recv_srv_alive())
		SHORT_SLEEP(GTMRECV_WAIT_FOR_UPD_SHUTDOWN);
	upd_helper_ctl->reap_helpers = HELPER_REAP_NONE; /* just in case recvr died */

	/* count available slots so receiver doesn't have to */
	for (avail_slots = 0, helper = upd_helper_ctl->helper_list, helper_top = helper + MAX_UPD_HELPERS;
		helper < helper_top; helper++)
	{
		if (0 == helper->helper_pid)
		{
			avail_slots++;
			helper->helper_pid_prev = 0; /* force out abnormally terminated helpers as well */
			helper->helper_shutdown = NO_SHUTDOWN; /* clean state */
		}
	}
	if (avail_slots < n_readers + n_writers)
	{
		SNPRINTF(err_str, SIZEOF(err_str),
				"%d helpers will exceed the maximum allowed (%d), limit the helpers to %d\n",
				n_readers + n_writers, MAX_UPD_HELPERS, avail_slots);
		gtm_putmsg(VARLSTCNT(4) ERR_REPLERR, 2, LEN_AND_STR(err_str));
		return ABNORMAL_SHUTDOWN;
	}

	upd_helper_ctl->start_n_readers = n_readers;
	upd_helper_ctl->start_n_writers = n_writers;
	SHM_WRITE_MEMORY_BARRIER;
	upd_helper_ctl->start_helpers = TRUE; /* hey receiver, let's go, start 'em up */
	while (upd_helper_ctl->start_helpers && SRV_ALIVE == is_recv_srv_alive())
		SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START);
	if (!upd_helper_ctl->start_helpers)
	{
		started_readers = upd_helper_ctl->start_n_readers;
		started_writers = upd_helper_ctl->start_n_writers;
		SNPRINTF(err_str, SIZEOF(err_str), "%s %d out of %d readers and %d out of %d writers started",
				((started_readers + started_writers) == (n_readers + n_writers)) ? "All" : "Only",
				started_readers, n_readers, started_writers, n_writers);
		if ((started_readers + started_writers) == (n_readers + n_writers))
		{
			gtm_putmsg(VARLSTCNT(4) ERR_REPLINFO, 2, LEN_AND_STR(err_str));
			return NORMAL_SHUTDOWN;
		}
		gtm_putmsg(VARLSTCNT(4) ERR_REPLWARN, 2, LEN_AND_STR(err_str));
		return ABNORMAL_SHUTDOWN;
	}
	gtm_putmsg(VARLSTCNT(4) ERR_REPLERR, 2,
			LEN_AND_LIT("Receiver server is not alive to start helpers. Start receiver server first"));
	return ABNORMAL_SHUTDOWN;
}
int 	mu_rndwn_replpool(replpool_identifier *replpool_id, repl_inst_hdr_ptr_t repl_inst_filehdr, int shm_id, boolean_t *ipc_rmvd)
{
	int			semval, status, save_errno, nattch;
	char			*instfilename, pool_type;
	sm_uc_ptr_t		start_addr;
	struct shmid_ds		shm_buf;
	unix_db_info		*udi;
	sgmnt_addrs		*csa;
	boolean_t		anticipatory_freeze_available, force_attach;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(INVALID_SHMID != shm_id);
	instfilename = replpool_id->instfilename;
	pool_type = replpool_id->pool_type;
	assert((JNLPOOL_SEGMENT == pool_type) || (RECVPOOL_SEGMENT == pool_type));
	anticipatory_freeze_available = ANTICIPATORY_FREEZE_AVAILABLE;
	force_attach = (jgbl.onlnrlbk || (!jgbl.mur_rollback && !argumentless_rundown && anticipatory_freeze_available));
	if (-1 == shmctl(shm_id, IPC_STAT, &shm_buf))
	{
		save_errno = errno;
		ISSUE_REPLPOOLINST_AND_RETURN(save_errno, shm_id, instfilename, "shmctl()");
	}
	nattch = shm_buf.shm_nattch;
	if ((0 != nattch) && !force_attach)
	{
		util_out_print("Replpool segment (id = !UL) for replication instance !AD is in use by another process.",
				TRUE, shm_id, LEN_AND_STR(instfilename));
		return -1;
	}
	if (-1 == (sm_long_t)(start_addr = (sm_uc_ptr_t) do_shmat(shm_id, 0, 0)))
	{
		save_errno = errno;
		ISSUE_REPLPOOLINST_AND_RETURN(save_errno, shm_id, instfilename, "shmat()");
	}
	ESTABLISH_RET(mu_rndwn_replpool_ch, -1);
	/* assert that the identifiers are at the top of replpool control structure */
	assert(0 == offsetof(jnlpool_ctl_struct, jnlpool_id));
	assert(0 == offsetof(recvpool_ctl_struct, recvpool_id));
	memcpy((void *)replpool_id, (void *)start_addr, SIZEOF(replpool_identifier));
	if (memcmp(replpool_id->label, GDS_RPL_LABEL, GDS_LABEL_SZ - 1))
	{
		if (!memcmp(replpool_id->label, GDS_RPL_LABEL, GDS_LABEL_SZ - 3))
			util_out_print(
				"Incorrect version for the replpool segment (id = !UL) belonging to replication instance !AD",
					TRUE, shm_id, LEN_AND_STR(instfilename));
		else
			util_out_print("Incorrect replpool format for the segment (id = !UL) belonging to replication instance !AD",
					TRUE, shm_id, LEN_AND_STR(instfilename));
		DETACH_AND_RETURN(start_addr, shm_id, instfilename);
	}
	if (memcmp(replpool_id->now_running, gtm_release_name, gtm_release_name_len + 1))
	{
		util_out_print("Attempt to access with version !AD, while already using !AD for replpool segment (id = !UL)"
				" belonging to replication instance !AD.", TRUE, gtm_release_name_len, gtm_release_name,
				LEN_AND_STR(replpool_id->now_running), shm_id, LEN_AND_STR(instfilename));
		DETACH_AND_RETURN(start_addr, shm_id, instfilename);
	}
	/* Assert that if we haven't yet attached to the journal pool yet, we have the corresponding global vars set to NULL */
	assert((JNLPOOL_SEGMENT != pool_type) || ((NULL == jnlpool.jnlpool_ctl) && (NULL == jnlpool_ctl)));
	if (JNLPOOL_SEGMENT == pool_type)
	{	/* Initialize variables to simulate a "jnlpool_init". This is required by "repl_inst_flush_jnlpool" called below */
		jnlpool_ctl = jnlpool.jnlpool_ctl = (jnlpool_ctl_ptr_t)start_addr;
		assert(NULL != jnlpool.jnlpool_dummy_reg);
		udi = FILE_INFO(jnlpool.jnlpool_dummy_reg);
		csa = &udi->s_addrs;
		csa->critical = (mutex_struct_ptr_t)((sm_uc_ptr_t)jnlpool.jnlpool_ctl + JNLPOOL_CTL_SIZE);
		csa->nl = (node_local_ptr_t)((sm_uc_ptr_t)csa->critical + CRIT_SPACE + SIZEOF(mutex_spin_parms_struct));
		/* secshr_db_clnup uses this relationship */
		assert(jnlpool.jnlpool_ctl->filehdr_off);
		assert(jnlpool.jnlpool_ctl->srclcl_array_off > jnlpool.jnlpool_ctl->filehdr_off);
		assert(jnlpool.jnlpool_ctl->sourcelocal_array_off > jnlpool.jnlpool_ctl->srclcl_array_off);
		/* Initialize "jnlpool.repl_inst_filehdr" and related fields as "repl_inst_flush_jnlpool" relies on that */
		jnlpool.repl_inst_filehdr = (repl_inst_hdr_ptr_t)((sm_uc_ptr_t)jnlpool.jnlpool_ctl
									+ jnlpool.jnlpool_ctl->filehdr_off);
		jnlpool.gtmsrc_lcl_array = (gtmsrc_lcl_ptr_t)((sm_uc_ptr_t)jnlpool.jnlpool_ctl
									+ jnlpool.jnlpool_ctl->srclcl_array_off);
		jnlpool.gtmsource_local_array = (gtmsource_local_ptr_t)((sm_uc_ptr_t)jnlpool.jnlpool_ctl
										+ jnlpool.jnlpool_ctl->sourcelocal_array_off);
		if (0 == nattch)
		{	/* No one attached. So, we can safely flush the journal pool so that the gtmsrc_lcl structures in the
			 * jnlpool and disk are in sync with each other. More importantly we are about to remove the jnlpool
			 * so we better get things in sync before that. If anticipatory freeze scheme is in effect, then we
			 * need to keep the journal pool up and running. So, don't reset the crash field in the instance file
			 * header (dictated by the second parameter to repl_inst_flush_jnlpool below).
			 * Note:
			 * If mu_rndwn_repl_instance created new semaphores (in mu_replpool_remove_sem), we need to flush those
			 * to the instance file as well. So, override the jnlpool_semid and jnlpool_semid_ctime with the new
			 * values.
			 */
			assert((INVALID_SEMID != repl_inst_filehdr->jnlpool_semid)
					&& (0 != repl_inst_filehdr->jnlpool_semid_ctime));
			jnlpool.repl_inst_filehdr->jnlpool_semid = repl_inst_filehdr->jnlpool_semid;
			jnlpool.repl_inst_filehdr->jnlpool_semid_ctime = repl_inst_filehdr->jnlpool_semid_ctime;
			repl_inst_flush_jnlpool(FALSE, !anticipatory_freeze_available);
			assert(!jnlpool.repl_inst_filehdr->crash || anticipatory_freeze_available);
			/* Refresh local copy (repl_inst_filehdr) with the copy that was just flushed (jnlpool.repl_inst_filehdr) */
			memcpy(repl_inst_filehdr, jnlpool.repl_inst_filehdr, SIZEOF(repl_inst_hdr));
			if (!anticipatory_freeze_available)
			{ 	/* Now that jnlpool has been flushed and there is going to be no journal pool, reset
				 * "jnlpool.repl_inst_filehdr" as otherwise other routines (e.g. "repl_inst_recvpool_reset") are
				 * affected by whether this is NULL or not.
				 */
				jnlpool.jnlpool_ctl = NULL;
				jnlpool_ctl = NULL;
				jnlpool.gtmsrc_lcl_array = NULL;
				jnlpool.gtmsource_local_array = NULL;
				jnlpool.jnldata_base = NULL;
				jnlpool.repl_inst_filehdr = NULL;
			}
		} /* else we are ONLINE ROLLBACK. repl_inst_flush_jnlpool will be done later after gvcst_init in mur_open_files */
	}
	if ((0 == nattch) && (!anticipatory_freeze_available || (RECVPOOL_SEGMENT == pool_type)))
	{
		if (-1 == shmdt((caddr_t)start_addr))
		{
			save_errno = errno;
			ISSUE_REPLPOOLINST_AND_RETURN(save_errno, shm_id, instfilename, "shmdt()");
		}
		if (0 != shm_rmid(shm_id))
		{
			save_errno = errno;
			ISSUE_REPLPOOLINST_AND_RETURN(save_errno, shm_id, instfilename, "shm_rmid()");
		}
		if (JNLPOOL_SEGMENT == pool_type)
		{
			repl_inst_filehdr->jnlpool_shmid = INVALID_SHMID;
			repl_inst_filehdr->jnlpool_shmid_ctime = 0;
			assert((NULL == jnlpool.jnlpool_ctl) && (NULL == jnlpool_ctl));
			*ipc_rmvd = TRUE;
		} else
		{
			repl_inst_filehdr->recvpool_shmid = INVALID_SHMID;
			repl_inst_filehdr->recvpool_shmid_ctime = 0;
			*ipc_rmvd = TRUE;
		}
	} else
	{	/* Else we are ONLINE ROLLBACK or anticipatory freeze is in effect and so we want to keep the journal pool available
		 * for the duration of the rollback. Do not remove and/or reset the fields in the file header
	   	 */
		assert((JNLPOOL_SEGMENT != pool_type) || ((NULL != jnlpool.jnlpool_ctl) && (NULL != jnlpool_ctl)));
		if (JNLPOOL_SEGMENT == pool_type)
			*ipc_rmvd = FALSE;
		if (RECVPOOL_SEGMENT == pool_type)
			*ipc_rmvd = FALSE;
	}
	REVERT;
	return 0;
}