1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/****************************************************************
* *
* Copyright (c) 2003-2019 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#if defined(UNIX)
#include "gtm_unistd.h"
#elif defined(VMS)
#include <rms.h>
#include <iodef.h>
#include <psldef.h>
#include <ssdef.h>
#include <efndef.h>
#include "iosb_disk.h"
#endif
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsroot.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "jnl.h"
#include "buddy_list.h"
#include "hashtab_int4.h" /* needed for muprec.h */
#include "hashtab_int8.h" /* needed for muprec.h */
#include "hashtab_mname.h" /* needed for muprec.h */
#include "muprec.h"
#include "read_db_files_from_gld.h"
#include "mu_gv_cur_reg_init.h"
#include "mur_db_files_from_jnllist.h"
#include "mur_read_file.h"
#include "iosp.h"
#include "gtmio.h"
#include "gtmmsg.h"
GBLREF gd_region *gv_cur_region;
GBLREF gd_addr *gd_header;
error_def(ERR_JNLREAD);
error_def(ERR_PREMATEOF);
error_def(ERR_FILEPARSE);
gld_dbname_list *mur_db_files_from_jnllist(char *jnl_file_list, unsigned short jnl_file_list_len, int *db_total)
{
gd_region *reg, *reg_start, *reg_top;
gd_segment *seg;
int db_tot;
unsigned int db_fname_len;
uint4 ustatus;
gld_dbname_list head, *tdblist, *dblist = &head;
char *cptr, *ctop, *cptr_last, db_fname[GTM_PATH_MAX];
jnl_ctl_list jctl_temp, *jctl = &jctl_temp;
jnl_file_header *jfh;
#if defined(VMS)
io_status_block_disk iosb;
#endif
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
db_tot = 0;
tdblist = head.next = NULL;
cptr = jnl_file_list;
ctop = &jnl_file_list[jnl_file_list_len];
memset(&jctl_temp, 0, SIZEOF(jctl_temp));
if (NULL != gd_header)
{ /* global directory has already been opened by a "gvinit" in mur_open_files (for recover or rollback). */
reg_start = gd_header->regions;
reg_top = reg_start + gd_header->n_regions;
} else
{ /* Do not use global directory regions. Create regions using mu_gv_cur_reg_init from dbname in jnl file header */
reg_start = NULL;
reg_top = NULL;
}
/* Get full path of db file names pointed to by regions in global directory.
* This is needed for later comparison with db file names in journal file header.
*/
for (reg = reg_start; reg < reg_top; reg++)
{
seg = reg->dyn.addr;
if (!get_full_path((char *)seg->fname, (unsigned int)seg->fname_len,
(char *)&db_fname[0], &db_fname_len, GTM_PATH_MAX, &ustatus))
{
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_FILEPARSE, 2, seg->fname_len, seg->fname, ustatus);
if (!TREF(skip_DB_exists_check))
return NULL;
}
assert(db_fname_len && (db_fname_len < MAX_FN_LEN + 1));
seg->fname_len = db_fname_len;
memcpy(seg->fname, &db_fname[0], db_fname_len);
/* This code is lifted from the tail of "mu_gv_cur_reg_init". Any changes here need to be reflected there */
FILE_CNTL_INIT(seg);
}
while (cptr < ctop)
{
cptr_last = cptr;
while (0 != *cptr && ',' != *cptr && '"' != *cptr && ' ' != *cptr)
++cptr;
if (!get_full_path(cptr_last, (unsigned int)(cptr - cptr_last),
(char *)jctl->jnl_fn, &jctl->jnl_fn_len, MAX_FN_LEN, &ustatus))
{
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_FILEPARSE, 2, cptr - cptr_last, cptr_last, ustatus);
return NULL;
}
cptr++; /* skip separator */
if (SS_NORMAL != mur_fopen_sp(jctl, NULL))
return NULL;
jctl->jfh = (jnl_file_header *)malloc(REAL_JNL_HDR_LEN);
jfh = jctl->jfh;
DO_FILE_READ(jctl->channel, 0, jfh, REAL_JNL_HDR_LEN, jctl->status, jctl->status2);
if (SS_NORMAL != jctl->status) /* read fails */
{
gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_JNLREAD, 3, jctl->jnl_fn_len, jctl->jnl_fn, 0, jctl->status);
/* should we do mur_fclose(jctl) here ? */
return NULL;
}
CHECK_JNL_FILE_IS_USABLE(jfh, jctl->status, TRUE, jctl->jnl_fn_len, jctl->jnl_fn);
if (SS_NORMAL != jctl->status)
/* should we do mur_fclose(jctl) here ? */
return NULL; /* gtm_putmsg would have already been done by CHECK_JNL_FILE_IS_USABLE macro */
/* Check if db file name in journal file header points to any region in already allocated list */
for (tdblist = head.next; NULL != tdblist; tdblist = tdblist->next)
{ /* We cannot call is_file_identical because file may not really exist */
seg = tdblist->gd->dyn.addr;
if ((seg->fname_len == jfh->data_file_name_length)
&& !memcmp(seg->fname, jfh->data_file_name, seg->fname_len))
break; /* match found */
}
if (NULL == tdblist)
{ /* Did not find any existing db structure to match this jnl file. Allocate one. */
/* Check if db file name in journal file header points to any region in the current global directory.
* If so use that region structure. If not, allocate one.
*/
for (reg = reg_start; reg < reg_top; reg++)
{
seg = reg->dyn.addr;
if ((seg->fname_len == jfh->data_file_name_length)
&& !memcmp(seg->fname, jfh->data_file_name, seg->fname_len))
break; /* Found db in gld file. Use that region structure. */
}
if (reg == reg_top)
{ /* Could not find db in gld file or empty gld file. Allocate region structure */
mu_gv_cur_reg_init();
reg = gv_cur_region;
seg = (gd_segment *)reg->dyn.addr;
seg->fname_len = jfh->data_file_name_length;
if (seg->fname_len >= SIZEOF(seg->fname))
seg->fname_len = SIZEOF(seg->fname) - 1;
memcpy(seg->fname, jfh->data_file_name, seg->fname_len);
seg->fname[seg->fname_len] = 0;
}
dblist = dblist->next = (gld_dbname_list *)malloc(SIZEOF(gld_dbname_list));
memset(dblist, 0, SIZEOF(gld_dbname_list));
reg->stat.addr = (void *)dblist; /* is it necessary ??? */
dblist->gd = reg;
db_tot++;
}
/* else : multiple journal files for same database. continue processing */
if (!mur_fclose(jctl)) /* cannot do this until "jfh" usages are done above */
return NULL;
}
*db_total = db_tot;
return head.next;
}
|