/*+ Function: GD_LOAD Syntax: gd_addr *gd_load(mstr *gd_name) Open a global directory file and verify that it is a valid GD. Determine if it has already been opened. If not, setup and initialize the GT.M structures used to access the GD based on the information in the file, enter in the linked list of global directories and return a pointer to it. If already opened, return a pointer to it. Prototype: ? Return: gd_addr * (all errors are signalled) Arguments: gd_name is the name of the file to be opened Side Effects: None Notes: A) While checking may be done earlier for duplicate names, unique identification of files can require OS specific operations useable only after the file is open, so checks must be done within this function for duplicate files. -*/ gd_addr *gd_load(mstr *v) { void *file_ptr; /* is a temporary structure as the file open and manipulations are currently stubs */ header_struct *header, temp_head, disp_head; gd_addr *table, *gd_addr_ptr; gd_binding *map, *map_top; gd_region *reg, *reg_top; uint4 t_offset, size; gd_gblname *gnam, *gnam_top; int i, n_regions, arraysize, disp_len; trans_num *array; # ifdef DEBUG boolean_t prevMapIsSpanning, currMapIsSpanning, gdHasSpanGbls; boolean_t isSpannedReg[256]; /* currently we allow for a max of 256 regions in this dbg code */ # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; file_ptr = open_gd_file(v); for (gd_addr_ptr = gd_addr_head; gd_addr_ptr; gd_addr_ptr = gd_addr_ptr->link) { /* if already open then return old structure */ if (comp_gd_addr(gd_addr_ptr, file_ptr)) { close_gd_file(file_ptr); return gd_addr_ptr; } } file_read(file_ptr, SIZEOF(header_struct), (uchar_ptr_t)&temp_head, 1); /* Read in header and verify is valid GD */ for (i = 0; i < GDE_LABEL_NUM; i++) { if (!memcmp(temp_head.label, gde_labels[i], GDE_LABEL_SIZE - 1)) break; } if (GDE_LABEL_NUM == i) { close_gd_file(file_ptr); disp_len = SIZEOF(disp_head.label); format2disp(temp_head.label, SIZEOF(temp_head.label), disp_head.label, &disp_len); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_GDINVALID, 6, v->len, v->addr, LEN_AND_LIT(GDE_LABEL_LITERAL), disp_len, disp_head.label); } size = LEGAL_IO_SIZE(temp_head.filesize); header = (header_struct *)malloc(size); file_read(file_ptr, size, (uchar_ptr_t)header, 1); /* Read in body of file */ table = (gd_addr *)((char *)header + SIZEOF(header_struct)); table->local_locks = (struct gd_region_struct *)((UINTPTR_T)table->local_locks + (UINTPTR_T)table); assert(table->var_maps_len == ((UINTPTR_T)table->regions - (UINTPTR_T)table->maps) - (table->n_maps * SIZEOF(gd_binding))); table->maps = (struct gd_binding_struct *)((UINTPTR_T)table->maps + (UINTPTR_T)table); table->regions = (struct gd_region_struct *)((UINTPTR_T)table->regions + (UINTPTR_T)table); table->segments = (struct gd_segment_struct *)((UINTPTR_T)table->segments + (UINTPTR_T)table); table->gblnames = (struct gd_gblname_struct *)((UINTPTR_T)table->gblnames + (UINTPTR_T)table); table->end = (table->end + (UINTPTR_T)table); n_regions = table->n_regions; for (reg = table->regions, reg_top = reg + n_regions; reg < reg_top; reg++) { t_offset = reg->dyn.offset; reg->dyn.addr = (gd_segment *)((char *)table + t_offset); # ifdef DEBUG assert((reg - table->regions) < ARRAYSIZE(isSpannedReg)); isSpannedReg[reg - table->regions] = FALSE; # endif } # ifdef DEBUG prevMapIsSpanning = FALSE; currMapIsSpanning = FALSE; gdHasSpanGbls = FALSE; # endif for (map = table->maps, map_top = map + table->n_maps; map < map_top; map++) { t_offset = map->reg.offset; map->reg.addr = (gd_region *)((char *)table + t_offset); # ifdef DEBUG currMapIsSpanning = ((map->gvname_len + 1) != map->gvkey_len); if (currMapIsSpanning) gdHasSpanGbls = TRUE; if (currMapIsSpanning || prevMapIsSpanning) isSpannedReg[map->reg.addr - table->regions] = TRUE; prevMapIsSpanning = currMapIsSpanning; # endif t_offset = map->gvkey.offset; map->gvkey.addr = (char *)table + t_offset; assert('\0' == map->gvkey.addr[map->gvname_len]); assert('\0' == map->gvkey.addr[map->gvkey_len]); assert('\0' == map->gvkey.addr[map->gvkey_len - 1]); assert((map->gvname_len + 1) <= map->gvkey_len); } # ifdef DEBUG assert(table->has_span_gbls == gdHasSpanGbls); for (reg = table->regions, reg_top = reg + n_regions; reg < reg_top; reg++) assert(reg->is_spanned == isSpannedReg[reg - table->regions]); for (gnam = table->gblnames, gnam_top = gnam + table->n_gblnames; gnam < gnam_top; gnam++) { assert(SIZEOF(gnam->gblname) == (MAX_MIDENT_LEN + 1)); assert('\0' == gnam->gblname[MAX_MIDENT_LEN]); } # endif table->link = gd_addr_head; gd_addr_head = table; fill_gd_addr_id(gd_addr_head, file_ptr); close_gd_file(file_ptr); table->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(table->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); if (table->has_span_gbls && (TREF(gd_targ_reg_array_size) < n_regions)) { array = TREF(gd_targ_reg_array); if (NULL != array) free(array); arraysize = n_regions * SIZEOF(*array); array = malloc(arraysize); memset(array, 0, arraysize); TREF(gd_targ_reg_array) = array; TREF(gd_targ_reg_array_size) = arraysize; } return table; }
gd_addr *gd_load(mstr *v) { void *file_ptr; /* This is a temporary structure as the file open and manipulations are currently stubs */ header_struct *header, temp_head; gd_addr *table, *gd_addr_ptr; gd_binding *map, *map_top; gd_region *reg, *reg_top; uint4 t_offset, size; short i; error_def(ERR_GDINVALID); file_ptr = open_gd_file(v); for (gd_addr_ptr = gd_addr_head; gd_addr_ptr; gd_addr_ptr = gd_addr_ptr->link) { /* if already open then return old structure */ if (comp_gd_addr(gd_addr_ptr, file_ptr)) { close_gd_file(file_ptr); return gd_addr_ptr; } } file_read(file_ptr, sizeof(header_struct), (uchar_ptr_t)&temp_head, 1); /* Read in header and verify is valid GD */ for (i = 0; i < GDE_LABEL_NUM; i++) { if (!memcmp(temp_head.label, gde_labels[i], GDE_LABEL_SIZE - 1)) break; } if (GDE_LABEL_NUM == i) { close_gd_file(file_ptr); rts_error(VARLSTCNT(8) ERR_GDINVALID, 6, v->len, v->addr, LEN_AND_LIT(GDE_LABEL_LITERAL), sizeof(temp_head.label), temp_head.label); } size = LEGAL_IO_SIZE(temp_head.filesize); header = (header_struct *)malloc(size); file_read(file_ptr, size, (uchar_ptr_t)header, 1); /* Read in body of file */ table = (gd_addr *)((char *)header + sizeof(header_struct)); table->local_locks = (struct gd_region_struct *)((UINTPTR_T)table->local_locks + (UINTPTR_T)table); table->maps = (struct gd_binding_struct *)((UINTPTR_T)table->maps + (UINTPTR_T)table); table->regions = (struct gd_region_struct *)((UINTPTR_T)table->regions + (UINTPTR_T)table); table->segments = (struct gd_segment_struct *)((UINTPTR_T)table->segments + (UINTPTR_T)table); table->end = (table->end + (UINTPTR_T)table); for (map = table->maps, map_top = map + table->n_maps; map < map_top; map++) { t_offset = map->reg.offset; map->reg.addr = (gd_region *)((char *)table + t_offset); } for (reg = table->regions, reg_top = reg + table->n_regions; reg < reg_top; reg++) { t_offset = reg->dyn.offset; reg->dyn.addr = (gd_segment *)((char *)table + t_offset); } table->link = gd_addr_head; gd_addr_head = table; fill_gd_addr_id(gd_addr_head, file_ptr); close_gd_file(file_ptr); table->tab_ptr = (hash_table_mname *)malloc(sizeof(hash_table_mname)); init_hashtab_mname(table->tab_ptr, 0); return table; }
short rc_fnd_file(rc_xdsid *xdsid) { gv_namehead *g; short dsid, node; gd_binding *map; char buff[1024], *cp, *cp1; mstr fpath1, fpath2; mval v; int i, keysize; int len, node2; GET_SHORT(dsid, &xdsid->dsid.value); GET_SHORT(node, &xdsid->node.value); if (!dsid_list) { /* open special database, set up entry */ dsid_list = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list)); dsid_list->dsid = RC_NSPACE_DSID; dsid_list->next = NULL; fpath1.addr = RC_NSPACE_PATH; fpath1.len = SIZEOF(RC_NSPACE_PATH); if (SS_NORMAL != TRANS_LOG_NAME(&fpath1, &fpath2, buff, SIZEOF(buff), do_sendmsg_on_log2long)) { char msg[256]; SPRINTF(msg, "Invalid DB filename, \"%s\"", fpath1.addr); gtcm_rep_err(msg, errno); return RC_BADFILESPEC; } if (fpath2.len > MAX_FN_LEN) return RC_BADFILESPEC; dsid_list->fname = (char *)malloc(fpath2.len + 1); memcpy(dsid_list->fname, fpath2.addr, fpath2.len); *((char*)(dsid_list->fname + fpath2.len)) = 0; gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region)); memset(gv_cur_region, 0, SIZEOF(gd_region)); gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment)); memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment)); memcpy(gv_cur_region->dyn.addr->fname, fpath2.addr, fpath2.len); gv_cur_region->dyn.addr->fname_len = fpath2.len; gv_cur_region->dyn.addr->acc_meth = dba_bg; ESTABLISH_RET(rc_fnd_file_ch1, RC_SUCCESS); gvcst_init(gv_cur_region); REVERT; change_reg(); /* check to see if this DB has the reserved bytes field set * correctly. Global pages must always have some extra unused * space left in them (RC_RESERVED bytes) so that the page * will fit into the client buffer when unpacked by the * client. */ if (cs_data->reserved_bytes < RC_RESERVED) { OMI_DBG((omi_debug, "Unable to access database file: \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n", fpath2.addr)); free(dsid_list->fname); dsid_list->fname = NULL; free(dsid_list); dsid_list = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } gv_keysize = DBKEYSIZE(gv_cur_region->max_key_size); GVKEY_INIT(gv_currkey, gv_keysize); GVKEY_INIT(gv_altkey, gv_keysize); cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (gv_keysize - 1)); g = cs_addrs->dir_tree; g->first_rec = (gv_key*)(g->clue.base + gv_keysize); g->last_rec = (gv_key*)(g->first_rec->base + gv_keysize); g->clue.top = g->last_rec->top = g->first_rec->top = gv_keysize; g->clue.prev = g->clue.end = 0; g->root = DIR_ROOT; dsid_list->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding)); dsid_list->gda->n_maps = 3; dsid_list->gda->n_regions = 1; dsid_list->gda->n_segments = 1; dsid_list->gda->maps = (gd_binding*)((char*)dsid_list->gda + SIZEOF(gd_addr)); dsid_list->gda->max_rec_size = gv_cur_region->max_rec_size; map = dsid_list->gda->maps; map ++; memset(map->name, 0, SIZEOF(map->name)); map->name[0] = '%'; map->reg.addr = gv_cur_region; map++; map->reg.addr = gv_cur_region; memset(map->name, -1, SIZEOF(map->name)); dsid_list->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(dsid_list->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); change_reg(); if (rc_overflow->top < cs_addrs->hdr->blk_size) { if (rc_overflow->buff) free(rc_overflow->buff); rc_overflow->top = cs_addrs->hdr->blk_size; rc_overflow->buff = (char*)malloc(rc_overflow->top); if (rc_overflow_size < rc_overflow->top) rc_overflow_size = rc_overflow->top; } } for (fdi_ptr = dsid_list; fdi_ptr && (fdi_ptr->dsid != dsid); fdi_ptr = fdi_ptr->next) ; if (!fdi_ptr) { /* need to open new database, add to list, set fdi_ptr */ gd_header = dsid_list->gda; gv_currkey->end = 0; v.mvtype = MV_STR; v.str.len = RC_NSPACE_GLOB_LEN-1; v.str.addr = RC_NSPACE_GLOB; GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str); if (!gv_target->root) /* No namespace global */ return RC_UNDEFNAMSPC; v.mvtype = MV_STR; v.str.len = SIZEOF(RC_NSPACE_DSI_SUB)-1; v.str.addr = RC_NSPACE_DSI_SUB; mval2subsc(&v,gv_currkey); node2 = node; MV_FORCE_MVAL(&v,node2); mval2subsc(&v,gv_currkey); i = dsid / 256; MV_FORCE_MVAL(&v,i); mval2subsc(&v,gv_currkey); if (gvcst_get(&v)) return RC_UNDEFNAMSPC; for (cp = v.str.addr, i = 1; i < RC_FILESPEC_PIECE; i++) for (; *cp++ != RC_FILESPEC_DELIM; ) ; for (cp1 = cp; *cp1++ != RC_FILESPEC_DELIM; ) ; cp1--; len = (int)(cp1 - cp); if (len > MAX_FN_LEN) return RC_BADFILESPEC; fdi_ptr = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list)); fdi_ptr->fname = (char *)malloc(len+1); fdi_ptr->dsid = dsid; memcpy(fdi_ptr->fname, cp, len); *(fdi_ptr->fname + (len)) = 0; gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region)); memset(gv_cur_region, 0, SIZEOF(gd_region)); gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment)); memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment)); memcpy(gv_cur_region->dyn.addr->fname, cp, len); gv_cur_region->dyn.addr->fname_len = len; gv_cur_region->dyn.addr->acc_meth = dba_bg; ESTABLISH_RET(rc_fnd_file_ch2, RC_SUCCESS); gvcst_init(gv_cur_region); REVERT; change_reg(); /* check to see if this DB has the reserved bytes field set * correctly. Global pages must always have some extra unused * space left in them (RC_RESERVED bytes) so that the page * will fit into the client buffer when unpacked by the * client. */ if (cs_data->reserved_bytes < RC_RESERVED) { OMI_DBG((omi_debug, "Unable to access database file: \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n", fdi_ptr->fname)); free(dsid_list->fname); dsid_list->fname = NULL; free(dsid_list); dsid_list = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } assert(!cs_addrs->hold_onto_crit); /* this ensures we can safely do unconditional grab_crit and rel_crit */ grab_crit(gv_cur_region); cs_data->rc_srv_cnt++; if (!cs_data->dsid) { cs_data->dsid = dsid; cs_data->rc_node = node; } else if (cs_data->dsid != dsid || cs_data->rc_node != node) { cs_data->rc_srv_cnt--; rel_crit(gv_cur_region); OMI_DBG((omi_debug, "Dataset ID/RC node mismatch")); OMI_DBG((omi_debug, "DB file: \"%s\"\n", dsid_list->fname)); OMI_DBG((omi_debug, "Stored DSID: %d\tRC Node: %d\n", cs_data->dsid, cs_data->rc_node)); OMI_DBG((omi_debug, "RC Rq DSID: %d\tRC Node: %d\n", dsid,node)); free(fdi_ptr->fname); fdi_ptr->fname = NULL; free(fdi_ptr); fdi_ptr = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } rel_crit(gv_cur_region); keysize = DBKEYSIZE(gv_cur_region->max_key_size); GVKEYSIZE_INCREASE_IF_NEEDED(keysize); cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (keysize - 1)); g = cs_addrs->dir_tree; g->first_rec = (gv_key*)(g->clue.base + keysize); g->last_rec = (gv_key*)(g->first_rec->base + keysize); g->clue.top = g->last_rec->top = g->first_rec->top = keysize; g->clue.prev = g->clue.end = 0; g->root = DIR_ROOT; fdi_ptr->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding)); fdi_ptr->gda->n_maps = 3; fdi_ptr->gda->n_regions = 1; fdi_ptr->gda->n_segments = 1; fdi_ptr->gda->maps = (gd_binding*)((char*)fdi_ptr->gda + SIZEOF(gd_addr)); fdi_ptr->gda->max_rec_size = gv_cur_region->max_rec_size; map = fdi_ptr->gda->maps; map ++; memset(map->name, 0, SIZEOF(map->name)); map->name[0] = '%'; map->reg.addr = gv_cur_region; map++; map->reg.addr = gv_cur_region; memset(map->name, -1, SIZEOF(map->name)); fdi_ptr->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(fdi_ptr->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); fdi_ptr->next = dsid_list->next; dsid_list->next = fdi_ptr; } gv_cur_region = fdi_ptr->gda->maps[1].reg.addr; change_reg(); if (rc_overflow->top < cs_addrs->hdr->blk_size) { if (rc_overflow->buff) free(rc_overflow->buff); rc_overflow->top = cs_addrs->hdr->blk_size; rc_overflow->buff = (char*)malloc(rc_overflow->top); if (rc_overflow_size < rc_overflow->top) rc_overflow_size = rc_overflow->top; } if (!rc_overflow -> top) { rc_overflow -> top = rc_overflow_size; rc_overflow->buff = (char *)malloc(rc_overflow->top); } gd_header = fdi_ptr->gda; return RC_SUCCESS; }