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); }
/* 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; }
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;)
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; }
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; }
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); }
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); }
/* 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)); }
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 = >m_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); }
/* 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);)
/* 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; }
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); }
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)); } } }
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); }
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; }
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)); } }
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; } }
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); }
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; }
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; }
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)); } }
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
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, >msrclcl_ptr->resync_seqno, >msrclcl_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, >msrclcl_ptr->connect_jnl_seqno, >msrclcl_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; }