Example #1
0
/*{
** 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);
}
Example #2
0
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;
}
Example #3
0
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 */
Example #4
0
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 */
Example #5
0
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;
}
Example #6
0
/*{
** 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);
}
Example #7
0
/*{
** 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);
}
Example #8
0
/*{
** 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);
}
Example #9
0
/*{
** 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);
}
Example #10
0
/*{
** 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;
}