/* PROGRAM: dsmBlobUnlock - Unlock an explicitly locked blob * * RETURNS: status code received from rmUpdateRecord, lkrels or other procedures * which this procedure invokes. */ dsmStatus_t dsmBlobUnlock( dsmContext_t *pcontext, /* IN database context */ dsmBlob_t *pBlob) /* IN blob descriptor */ { dsmStatus_t returnCode = DSM_S_BLOBLIMIT; TRACE_CB(pcontext, "dsmBlobUnlock"); pcontext->pdbcontext->inservice++; /* "post-pone" signal handling while in DSM API */ SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */ returnCode = dsmThreadSafeEntry(pcontext); if (DSM_S_SUCCESS == returnCode) { returnCode = dbBlobUnlock(pcontext, pBlob); } else { returnCode = dsmEntryProcessError(pcontext, returnCode, (TEXT *)"dsmBlobUnlock"); } done: dsmThreadSafeExit(pcontext); pcontext->pdbcontext->inservice--; return returnCode; } /* end dsmBlobUnlock */
dsmStatus_t dsmBlobPut( dsmContext_t *pcontext, /* IN database context */ dsmBlob_t *pBlob, /* IN blob descriptor */ dsmText_t *pName) /* IN reference name for messages */ { dsmStatus_t returnCode = DSM_S_BLOBLIMIT; TRACE_CB(pcontext, "dsmBlobPut"); pcontext->pdbcontext->inservice++; /* "post-pone" signal handling while in DSM API */ SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */ returnCode = dsmThreadSafeEntry(pcontext); if (DSM_S_SUCCESS == returnCode) { returnCode = dbBlobPut(pcontext, pBlob, pName); } else { returnCode = dsmEntryProcessError(pcontext, returnCode, (TEXT *)"dsmBlobPut"); } #ifdef DSM_BLOB_PUT_TEST MSGD_CALLBACK(pcontext, "%LdsmBlobPut: maxLength = %l", pBlob->maxLength); MSGD_CALLBACK(pcontext, "%LdsmBlobPut: segLength = %l", pBlob->segLength); MSGD_CALLBACK(pcontext, "%LdsmBlobPut: totLength = %l", pBlob->totLength); #endif done: dsmThreadSafeExit(pcontext); pcontext->pdbcontext->inservice--; return returnCode; } /* end dsmBlobPut */
DSMVOID kyinitKeydb( dsmKey_t *pkkey, COUNT ixnum, COUNT numcomps, GTBOOL substrok) { TEXT *pkeystr; COUNT i; #if 1 TRACE("kyinit") #else TRACE_CB(pcontext, "kyinit") #endif /* initialize the key format part of the ditem */ pkkey->index = ixnum; pkkey->keycomps = numcomps; pkkey->ksubstr = substrok; #if 0 /* make sure the keystring is long enough for the dummy key */ /* BUM - assume numcomps always > 0 */ if ((UCOUNT)(numcomps + 2) > pkditem->dpad) FATAL_MSGN_CALLBACK(pcontext, ixFTL003); /*FATAL*/ #endif /* now initialize the dummy keystring */ pkeystr = pkkey->keystr; *(TTINY*)pkeystr = numcomps + 2; for (i=0; i<numcomps; i++) *(TTINY*)++pkeystr = KEY_ILLEGAL; *(TTINY*)++pkeystr = numcomps + 2; return; } /* end kyinitKeydb */
/* 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 *)¬e, dlen, pdata); if (rlainote (pcontext, (RLNOTE *)¬e)) { /* 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 *)¬e, 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 */
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; }