Пример #1
0
/*{
** Name: PSF_SESSCB	- get session control block.
**
** Description:
**      Get the session control block from SCF. 
**
** Inputs:
**	none
**
** Outputs:
**	Returns:
**          sess_cb                     session control block ptr
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**      8-oct-86 (daved)
**          written
**	14-jul-93 (ed)
**	    replacing <dbms.h> by <gl.h> <sl.h> <iicommon.h> <dbdbms.h>
**	10-aug-93 (andre)
**	    removed declaration of scf_call()
**	08-sep-93 (swm)
**	    Changed sizeof(DB_SESSID) to sizeof(CS_SID) to reflect recent CL
**	    interface revision.
**	10-Jan-2001 (jenjo02)
**	    Use (new) GET_PSS_SESBLK macro instead of
**	    scf_call(SCU_INFORMATION) to return session's
**	    PSS_SESBLK*.
[@history_line@]...
[@history_template@]...
*/
PSS_SESBLK*
psf_sesscb(void)
{
    CS_SID	sid;

    CSget_sid(&sid);
    return(GET_PSS_SESBLK(sid));
}
Пример #2
0
/*
**  Name: AllocConn      - Allocate a new connection block
**
**  Description:
**      Allocate a piece of ME storage to hold the new CM_CONN_BLK
**
**  Inputs:
**      conn_db		- DataBase handle
**	conn_userid	- Userid handle
**	conn_hndl	_ Connection handle
**
**  Outputs:
**
**  Returns:
**      The addr(Connection entry)
**
**  History:
**      27-Feb-98 (shero03)
**          Created.
*/
P_CM_CONN_BLK ccm_AllocConn(i4  conn_id, i4  conn_flag,
		   	PTR conn_DB, PTR conn_Userid, PTR conn_hndl)
{
    CM_CONN_BLK	*entry;

    entry = (CM_CONN_BLK *)HSH_AllocEntry(pCM_cb->cm_used_conn_index,
    					 NULL, 0, sizeof(CM_CONN_BLK));
    if (entry)
    {
        entry->cm_conn_id = conn_id;         /* initialize the ID field     */
        if (pCM_cb->cm_flags & CM_FLAG_MULTITHREADED)
            CSget_sid(&entry->cm_conn_SID);      /* Fill in the SID         */
        else
            entry->cm_conn_SID = 1;
        entry->cm_conn_flags = conn_flag;
        entry->cm_conn_DB = conn_DB;         /* Fill in the DB handle       */
        entry->cm_conn_User = conn_Userid;   /* Fill in the Userid Handle   */
        entry->cm_conn_hndl = conn_hndl;     /* Fill in the Conn Handle     */
    }

    return entry;			/* return the addr(new entry)	     */
}		/* proc - AllocConn */
Пример #3
0
/*{
** Name: rdt_clear_cache - Clear RDf cache
**
** Description:
**      This function causes one or more RDF cache(s) to be cleared, as follows:
**	    Trace Point:	    Caches Cleared:
**	        rd1		    RELcache
**		rd2		    RELcache, QTREE cache
**		rd3		    LDBdesc cache
**		rd4		    LDBdesc cache, RELcache, QTREE cache
**		rd5		    Defaults Cache
**		rd10		    ALL RDF CACHES
**
** Inputs:
**	trace_pt			value of trace point.
** Outputs:
**	none
**
**	Returns:
**	    E_DB_OK			Function completed normally.
**	    E_DB_ERROR			Function failed due to error by caller;
**	    E_DB_FATAL			Function failed due to some internal
**					problem; 
**	Exceptions:
**		none
**
** Side Effects:
**	none.
**
** History:
**	 (teresa)
**	    Initial creation -- the original subroutine header section seems
**	    to have gotten lost, so recreated today (7-jan-91)
**	07-jan-91 (teresa)
**	    Fix AV caused by uninitialized rdr_types_mask and rdr_2types_mask.
**	    (bug 41956)
**	23-Jan-92 (teresa)
**	    SYBIL:  change criter for QTREE invalidation from rdi_qthash (which
**		    is no longer in the structure to setting facility ID to
**		    PSF to invalidate QTREE hash.
**	16-jul-92 (teresa)
**	    prototypes
**	16-sep-92 (teresa)
**	    modify to take trace_pt as argument and handle trace points 3 and 4.
**	07-Mar-2001 (jenjo02)
**	    Supply session id to rdf_invalidate in RDF_CB.
**	13-May-2009 (kschendel) b122041
**	    Compiler warning fixes.
*/
DB_STATUS
rdt_clear_cache(i4	    trace_pt)
{
    RDF_GLOBAL	    global;
    RDF_CB	    rdfcb;
    RDI_FCB	    fcb;
    DB_STATUS	    status;

    global.rdfcb = &rdfcb;

    rdfcb.rdf_rb.rdr_fcb = (PTR ) &fcb;
    rdfcb.rdf_info_blk = NULL;
    rdfcb.rdf_rb.rdr_db_id = NULL;
    rdfcb.rdf_rb.rdr_types_mask = 0;
    rdfcb.rdf_rb.rdr_2types_mask = 0;
    CSget_sid(&rdfcb.rdf_rb.rdr_session_id);

/* trace
** point   cache	    action (call rdf_invalidate with )
** ------  ---------    ---------------------
** RD0001  RELcache	rdi_fac_id = DB_RDF_ID, rdr_2types_mask = 0
** RD0002  RELcache &	
**          QTREE	rdi_fac_id = DB_PSF_ID, rdr_2types_mask = 0
** RD0003  LDBdesc	rdr_2types_mask = RDR2_INVL_LDBDESC
** RD0004  rel,QTREE,   rdi_fac_id=DB_PSF_ID, then call a second time with
**	    LDBdesc	rdr_2types_mask=RDR2_INVL_LDBDESC
** RD0005  Defaults	rdi_fac_id=DB_RDF_ID, rdr_2types_mask=RDR2_INVL_DEFAULT
** RD0010  ALL		Three calls:  
**			1 rdi_fac_id=DB_RDF_ID,rdr_2types_mask=RDR2_INVL_LDBDESC
**			2 rdi_fac_id=DB_RDF_ID,rdr_2types_mask=RDR2_INVL_DEFAULT
**			3 rdi_fac_id=DB_PSF_ID,rdr_2types_mask = 0
*/

    switch (trace_pt)
    {
    case RD0001:
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_RDF_ID;
	status = rdf_invalidate(&global, &rdfcb);
	break;
    case RD0002:
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_PSF_ID;
	status = rdf_invalidate(&global, &rdfcb);
	break;
    case RD0003:
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_RDF_ID;
	rdfcb.rdf_rb.rdr_2types_mask = RDR2_INVL_LDBDESC;
	status = rdf_invalidate(&global, &rdfcb);
	break;
    case RD0004:
	/* invalidate LDBdesc cache first, then RELcache and QTREE cache */
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_RDF_ID;
	rdfcb.rdf_rb.rdr_2types_mask = RDR2_INVL_LDBDESC;
	status = rdf_invalidate(&global, &rdfcb);	    /* LDBdesc cache */
	if (status != E_DB_OK)
	    break;
	rdfcb.rdf_rb.rdr_2types_mask = 0;
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_PSF_ID;
	status = rdf_invalidate(&global, &rdfcb);	    /* RELcache, QTREE*/
	break;
    case RD0005:
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_RDF_ID;
	rdfcb.rdf_rb.rdr_2types_mask = RDR2_INVL_DEFAULT;
	status = rdf_invalidate(&global, &rdfcb);
	break;
    case RD0010:
	/* invalidate LDBdesc cache first, then default cache, then
	** RELcache and QTREE cache 
	*/
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_RDF_ID;
	rdfcb.rdf_rb.rdr_2types_mask = RDR2_INVL_LDBDESC;
	status = rdf_invalidate(&global, &rdfcb);	    /* LDBdesc cache */
	if (status != E_DB_OK)
	    break;
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_RDF_ID;
	rdfcb.rdf_rb.rdr_2types_mask = RDR2_INVL_DEFAULT;
	status = rdf_invalidate(&global, &rdfcb);	    /* Default cache */
	if (status != E_DB_OK)
	    break;
	fcb.rdi_fac_id = fcb.rdi_fac_id = DB_PSF_ID;
	rdfcb.rdf_rb.rdr_2types_mask = 0;
	status = rdf_invalidate(&global, &rdfcb);	    /* RELcache, QTREE*/
	break;
    default:
	/* do nothing if trace_pt is an unexpected value */
	break;
    }    
    return status;
}
Пример #4
0
/*{
** Name: rdf_trace - Call RDF trace operation.
**
**	External call format:	status = rdf_trace(&db_debug_cb)
**
** Description:
**      This function is the standard entry point to RDF for setting and
**	clearing tracepoints(the "set trace point" command). Because RDF 
**	is a service facility, trace point for RDF can only be set on 
**	the server basis. There is no session level trace point. 
**	Db_debug_cb is the tracing control block that contains the trace 
**	flag information.
**
**	See file <rdftrace.h> for a description of all possible
**	RDF trace points.
**	
** Inputs:
**      debug_cb		    Pointer to a DB_DEBUG_CB
**        .db_trswitch              What operation to perform
**	    DB_TR_NOCHANGE	    None
**	    DB_TR_ON		    Turn on a tracepoint
**	    DB_TR_OFF		    Turn off a tracepoint
**	  .db_trace_point	    Trace point ID(the flag number)
**	  .db_value_count	    The number of values specified in
**				    the value array
**	  .db_vals[2]		    Optional values, to be interpreted
**				    differently for each tracepoint
** Outputs:
**	none
**
**	Returns:
**	    E_DB_OK			Function completed normally.
**	    E_DB_ERROR			Function failed due to error by caller;
**	    E_DB_FATAL			Function failed due to some internal
**					problem; 
**	Exceptions:
**		none
**
** Side Effects:
**	The trace vector in the server control block of RDF will be updated
**	to contain the trace information. The trace information will be persist
**	throughout the life of the server.
**
** History:
**	15-apr-86 (ac)
**          written
**	02-mar-87 (puree)
**	    replace global server control block with global pointer.
**	14-dec-1989 (teg)
**	    modify to go get svcb from SCF instead of using a global pointer
**	    to it.
**	16-jul-92 (teresa)
**	    prototypes
**	16-sep-92 (teresa)
**	    implement trace points rd3 and rd4 to clear ldbdesc cache.
**	22-apr-94 (teresa)
**	    added trace points rd11 and rd12 to dump memory statistics or all
**	    statistics.  This is an action trace point -- the dump occurs when 
**	    the trace point is selected rather than during query execution.
**	20-nov-2007 (thaju02)
**	    If trace point RD0022/RDU_CHECKSUM specified, invalidate 
**	    relcache. Entries need rdr_checksum to be calc/init'd 
**	    otherwise E_RD010D errors may be reported. (B119499)
*/
DB_STATUS
rdf_trace(DB_DEBUG_CB *debug_cb)
{
    i4		flag;
    i4		firstval;
    i4		secondval;
    DB_STATUS		status;
    i4		trace_scope;

    /* assure flag is legal */
    flag = debug_cb->db_trace_point;
    if (flag >= RDF_NB)
    {
	return (E_DB_ERROR);
    }

    /* There can be UP TO two values, but maybe they weren't given */
    firstval = (debug_cb->db_value_count > 0) ? debug_cb->db_vals[0] : 0L;
    secondval = (debug_cb->db_value_count > 1) ? debug_cb->db_vals[1] : 0L;

    /* see if this is an action trace.  Action traces require an immediate
    ** action rather than turning trace flags on/off/etc.
    */
    if ( (debug_cb->db_trswitch==DB_TR_ON) && (flag <= RD_ACT_MAX) )
    {
	/* see which action is requested.  Not all actions are implemented
	** yet, so its possible that this call may  become a no-opt 
	*/
	switch (flag)
	{
	case RD0001:
	case RD0002:
	case RD0003:
	case RD0004:
	case RD0005:
	case RD0010:
	    status=rdt_clear_cache(flag);
	    if (DB_FAILURE_MACRO(status))
	    {
		return(E_DB_ERROR);
	    }
	    break;
	case RD0011:
	    /* dump memory info.  This trace is used by tech support when
	    ** debugging out of memory errors. */
	    TRdisplay("\n...............................................\n");
	    TRdisplay("RDF Cache Memory Available:   %d\n",Rdi_svcb->rdv_memleft);
	    TRdisplay("RDF memory cache size     :   %d\n", 
			Rdi_svcb->rdv_pool_size);
	    TRdisplay("Max number of objects allowed on Cache:\n");
	    TRdisplay("   RELcache: %d,	    QTREE Cache: %d, \n",
			Rdi_svcb->rdv_cnt0_rdesc, Rdi_svcb->rdv_cnt1_qtree);
	    TRdisplay("   LDBDesc Cache %d,   DEFAULTS cache: %d\n",
			Rdi_svcb->rdv_cnt2_dist, Rdi_svcb->rdv_cnt3_default);
	    TRdisplay("Hashids:\n");
	    TRdisplay("   RELcache: %d,	    QTREE Cache: %d, \n",
			Rdi_svcb->rdv_rdesc_hashid, Rdi_svcb->rdv_qtree_hashid);
	    TRdisplay("   LDBDesc Cache %d,   DEFAULTS cache: %d\n",
			Rdi_svcb->rdv_dist_hashid, Rdi_svcb->rdv_def_hashid);
	    TRdisplay("...............................................\n");
	    break;
	case RD0012:
	    /* dump all of the RDF statistics */
	    rdf_report ( &Rdi_svcb->rdvstat );
	    break;

	    default:
		break;

	}
    }
    else
    {

	/*
	** determine if this is a session wide trace or a server wide trace
	** and process accordingly
	*/
	trace_scope = trace_type(flag);
	if (trace_scope == SVR_WIDE_TRACE)
	{   
	    /* turn trace on in svcb
	    **
	    ** Three possible actions: Turn on flag, turn it off, or do nothing.
	    */
	    switch (debug_cb->db_trswitch)
	    {
	    case DB_TR_ON:
		    if ((flag == RD0022) && 
			!(ult_check_macro(&Rdi_svcb->rdf_trace, 
					flag, &firstval, &secondval)))
		    {
			    /* setting RDU_CHECKSUM */
			    RDF_GLOBAL      global;
			    RDF_CB          rdfcb;
			    RDI_FCB         fcb;

			    global.rdfcb = &rdfcb;
			    rdfcb.rdf_rb.rdr_fcb = (PTR)&fcb;
			    rdfcb.rdf_info_blk = NULL;
			    rdfcb.rdf_rb.rdr_db_id = NULL;
			    rdfcb.rdf_rb.rdr_types_mask = 0;
			    rdfcb.rdf_rb.rdr_2types_mask = 0;
			    CSget_sid(&rdfcb.rdf_rb.rdr_session_id);
			    fcb.rdi_fac_id = DB_RDF_ID;
			    status = rdf_invalidate(&global, &rdfcb);
			    if (DB_FAILURE_MACRO(status))
				return(E_DB_ERROR);
		    }
		    ult_set_macro(&Rdi_svcb->rdf_trace, flag, firstval, secondval);
		break;

	    case DB_TR_OFF:
		    ult_clear_macro(&Rdi_svcb->rdf_trace, flag);
		break;

	    case DB_TR_NOCHANGE:
		/* Do nothing */
		break;

	    default:
		return (E_DB_ERROR);
	    };
	}
	else
	{
	    CS_SID	    sid;
	    RDF_SESS_CB	    *rdf_sess_cb;

	    /* 
	    ** this trace point is session specific, so use the session control
	    ** block for this trace point.
	    */

	    CSget_sid(&sid);
	    rdf_sess_cb = GET_RDF_SESSCB(sid);

	    /*
	    ** Three possible actions: Turn on flag, turn it off, or do nothing.
	    */

	    switch (debug_cb->db_trswitch)
	    {
	    case DB_TR_ON:
		    ult_set_macro(&rdf_sess_cb->rds_strace, 
				  flag, firstval, secondval);
		break;

	    case DB_TR_OFF:
		    ult_clear_macro(&rdf_sess_cb->rds_strace, flag);
		break;

	    case DB_TR_NOCHANGE:
		/* Do nothing */
		break;

	    default:
		return (E_DB_ERROR);
	    }
	}
    }
    return (E_DB_OK);
}
Пример #5
0
/*{
** Name: GM_gcmsend	- make GCa_call for GCM request.
**
** Description:
**	Makes the call...
**
** Re-entrancy:
**	yes.
**
** Inputs:
**	conn		the connect block with the prepared message to send.
**
** Outputs:
**	conn
**
** Returns:
**	E_DB_OK
**	E_DB_ERROR
**
** History:
**	8-oct-92 (daveb)
**	    created.
**	12-Nov-1992 (daveb)
**	    Need GCA_ALT_EXIT for our completiong routien to be seen.
**	    Add fs_parms var to simplify debugging.
**	14-Nov-1992 (daveb)
**	    take *cl_stat to fill in.
**	20-Nov-1992 (daveb)
**	    Put in more TRdisplay error logging, to fix later.
**	2-Dec-1992 (daveb)
**	    Check for server failed in quick abort case.  Trying to avoid
**	    lots of errors re-connectiong to non-gcm servers.
**	08-sep-93 (swm)
**	    Changed sid type from i4 to CS_SID to match recent CL
**	    interface revision.
**	20-jul-95 (canor01)
**	    pass the SCB to IIGCa_call() instead of the SID
*/
static DB_STATUS
GM_gcmsend( GM_CONN_BLK *conn, STATUS *cl_stat )
{
    DB_STATUS	db_stat;
    CS_SID	sid;
    i4		resume = 0;
    STATUS	local_status;
    GCA_FS_PARMS	*fs_parms = &conn->conn_fs_parms;
    GM_PLACE_BLK	*place = conn->conn_place;

    conn->conn_state = GM_CONN_GCM_WORKING;
    CSget_sid(&sid);
    
    GM_incr( &GM_globals.gwm_stat_sem, &GM_globals.gwm_gcm_sends );

    if( place->place_type == GM_PLACE_SRVR &&
       ((place->place_srvr.srvr_flags & GCA_RG_MIB_MASK) == 0 ||
       place->place_srvr.srvr_state == GM_SRVR_FAILED ))
    {
	/* nothing can be had from this server.  We did a lot of
	   setup work for nothing. FIXME -- move this test higher up? */

	conn->conn_rsb->response.err_element = 0;
	conn->conn_rsb->response.status = *cl_stat = MO_NO_INSTANCE;
	conn->conn_state = GM_CONN_EMPTIED;
	return( E_DB_ERROR );
    }

    do
    {
	*cl_stat = IIGCa_call(GCA_FASTSELECT,
			      (GCA_PARMLIST *)fs_parms,
			      GCA_ASYNC_FLAG | GCA_ALT_EXIT | resume,
			      (PTR)CS_find_scb(sid),
			      (i4) -1,
			      &local_status );
	
	if (*cl_stat != OK)
	{
	    /* "GWM Internal error:  Error making gcm send to %0c" */
	    GM_1error( (GWX_RCB *)0, E_GW8042_GCA_CALL, GM_ERR_INTERNAL,
		      0, (PTR)conn->conn_rsb->request.place );
	    GM_error( *cl_stat );
	    conn->conn_state = GM_CONN_ERROR;
	}
	else
	{
	    /* wait for completion routine to wake us */

	    *cl_stat = CSsuspend(CS_BIO_MASK, 0, 0);
	    if (*cl_stat != OK)
	    {
		/* "GWM Internal error:  CSsuspend problem" */
		GM_error( E_GW8043_CS_SUSPEND );
		GM_error( *cl_stat );
		conn->conn_state = GM_CONN_ERROR;
	    }
	    else		/* completion handler called */
	    {
		switch ( *cl_stat = conn->conn_fs_parms.gca_status )
		{
		case OK:

		    resume = 0;
		    conn->conn_state = GM_CONN_GCM_DONE;
		    break;
		    
		case E_GCFFFE_INCOMPLETE:

		    GM_incr( &GM_globals.gwm_stat_sem,
			    &GM_globals.gwm_gcm_reissues );
		    resume = GCA_RESUME;
		    break;

		case E_GC0032_NO_PEER:

		    resume = 0;

		    /* "GWM Internal error:  Got 'no peer' to %0c (%1c %2x)" */
		    GM_3error( (GWX_RCB *)0, E_GW8044_NO_PEER,
			      GM_ERR_INTERNAL,
			      0, place->place_key,
			      0, place->place_srvr.srvr_class,
			      sizeof(place->place_srvr.srvr_flags),
			      (PTR)&place->place_srvr.srvr_flags );
		    GM_error( *cl_stat );
		    conn->conn_state = GM_CONN_ERROR;
		    break;

		default:

		    resume = 0;

		    /* "GWM Internal error:
		       GCM completion error to %0c (%1c %2x)" */
		    GM_3error( (GWX_RCB *)0, E_GW8045_GCA_COMPLETION,
			      GM_ERR_INTERNAL,
			      0, (PTR)place->place_key,
			      0, (PTR)place->place_srvr.srvr_class,
			      sizeof(place->place_srvr.srvr_flags),
			      (PTR)&place->place_srvr.srvr_flags );
		    GM_error( *cl_stat );
		    conn->conn_state = GM_CONN_ERROR;
		    place->place_srvr.srvr_state = GM_SRVR_FAILED;
		    break;
		}
	    }
	}
    } while( resume != 0 );
    
    db_stat = (*cl_stat == OK) ? E_DB_OK : E_DB_ERROR;

    return( db_stat );
}
Пример #6
0
STATUS
dmf_get_srs(
    DB_SPATIAL_REF_SYS *db_srs,
    i4 *errcode)
{
	DMT_SHW_CB srs_show;
	DMT_TBL_ENTRY srs_table;
	STATUS status;
    DML_SCB	*scb;
    CS_SID sid;
    DMT_CB dmt_cb;
    DMR_CB dmr_cb;
    DMR_ATTR_ENTRY key, *kptr = &key;
    SRS_ROW row;

    CSget_sid(&sid);
	scb = GET_DML_SCB(sid);

	/*
	** make sure we are have a transaction
	*/
	if (scb->scb_x_ref_count != 1)
	{
		*errcode = E_AD5603_NO_TRANSACTION;
	    return E_DB_ERROR;
	}

	/*
	 * First we need to grab spatial_ref_sys information
	 */
	MEfill(sizeof(DB_OWN_NAME), ' ', &srs_show.dmt_owner);
	MEfill(sizeof(DB_TAB_NAME), ' ', &srs_show.dmt_name);
	STncpy(srs_show.dmt_name.db_tab_name, "spatial_ref_sys", STlen("spatial_ref_sys"));
	STncpy(srs_show.dmt_owner.db_own_name, "$ingres", STlen("$ingres"));
	srs_show.type = DMT_SH_CB;
	srs_show.length = sizeof(DMT_SHW_CB);
	srs_show.dmt_session_id = sid;
	srs_show.dmt_db_id = (PTR) scb->scb_x_next->xcb_odcb_ptr;
	srs_show.dmt_flags_mask = DMT_M_NAME | DMT_M_TABLE;
	srs_show.dmt_char_array.data_address = (PTR) NULL;
	srs_show.dmt_char_array.data_in_size = 0;
	srs_show.dmt_char_array.data_out_size = 0;
	srs_show.dmt_table.data_address = (PTR) &srs_table;
	srs_show.dmt_table.data_in_size = sizeof(DMT_TBL_ENTRY);
	status = dmt_show(&srs_show);
	if(status != E_DB_OK)
	{
		//something went wrong
		*errcode = E_AD5604_SRS_NONEXISTENT;
		return status;
	}
	/*
	 * Next open the spatial_ref_sys table
	 */
	MEfill(sizeof(DMT_CB), 0, (PTR) &dmt_cb);
	dmt_cb.type = DMT_TABLE_CB;
	dmt_cb.length = sizeof(DMT_CB);
	dmt_cb.dmt_db_id = (PTR) scb->scb_x_next->xcb_odcb_ptr;
	STRUCT_ASSIGN_MACRO(srs_table.tbl_id, dmt_cb.dmt_id);
	dmt_cb.dmt_flags_mask = 0;
	dmt_cb.dmt_lock_mode = DMT_IS;
	dmt_cb.dmt_update_mode = DMT_U_DIRECT;
	dmt_cb.dmt_mustlock = FALSE;
	dmt_cb.dmt_access_mode = DMT_A_READ;
	dmt_cb.dmt_char_array.data_in_size = 0;
	dmt_cb.dmt_sequence = 0;
	dmt_cb.dmt_tran_id = (PTR) scb->scb_x_next;
	status = dmt_open(&dmt_cb);
	if (status != E_DB_OK)
	{
		*errcode = E_AD5601_GEOSPATIAL_INTERNAL;
		return status;
	}
	/*
	 * Let's set up for the actual gets
	 */
	dmr_cb.type = DMR_RECORD_CB;
	dmr_cb.length = sizeof(DMR_CB);
	dmr_cb.dmr_access_id = dmt_cb.dmt_record_access_id;
	dmr_cb.dmr_tid = 0;
	dmr_cb.dmr_q_fcn = NULL;
	dmr_cb.dmr_position_type = DMR_QUAL;
	kptr->attr_number = SRS_SRID_COL;
	kptr->attr_operator = DMR_OP_EQ;
	kptr->attr_value = (char *) &db_srs->srs_srid;
	dmr_cb.dmr_attr_desc.ptr_address = (PTR) &kptr;
	dmr_cb.dmr_attr_desc.ptr_in_count = 1;
	dmr_cb.dmr_attr_desc.ptr_size = sizeof (DMR_ATTR_ENTRY);
	dmr_cb.dmr_flags_mask = 0;
	status = dmr_position(&dmr_cb);
	if (status != E_DB_OK)
	{
		if (dmr_cb.error.err_code == E_DM0055_NONEXT)
			*errcode = E_AD5605_INVALID_SRID;
		else
			*errcode = E_AD5601_GEOSPATIAL_INTERNAL;
		dmt_close(&dmt_cb);
		return status;
	}

	dmr_cb.dmr_data.data_in_size = SRS_ROW_SIZE;
	dmr_cb.dmr_data.data_address = row;
	dmr_cb.dmr_flags_mask = DMR_NEXT;
	status = dmr_get(&dmr_cb);
	if (status != E_DB_OK)
	{
		if (dmr_cb.error.err_code == E_DM0055_NONEXT)
		{
			*errcode = E_AD5605_INVALID_SRID;
		}
		else
		{
			*errcode = E_AD5601_GEOSPATIAL_INTERNAL;
		}
		dmt_close(&dmt_cb);
		return status;
	}

	/*
	 * If we get here we retrieved a row yay!
	 */
	MEcopy((row + SRS_AUTH_NAME_OFFSET), sizeof(db_srs->srs_auth_name), db_srs->srs_auth_name);
	db_srs->srs_auth_name[STlen(db_srs->srs_auth_name)] = '\0';
	MEcopy((row + SRS_AUTH_ID_OFFSET), sizeof(i4), &db_srs->srs_auth_id);
	MEcopy((row + SRS_SRTEXT_OFFSET), sizeof(db_srs->srs_srtext), db_srs->srs_srtext);
	db_srs->srs_srtext[STlen(db_srs->srs_srtext)] = '\0';
	MEcopy((row + SRS_PROJ4TEXT_OFFSET), sizeof(db_srs->srs_proj4text), db_srs->srs_proj4text);
	db_srs->srs_proj4text[STlen(db_srs->srs_proj4text)] = '\0';
	/*
	 * Must close the table when we're done
	 */
	status = dmt_close(&dmt_cb);
	if(status != E_DB_OK)
	{
		/* close failed?? */
		*errcode = E_AD5601_GEOSPATIAL_INTERNAL;
		return status;
	}
	return E_DB_OK;
}
Пример #7
0
/*{
**
** Name: dmc_write_behind_common  -  the guts of a write behind thread
**
** Description:
**
**	The dmc_write_behind routine is used for implementing an asynchronous
**	write behind thread.  It wakes up whenever signaled by an LK event
**	and writes dirty pages out of the cache to make room for new pages
**	to be read in.
**
**	The dmc_write_behind routine should only be called within a special
**	session that is dedicated for this purpose.  This routine will not
**	return under normal circumstances until server shutdown time.
**
**	This routine uses two routines in DM0P to drive the write behind
**	thread:
**	    DM0P_BMFLUSH_WAIT waits for a session in the buffer manager
**	    to signal the event to wake up the write behind threads.  This
**	    is signalled when some specified percent of the buffer manager
**	    is filled with dirty pages.
**
**	    DM0P_FLUSH_PAGES goes through the buffer manager modified queue
**	    in reverse priority order writing pages until some specified
**	    percentage of the buffer manager is free.
**
**	This routine will return only if the event wait in DM0P_BMFLUSH_WAIT
**	is cancelled by an interrupt.  At server shutdown time, the server
**	is expected to interrupt all the write behind threads.
**
**	This common code is executed by both Primary and Cloned
**	WriteBehind agents.
**
** Inputs:
**	i_am_a_clone		FALSE if this is the Primary WB Agent,
**				TRUE if a Clone.
**	cfa			Agent's data.
**
** Outputs:
**     dmf_err
** 	.error.err_code	    One of the following error numbers.
**			    E_DB_OK
**			    E_DM004A_INTERNAL_ERROR
**			    E_DM004B_LOCK_QUOTA_EXCEED
**			    E_DM0062_TRAN_QUOTA_EXCEED
**			    E_DM0117_WRITE_BEHIND
**
** Returns:
**     E_DB_OK
**     E_DB_FATAL
**
** History:
**      30-jun-1988 (rogerk)
**          Created for Jupiter.      
**      30-Jan-1989 (ac)
**          Added arguments to LGbegin().      
**	15-may-1989 (rogerk)
**	    Return resource errors if resource limit is exceeded.
**      2-oct-1992 (ed)
**          Use DB_MAXNAME to replace hard coded numbers
**          - also created defines to replace hard coded character strings
**          dependent on DB_MAXNAME
**	18-oct-1993 (rogerk)
**	    Add check for LOGFULL status.  We don't execute write behind when
**	    in logfull to avoid background log forces which wreak havoc on
**	    the recovery logspace reservation algorithms.
**	10-oct-93 (swm)
**	    Bug #56438
**	    Put LG_DBID into automatic variable lg_dbid rather than overloading
**	    dmc_cb->dmc_db_id.
**	31-jan-1994 (bryanp) B58380, B58381
**	    Log LG/LK status code if LG or LK call fails.
**	    Check return code from CSsuspend.
**	10-Mar-1998 (jenjo02)
**	    Support for demand-driven WriteBehind threads. Changed prototype
**	    to pass a boolean indicating whether this is the primary or
**	    cloned WB thread and a pointer to DB_ERROR instead of a pointer
**	    to DMC_CB.
**	    Made this a common function called by Primary and Cloned threads.
*/
static DB_STATUS
dmc_write_behind_common(
i4	    i_am_a_clone,
char	    *cfa,
DB_ERROR    *dmf_err)
{
    DM_SVCB	    *svcb = dmf_svcb;
    DB_TRAN_ID	    tran_id;
    LG_LXID	    lx_id;
    DM0L_ADDDB	    add_info;
    TIMERSTAT	    stat_block;
    i4	    lock_list;
    i4		    len_add_info;
    i4		    event_mask;
    i4		    events, wakeup_event;
    i4		    have_locklist = FALSE;
    i4		    have_transaction = FALSE;
    i4		    lg_added = FALSE;
    DB_STATUS	    status = E_DB_OK;
    i4	    wbcount = 0;
    i4	    wait_time = 0;
    i4	    base_time = 0;
    i4	    flush_time, new_time;
    i4	    length;
    i4	    lgd_status;
    STATUS	    stat;
    i4	    error;
    CL_ERR_DESC	    sys_err;
    DB_OWN_NAME	    user_name;
    LG_DBID	    lg_dbid;

#ifdef xDEBUG
    CS_SID	sid;
    i4	pid;

    PCpid(&pid);
    CSget_sid(&sid);

    TRdisplay("Starting Write Behind Thread %x in server process %d\n",
	sid, pid);
#endif

    CLRDBERR(dmf_err);

    if (status == E_DB_OK)
    {
	/*
	** Add write behind thread to logging system.
	** Write behind thread does not actually open a database, so use
	** the LG_NOTDB flag.
	*/
	STmove((PTR)DB_WRITEBEHIND_THREAD, ' ', sizeof(add_info.ad_dbname),
	    (PTR) &add_info.ad_dbname);
	MEcopy((PTR)DB_INGRES_NAME, sizeof(add_info.ad_dbowner),
	    (PTR) &add_info.ad_dbowner);
	MEcopy((PTR)"None", 4, (PTR) &add_info.ad_root);
	add_info.ad_dbid = 0;
	add_info.ad_l_root = 4;
	len_add_info = sizeof(add_info) - sizeof(add_info.ad_root) + 4;

	stat = LGadd(dmf_svcb->svcb_lctx_ptr->lctx_lgid, LG_NOTDB,
	    (char *)&add_info, 
	    len_add_info, &lg_dbid, &sys_err);
	if (stat != OK)
	{
	    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    uleFormat(NULL, E_DM900A_BAD_LOG_DBADD, &sys_err, ULE_LOG, NULL,
		(char *)NULL, 0L, (i4 *)NULL, &error, 4, 0,
		dmf_svcb->svcb_lctx_ptr->lctx_lgid,
		sizeof(add_info.ad_dbname), (PTR) &add_info.ad_dbname,
		sizeof(add_info.ad_dbowner), (PTR) &add_info.ad_dbowner,
		4, (PTR) &add_info.ad_root);
	    if (stat == LG_EXCEED_LIMIT)
		SETDBERR(dmf_err, 0, E_DM0062_TRAN_QUOTA_EXCEEDED);
	    else
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
	    status = E_DB_ERROR;
	}
	else
	    lg_added = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*
	** Begin transaction in order to do LG and LK calls.
	** Must specify NOPROTECT transaction so that LG won't pick us
	** as a force-abort victim.  Also, the Log File BOF can be advanced
	** past this transaction's position in the log file, which means that
	** the Write Behind thread should do no logging nor work that could
	** require backout.
	*/
	STmove((PTR)DB_WRITEBEHIND_THROWN, ' ', sizeof(DB_OWN_NAME), 
							(PTR) &user_name);
	stat = LGbegin(LG_NOPROTECT, lg_dbid, &tran_id, &lx_id,
	    sizeof(DB_OWN_NAME), user_name.db_own_name, 
	    (DB_DIS_TRAN_ID*)NULL, &sys_err);
	if (stat != OK)
	{
	    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    uleFormat(NULL, E_DM900C_BAD_LOG_BEGIN, &sys_err, ULE_LOG, NULL, 
		(char *)NULL, (i4)0, (i4 *)NULL, &error, 1, 
		0, lg_dbid);
	    if (stat == LG_EXCEED_LIMIT)
		SETDBERR(dmf_err, 0, E_DM0062_TRAN_QUOTA_EXCEEDED);
	    else
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
	    status = E_DB_ERROR;
	}
	else
	    have_transaction = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*
	** Create locklist to use to wait for Write Behind event.
	*/
	stat = LKcreate_list(LK_NONPROTECT, (i4) 0,
	    (LK_UNIQUE *)&tran_id, (LK_LLID *)&lock_list, (i4)0, 
	    &sys_err);
	if (stat != OK)
	{
	    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    uleFormat(NULL, E_DM901A_BAD_LOCK_CREATE, &sys_err, ULE_LOG, NULL, 
		(char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    if (stat == LK_NOLOCKS)
		SETDBERR(dmf_err, 0, E_DM004B_LOCK_QUOTA_EXCEEDED);
	    else
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
	    status = E_DB_ERROR;
	}
	else
	    have_locklist = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*
	** Now begin loop of waiting for Write Behind event and flushing
	** the buffer manager.
	*/
	do
	{
	    if (DMZ_ASY_MACRO(2))
	    {
		new_time = TMsecs();
		flush_time = new_time - base_time - wait_time;
		base_time = new_time;

		/* Write Write Behind thread statistics. */
		stat = CSstatistics(&stat_block, 0);
		TRdisplay("%22*- DMF Write Behind Thread statistics %21*-\n");
		TRdisplay("    Write Behind wakeups: %d    Cpu : %d    Dio : %d\n",
		    wbcount, stat_block.stat_cpu, stat_block.stat_dio);
		TRdisplay("    Time waiting for event: %d seconds\n",
		    wait_time);
		TRdisplay("    Time to flush pages: %d seconds\n",
		    flush_time);
		TRdisplay("%79*-\n");
	    }

	    /*
	    ** Cloned threads don't wait for a signal, they just
	    ** help flush the cache, then go away.
	    */
	    if (i_am_a_clone == FALSE)
	    {
		/*
		** Wait for the next signal that the buffer manager needs to have
		** pages flushed.
		**
		** This routine will also clear the event from the previous 
		** signal.
		*/
		status = dm0p_wbflush_wait(cfa, lock_list, dmf_err);
		if (status != E_DB_OK)
		{
		    /*
		    ** If warning is returned, that's a signal that
		    ** this thread is to terminate.
		    */
		    if (status == E_DB_WARN)
		    {
			status = E_DB_OK;
			break;
		    }
		    else
		    {
			if (dmf_err->err_code > E_DM_INTERNAL)
			{
			    uleFormat(dmf_err, 0, NULL, ULE_LOG, NULL, 
			    	(char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
			    SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
			}
			break;
		    }
		}
	    }

	    /*
	    ** Check LOGFULL status.  We don't execute write behind when in
	    ** logfull to avoid background log forces which wreak havoc on
	    ** the recovery logspace reservation algorithms.
	    */
	    stat = LGshow(LG_S_LGSTS, (PTR)&lgd_status, 
			    sizeof(lgd_status), &length, &sys_err);
	    if (stat != OK)
	    {
		uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		    ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
		uleFormat(NULL, E_DM9017_BAD_LOG_SHOW, &sys_err, ULE_LOG, NULL, 
		    (char *)NULL, (i4)0, (i4 *)NULL, &error, 1, 
		    0, LG_S_LGSTS);
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
		status = E_DB_ERROR;
		break;
	    }

	    /*
	    ** If logfull, skip the cache flush.
	    */
	    if (lgd_status & LGD_LOGFULL)
	    {
		/*
		** Pause for a moment since the write-behind event will likely
		** be immediately resignaled. We expect that this 5-second
		** wait will return with "timed-out"; if it returns with
		** "interrupted", then the server is being shut down. If it
		** returns with any other return code, something is awry.
		*/
		stat = CSsuspend(CS_TIMEOUT_MASK | CS_INTERRUPT_MASK, 5, 0);
		if (stat == E_CS0008_INTERRUPTED)
		{
		    status = E_DB_OK;
		    break;
		}
		if (stat != E_CS0009_TIMEOUT)
		{
		    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
			ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
		    SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
		    status = E_DB_ERROR;
		    break;
		}
	    }
	    else
	    {
		/*
		** Flush some dirty pages out of the Buffer Manager.
		*/

		if (dmf_svcb->svcb_status & SVCB_IOMASTER) 
		{
		    /* in IOMASTER server use same func as write-along thread */
		    i4 numforce;
		    u_i4 duty = 0xffffffff;
		    status = dm0p_write_along(lock_list, (i4)lx_id, 
			    &numforce, duty, dmf_err);
		}
		else
		    status = dm0p_flush_pages(lock_list, (i4)lx_id, 
				    cfa,
				    dmf_err);

		if (status != E_DB_OK)
		{
		    if (dmf_err->err_code > E_DM_INTERNAL)
		    {
			uleFormat(dmf_err, 0, NULL, ULE_LOG, NULL, 
			    (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
			SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
		    }
		    break;
		}
	    }

	    /*
	    ** If dumping statistics, save time for event to be signaled.
	    */
	    if (DMZ_ASY_MACRO(2))
		wait_time = TMsecs() - base_time;
	    wbcount++;

	} while (i_am_a_clone == FALSE);
    }

    if (i_am_a_clone == FALSE)
    {
	/* Write Fast Commit thread statistics. */
	stat = CSstatistics(&stat_block, 0);
	TRdisplay("\n%22*- DMF Write Behind Thread statistics %21*-\n");
	TRdisplay("    Write Behind wakeup: %d    Cpu : %d    Dio : %d\n",
	    wbcount, stat_block.stat_cpu, stat_block.stat_dio);
	TRdisplay("%79*-\n");
    }

    /*
    ** Clean up transaction and/or lock list left hanging around.
    */
    if (have_transaction)
    {
	stat = LGend(lx_id, 0, &sys_err);
	if (stat != OK)
	{
	    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    uleFormat(NULL, E_DM900E_BAD_LOG_END, &sys_err, ULE_LOG, NULL, 
		(char *)NULL, (i4)0, (i4 *)NULL, &error, 1, 0, lx_id);
	    if ( status == E_DB_OK )
	    {
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
		status = E_DB_ERROR;
	    }
	}
	have_transaction = FALSE;
    }

    if (have_locklist)
    {
	stat = LKrelease(LK_ALL, lock_list, (LK_LKID *)0, (LK_LOCK_KEY *)0,
	    (LK_VALUE *)0, &sys_err);
	if (stat != OK)
	{
	    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    uleFormat(NULL, E_DM901B_BAD_LOCK_RELEASE, &sys_err, ULE_LOG, NULL, 
		(char *)NULL, (i4)0, (i4 *)NULL, &error, 1, 0, lock_list);
	    if ( status == E_DB_OK )
	    {
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
		status = E_DB_ERROR;
	    }
	}
	have_locklist = FALSE;
    }

    if (lg_added)
    {
	stat = LGremove(lg_dbid, &sys_err);
	if (stat != OK)
	{
	    uleFormat(NULL, stat, (CL_ERR_DESC *)&sys_err, 
		ULE_LOG, NULL, (char *)NULL, (i4)0, (i4 *)NULL, &error, 0);
	    uleFormat(NULL, E_DM9016_BAD_LOG_REMOVE, &sys_err, ULE_LOG, NULL, 
		    (char *)NULL, (i4)0, (i4 *)NULL, &error, 1, 0, lg_dbid);
	    if ( status == E_DB_OK )
	    {
		SETDBERR(dmf_err, 0, E_DM0117_WRITE_BEHIND);
		status = E_DB_ERROR;
	    }
	}
    }

    return (status);
}
Пример #8
0
/*{
** Name: SRopen - Opens a file.
**
** Description:
**      The SRopen routine is used to open a direct access file.  
**      It will open the file for write access and will
**      place no locks on the file.  If the create_flag is set 
**      it will create it and allocate the amount specified.
**      Additional space may be required to accomplish the sort.
**      An unlimited number of extensions must be allowed.
**      You can specify that nothing should be allocated at
**      create time.
**   
**	SR files are allocated in SR_MIN_INCR-block chunks,
**	i.e. (SR_MIN_INCR/2) Kb chunks.  Ideally, one reads and
**	writes SR files using a constant page size;  but, it's
**	allowable to read with a larger page size as long as both
**	old and new page sizes are a power of 2 no larger than
**	(SR_MIN_INCR/2) Kb.  Likewise, it's allowable to read an
**	existing SR file with a smaller page size as long as it
**	divides evenly into the original page size.  In general there
**	is no burning need to flail around with SR file page sizes...
**   
** Inputs:
**      f                    Pointer to the SR file
**                           context needed to do I/O.
**      path                 Pointer to the directory name
**                           for the file.
**      pathlength           Length of path name.
**      filename             Pointer to file name.
**      filelength           Length of file name.
**      pagesize             Value indicating size of page 
**                           in bytes.  Must be a multiple of
**				the VMS page size of 512 bytes.
**      create_flag          Value indicating if creation needed.
**                           Must be SR_IO_CREATE.
**      n                    Value indicating number of pages to
**                           pre-allocate.
**      
** Outputs:
**      f                    Updates the file control block.
**      err_code             Pointer to a variable used
**                           to return operating system 
**                           errors.
**    Returns:
**          OK
**          SR_BADDIR		Error in path specification.
**          SR_BADOPEN		Error opening file.
**          SR_BADFILE		Bad file context.
**          SR_PADPARAM		Parameter(s) in error.
**	    SR_EXCEED_LIMIT	Too many open files, exceeding disk quota
**				or exceeding available disk space.
**    Exceptions:
**        none
**
** Side Effects:
**        none
**
** History:
**    30-sep-85 (jennifer)
**          Created new for 5.0.
**      02-apr-86 (jennifer)
**          Modified the system error returned from a i4 to
**          the type CL_ERR_DESC per CL request.
**	27-jul-87 (rogerk)
**	    Added return code SR_EXCEED_LIMIT.
**	17-aug-87 (rogerk)
**	    Save local return status after CSsuspend call before acting on
**	    its value.  We were losing the return status from the allocate
**	    call by seting the local return status from CSsuspend later on.
**	11-may-98 (kinte01)
**	    Added page size for 65536
*/
STATUS
SRopen(
SR_IO           *f,
char            *path,
u_i4		pathlength,
char            *filename,
u_i4	        filelength,
i4		pagesize,
u_i4		create_flag,
i4         n,
CL_ERR_DESC	*err_code)
{
    IOSB		local_iosb;         /* Operation return status. */
    i4 	        s;		    /* Request return status. */
    FIBDEF		*fib;
    struct
    {
	i4	    count;
	char	    *pointer;
    }			descriptor;
    CS_SID		sid;

    CL_CLEAR_ERR(err_code);

#ifdef SR_CHECK_RESUME
    if (SR_check_resume)
    {
       SR_check_init();
    }
#endif 

    /* Page size has to be a multiple of 512. */
    if ((pagesize & 511) != 0)
	return (SR_BADPARAM);

    /* Initialize file control block. */

    MEfill (sizeof(SR_IO), NULL, (PTR)f);
    f->io_type = SR_IO_ASCII_ID;
    CSget_sid(&sid);

    /* Assign a channel for I/O. */

    descriptor.count = pathlength;
    descriptor.pointer = path;
    s = sys$assign(&descriptor, &f->io_channel, 0, 0);
    if ((s & 1) == 0)
    {
        err_code->error = s;
	if ((s == SS$_EXQUOTA) || (s == SS$_EXDISKQUOTA) || (s == SS$_NOIOCHAN))
	    return (SR_EXCEED_LIMIT);
        return (SR_BADOPEN); 
    }

    /* Access the file with no locking.*/

    fib = (FIBDEF *)f->io_fib;
    fib->fib$l_acctl = FIB$M_NOLOCK | FIB$M_WRITE;
    fib->fib$w_nmctl = 0;
    fib->fib$w_exctl = 0;
    f->io_fib_desc.str_len = sizeof(f->io_fib);
    f->io_fib_desc.str_str = f->io_fib;

    /*	Queue the Create call. */
    s = sr_qio(EFN$C_ENF, f->io_channel, 
		IO$_CREATE | IO$M_CREATE | IO$M_ACCESS | IO$M_DELETE,
		&local_iosb, sr_resume_fcn, sid,
		&f->io_fib_desc, 0, 0, 0, 0, 0);

    if (s & 1)
    {
	/*  Successfully queued, wait for completion. */

#ifdef SR_SUSPEND_THREAD
        SR_SUSPEND_THREAD;
#endif
	s = local_iosb.iosb$w_status;
	if (local_iosb.iosb$w_status & 1)
	{
	    /*	Successful completion, setup the control block. */

	    fib->fib$l_acctl = 0;
	    f->io_block_size = pagesize;
	    f->io_blks = pagesize >> 9;

	    /* Don't bother with io_log2_blk, nothing uses it... */
	    if (n != 0)
	    {
		/*  Preallocate space for the file. */

		s = iiSRallocate(f, n, sid, err_code);
		if (s == OK)
		    return (OK);

		/*
		** If allocate returns an error, stuff the os errcode into
		** 's' for processing below.
		*/
		s = err_code->error;
	    }
	    else
	    {
		return (OK);
	    }
	}
Пример #9
0
STATUS
SRclose(
SR_IO		*f,
i4		delete_flag,
CL_ERR_DESC	*err_code)
{
    IOSB		local_iosb;         /*  Operation return status. */
    int			s;                  /*  Request return status. */
    CS_SID		sid;
#ifdef xDEBUG
    long		device_class;
    long		dvi_length;
    ILE3		itmlst = {4, DVI$_DEVCLASS, &device_class, &dvi_length};
#endif

    CL_CLEAR_ERR(err_code);
    /*	Check for valid control block. */

    if (f->io_type != SR_IO_ASCII_ID) 
        return (SR_BADFILE);

    /*	Check that the file is open. */

    if (f->io_channel == 0)
        return (OK);
    
    CSget_sid(&sid);
    
#ifdef xDEBUG
    /*
    ** Check that the channel we are deallocating is still connected
    ** to a disk device.  This will trap the errors where we are
    ** conflicting with GCF on IO channels.
    */
    s = sr_getdvi(EFN$C_ENF, f->io_channel, 0, &itmlst, &local_iosb,
 	          sr_resume_fcn, sid, 0);
    if (s & 1)
    {
#ifdef SR_SUSPEND_THREAD
        SR_SUSPEND_THREAD;
#endif
	s = local_iosb.iosb$w_status;
    }
    if (((s & 1) == 0) || (device_class != DC$_DISK))
    {
	/*
	** This io channel is no longer any good, or is not what we
	** think it is.  Return BADCLOSE and either the system error
	** (if one was returned), or SS$_NOTFILEDEV.
	*/
	err_code->error = s;
	if (s & 1)
	    err_code->error = SS$_NOTFILEDEV;
	return (SR_BADCLOSE);
    }
#endif

    /*	Queue request to close and delete the file. */
    s = sr_qio(EFN$C_ENF, f->io_channel, 
		IO$_DEACCESS, &local_iosb, sr_resume_fcn, sid,
		0, 0, 0, 0, 0, 0);

    if (s & 1)
    {
	/*  Successfully queued, wait for completion. */

#ifdef SR_SUSPEND_THREAD
        SR_SUSPEND_THREAD;
#endif
	if (local_iosb.iosb$w_status & 1)
	{
	    /*	Deassign the channel. */

	    s = sys$dassgn(f->io_channel);
	    if (s & 1)
	    {
		/*  Return successful. */

		f->io_channel = 0;
		f->io_type = 0;
		return (OK);
	    }   
	}
	else
	    s = local_iosb.iosb$w_status;
    }

    err_code->error = s;
    return (SR_BADCLOSE);
}
Пример #10
0
/*
** Name: scs_check_external_password 
**
** Description:
**	Check the external password for a role
**
** Inputs:
**	scb 		- SCB
**
** 	authname 	- Role/User name being checked
**
**	password 	- Role/User password
**
**	auth_role	- TRUE if authenticating a role
**
** Returns:
**	E_DB_OK - Access is allowed
**
**	E_DB_WARN - Access is denied
**
**	E_DB_ERROR - Failure determining access
**
** History:
**	9-mar-94 (robf)
**		Created
**	11-mar-94 (robf)
**           Distinguish between access disallowed and some other
**	     error. Add SCF activity in case auth. server take a while
**	15-mar-94 (robf)
**	     Rework to allow for user or role authentication, add
**	     parameter auth_role. Make routine external, 
**	     name scs_check_external_password, and move to scseauth.c
**      22-mar-1996 (stial01)
**          Cast length passed to sc0m_allocate to i4.
**	16-jul-96 (stephenb)
**	    Add effective user to parameter list and pass to authentication
**	    server (fix primarily for ICE authentication, but useful 
**	    information for the user anyway).
**	16-Nov-1998 (jenjo02)
**	    When suspending on BIO read, use CS_BIOR_MASK.
*/
DB_STATUS
scs_check_external_password (
	SCD_SCB *scb, 
	DB_OWN_NAME *authname, 
	DB_OWN_NAME *e_authname,
	DB_PASSWORD *password,
	bool	    auth_role
)
{
    DB_STATUS 	status = E_DB_WARN;
    STATUS    	cl_stat;
    STATUS    	local_status;
    char 	pmname[64];
    char 	*pmvalue;
    char  	target[64];
    GCA_FS_PARMS fs_parms; 
    SCS_REBUFF   *re_buff = NULL;
    char	 *work_buff;
    i4		 resume = 0;
    CS_SID	 sid;
    PTR		 save_data_area;
    char	 *q;
    char	 *gcmvalue;
    i4	 	 error_index;
    i4	 error_status;
    char	 *act_string;
    char	 blank_string[32] = "";

    for (;;)
    {
	
	if (auth_role)
		act_string = "Validating external role password";
	else
		act_string = "Validating external user password";

	MEcopy((PTR)act_string, STlength(act_string),
				scb->scb_sscb.sscb_ics.ics_act1);
	scb->scb_sscb.sscb_ics.ics_l_act1 = (i4)STlength(act_string);
	/*
	** Find the authentication mechanism for this role
	*/
	if (auth_role)
	{
	    STprintf(pmname, "ii.$.secure.role_auth.%*s",
		scs_trimwhite(sizeof(*authname),
			(char*)authname), 
		(char*)authname);
	}
	else
	{
	    STprintf(pmname, "ii.$.secure.user_auth.%*s",
		scs_trimwhite(sizeof(*authname),
			(char*)authname), 
		(char*)authname);
	}
	cl_stat = PMget(pmname, &pmvalue);
	if (cl_stat != OK)
	{
	        sc0e_put(E_SC035A_EXTPWD_NO_AUTH_MECH, 0, 1,
		         scs_trimwhite(sizeof(*authname),
			      (char*)authname),
			(PTR)authname,
			0, (PTR)0,
			0, (PTR)0,
			0, (PTR)0,
			0, (PTR)0,
			0, (PTR)0 );
		status = E_DB_ERROR;
		break;
	}
	/*
	** Now we know the target mechanism, set up target destination
	**
	** Legal values are either 'value' which maps to value/authsvr
	** or @value which is sent untranslated. 
	*/
	if (*pmvalue != '@')
		STprintf(target,"%s/authsvr",pmvalue);
	else
		STprintf(target,"%s", pmvalue+1);
	/*
	** Allocate buffer for processing the request
	*/
        status = sc0m_allocate(SCU_MZERO_MASK,
		    (i4)sizeof(SCS_REBUFF),
		    DB_SCF_ID,
		    (PTR)SCS_MEM,
		    SCRE_TAG,
		    (PTR*)&re_buff);
        if (status != E_DB_OK)
        {
		/* sc0m_allocate puts error codes in return status */
		sc0e_0_put(status, 0);
		status = E_DB_ERROR;
		break;
    	}
	work_buff = re_buff->work_buff;
	gcmvalue = re_buff->gcmvalue;

	CSget_sid(&sid);

	save_data_area = work_buff;
	/*
	** Build the fastselect request
	*/
	fs_parms.gca_user_name = NULL;
	fs_parms.gca_password = NULL;
	fs_parms.gca_account_name = NULL;
	fs_parms.gca_completion = cep_complete;
	fs_parms.gca_closure = NULL;
	fs_parms.gca_peer_protocol = GCA_PROTOCOL_LEVEL_61;
	fs_parms.gca_partner_name = target;
	fs_parms.gca_modifiers = GCA_RQ_GCM;
	fs_parms.gca_buffer = work_buff;
	fs_parms.gca_b_length = RQ_BUFF_SIZE;
	fs_parms.gca_message_type = GCM_SET;

	q = save_data_area;
	q += sizeof(i4);	/* Past error_status */
	q += sizeof(i4);	/* Past error_index */
	q += sizeof(i4);	/* Past future[0] */
	q += sizeof(i4);	/* Past future[1] */
	q += gcm_put_int(q, -1);/* Client perms */
	q += gcm_put_int(q, 1); /* Row count */
	q += gcm_put_int(q, 1); /* Element count */
	if (auth_role)
	    q += gcm_put_str(q, "exp.scf.auth_server.role_authenticate"); /* Class id */
	else
	    q += gcm_put_str(q, "exp.scf.auth_server.user_authenticate"); /* Class id */
	q += gcm_put_str(q, "0"); 		  /* Instance */
	/*
	** Now build the value.
	** This consists of:
	** Role:
	**  flag 	 - 4 byte integer, currently 0
	**  real user 	 - 32 byte blank-padded
	**  effective user - 32 byte blank-padded
	**  role         - 32 byte blank-padded
	**  password     - 24 byte blank-padded
	** User:
	**  flag 	 - 4 byte integer, currently 1
	**  real user 	 - 32 byte blank-padded
	**  effective user - 32 byte blank-padded
	**  password     - 24 byte blank-padded
	** These are all padded into a single GCM value.
	** Note: This assumes no NULL values in any of the fields.
	*/
	if (auth_role)
	{
	    STprintf(gcmvalue,"%-4.4s%32.32s%32.32s%32.32s%-24.24s",
		"0",
		(char*)&scb->scb_sscb.sscb_ics.ics_rusername,
		e_authname ? (char*)e_authname : blank_string,
		(char*)authname,
		(char*)password);
	}
	else
	{
	    STprintf(gcmvalue,"%-4.4s%32.32s%32.32s%-24.24s",
		"1",
		(char*)authname,
		e_authname ? (char*)e_authname : blank_string,
		(char*)password);
	}
	q += gcm_put_str(q, gcmvalue );	  	  /* Value */
	fs_parms.gca_msg_length = (i4)(q - save_data_area);
	break;
    }

    /*
    ** Now do the fastselect
    */
    resume = 0;
    if (status == E_DB_OK)
    do 
    {

	cl_stat = IIGCa_call(GCA_FASTSELECT,
			(GCA_PARMLIST *)&fs_parms,
			GCA_ASYNC_FLAG | GCA_ALT_EXIT | resume,
			(PTR)CS_find_scb(sid),
			(i4) -1,
			&local_status);
        if (cl_stat != OK)
        {
	    sc0e_0_put(cl_stat, 0);
	    sc0e_0_put(E_SC0357_EXTPWD_GCA_FASTSELECT, 0);
	    status = E_DB_ERROR;
	    break;
        }
        else
        {
            /* wait for completion routine to wake us */
            cl_stat = CSsuspend(CS_BIOR_MASK, 0, 0);
            if (cl_stat != OK)
            {
	        sc0e_0_put(cl_stat, 0);
	        sc0e_0_put(E_SC0356_EXTPWD_GCA_CSSUSPEND, 0);
	        status = E_DB_ERROR;
		resume = 0;
		break;
            }
            else                /* completion handler called */
            {
                switch ( cl_stat = fs_parms.gca_status )
                {
                case OK:

                    resume = 0;
                    break;

                case E_GCFFFE_INCOMPLETE:

                    resume = GCA_RESUME;
                    break;

                case E_GC0032_NO_PEER:
		case E_GC0138_GCN_NO_SERVER:
		case E_GC0139_GCN_NO_DBMS:

                    resume = 0;

		    sc0e_put(E_SC0355_EXTPWD_GCA_NOPEER, 0, 2,
				 scs_trimwhite(sizeof(*authname),
				      (char*)authname),
				(PTR)authname,
				(i4)STlength(target),
				(PTR)target,
		     		0, (PTR)0,
		     		0, (PTR)0,
		     		0, (PTR)0,
		     		0, (PTR)0 );
		    status = E_DB_ERROR;
                    break;

                default:

                    resume = 0;

	       	    sc0e_0_put(cl_stat, 0);
		    sc0e_0_put(E_SC0354_EXTPWD_GCA_COMPLETION, 0);
		    status = E_DB_ERROR;
                    break;
                }
            }
        }
    } while( resume != 0 );
    /*
    ** Check if select worked OK, if not skip to the end
    */
    if (status == E_DB_OK)
    {
	/*
	** Got result of fastselect, so unpack and see what happened
	*/
	q = save_data_area;
	q += gcm_get_int(q, &error_status);
	q += gcm_get_int(q, &error_index);
	if (error_status != 0)
	{
	   if (error_index == -1)
	   {
	       	sc0e_0_put(error_status, 0);
		sc0e_0_put(E_SC0359_EXTPWD_GCM_ERROR, 0);
	        status = E_DB_ERROR;
	   }
	   else
	   {
		/* Access is denied */
		status = E_DB_WARN;
	    }
	}
	else
	{
		/* Access is allowed */
		status = E_DB_OK;
	}
    }

    /* Reset activity */
    scb->scb_sscb.sscb_ics.ics_l_act1 = 0;

    /*
    ** Free buffer if allocated
    */
    if (re_buff)
    {
	if (sc0m_deallocate(0, (PTR *) &re_buff) != E_DB_OK)
	{
	    sc0e_0_put(status, 0);
	}
    }
    return(status);
}