File: mur_db_files_from_jnllist.c

package info (click to toggle)
fis-gtm 6.3-014-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 36,680 kB
  • sloc: ansic: 333,039; asm: 5,180; csh: 4,956; sh: 1,924; awk: 291; makefile: 66; sed: 13
file content (174 lines) | stat: -rwxr-xr-x 6,299 bytes parent folder | download | duplicates (2)
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;
}