Exemple #1
0
/* PROGRAM: dsmMandatoryFieldsGet - find cached file metadata.  This cache
 *                                  is stored in shared memory
 *
 * RETURNS: DSM_S_SUCCES
 *
 */
dsmStatus_t
dsmMandatoryFieldsGet(dsmContext_t *pcontext,
           struct meta_filectl     *pmetactl,    /* mand. table from shm    */
           dsmDbkey_t              fileDbkey,    /* dbkey of _file record   */
           int                     fileNumber,   /* file # of _file record  */
           dsmBoolean_t            fileKey,      /* dbkey/file# of _file    */
           dsmBoolean_t            copyFound,    /* flag to copy mand. flds */
           struct mand             *pmand)       /* storage for mand. array */
{
 
    dbcontext_t *pdbcontext = pcontext->pdbcontext;
    dsmStatus_t returnCode;
    int                     metaSize;
 
    pdbcontext->inservice++; /* postpone signal handler processing */

    SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */

    if ((returnCode = dsmThreadSafeEntry(pcontext)) != DSM_S_SUCCESS)
    {
        returnCode = dsmEntryProcessError(pcontext, returnCode,
                      (TEXT *)"dsmMandatoryFieldsGet");
        goto done;
    }

    MT_LOCK_SCC ();
 
    /* Check if the entry already exists */
    dsmMandFindEntry(pcontext, &pmetactl, fileDbkey, fileNumber, fileKey);

    if (pmetactl != NULL)
    {
        DEBUG_FPRINTF(stderr, "dbmanb: cache entry found, returning\n");
 
        if (copyFound != 0)
        {
            metaSize = (pmetactl->nmand+1)*sizeof(struct mand);
            bufcop((TEXT *)pmand, (TEXT *)pmetactl->mand, metaSize);
        }
    }
 
    MT_UNLK_SCC ();

    returnCode = DSM_S_SUCCESS;
done:

    dsmThreadSafeExit(pcontext);
    pdbcontext->inservice--;

    return returnCode;
 
}
Exemple #2
0
LOCALF 
int rlaiVersion(
	dsmContext_t	*pcontext,
	AIBLK		 *paiblk) /* Pointer to ai file header        */
{
    LONG     AiVersion;
    LONG     rc = 1;

    /* Make sure that the header length is in the ball park     */
    if( paiblk->aihdr.aihdrlen > (COUNT)(sizeof(AIHDR) + sizeof(AIFIRST)))
    {
	/* This is not a Progress ai file */
	MSGN_CALLBACK(pcontext, rlMSG104);
	return ( rc );
    }

    /* Copy ai version to avoid alignment errors when testing the
       ai version in what is a bogus block.                        */
    bufcop((TEXT *)&AiVersion,
	   ((TEXT *)paiblk + paiblk->aihdr.aihdrlen - sizeof(LONG)),
	   sizeof(LONG));

    if( AiVersion != AIVERSION )
    {
	/* Invalid after image version number found in ai file header */
	MSGN_CALLBACK(pcontext, rlMSG100); 
	if( paiblk->aihdr.aihdrlen != sizeof(AIHDR) + sizeof(AIFIRST))
	{
	    if ( paiblk->aihdr.aihdrlen == 
		sizeof(AIHDRv0) + sizeof(AIFIRSTv0))
	    {
		/* This is a version 0 Progress ai file. */
		MSGN_CALLBACK(pcontext, rlMSG101); 
		/* The ai file must be truncated.    */
		MSGN_CALLBACK(pcontext, rlMSG102);                   
		/* See documentation for aimage truncate */
		MSGN_CALLBACK(pcontext, rlMSG103); 
		return ( rc );
	    }
	    /* This is not a Progress ai file */
	    MSGN_CALLBACK(pcontext, rlMSG104); 
	    return ( rc );
	}
    }
    rc = 0;
    return ( rc );
}
Exemple #3
0
/* PROGRAM: utapath - given a file name, possibly fully qualified,
 *		an optional suffix, a target buffer, and the length
 *		of the target buffer, put the pieces of the file name
 *		together into the output buffer. If the pathname is
 *		not fully qualified, prepend the current working
 *		directory.
 *
 *		Needs work for MSDOS.
 *
 * RETURNS: the output buffer updated, truncated if the result is
 *		too long
 *
 */
TEXT *
utapath (TEXT	*fullpath,	/* fully qualified path name */
    	 int	 pathlen,	/* length of answer buffer */
		 TEXT	*filename,	/* file name, possibly qualified */
		 TEXT	*suffix)	/* suffix for file name */

{
    TEXT *ptxt;		/* current location */
    int	 used = 0;	/* amount used */
    int	 drvno = 0;	
#if OPSYS==WIN32API

        int  i,
             j;
#endif

    /* if file name not fully qualified, get pathname of current
       working directory into answer buffer */
#if OPSYS==UNIX
    if (*filename != '/')
#endif

#if OPSYS==WIN32API
    /* handle drive specfier, if any */
    j = stlen(filename);    
    for (i = 1, ptxt = filename; i <= j; i++, ptxt++)
        if (*ptxt == ':') break;
    if (i < j && i != 2)       
    {     /* file server volume name is specified */
        bufcop(fullpath, filename, i);
        used += i;
        filename += i;
    }
    if ((i == 2) && (filename[1] == ':'))
    {	bufcop(fullpath, filename, 2);
	used += 2;
	drvno = toupper(*filename) - 64;      /* A = 1 B = 2 ..etc */
	filename += 2;
    }
    else
	drvno = 0;   /* means use current drive */

    if ((*filename != '/') && (*filename != '\\'))
#endif  /* OPSYS == WIN32API */
    {
        
        used += utpwd (fullpath+used, pathlen ,drvno);


        if (*filename)
        {
	        if((*(fullpath+used-1) != '\\') && (*(fullpath+used-1) != '/'))
	        {    ptxt = (TEXT *)stcopy ( (TEXT *)fullpath+used, (TEXT *)"/" );
	            ++used;
	        }
        }
    }

    ptxt = fullpath + used;

    /* move in filename and suffix */
    used += stncop ( ptxt, filename, (pathlen - used) );
    ptxt = fullpath + used;
    used += stncop ( ptxt, suffix, (pathlen - used) );
    used = utfCompressPath(fullpath);
    /* return pointer to null terminator */
    return (fullpath + used);
}
Exemple #4
0
/* PROGRAM: rlmemwt - write the transaction table and phy. backout flag
 *		      into an rlnote
 *
 * RETURNS: DSMVOID
 */
DSMVOID
rlmemwt(dsmContext_t *pcontext)
{
    dbcontext_t *pdbcontext = pcontext->pdbcontext;
    dbshm_t     *pdbpub = pdbcontext->pdbpub;
    MEMNOTE      note;
    TEXT        *ptx;
    TX          *ptrn;
    TEXT        *pdata;
    COUNT        dlen;
    TRANTAB     *ptran = pdbcontext->ptrantab;
    int          i,j,numToGo;
	
TRACE_CB(pcontext, "rlmemwt")

    INITNOTE(note, RL_INMEM, RL_PHY );

    note.rlpbkout = pdbcontext->prlctl->rlpbkout;
    note.lasttask = pdbcontext->pmstrblk->mb_lasttask;
    note.numLive  = pdbcontext->ptrantab->numlive;
    note.numMemnotes = (note.numLive / (UCOUNT)MAX_ENTRIES_PER_NOTE) + 1; 
    note.tmsize = sizeof (TX) - sizeof(txPlus_t);

    /* This is a funny note.  It describes physical state but since no action
    is taken and no database blocks depend on it so we'll write it with... */

    note.rlnote.rlArea   = 0;	/* bug 20000114-034 by dmeyer in v9.1b */
    note.rlnote.rldbk	 = 0;
    note.rlnote.rlupdctr = 0;
    
    note.spare[0] = 0;
    note.spare[1] = 0;
    
    /* put 0 in the trn id part of the note */
    note.rlnote.rlTrid = 0;

    if ( ptran->numlive > MAX_ENTRIES_PER_NOTE )
        note.numThisNote = MAX_ENTRIES_PER_NOTE;
    else
        note.numThisNote = ptran->numlive;
	
    dlen = note.numThisNote * note.tmsize;
    /* bug 93-01-21-035: use stRent instead of stkpush */

    pdata = (TEXT *)stRentd (pcontext, pdsmStoragePool, (unsigned)dlen);
    
    numToGo = ptran->numlive;
    ptrn = ptran->trn;
    for ( j = 0; j < (int)note.numMemnotes; j++)
    {
       note.noteSequence = j + 1;

       MT_LOCK_AIB();
       note.aiupdctr = pdbcontext->pmstrblk->mb_aictr;
       note.ainew    = pdbcontext->pmstrblk->mb_ai.ainew;

       if(pdbcontext->ptlctl)
       {
           note.tlWriteBlockNumber = pdbcontext->ptlctl->writeLocation;
           note.tlWriteOffset = pdbcontext->ptlctl->writeOffset;

       }
       else
       {
           note.tlWriteBlockNumber = 0;
           note.tlWriteOffset = 0;
       }
       
       if (pdbpub->qaictl)
           note.aiwrtloc =
               pdbcontext->paictl->ailoc + pdbcontext->paictl->aiofst;

       else note.aiwrtloc = 0; /* bug 20000114-034 by dmeyer in v9.1b */

       MT_UNLK_AIB();
       
       for(i=note.numThisNote, ptx = pdata;
	i > 0; ptrn++)
       {
          /* Only copy the transaction if it is in an active state */
	  if (ptrn->txstate && (ptrn->txstate != TM_TS_ALLOCATED) )
	  {
	     bufcop (ptx, (TEXT *)ptrn, note.tmsize);
	     ptx += note.tmsize;
	     i--;
	  }
       }

       /* Why not just use rlputnote here? */
       rlwrite(pcontext, (RLNOTE *)&note, dlen, pdata);
       if (rlainote (pcontext, (RLNOTE *)&note))
       {
	  /* write note to ai also. Notice that the ai information which is
	     recorded in the note will change when we do this. */
	  
	  MT_LOCK_AIB ();
	  
	  rlaiwrt (pcontext, (RLNOTE *)&note, dlen, pdata,
                   ++pdbcontext->pmstrblk->mb_aictr,
		   pcontext->pusrctl->uc_lstdpend);
	  
	  MT_UNLK_AIB ();
       }
       numToGo -= note.numThisNote;
       if( numToGo > MAX_ENTRIES_PER_NOTE )
	  note.numThisNote = MAX_ENTRIES_PER_NOTE;
       else
       {
	  note.numThisNote = numToGo;
	  dlen = numToGo * note.tmsize;
       }
       
    }
    /* bug 93-01-21-035: use stVacate instead of stkpop */
    stVacate (pcontext, pdsmStoragePool, pdata);
    
    /* Write out the ready to commit tx table if there any */
    if( pdbcontext->ptrcmtab != NULL )
	rlrctwt(pcontext);
	
}  /* end rlmemwt */
Exemple #5
0
dsmStatus_t
dsmBlobDmp(
    dsmContext_t        *pcontext,      /* IN database context */
    dsmBlob_t           *pBlob,         /* IN blob descriptor */
    GBOOL                 silent)        /* IN silent except if an error */
{
    dsmStatus_t   returnCode;
    dbcontext_t  *pdbcontext;
    xDbkey_t      xDbkey;        /* extended dbkey (area & recid) */
    LONG          recordSize, segRC;
    LONG          maxRecordSize;
    dsmBuffer_t *pRecord;       /* With the 1 byte indicator */
    dsmBuffer_t *pSegTab;       /* With the 1 byte indicator */
    dsmBuffer_t *pST;           /* within pSegTab */
    LONG          nent;          /* number seg tab entries */
    LONG          segLen;
    LONG          i;
    LONG         remainder;
    long	 tl;
    LONG          n_ds = 0, n_ss = 0;
    dsmBuffer_t  pName [] = "bozo";
    void         printf (...);

    TRACE_CB(pcontext, "dsmBlobDmp");

    pdbcontext = pcontext->pdbcontext;
    if (pdbcontext->usertype & SELFSERVE) 
    {
	if (pdbcontext->resyncing || lkservcon(pcontext))
	    return DSM_S_CTRLC;                  /* Self-service only */
    }

    xDbkey.dbkey = pBlob->blobId;

    if (!silent)
        printf ("\nBlobId: %10ld ", xDbkey.dbkey);

    returnCode = omIdToArea (pcontext, DSMOBJECT_BLOB, 
                             (COUNT)pBlob->blobObjNo, &(xDbkey.area));

    if (returnCode) {
        if (!silent)
            printf ("omIdToArea for object Type: %ld blobObjNo: %ld returned %ld <--\n",
                    DSMOBJECT_BLOB, pBlob->blobObjNo, returnCode);
        return returnCode;
    }

    pdbcontext->inservice++;
    
    maxRecordSize = DSMBLOBMAXLEN + 1;

    pRecord = (dsmBuffer_t *)utmalloc (maxRecordSize);
    if (!pRecord)
    {
        pdbcontext->inservice--;
        returnCode = DSM_S_BLOBNOMEMORY;
        return returnCode;
    }

    /* returns size of record if record is found.  Returns
     * a negative number if record is not found.
     */
    recordSize = rmFetchRecord(pcontext, xDbkey.area, xDbkey.dbkey, pRecord,
                            (COUNT)maxRecordSize, 0 /* not continuation */);
    if (recordSize == 4 && xlng (pRecord) == 0) 
    {
        pBlob->segLength = 0;
        returnCode = DSM_S_BLOBDNE;
        if (!silent)
            printf ("D.N.E. recordSize: 4, record: 0 0 0 0 <--\n");
    }
    else if (recordSize < 0) 
    {
        pBlob->segLength = 0;
	returnCode = (dsmStatus_t) recordSize;
        if (!silent)
            printf ("returnCode: %ld <--\n", returnCode);
    }
    else
    {
        returnCode =  DSM_S_BLOBOK;

        /* Set the total length of the blob */

        if (*pRecord == DSMBLOBDATA) 
        {
            n_ds++;
            pBlob->totLength = recordSize - 1;
        } else if (recordSize > 10)
            pBlob->totLength = xlng (pRecord + 7);
        else {
            pBlob->totLength = 0;
            returnCode = DSM_S_BLOBBAD;
        }

        if (!silent)
            printf ("Length: %10ld Type: %s\n", pBlob->totLength,
                    (char *) ((*pRecord == DSMBLOBDATA) ? "Direct" :
                              (*pRecord == DSMBLOBSEG) ? "Segmented" : "Bad <--"));
        tl = remainder = pBlob->totLength;

        if (returnCode == DSM_S_BLOBOK && *pRecord != DSMBLOBDATA) {
            if (xlng(pRecord+3) == 0)       /* Only 1 seg table */
                pSegTab = utmalloc (recordSize);
            else
                pSegTab = utmalloc (BLOBMAXSEGTAB);
            if (!pSegTab) 
            {
               utfree (pRecord);
               pdbcontext->inservice--;
               returnCode = DSM_S_BLOBNOMEMORY;
               return returnCode;
            }

            bufcop (pSegTab, pRecord, recordSize);

            while (returnCode == DSM_S_BLOBOK) 
            {
                n_ss++;
                pST = pSegTab + SEGHDR_LEN;
                nent = xct (pSegTab + 1);
                if (!silent) 
                    printf (" SegTab: %10ld number entries: %d %s\n", 
                            xDbkey.dbkey, nent, ((nent < 1 || nent > MAXSEGENT) ?
                                                 "<--" : ""));

                if (nent < 1 || nent > MAXSEGENT) 
                {
                    returnCode = DSM_S_BLOBBAD;
                    break;
                }
 
                for (i = 0; i < nent; i++, pST += SEGENT_LEN)
                {
                    segLen = xct (pST);
                    xDbkey.dbkey = xlng (pST + 2);
                    segRC = rmFetchRecord(pcontext, xDbkey.area,
                                       xDbkey.dbkey, pRecord,
                                       (COUNT)maxRecordSize, 0);
                    if (segRC <= 0) 
                    {
                        printf (" Seg%3d: %10ld returnCode: %d <--\n", i, 
                                xDbkey.dbkey, segRC);
                        returnCode = (dsmStatus_t)
                            (segRC ? segRC : DSM_S_BLOBBAD);
                        break;
                    }
                    if (segRC - 1 != xct (pST) || 
                        *pRecord != DSMBLOBDATA) 
                    {
                        printf (" Seg%3d: %10ld Len: %d ActualLen: %d type: %d <--\n",
                                i, xDbkey.dbkey, xct (pST), segRC - 1, *pRecord);
                        returnCode = DSM_S_BLOBBAD;
                        break;
                    }
                    if (!silent)
                         printf (" Seg%3d: %10ld Len: %d\n", i, xDbkey.dbkey, xct (pST));
                    n_ds++;
                    remainder -= xct (pST);
                } /* for i ... < nent */

                if (returnCode != DSM_S_BLOBOK)
                    break;

                xDbkey.dbkey = xlng (pSegTab + 3);

                if (!silent)
                    printf ("  N Seg: %10ld\n", xDbkey.dbkey);

                if (!xDbkey.dbkey) {
                    break;
                }
                returnCode = dbBlobFetch (pcontext, &xDbkey, pSegTab,
                                           BLOBMAXSEGTAB, 
                                           DSMBLOBSEG, pName);
            } /* while remainder */

            if (remainder)
                printf ("Length error: remainder: %10ld <--\n", remainder);

            utfree (pSegTab);

        } /* inital blob segemnt ok */
    } /* initial rmfetch ok */

    utfree (pRecord);

    pdbcontext->inservice--;
    if (!silent)
         printf ("tl: %10ld ds: %4d ss: %4d\n", tl, n_ds, n_ss);
    return returnCode;
}
Exemple #6
0
int
cxDoSplit(
        dsmContext_t    *pcontext,
	dsmTable_t table, /* Table number the index is on  */
        FINDP   *pfndp,   /* parameter block for the FIND */
        CXBAP   *pbap,    /* block access params at the next higher level. */
                          /* Its descrption is put here                    */
        int     leftents) /* number of entry left in the left block by split*/
{
        CXBLK     *pixblk;      /* the idx block to be split */
        TEXT      *pos;
        TEXT      *pend;
        COUNT      len1, len2;
        CXSPLIT    note;
        int        cs;
        TEXT    tmp[MAXDBBLOCKSIZE+MAXKEYSZ];

    pixblk = pfndp->pblkbuf;

    /* get a firm grip on both blocks */
    /**** the in use count guaranties that the old block is there */
    /* get new block - the right block  */
    cxGetNewBlock(pcontext, table, pfndp->pkykey->index,
		  pfndp->pkykey->area,pbap);

    /* decide the split point */
    pos = pfndp->position; /* split position */
    len1 = pos - pixblk->ixchars;

    len2 = pixblk->IXLENENT - len1;
    INITNOTE( note, RL_CXSP1, RL_PHY );
    INIT_S_CXSPLIT_FILLERS( note );	/* bug 20000114-034 by dmeyer in v9.1b */

    bufcop( &(note.ixhdr1), &(pixblk->ix_hdr), sizeof(note.ixhdr1) );
    bufcop( &(note.ixhdr2), &(pixblk->ix_hdr), sizeof(note.ixhdr2) );
    note.extracs = 0;

/*    if (len2 && *pos)    if key in split position is compressed */ 
    cs = CS_GET(pos);
    if (len2 && cs)     /* if key in split position is compressed */
    {

        /* the 1st entry in the new block is compressed, we must
        have the missing part in the note to allow decompression */
/*        note.extracs = *pos; */
        note.extracs = cs;
        pend = pixblk->ixchars + pixblk->IXLENENT;
        if ((MAXIXCHRS - pixblk->IXLENENT) < note.extracs)
        {
            /* no space in the block, use tmp area */
            bufcop(&tmp[0], pos, len2);
            bufcop(&tmp[0] + len2, pfndp->pinpkey, note.extracs);
            pos = &tmp[0];
        }
        else
        {
            /* there is space to attach the extra at end of the block data */
            bufcop(pend, pfndp->pinpkey, note.extracs);
        }
    }
    note.ixhdr1.ih_lnent = len1;
    note.ixhdr2.ih_lnent = len2 + note.extracs;
    note.ixhdr1.ih_nment = leftents;
    note.ixhdr2.ih_nment -= leftents;

    /* Do the original block */
    rlLogAndDo (pcontext, (RLNOTE *)&note, pfndp->bufHandle,
                 (COUNT)(len2+note.extracs), (TEXT *)pos);

    /* and then the new block */
    note.rlnote.rlcode = RL_CXSP2;
    rlLogAndDo (pcontext, (RLNOTE *)&note, pbap->bufHandle,
                 (COUNT)(len2+note.extracs), (TEXT *)pos);

    return(0);

}  /* cxDoSplit */
Exemple #7
0
/* PROGRAM: dsmMandatoryFieldsCachePut - build mandatory field cache and it
 *                                       is stored in shared memory
 *
 * RETURNS: DSM_S_SUCCES
 *
 */
dsmStatus_t
dsmMandatoryFieldsPut(dsmContext_t *pcontext,
           struct meta_filectl *pInMetactl,    /* new metadata ctl for cache */
           struct meta_filectl *pOldmetactl,   /* old metadata ctl for cache */
           DL_VECT             *pdl_vect_in,   /* next dl column vector */
           DL_VECT             *pdl_col_in,    /* next dl columns list to use */
           int                 ndl_ent,        /* # delayed columns */
           int                 mandtblSize,    /* size of mand fld table */
           int                 useCache,       /* use shm cache ? */
           struct mand         *pmand)         /* storage for all mand flds */
{
    dbcontext_t           *pdbcontext = pcontext->pdbcontext;
    dbshm_t               *pdbshm     = pdbcontext->pdbpub;
    dsmStatus_t           returnCode;
    SHPTR                 *pmandhashtbl, qhashentry;
    struct meta_filectl   *pmetactl = NULL;
 
    pdbcontext->inservice++; /* postpone signal handler processing */

    SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */

    if ((returnCode = dsmThreadSafeEntry(pcontext)) != DSM_S_SUCCESS)
    {
        returnCode = dsmEntryProcessError(pcontext, returnCode,
                      (TEXT *)"dsmMandatoryFieldsPut");
        goto done;
    }
 
    /* get the schema cache latch */
    MT_LOCK_SCC ();
 
    /* Check if the entry already exists */
    dsmMandFindEntry(pcontext, &pmetactl, pInMetactl->fildbk, 
                     pInMetactl->filno, FILE_IDENT_DBKEY);

    if (pmetactl != NULL)
    {
        /* entry had already been made */
        goto okdone;
    }

    /* get ptr to hash table array */
    if (pdbshm->qmandctl)
        pmandhashtbl = (SHPTR *) QP_TO_P(pdbcontext, pdbshm->qmandctl);
    else /* need to allocate it */
    {
        pmandhashtbl = (SHPTR *)
            stRent(pcontext, XSTPOOL(pdbcontext, pdbshm->qdbpool),
                   SIZE_MAND_HASH * sizeof(SHPTR));
        pdbshm->qmandctl = P_TO_QP(pcontext, pmandhashtbl);
    }

    /* allocate storage in shm */
    pmetactl = (struct meta_filectl *)stRent(pcontext,
                       XSTPOOL(pdbcontext, pdbshm->qdbpool),
                       (unsigned)(sizeof(struct meta_filectl) + mandtblSize));
 
    pmetactl->fildbk            = pInMetactl->fildbk;
    pmetactl->filno             = pInMetactl->filno;
    pmetactl->nmand             = pInMetactl->nmand;
    pmetactl->schemavers        = pInMetactl->schemavers;
    if ( (useCache != MANB_USECACHE_NONE) &&
         (mandtblSize > 0) )
    {
        bufcop(pmetactl->mand, pmand, (int) mandtblSize);
    }
 
    if ((useCache == MANB_USECACHE_PHYSICAL) &&
        (pOldmetactl != NULL))
    {
        pOldmetactl->filno          = 0;
        pOldmetactl->fildbk         = 0;
    }
 
    /* Chain this structure in shared memory.  The assumption is that
       an entry for this fildbk does not already exist on the cache. */
    qhashentry = pmandhashtbl[ABS(pmetactl->filno) % SIZE_MAND_HASH];
        
    pmetactl->qnext   = qhashentry;
    pmandhashtbl[ABS(pmetactl->filno) % SIZE_MAND_HASH] =
        P_TO_QP(pcontext, pmetactl);
 
    DEBUG_FPRINTF(pmetactl, "dbmanb (chained to sh mem):");

okdone:
    MT_UNLK_SCC ();

    returnCode = DSM_S_SUCCESS;

done:
    dsmThreadSafeExit(pcontext);
    pdbcontext->inservice--;

    return returnCode;
}