/*{ ** Name: CS_destroy_serv_segment() - Destroy the server segment. ** ** Description: ** Destroy the server shared memory segment. This should be called when ** server is shut down (ie. should be put into the last chance exception ** handler of CS). ** ** Eventually the abnormal exit code must take care of cleaning up this ** shared memory segment. ** ** This call is internal to CS is meant only to be called by CS, and may ** only exist on unix systems supporting shared memory. ** ** Inputs: ** id id of server segment. ** ** Outputs: ** address on success, set to point to segment ** err_code system dependent error information. ** ** Returns: ** E_DB_OK ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 08-sep-88 (mmm) ** First Version ** 12-jun-89 (rogerk) ** Changed MEsmdestroy to take character memory key, not LOCATION ptr. */ STATUS CS_destroy_serv_segment(u_i4 serv_seg_num, CL_ERR_DESC *err_code) { STATUS status = OK; char segname[48]; STcopy("server.", segname); CVna((i4)serv_seg_num, segname+STlength(segname)); #ifdef xCL_NEED_SEM_CLEANUP CS_cp_sem_cleanup(segname,err_code); #endif status = MEsmdestroy(segname, err_code); if (status) { /* Unable to attach allocated shared memory segment. */ status = FAIL; } Cs_sm_cb->css_servinfo[serv_seg_num].csi_in_use = FALSE; /* FIX ME - probably add code to update system control stuctures to ** keep track of when a shared memory segment is mapped. */ return(status); }
static void formatXID( IIAPI_XA_DIS_TRAN_ID *xid, char *str ) { u_i4 count, val; u_i1 *data; CVlx( xid->xa_tranID.xt_formatID, str ); str += STlength( str ); *(str++) = ':'; CVla( xid->xa_tranID.xt_gtridLength, str ); str += STlength( str ); *(str++) = ':'; CVla( xid->xa_tranID.xt_bqualLength, str ); str += STlength( str ); data = (u_i1 *)xid->xa_tranID.xt_data; count = (xid->xa_tranID.xt_gtridLength + xid->xa_tranID.xt_bqualLength + sizeof( i4 ) - 1) / sizeof( i4 ); while( count-- ) { val = (*data << 24) | (*(data+1) << 16) | (*(data+2) << 8) | *(data+3); data+= 4; *(str++) = ':'; CVlx( val, str ); str += STlength( str ); } STcat( str, ERx( ":XA" ) ); str += STlength( str ); *(str++) = ':'; CVna( xid->xa_branchSeqnum, str ); str += STlength( str ); *(str++) = ':'; CVna( xid->xa_branchFlag, str ); str += STlength( str ); STcat( str, ERx( ":EX" ) ); return; }
FUNC_EXTERN DB_STATUS IICXcreate_icas_xn_cb( IICX_ID *cx_id, /* IN */ IICX_CB **cx_cb_p_p /* OUT */ ) { DB_STATUS db_status; STATUS cl_status; char ebuf[20]; IICX_ICAS_XN_CB *icas_xn_cb_p; i4 i; /* LOCK the ICAS XN MAIN CB. CHECK !!! */ if (IIcx_icas_xn_main_cb->num_free_icas_xn_cbs > 0) { *cx_cb_p_p = IIcx_icas_xn_main_cb->icas_xn_cb_free_list; IIcx_icas_xn_main_cb->icas_xn_cb_free_list = (*cx_cb_p_p)->cx_next; if ((*cx_cb_p_p)->cx_next != NULL) (*cx_cb_p_p)->cx_next->cx_prev = (*cx_cb_p_p)->cx_prev; IIcx_icas_xn_main_cb->num_free_icas_xn_cbs--; } if (*cx_cb_p_p != NULL) { /* UNLOCK the ICAS XN Main CB. CHECK !!! */ return( E_DB_OK ); } /* UNLOCK the ICAS XN Main CB. CHECK !!! */ /* No free ICAS XN CBs. Create one if appropriate */ db_status = IICXget_new_cx_cb( cx_cb_p_p ); if (DB_FAILURE_MACRO(db_status)) { return(db_status); } if ((icas_xn_cb_p = (IICX_ICAS_XN_CB *)MEreqmem((u_i4)0, (u_i4)sizeof(IICX_ICAS_XN_CB), TRUE, (STATUS *)&cl_status)) == NULL) { CVna((i4)cl_status, ebuf); IICXerror(GE_NO_RESOURCE, E_CX0002_CX_CB_ALLOC, 2, ebuf, ERx("IICX_ICAS_XN_CB")); return( E_DB_FATAL ); } (*cx_cb_p_p)->cx_sub_cb.icas_xn_cb_p = icas_xn_cb_p; return( E_DB_OK ); } /* IICXcreate_icas_xn_cb */
DB_STATUS IICXfree_icas_xn_cb( IICX_ICAS_XN_CB *icas_xn_cb_p /* IN */ ) { STATUS cl_status; char ebuf[20]; if ((cl_status = MEfree( (PTR)icas_xn_cb_p )) != OK) { CVna((i4)cl_status, ebuf); IICXerror(GE_LOGICAL_ERROR, E_CX0003_CX_CB_FREE, 2, ebuf, ERx("IIcx_icas_xn_cb")); return( E_DB_FATAL ); } return( E_DB_OK ); } /* IICXfree_icas_xn_cb */
STATUS IILQasAdfcbSetup( II_THR_CB *thr_cb ) { II_LBQ_CB *IIlbqcb = thr_cb->ii_th_session; II_LBQ_CB *def = &thr_cb->ii_th_defsess; /* ** Setup the static ADF CB. */ /* ??? Semaphore protect adf_cb/FEadfcb() */ if ( ! adf_cb && ! (adf_cb = FEadfcb()) ) { IIlocerr(GE_NO_RESOURCE, E_LQ0003_ADFINIT, II_ERR, 0, (char *)0); return FAIL; } /* ** Default sessions use the static ADF CB. */ if ( ! def->ii_lq_adf ) def->ii_lq_adf = adf_cb; /* ** Real sessions receive their own copy of the ADF CB. */ if ( ! IIlbqcb->ii_lq_adf ) { if ((IIlbqcb->ii_lq_adf = (ADF_CB *)MEreqmem((u_i4)0, (u_i4)sizeof(ADF_CB), TRUE, (STATUS *) NULL)) == NULL) { char ebuf[10]; CVna(IIlbqcb->ii_lq_sid, ebuf); IIlocerr(GE_NO_RESOURCE, E_LQ00E8_ADFALLOC, II_ERR, 1, ebuf); return FAIL; } /* Fill with the default values of the static ADF control block */ MEcopy((PTR)def->ii_lq_adf, (u_i2)sizeof(ADF_CB), (PTR)IIlbqcb->ii_lq_adf); } return OK; }
/*{ ** Name: CS_map_serv_segment() - Map the server segment. ** ** Description: ** Maps the server control block to this process. ** ** Upon successful exectution of this routine the process may access ** memory shared among server and slave processes. ** ** This call is internal to CS is meant only to be called by CS, and may ** only exist on unix systems supporting shared memory. ** ** Inputs: ** serv_seg_num id of server segment. ** ** Outputs: ** address on success, set to point to segment ** err_code system dependent error information. ** ** Returns: ** E_DB_OK ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 08-sep-88 (mmm) ** First Version ** 12-jun-89 (rogerk) ** Added allocated_pages argument to MEget_pages calls. ** Changed shared memory key to a character string rather than a ** LOCATION pointer. ** 26-aug-89 (rexl) ** Added calls to protect page allocator. */ STATUS CS_map_serv_segment(u_i4 serv_seg_num, PTR *address, CL_ERR_DESC *err_code) { STATUS status = OK; char segname[48]; SIZE_TYPE alloc_pages; if (!address) { SETCLERR(err_code, 0, 0); status = FAIL; } else { # ifdef SERV_MAP_ADDR *address = (PTR) SERV_MAP_ADDR; # else *address = (PTR) 0; # endif /* SERV_MAP_ADDR */ Cs_svinfo = &Cs_sm_cb->css_servinfo[serv_seg_num]; STcopy("server.", segname); CVna((i4)serv_seg_num, segname+STlength(segname)); # ifdef SERV_MAP_ADDR status = MEget_pages(ME_SSHARED_MASK|ME_ADDR_SPEC, 0, segname, address, &alloc_pages, err_code); # else status = MEget_pages(ME_SSHARED_MASK, 0, segname, address, &alloc_pages, err_code); # endif /* SERV_MAP_ADDR */ if (status) { /* Unable to attach allocated shared memory segment. */ status = FAIL; } } return(status); }
/*{ ** Name: CS_des_installation() - destroy shared resources of an installation. ** ** Description: ** Destroy the system shared memory segment, the logging/locking ** shared memory segment, and the system semaphores associated with the ** current installtion. This is called from the logging code as a ** result of "rcpconfig /shutdown". ** ** It assumes that all the shared memory segments have already been ** initialized by the appropriate routines. The order of destruction ** is important as a reverse may cause access violations on some ** implementation of shared memory (where the segment disappears as ** soon as it destroyed). ** ** Any subsequent logging/locking or event routines called after this ** routine will likely fail, so the caller should exit soon after this ** call. ** ** Inputs: ** none. ** ** Outputs: ** none. ** ** ** History: ** 08-sep-88 (anton) ** use LOcations for segments and destroy server segments ** 09-jun-88 (mmm) ** written. ** 12-jun-89 (rogerk) ** Change MEsmdestroy calls to take character string key instead ** of LOCATION pointer. ** 22-dec-92 (mikem) ** Changed a for(;;) to a do..while(FALSE) to shut up stupid acc ** warning. ** 02-feb-92 (sweeney) ** remove orphaned call to MEsmdestroy() on lockseg. ** 26-jul-1993 (bryanp) ** Remove no-longer-needed system semaphores (css_semid sems). ** 03-jun-1996 (canor01) ** Clean up semaphores for operating system threads. ** 16-sep-2002 (somsa01) ** Make sure we run the appropriate "cscleanup" in the case of ** ADD_ON64. ** 22-Jun-2009 (kschendel) SIR 122138 ** VMS doesn't do hybrids, but update the conditional anyway. */ STATUS CS_des_installation(void) { STATUS status; LOCATION loc; char *string; PID pid; char *argv[1]; CL_ERR_DESC err_code; i4 i; char segname[48]; /* stop all servers that are still active, forcing them to exit if ** they have not already exited. */ /* call the cscleanup code to clean up all the server slots still out ** there. */ if ((NMloc(SUBDIR, PATH, "utility", &loc) == OK) && #if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH64) (LOfaddpath(&loc, "lp64", &loc) == OK) && #endif (LOfstfile("cscleanup", &loc) == OK)) { /* if everything is successful try and run the cleanup program, ** else just do the rest and make user run "cscleanup" by themselves. */ LOtos(&loc, &string); argv[0] = string; PCspawn(1, argv, TRUE, (LOCATION *) NULL, (LOCATION *) NULL, &pid); } do { /* destroy any left over server segements */ for (i = 0; i < MAXSERVERS; i++) { STcopy("server.", segname); CVna(i, segname+STlength(segname)); #ifdef xCL_NEED_SEM_CLEANUP CS_cp_sem_cleanup(segname, &err_code); #endif (VOID) MEsmdestroy(segname, &err_code); } /* FIX ME */ /* kill off slave processes here or in cscleanup code */ /* destroy the system shared memory segment */ #ifdef xCL_NEED_SEM_CLEANUP CS_cp_sem_cleanup("sysseg.mem", &err_code); #endif status = MEsmdestroy("sysseg.mem", &err_code); if (status) break; } while (FALSE); return(status); }
/*{ ** Name: CS_alloc_serv_segment() - Create shared memory for a server ** ** Description: ** Allocate a shared memory segment of "size" bytes. All data placed ** in this segment should be position independent. ** ** Upon success this function will create the shared memory segment with ** the given id and size. To actually access the shared memory segment ** the user must make a CS_map_server_segment() call. It is expected ** that this single request will fulfill all shared memory needs particular ** to a single server. It may be difficult or impossible to extend the ** shared memory resources of some machines to provide for more than 3 ** different shared memory segments mapped to a single process (the ** control segment, the locking/logging segment, and the server segment). ** ** It is expected that CS will call CS_alloc_serv_segment() and ** CS_map_serv_segment() once at server initialization. ** Slaves will only call the map function. ** ** This call is internal to CS is meant only to be called by CS, and may ** only exist on unix systems supporting shared memory. ** ** Inputs: ** size size in bytes of shared mem segment. ** ** Outputs: ** id on success set to id of segment. ** err_code system dependent error code. ** ** Returns: ** E_DB_OK ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 08-sep-88 (mmm) ** First Version ** 12-jun-89 (rogerk) ** Changed arguments to MEget_pages, MEdetach calls. They now use ** character name keys rather than a LOCATION pointer. Changed ** ME_loctokey call to ME_getkey. ** 26-aug-89 (rexl) ** Added calls to protect page allocator. ** 3-jul-1992 (bryanp) ** Explicitly ACLR the TAS objects when allocating server segment. ** 07-nov-1996 (canor01) ** Explicitly initialize the csi_spinlock object. */ STATUS CS_alloc_serv_segment(SIZE_TYPE size, u_i4 *server_seg_num, PTR *address, CL_ERR_DESC *err_code) { STATUS status = OK; CS_SERV_INFO *serv_info; PTR dummy; i4 i; SIZE_TYPE alloc_pages; char segname[48]; status = CS_find_server_slot(&i); serv_info = Cs_sm_cb->css_servinfo; if (!address) { address = &dummy; } if (status) { SETCLERR(err_code, 0, 0); /* since find_server_slot doesn't set */ } else { /* now allocate and initialize the server segment */ STcopy("server.", segname); CVna(i, segname+STlength(segname)); size = (size + ME_MPAGESIZE - 1) & ~ (ME_MPAGESIZE - 1); # ifdef SERV_MAP_ADDR *address = (PTR) SERV_MAP_ADDR; status = MEget_pages(ME_MZERO_MASK|ME_SSHARED_MASK|ME_CREATE_MASK| ME_ADDR_SPEC, size/ME_MPAGESIZE, segname, address, &alloc_pages, err_code); # else status = MEget_pages(ME_MZERO_MASK|ME_SSHARED_MASK|ME_CREATE_MASK, size/ME_MPAGESIZE, segname, address, &alloc_pages, err_code); # endif if (status) { /* Unable to create lg/lk shared memory segment */ status = FAIL; } else { /* initialize it's description in the master control block */ Cs_svinfo->csi_serv_desc.cssm_size = size; Cs_svinfo->csi_serv_desc.cssm_id = ME_getkey(segname); *server_seg_num = i; /* ** Explicitly clear these TAS objects, for machines such as the HP ** where MEfill'ing the memory with zeros does not initialize the ** TAS objects to "clear" state. */ CS_ACLR(&Cs_svinfo->csi_nullev); CS_ACLR(&Cs_svinfo->csi_events_outstanding); CS_ACLR(&Cs_svinfo->csi_wakeme); CS_SPININIT(&Cs_svinfo->csi_spinlock); for (i = 0; i < (sizeof(Cs_svinfo->csi_subwake) / sizeof(Cs_svinfo->csi_subwake[0])); i++) { CS_ACLR(&Cs_svinfo->csi_subwake[i]); } if (address == &dummy) MEdetach(segname, address, err_code); /* and free pages */ /* FIX ME - bunch of other stuff */ } } return(status); }
/*{ ** Name: CK_subst - build a CK command from template and requirements ** ** Description: ** This function will search a CK command template file for ** a line meeting the requirements of the inputs and will substitute ** various esacpe sequences with other strings such as file names. ** ** Based on a II_subst of the 5.0 UNIX CL. ** ** Inputs: ** comlen length of cline space ** oper operation - one of 'B'egin, 'E'nd, 'W'ork ** dev device type - one of 'T'ape, 'D'isk ** dir direction - one of 'S'ave, 'R'estore ** type type (device type) 0 for disk, 1 for tape ** locnum location number (sequence or quantity) ** di_l_path length of di path string ** di_path di path string ** ckp_l_path length of checkpoint path string ** ckp_path checkpoint path string ** ckp_l_file length of checkpoint file string ** ckp_file checkpoint file string ** ** Outputs: ** cline space for generated command ** ** Returns: ** CK_FILENOTFOUND template file can't be found ** E_DB_OK ** ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 27-oct-88 (anton) ** Created. ** 16-may-90 (walt) ** Return CK_FILENOTFOUND if the template file (cktmpl.def) can't ** be opened. ** 23-may-1994 (bryanp) ** Modified Walt's 16-may-90 fix to use CK_TEMPLATE_MISSING, rather ** than CK_FILENOTFOUND, since CK_TEMPLATE_MISSING is a more ** specific, and therefore hopefully more useful, error message. ** 03-jan-1995 (dougb) ** Cross-integrate Unix change 415365: ** 02-dec-1994 (andyw) ** Check on granularity for partial backup */ STATUS CK_subst( char *cline, i4 comlen, char oper, char dev, char dir, u_i4 type, u_i4 locnum, u_i4 di_l_path, char *di_path, u_i4 ckp_l_path, char *ckp_path, u_i4 ckp_l_file, char *ckp_file) { STATUS ret_val = OK; auto LOCATION loc; auto char *s; auto FILE *fp; auto char *cp; char *command; command = MEreqmem(0, comlen, TRUE, &ret_val); if (!ret_val) { NMgtAt("II_CKTMPL_FILE", &s); if (s == NULL || *s == EOS) { ret_val = NMf_open("r", "cktmpl.def", &fp); } else { LOfroms( PATH & FILENAME, s, &loc ); ret_val = SIopen( &loc, "r", &fp); } if (ret_val) { ret_val = CK_TEMPLATE_MISSING; } } /* find command line - skip comments and blank lines */ if (!ret_val) { while ((ret_val = SIgetrec(command, comlen, fp)) == OK) { if (*command == '\n') { continue; } if (command[0] == oper && (command[1] == dir || command[1] == 'E') && (command[2] == dev || command[2] == 'E') && (command[3] == 'D' || command[3] == 'E') && command[4] == ':') { break; } } } _VOID_ SIclose(fp); if (!ret_val) { /* found the line - do the substitution */ s = command + 5; cp = cline; while (*s != '\n') { if (*s == '%') { switch (*++s) { case '%': *cp++ = '%'; break; case 'D': CK_lfill(&cp, di_l_path, di_path); break; case 'C': CK_lfill(&cp, ckp_l_path, ckp_path); break; case 'F': CK_lfill(&cp, ckp_l_file, ckp_file); break; case 'A': CK_lfill(&cp, ckp_l_path, ckp_path); # ifdef UNIX *cp++ = '/'; # endif CK_lfill(&cp, ckp_l_file, ckp_file); break; case 'T': *cp++ = type ? '1' : '0'; break; case 'N': CVna(locnum, cp); while (*cp) cp++; break; default: *cp++ = '%'; *cp++ = *s; } ++s; } else { *cp++ = *s++; } } *cp = EOS; } # ifdef xDEBUG TRdisplay("CK_subst %c %c %c: %s\n", oper, dir, dev, cline); # endif return(ret_val); }
/*{ ** Name: TMstamp_str - Convert a stamp to a string. ** ** Description: ** Convert a stamp to a string of the form: ** dd-mmm-yyyy hh:mm:ss.cc ** Note, this routine is for the sole use of DMF for ** auditing and rollforward. ** ** Inputs: ** time Pointer to timestamp. ** ** Outputs: ** string Pointer to output string. ** Must be TM_SIZE_STAMP bytes long. ** Returns: ** void ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 20-jan-1987 (Derek) ** Created. */ void TMstamp_str( TM_STAMP *time, char *string) { struct TMhuman human; SYSTIME tm; i4 csecs; char csecs_str[10]; /* initialize the SYSTIME */ tm.TM_secs = time->tms_sec; tm.TM_msecs = time->tms_usec / MICRO_PER_MILLI; if (TMbreak(&tm, &human) == OK) { /* Now format correctly "dd-mmm-yyyy hh:mm:ss.cc" */ /* dd- */ if (human.day[0] == ' ') *string++ = '0'; else *string++ = human.day[0]; *string++ = human.day[1]; *string++ = '-'; /* mmm- */ *string++ = human.month[0]; *string++ = human.month[1]; *string++ = human.month[2]; *string++ = '-'; /* yyyy- */ *string++ = human.year[0]; *string++ = human.year[1]; *string++ = human.year[2]; *string++ = human.year[3]; *string++ = ' '; /* hh: */ *string++ = human.hour[0]; *string++ = human.hour[1]; *string++ = ':'; /* mm: */ *string++ = human.mins[0]; *string++ = human.mins[1]; *string++ = ':'; /* ss. */ *string++ = human.sec[0]; *string++ = human.sec[1]; *string++ = '.'; /* cc */ /* print out 100th of second from internally stored microsecond */ csecs = (time->tms_usec / 10000); CVna(csecs, csecs_str); if (csecs <= 9) { *string++ = '0'; *string++ = csecs_str[0]; } else { *string++ = csecs_str[0]; *string++ = csecs_str[1]; } *string++ = '\0'; } else { /* For some reason one of the conversions failed. Since this ** routine is currently spec'd as returning void - the best we ** can do is return a bogus string. */ STcopy("dd-mmm-yyyy hh:mm:ss.cc", string); } return; }