void cvolcm_FlushNode(pwr_tStatus* sts, gdb_sNode* np) { pool_sQlink* vl; gdb_sVolume* vp; gdb_sCclassVolume* cvp; pwr_tStatus lsts; gdb_AssumeLocked; pwr_Assert(np != gdbroot->my_node && np != gdbroot->no_node); for (vl = pool_Qsucc(NULL, gdbroot->pool, &np->own_lh); vl != &np->own_lh; vl = pool_Qsucc(NULL, gdbroot->pool, &np->own_lh)) { vp = pool_Qitem(vl, gdb_sVolume, l.own_ll); pwr_Assert(vp->l.flags.b.isCached); if (vp->l.flags.b.isCached) cvolcm_FlushVolume(NULL, vp); } for (vl = pool_Qsucc(NULL, gdbroot->pool, &np->ccvol_lh); vl != &np->ccvol_lh; vl = pool_Qsucc(NULL, gdbroot->pool, &np->ccvol_lh)) { cvp = pool_Qitem(vl, gdb_sCclassVolume, ccvol_ll); hash_Remove(&lsts, gdbroot->ccvol_ht, cvp); if (EVEN(lsts)) errh_Bugcheck(lsts, "cached class volume inconsistency"); pool_Qremove(NULL, gdbroot->pool, &cvp->ccvol_ll); pool_Free(NULL, gdbroot->pool, cvp); } }
static qdb_sQue * addQueue ( qdb_sAppl *ap, qcom_tQix qix, char *name, qdb_eQue type, pwr_tBitMask flags ) { pwr_tStatus sts; qcom_sQid qid; qdb_sQue *qp; qid.nid = qdb->g->nid; qid.qix = qix; qp = qdb_AddQue(&sts, qix); if (qp == NULL) errh_Bugcheck(sts, "qdb_AddQue(&sts, &qid)"); qp->type = type; qp->flags.m = flags; strcpy(qp->name, name); if (qp->flags.b.broadcast) { qdb_AddBond(&sts, qp, qdb->exportque); } if (ap != NULL) { pool_QinsertPred(&sts, &qdb->pool, &qp->que_ll, &ap->que_lh); qp->aid = ap->aid; } return qp; }
void cvolcm_ExternVolumeFlush(gdb_sNode* np) { pool_sQlink* vl; gdb_sVolume* vp; pool_sQlink* ol; gdb_sObject* op; gdb_sMountServer* msp; pwr_tStatus sts; // Flush local node gdb_AssumeLocked; for (vl = pool_Qsucc(NULL, gdbroot->pool, &np->own_lh); vl != &np->own_lh; vl = pool_Qsucc(NULL, gdbroot->pool, vl)) { vp = pool_Qitem(vl, gdb_sVolume, l.own_ll); pwr_Assert(vp->l.flags.b.isCached); if (vp->l.flags.b.isCached) { for (ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh); ol != &vp->l.obj_lh; ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh)) { op = pool_Qitem(ol, gdb_sObject, l.obj_ll); if (op->l.flags.b.isMountServer) { msp = (gdb_sMountServer*)hash_Search( &sts, gdbroot->ms_ht, &op->g.oid); if (msp == NULL) errh_Bugcheck(sts, "mount server inconsitency"); msp->msor = pool_cNRef; pool_Qremove(NULL, gdbroot->pool, &msp->nodms_ll); /* Todo !!! Clear alarm and blocklevel in all mount clients. */ } cvol_FlushObject(op); } } } }
static pool_sSegment * mapSegment ( pwr_tStatus *sts, pool_sHead *php, pool_sSegment *psp ) { pwr_tStatus lsts; sect_sHead *shp; pwr_tBoolean created; char name[16]; pool_sGhead *gphp = php->gphp; /* Map the section */ segName(name, gphp->name, psp->gpsp->generation); shp = sect_Alloc(&lsts, &created, &psp->sect, psp->gpsp->size << pool_cOffsGranul, name); if (shp == NULL) errh_ReturnOrBugcheck(NULL, sts, lsts, ""); if (created) errh_Bugcheck(POOL__NOTCREATED, "pool was not created"); psp->generation = psp->gpsp->generation; psp->base = psp->sect.base; return psp; }
gdb_sNode * gdb_AddNode ( pwr_tStatus *sts, pwr_tNodeId nid, pwr_tBitMask flags ) { gdb_sNode *np; gdb_AssumeLocked; np = hash_Search(sts, gdbroot->nid_ht, &nid); if (np != NULL) return np; if (np != NULL) { if (flags & gdb_mAdd_failIfAdded) pwr_Return(NULL, sts, GDB__DUPLADD); else pwr_Return(np, sts, GDB__ALRADD); } np = pool_Alloc(sts, gdbroot->pool, sizeof(*np)); if (np == NULL) return NULL; np->nid = nid; np->buf_id = 1; /* Next available buffer id */ pool_Qinit(NULL, gdbroot->pool, &np->nid_htl); pool_Qinit(NULL, gdbroot->pool, &np->nod_ll); pool_Qinit(NULL, gdbroot->pool, &np->own_lh); pool_Qinit(NULL, gdbroot->pool, &np->ccvol_lh); pool_Qinit(NULL, gdbroot->pool, &np->nodms_lh); pool_Qinit(NULL, gdbroot->pool, &np->nodmo_lh); pool_Qinit(NULL, gdbroot->pool, &np->subc_lh); pool_Qinit(NULL, gdbroot->pool, &np->nodsubs_lh); pool_Qinit(NULL, gdbroot->pool, &np->nodsubb_lh); pool_Qinit(NULL, gdbroot->pool, &np->sansAct_lh); pool_Qinit(NULL, gdbroot->pool, &np->sansUpd_lh); pool_Qinit(NULL, gdbroot->pool, &np->sancAdd_lh); pool_Qinit(NULL, gdbroot->pool, &np->sancRem_lh); pool_Qinit(NULL, gdbroot->pool, &np->sancAct_lh); pool_Qinit(NULL, gdbroot->pool, &np->cacheNode.lh); #if defined OS_ELN np->cacheNode.lc_max = 100; #else np->cacheNode.lc_max = 200; #endif np->cacheNode.flags.b.cacheNode = 1; np->cacheNode.next = pool_Reference(NULL, gdbroot->pool, &gdbroot->db->cacheCom); np = hash_Insert(sts, gdbroot->nid_ht, np); if (np == NULL) errh_Bugcheck(GDH__WEIRD, "adding new node"); pool_QinsertPred(NULL, gdbroot->pool, &np->nod_ll, &gdbroot->db->nod_lh); return np; }
gdb_sAliasServer * gdb_AddAliasServer ( pwr_tStatus *sts, pwr_tObjid soid, pwr_tBitMask flags ) { gdb_sAliasServer *asp; gdb_sObject *op = NULL; gdb_AssumeLocked; pwr_Assert(cdh_ObjidIsNotNull(soid)); asp = hash_Search(sts, gdbroot->as_ht, &soid); if (asp != NULL) { if (flags & gdb_mAdd_failIfAdded) pwr_Return(NULL, sts, GDB__DUPLADD); else pwr_Return(asp, sts, GDB__ALRADD); } asp = pool_Alloc(sts, gdbroot->pool, sizeof(*asp)); if (asp == NULL) return NULL; asp->oid = soid; pool_Qinit(NULL, gdbroot->pool, &asp->as_htl); pool_Qinit(NULL, gdbroot->pool, &asp->as_ll); pool_Qinit(NULL, gdbroot->pool, &asp->cli_lh); asp = hash_Insert(sts, gdbroot->as_ht, asp); if (asp == NULL) errh_Bugcheck(GDH__WEIRD, "adding new alias server"); pool_QinsertPred(NULL, gdbroot->pool, &asp->as_ll, &gdbroot->db->as_lh); op = hash_Search(sts, gdbroot->oid_ht, &soid); if (op == NULL) errh_Bugcheck(GDH__WEIRD, "getting alias server object"); op->g.flags.b.isAliasServer = 1; return asp; }
static void respondError ( qcom_sGet *get, pwr_tObjid oid, pwr_tStatus rspsts ) { pwr_tStatus sts; net_sObjectR *rsp; qcom_sPut put; rsp = net_Alloc(&sts, &put, sizeof(*rsp), net_eMsg_objectR); if (rsp == NULL) errh_Bugcheck(sts, "net_Alloc"); rsp->sts = rspsts; rsp->oid = oid; rsp->count = 0; if (!net_Reply(&sts, get, &put, 0)) errh_Bugcheck(sts, "net_Reply"); }
static pool_sSegment * newSegment ( pwr_tStatus *sts, pool_sHead *php, size_t size /* Requested size in pool_sEntry units */ ) { pool_sGhead *gphp; pool_sGsegment *gpsp; pool_sSegment *psp; sect_sHead *shp; pwr_tBoolean created; pwr_tUInt32 i; char name[16]; if (size << pool_cOffsAlign > pool_cMaxSize) pwr_Return(NULL, sts, POOL__TOOBIG); gphp = php->gphp; /* Find an empty slot */ for (i = 0; i < pool_cSegs; i++) if (gphp->seg[i].generation == 0) break; if (i >= pool_cSegs) pwr_Return(NULL, sts, POOL__NOSLOT); gpsp = &gphp->seg[i]; psp = &php->seg[i]; /* Allocate the section */ segName(name, gphp->name, gphp->generation), shp = sect_Alloc(sts, &created, &psp->sect, size << pool_cOffsAlign, name); if (shp == NULL) return NULL; if (!created) errh_Bugcheck(POOL__ALLREXIST, ""); gpsp->type = pool_eSegType_dynamic; gpsp->size = size << (pool_cOffsAlign - pool_cOffsGranul); gpsp->fragmax = gpsp->fragsize = size; gpsp->generation = psp->generation = gphp->generation++; gpsp->alloccnt = 0; gpsp->fragcnt = gpsp->fragmaxcnt = 1; psp->base = psp->sect.base; psp->base->size = size; psp->base->next = pool_cNOffset; gpsp->freeroot.next = 0; return psp; }
static void deleteClient ( sub_sClient *cp ) { pwr_tStatus sts; gdb_sNode *np; gdb_AssumeLocked; cancelTimeoutWatch(cp); subc_RemoveFromMessage(cp); hash_Remove(&sts, gdbroot->subc_ht, cp); if (EVEN(sts)) errh_Bugcheck(sts, "remove client from hash table"); np = hash_Search(&sts, gdbroot->nid_ht, &cp->nid); if (np == NULL) errh_Bugcheck(sts, "node not found"); pool_Qremove(&sts, gdbroot->pool, &cp->subc_ll); np->subc_lc--; if (cp->userdata != pool_cNRef) { pool_FreeReference(NULL, gdbroot->rtdb, cp->userdata); } if (cp->cclass != pool_cNRef) { gdb_sCclass *ccp; ccp = pool_Address(NULL, gdbroot->pool, cp->cclass); if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "cached class address"); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; } pool_Free(NULL, gdbroot->pool, cp); }
void dl_Cancel ( pwr_tStatus *sts, pwr_tDlid dlid ) { dl_sLink *dp; gdb_sObject *op; cdh_uRefId rid; gdb_AssumeLocked; rid.pwr = dlid; if (rid.r.vid_3 != cdh_eVid3_dlid) { pwr_Status(sts, GDH__DLID); return; } dp = hash_Search(sts, gdbroot->subc_ht, &dlid); if (dp == NULL) { pwr_Status(sts, GDH__DLID); return; } dp = hash_Remove(sts, gdbroot->subc_ht, dp); if (dp == NULL) errh_Bugcheck(GDH__WEIRD, "hash_Remove"); pool_Qremove(NULL, gdbroot->pool, &dp->dl_ll); gdbroot->db->dl_lc--; op = pool_Address(NULL, gdbroot->pool, dp->opr); if (op == NULL) errh_Bugcheck(GDH__WEIRD, "direct link inconsitency"); gdb_UnlockObject(sts, op); pool_Free(NULL, gdbroot->pool, dp); return; }
static void addMyNode (void) { pwr_tStatus sts; qcom_sNode node; gdb_sNode *np; qcom_MyNode(&sts, &node); if (EVEN(sts)) errh_Bugcheck(sts, "qcom_MyNode"); if (node.nid != gdbroot->db->nid) errh_Bugcheck(GDH__WEIRD, "Qcom and Gdb dont agree on node identity"); np = addNode(&node); if (np == NULL) errh_Bugcheck(0, "addNode(myNode)"); gdb_ScopeLock { np->netver = net_cVersion; np->cclassSupport = TRUE; } gdb_ScopeUnlock; }
sub_sClient * subc_Create ( char *name, /* Input or NULL */ pwr_sAttrRef *arp, /* Input or NULL */ pool_sQlink *lh /* List header. */ ) { sub_sClient *cp; sub_sClient *rcp; pwr_tInt32 s; pwr_tStatus sts; gdb_AssumeLocked; s = sizeof(*cp) + (name == NULL ? 0 : strlen (name)); cp = pool_Alloc(NULL, gdbroot->pool, s); cp->sub_by_name = (name != NULL); if (cp->sub_by_name) strcpy(cp->name, name); else cp->aref = *arp; cp->subscriber = gdbroot->my_pid; cp->dt = default_dt; cp->tmo = default_tmo; cp->old = TRUE; /* No data yet */ /* The client is always counted in a np->subc_lc quota and must always be in a pool_sQlink list. */ pool_QinsertPred(NULL, gdbroot->pool, &cp->subc_ll, lh); gdbroot->no_node->subc_lc++; do { gdbroot->db->subcid.rix++; cp->sid = gdbroot->db->subcid; rcp = hash_Insert(&sts, gdbroot->subc_ht, cp); if (rcp != cp && sts != HASH__DUPLICATE) errh_Bugcheck(sts, "hash_Insert"); } while (rcp != cp); return cp; }
dl_sLink * dl_Create ( pwr_tStatus *sts, mvol_sAttribute *ap, pwr_sAttrRef *arp ) { pwr_tStatus lsts; dl_sLink *dp; dl_sLink *rdp; gdb_AssumeLocked; pwr_Assert(ap != NULL); pwr_Assert(ap->op != NULL); pwr_Assert(arp != NULL); dp = pool_Alloc(NULL, gdbroot->pool, sizeof(dl_sLink)); do { gdbroot->db->dlid.rix++; dp->dlid = gdbroot->db->dlid; rdp = hash_Insert(&lsts, gdbroot->subc_ht, dp); if (rdp != dp && lsts != HASH__DUPLICATE) errh_Bugcheck(lsts, "hash_Insert"); } while (rdp != dp); dp->user = gdbroot->my_pid; dp->aref = *arp; dp->opr = pool_ItemReference(NULL, gdbroot->pool, ap->op); /* Lock the object */ gdb_LockObject(sts, ap->op); /* Insert in list of direct links */ pool_QinsertSucc(NULL, gdbroot->pool, &dp->dl_ll, &gdbroot->db->dl_lh); gdbroot->db->dl_lc++; return dp; }
void cvolcm_FlushVolume ( pwr_tStatus *sts, gdb_sVolume *vp ) { pool_sQlink *ol; gdb_sObject *op; gdb_sMountServer *msp; gdb_AssumeLocked; for ( ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh); ol != &vp->l.obj_lh; ol = pool_Qsucc(NULL, gdbroot->pool, &vp->l.obj_lh) ) { op = pool_Qitem(ol, gdb_sObject, l.obj_ll); if (op->l.flags.b.isMountServer) { msp = hash_Search(sts, gdbroot->ms_ht, &op->g.oid); if (msp == NULL) errh_Bugcheck(*sts, "mount server inconsitency"); msp->msor = pool_cNRef; pool_Qremove(NULL, gdbroot->pool, &msp->nodms_ll); /* Todo !!! Clear alarm and blocklevel in all mount clients. */ } cvol_FlushObject(op); } pwr_Assert(vp->l.flags.b.inOwnList); pool_Qremove(NULL, gdbroot->pool, &vp->l.own_ll); vp->l.flags.b.inOwnList = 0; vp->g.nid = pwr_cNNodeId; pwr_Assert(pool_QisEmpty(NULL, gdbroot->pool, &vp->u.c.cacheLock.lh)); pwr_Assert(vp->u.c.cacheLock.lc == 0); pwr_Assert(pool_QisEmpty(NULL, gdbroot->pool, &vp->u.c.cacheVol.lh)); pwr_Assert(vp->u.c.cacheVol.lc == 0); vp->l.flags.b.isConnected = 0; vp->l.flags.b.isCached = 0; vp->l.flags.b.netCached = 0; vp->l.flags.b.remote = 0; }
gdb_sMountServer * gdb_AddMountServer ( pwr_tStatus *sts, pwr_tObjid soid, pwr_tBitMask flags ) { gdb_sMountServer *msp; gdb_AssumeLocked; // pwr_Assert(cdh_ObjidIsNotNull(soid)); if (cdh_ObjidIsNull(soid)) return NULL; msp = hash_Search(sts, gdbroot->ms_ht, &soid); if (msp != NULL) { if (flags & gdb_mAdd_failIfAdded) pwr_Return(NULL, sts, GDB__DUPLADD); else pwr_Return(msp, sts, GDB__ALRADD); } msp = pool_Alloc(sts, gdbroot->pool, sizeof(*msp)); if (msp == NULL) return NULL; msp->oid = soid; pool_Qinit(NULL, gdbroot->pool, &msp->ms_htl); pool_Qinit(NULL, gdbroot->pool, &msp->ms_ll); pool_Qinit(NULL, gdbroot->pool, &msp->nodms_ll); pool_Qinit(NULL, gdbroot->pool, &msp->volms_ll); pool_Qinit(NULL, gdbroot->pool, &msp->cli_lh); msp = hash_Insert(sts, gdbroot->ms_ht, msp); if (msp == NULL) errh_Bugcheck(GDH__WEIRD, "adding new mount server"); pool_QinsertPred(NULL, gdbroot->pool, &msp->ms_ll, &gdbroot->db->ms_lh); return msp; }
gdb_sClass * gdb_AddClass ( pwr_tStatus *sts, pwr_tClassId cid, pwr_tBitMask flags ) { gdb_sClass *cp; #if 0 pwr_Assert(cid != pwr_cNClassId); #endif gdb_AssumeLocked; cp = hash_Search(sts, gdbroot->cid_ht, &cid); if (cp != NULL) { if (flags & gdb_mAdd_failIfAdded) pwr_Return(NULL, sts, GDB__DUPLADD); else pwr_Return(cp, sts, GDB__ALRADD); } cp = pool_Alloc(sts, gdbroot->pool, sizeof(*cp)); if (cp == NULL) return NULL; cp->cid = cid; pool_Qinit(NULL, gdbroot->pool, &cp->cid_htl); pool_Qinit(NULL, gdbroot->pool, &cp->cid_lh); pool_Qinit(NULL, gdbroot->pool, &cp->class_ll); cp = hash_Insert(sts, gdbroot->cid_ht, cp); if (cp == NULL) errh_Bugcheck(GDH__WEIRD, "adding new class"); pool_QinsertPred(NULL, gdbroot->pool, &cp->class_ll, &gdbroot->db->class_lh); return cp; }
void cvolcm_CreateObject(qcom_sGet* get) { pwr_tStatus sts; gdb_sObject* op; gdb_sObject* pop; gdb_sObject* sop; pwr_tObjid soid; net_sCreateObject* cop = (net_sCreateObject*)get->data; gdb_AssumeUnlocked; gdb_ScopeLock { op = hash_Search(&sts, gdbroot->oid_ht, &cop->notify.oid); if (op != NULL) errh_Bugcheck(GDH__WEIRD, "cvolcm_CreateObject: object already exists"); pop = hash_Search(&sts, gdbroot->oid_ht, &cop->par.oid); if (pop == NULL) break; pop->g.soid = cop->par.soid; pop->g.flags.b.isParent = 1; soid = cop->par.oid; soid.oix = cop->sib.blink; sop = hash_Search(&sts, gdbroot->oid_ht, &soid); if (sop != NULL) sop->g.sib.flink = cop->sib.newflink; soid.oix = cop->sib.flink; sop = hash_Search(&sts, gdbroot->oid_ht, &soid); if (sop != NULL) sop->g.sib.blink = cop->sib.newblink; } gdb_ScopeUnlock; }
/** * Adds a remote class volume. */ void cvolcm_AddClassVolume( pwr_tStatus *sts, gdb_sNode *np, const net_sGvolume *vp ) { gdb_sCclassVolume *ccvp; gdb_sVolume *cvp; gdb_AssumeLocked; pwr_Assert(vp != NULL); ccvp = pool_Alloc(sts, gdbroot->pool, sizeof(*ccvp)); if (ccvp == NULL) return; ccvp->key.nid = vp->nid; ccvp->key.vid = vp->vid; ccvp->time = net_NetTimeToTime(&vp->time); cvp = hash_Search(sts, gdbroot->vid_ht, &vp->vid); if (cvp == NULL) /* This volume doesn't exist locally, but we may create it later on */ ccvp->equalClasses = 0; else { pwr_tTime t = net_NetTimeToTime( &cvp->g.time); ccvp->equalClasses = time_Acomp(&ccvp->time, &t) == 0 ? 1 : 0; } ccvp = hash_Insert(sts, gdbroot->ccvol_ht, ccvp); if (ccvp == NULL) errh_Bugcheck(GDH__WEIRD, "adding cached class volume"); pool_QinsertPred(NULL, gdbroot->pool, &ccvp->ccvol_ll, &np->ccvol_lh); }
cvol_sNotify * cvols_InitNotify ( gdb_sObject *op, cvol_sNotify *nmp, net_eMsg subtype ) { unsigned int size = 0; gdb_AssumeLocked; switch (subtype) { case net_eMsg_createObject: size = sizeof(net_sCreateObject); break; case net_eMsg_deleteObject: size = sizeof(net_sDeleteObject); break; case net_eMsg_moveObject: size = sizeof(net_sMoveObject); break; case net_eMsg_renameObject: size = sizeof(net_sRenameObject); break; default: errh_Bugcheck(2, "cvols_InitNotify"); } memset(nmp, 0, size); nmp->subtype = subtype; nmp->size = size; nmp->msg.hdr.oid = op->g.oid; return nmp; }
void * pool_Alloc ( pwr_tStatus *sts, pool_sHead *php, pwr_tUInt32 size ) { pwr_tStatus lsts = 1; pool_sGhead *gphp; pool_sGsegment *gpsp; pool_sSegment *psp; pool_sEntry *ep; pool_sEntry *prevp; pool_sEntry *tmpp; pwr_tUInt32 esize; /* True size ( incl header) in pool_sData units */ pwr_tUInt32 tmpsize; pwr_tBoolean found; pool_uRefBits pr; pwr_tUInt32 i = 0; #if 0 pwr_SetStatus(sts, 1); #endif gphp = php->gphp; if (size == gphp->la[0].size) { if (gphp->la[0].next != pool_cNOffset) return allocLookaside(sts, php, &gphp->la[0]); } else if (size == gphp->la[1].size) { if (gphp->la[1].next != pool_cNOffset) return allocLookaside(sts, php, &gphp->la[1]); } else if (size == gphp->la[2].size) { if (gphp->la[2].next != pool_cNOffset) return allocLookaside(sts, php, &gphp->la[2]); } else if (size == gphp->la[3].size) { if (gphp->la[3].next != pool_cNOffset) return allocLookaside(sts, php, &gphp->la[3]); } esize = entryUnits(size + sizeof(pool_sEntry)); /* Add space for header */ /* Find a segment where there is room. */ found = FALSE; for ( i = 0, gpsp = &gphp->seg[0], psp = &php->seg[0]; i < pool_cSegs; i++, gpsp++, psp++ ) { if (gpsp->generation == 0) break; if (gpsp->type != pool_eSegType_dynamic) continue; if (gpsp->fragmax >= esize) { found = TRUE; break; } } /* Allocate a new segment if noone fits, otherwise make sure the existing segment is mapped. */ if (!found) psp = newSegment(&lsts, php, MAX(gphp->extendsize, esize)); else psp = ensureMapped(&lsts, php, psp); if (psp == NULL) errh_ReturnOrBugcheck(NULL, sts, lsts, ""); /* Walk through the free list of the chosen segment. The segment is pointed out by psp/gpsp! */ ep = NULL; prevp = &gpsp->freeroot; while (prevp->next != pool_cNOffset) { tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize); if (tmpp->size >= esize) { /* Found */ ep = tmpp; break; } /* If the entry is larger or equal to the requested */ prevp = tmpp; /* Try next */ } /* While more entries in free list */ /* Now ep points to the chosen free list entry. Remove this entry from the list, or split it if it is larger than requested. We need to update the fragmentation information, too. If we come here without a selection there is an internal consistency problem. */ if (ep == NULL) errh_Bugcheck(POOL__BUGCHECK, ""); tmpsize = ep->size; if (ep->size == esize || (ep->size - esize > 0 && (ep->size - esize) * pool_cDataSize < sizeof(pool_sEntry))) { /* Entry fits exactly */ prevp->next = ep->next; --gpsp->fragcnt; } else { /* Entry is to big, split it */ prevp->next = prevp->next + esize; tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize); tmpp->next = ep->next; tmpp->size = ep->size - esize; ep->size = esize; } memset( entryPAdd(ep, sizeof(pool_sEntry)), 0, esize*pool_cDataSize - sizeof(pool_sEntry)); ep->next = cEntryMark; gpsp->alloccnt++; gpsp->fragsize -= esize; /* Keep track of the maximum fragment size and count */ if (tmpsize == gpsp->fragmax) { if ((--gpsp->fragmaxcnt) == 0) { /* In this special case we need to */ /* rebuild the fragmax&cnt info */ gpsp->fragmax = 0; gpsp->fragmaxcnt = 1; prevp = &gpsp->freeroot; while (prevp->next != pool_cNOffset) { tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize); if (tmpp->size >= gpsp->fragmax) { if (tmpp->size == gpsp->fragmax) gpsp->fragmaxcnt++; else { gpsp->fragmaxcnt = 1; gpsp->fragmax = tmpp->size; } /* new fragmax entry found */ } /* new or equal to fragmax found */ prevp = tmpp; /* next entry */ } /* While more entries in free list */ } /* If no more fragmax entries left */ } /* If this was a fragmax entry */ pr.m = pool_cNRef; pr.b.seg = psp->seg; pr.b.offs = (pool_tOffset)((char *)ep + sizeof(pool_sEntry) - (char *)psp->base); ep->next = pr.m; return (void *)(entryPAdd(ep, sizeof(pool_sEntry))); }
static gdb_sObject * unadoptObject ( pwr_tStatus *sts, gdb_sObject *op, gdb_sObject *pop, cvol_sNotify *nmp ) { gdb_AssumeLocked; if (nmp != NULL) { switch (nmp->subtype) { case net_eMsg_deleteObject: { net_sDeleteObject *dp = &nmp->msg.d; dp->sib.flink = op->g.sib.flink; dp->sib.newblink = op->g.sib.blink; dp->sib.blink = op->g.sib.blink; dp->sib.newflink = op->g.sib.flink; break; } case net_eMsg_moveObject: { net_sMoveObject *mp = &nmp->msg.m; mp->osib.flink = op->g.sib.flink; mp->osib.newblink = op->g.sib.blink; mp->osib.blink = op->g.sib.blink; mp->osib.newflink = op->g.sib.flink; break; } default: errh_Bugcheck(2, ""); } } vol_RemoveSiblist(sts, op, pop); if (nmp != NULL) { /* Copying the parent must be deferred until after the unadopt, since parent might be affected by that... */ switch (nmp->subtype) { case net_eMsg_deleteObject: { net_sDeleteObject *dp = &nmp->msg.d; dp->par.oid = pop->g.oid; dp->par.soid = pop->g.soid; break; } case net_eMsg_moveObject: { net_sMoveObject *mp = &nmp->msg.m; mp->opar.oid = pop->g.oid; mp->opar.soid = pop->g.soid; break; } default: errh_Bugcheck(2, ""); } } #if 0 op->g.f.poid = pwr_cNObjid; op->l.por = pool_cNRef; #endif pwr_Assert(op->l.flags.b.inFamilyTab); hash_Remove(sts, gdbroot->family_ht, op); op->l.flags.b.inFamilyTab = 0; #if 0 /* !!! To do!! */ malvl = MAX(op->g.alvl, op->g.malvl); mblvl = MAX(op->g.blvl, op->g.mblvl); if (malvl == pop->g.malvl || mblvl == pop->g.mblvl) { op->o.ablvl_idx = ++ghdi->db->ablvl_idx; vol_PropagateAlarmLevel(sts, op, malvl, 0, NO); vol_PropagateBlockLevel(sts, op, mblvl, 0, NO); } #endif return op; }
void ivol_BuildNode ( pwr_tStatus *status, ivol_sNode *lnp, const co_mFormat *formatp ) { gdb_sVolume *vp; pwr_sMountObject *MountObject; cdh_uVolumeId sys_vid; pwr_tObjid sys_oid; pwr_tObjid oid; gdb_sObject *op; gdb_sObject *vop; gdb_sObject *mop; pool_sQlink *vl; gdb_sClass *cp; pool_sQlink *cl; co_mFormat fm; pwr_tTime time; pwr_dStatus(sts, status, GDH__SUCCESS); /* Fill in remaining node information. */ gdbroot->db->nod_oid = lnp->nod_oid; gdbroot->my_node->nod_oid = gdbroot->db->nod_oid; gdbroot->my_node->vol_oid = gdbroot->db->vol_oid; /* Create the system volume and mount it in the root voulme. */ sys_vid.pwr = gdbroot->db->vid; sys_vid.v.vid_3 = cdh_eVid3_local; sys_oid.vid = sys_vid.pwr; sys_oid.oix = pwr_cNObjectIx; time_GetTime(&time); vp = gdb_LoadVolume(sts, sys_vid.pwr, "", pwr_eClass_SystemVolume, gdbroot->db->nid, time, gdb_mLoad_build, co_GetOwnFormat(&fm)); if (vp == NULL) errh_Bugcheck(*sts, ""); /* Create the volume object. */ vop = loadObject(sts, vp, vp->g.name.orig, sys_oid, pwr_eClass_SystemVolume, sizeof(pwr_sSystemVolume), pwr_cNObjid, net_mGo__, pwr_cNObjid); if (vop == NULL) errh_Bugcheck(*sts, ""); vop->u.n.flags.b.bodyDecoded = 1; /* Create the 'pwrNode' object. */ oid = vol_Oid(sts, vp, pwr_eClass_NodeHier); op = loadObject(sts, vp, "pwrNode", oid, pwr_eClass_NodeHier, sizeof(pwr_sNodeHier), sys_oid, net_mGo__, pwr_cNObjid); if (op == NULL) errh_Bugcheck(*sts, ""); op->u.n.flags.b.bodyDecoded = 1; errh_Info("Created pwrNode, oid: %s", cdh_ObjidToString(NULL, oid, 1)); /* Create a mount object in the root volume, to mount the 'pwrNode' object. */ pwr_Assert(gdbroot->my_volume != NULL); oid = vol_Oid(sts, gdbroot->my_volume, pwr_eClass_MountObject); mop = loadObject(sts, gdbroot->my_volume, "pwrNode", oid, pwr_eClass_MountObject, sizeof(pwr_sMountObject), gdbroot->db->vol_oid, net_mGo_isMountClient, op->g.oid); if (mop == NULL) errh_Bugcheck(*sts, ""); mop->u.n.flags.b.bodyDecoded = 1; MountObject = pool_Address(NULL, gdbroot->rtdb, mop->u.n.body); strcpy(MountObject->Description, "Mounts the system volume object pwr_Node."); MountObject->Object = op->g.oid; /* Build all native volumes. */ for ( vl = pool_Qsucc(sts, gdbroot->pool, &gdbroot->db->vol_lh); vl != &gdbroot->db->vol_lh; vl = pool_Qsucc(sts, gdbroot->pool, vl) ) { vp = pool_Qitem(vl, gdb_sVolume, l.vol_ll); if (vp->l.flags.b.isNative) ivol_BuildVolume(sts, vp); } /* Link class definitions. */ for ( cl = pool_Qsucc(sts, gdbroot->pool, &gdbroot->db->class_lh); cl != &gdbroot->db->class_lh; ) { cp = pool_Qitem(cl, gdb_sClass, class_ll); /* NOTA BENE !! mvol_LinkClass will change the linkage. */ cl = pool_Qsucc(sts, gdbroot->pool, cl); mvol_LinkClass(sts, cp, gdb_mAdd__); } /* Link Sub classes to attributes. */ for ( cl = pool_Qsucc(sts, gdbroot->pool, &gdbroot->db->class_lh); cl != &gdbroot->db->class_lh; ) { cp = pool_Qitem(cl, gdb_sClass, class_ll); cl = pool_Qsucc(sts, gdbroot->pool, cl); if (cp->hasSc) mvol_LinkSubClassToAttribute(sts, cp); } /* Build ScObjects for native volumes. */ for ( vl = pool_Qsucc(sts, gdbroot->pool, &gdbroot->db->vol_lh); vl != &gdbroot->db->vol_lh; vl = pool_Qsucc(sts, gdbroot->pool, vl) ) { vp = pool_Qitem(vl, gdb_sVolume, l.vol_ll); if (vp->l.flags.b.isNative) buildScObjects(sts, vp); } /* Build class attribute tree */ mvol_BuildCatt(sts); convFctn = dvms_GetFctns(formatp); if (convFctn != NULL) decodeObjects(formatp->b.bo); convFctn = NULL; mountClients(sts, gdbroot->my_volume); }
static gdb_sVolume * mountVolume ( pwr_tStatus *sts, gdb_sObject *op ) { gdb_sVolume *vp; gdb_sMountServer *msp; void *p; pwr_tObjid soid = pwr_cNObjid; gdb_sObject *vop; co_mFormat fm; pwr_tTime time; if (op->g.oid.vid != gdbroot->db->vid) errh_Bugcheck(GDH__WEIRD, "only root volumes can mount"); p = pool_Address(sts, gdbroot->rtdb, op->u.n.body); if (p == NULL) return NULL; switch (op->g.cid) { case pwr_eClass_MountObject: soid = ((pwr_sMountObject *)p)->Object; if ( cdh_ObjidIsNull(soid)) { *sts = GDH__NOMOUNTOBJECT; return NULL; } vp = vol_MountVolume(sts, soid.vid); break; case pwr_eClass_MountVolume: soid.vid = ((pwr_sMountVolume *)p)->Volume; if ( soid.vid == 0) { *sts = GDH__NOMOUNTOBJECT; return NULL; } vp = vol_MountVolume(sts, soid.vid); break; case pwr_eClass_CreateVolume: soid.vid = ((pwr_sCreateVolume *)p)->Volume; time_GetTime(&time); vp = gdb_LoadVolume(sts, soid.vid, op->g.f.name.orig, pwr_eClass_DynamicVolume, gdbroot->db->nid, time, gdb_mLoad_build, co_GetOwnFormat(&fm)); /* Create the volume object. */ vop = loadObject(sts, vp, vp->g.name.orig, soid, pwr_eClass_DynamicVolume, sizeof(pwr_sDynamicVolume), pwr_cNObjid, net_mGo__, pwr_cNObjid); if (vop == NULL) errh_Bugcheck(*sts, ""); break; } if (vp == NULL) return NULL; pwr_Assert(cdh_ObjidIsEqual(op->g.soid, soid)); if (!op->u.n.flags.b.inMountClientList) { msp = vol_AddMountClient(sts, op); if (msp == NULL) return NULL; } return vp; }
static gdb_sObject * adoptObject ( pwr_tStatus *sts, gdb_sObject *op, gdb_sObject *pop, cvol_sNotify *nmp ) { gdb_AssumeLocked; vol_InsertSiblist(sts, op, pop); /* Connect to parent. */ op->g.f.poid = pop->g.oid; pwr_Assert(!op->l.flags.b.inFamilyTab); hash_Insert(sts, gdbroot->family_ht, op); op->l.flags.b.inFamilyTab = 1; if (nmp != NULL) { switch (nmp->subtype) { case net_eMsg_createObject: { net_sCreateObject *cp = &nmp->msg.c; cp->sib.flink = op->g.sib.flink; cp->sib.newblink = op->g.oid.oix; cp->sib.blink = op->g.sib.blink; cp->sib.newflink = op->g.oid.oix; cp->par.oid = pop->g.oid; cp->par.soid = pop->g.soid; break; } case net_eMsg_moveObject: { net_sMoveObject *mp = &nmp->msg.m; mp->sib = op->g.sib; mp->nsib.flink = op->g.sib.flink; mp->nsib.newblink = op->g.oid.oix; mp->nsib.blink = op->g.sib.blink; mp->nsib.newflink = op->g.oid.oix; mp->npar.oid = pop->g.oid; mp->npar.soid = pop->g.soid; break; } default: errh_Bugcheck(2, ""); } } #if 0 /* !!! To do!!!*/ malvl = MAX(op->g.alvl, op->g.malvl); mblvl = MAX(op->g.blvl, op->g.mblvl); if (malvl > pop->g.malvl || mblvl > op->g.mblvl) { op->o.ablvl_idx = ++gdbroot->db->ablvl_idx; vol_PropagateAlarmLevel(sts, op, 0, malvl, NO); vol_PropagateBlockLevel(sts, op, 0, mblvl, NO); } #endif return op; }
static gdb_sNode * testClient ( pwr_tStatus *sts, sub_sClient *cp ) { pwr_tStatus lsts = GDH__SUCCESS; pwr_tSubid sid = cp->sid; cdh_sParseName parseName; cdh_sParseName *pn; gdb_sObject *op = NULL; sub_sClient *rcp; gdb_sVolume *vp; gdb_sNode *np = NULL; mvol_sAttribute attribute; mvol_sAttribute *ap; pwr_sAttrRef *arp; pwr_sAttrRef *rarp; gdb_sCclass *ccp; gdb_sCclass *ccpLocked; pool_tRef ccr; pwr_tUInt32 ridx; pwr_tBoolean equal; pwr_tBoolean fetched; gdb_AssumeLocked; do { if (cp->sub_by_name) { /* Lookup by name. */ pn = cdh_ParseName(&lsts, &parseName, pwr_cNObjid, cp->name, 0); if (pn == NULL) break; do { ap = vol_NameToAttribute(&lsts, &attribute, pn, gdb_mLo_global, vol_mTrans_all); if (ap == NULL) break; rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ arp = mvol_AttributeToAref(&lsts, ap, &cp->aref); if (arp == NULL) break; op = ap->op; /* */ vp = pool_Address(NULL, gdbroot->pool, op->l.vr); np = hash_Search(&lsts, gdbroot->nid_ht, &vp->g.nid); if (np == NULL) { op = NULL; break; } ccp = NULL; equal = 1; /* Get cached class if needed */ if (!op->u.c.flags.b.classChecked || !op->u.c.flags.b.classEqual) { ccp = cmvolc_GetCachedClass(&lsts, np, vp, ap, &equal, &fetched, NULL); if (EVEN(lsts)) { np = NULL; op = NULL; break; } if (fetched) { rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ } if (equal) { if (cp->cclass != pool_cNRef) { ccp = pool_Address(NULL, gdbroot->pool, cp->cclass); if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "cached class address"); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; } ccp = NULL; } else { ccr = pool_ItemReference(NULL, gdbroot->pool, ccp); if (ccr == pool_cNRef) errh_Bugcheck(GDH__WEIRD, "cache class address to reference"); if (ccr != cp->cclass) { if (cp->cclass != pool_cNRef) { gdb_sCclass *cc2p = pool_Address(NULL, gdbroot->pool, cp->cclass); cmvolc_UnlockClass(NULL, cc2p); } cmvolc_LockClass(NULL, ccp); cp->cclass = ccr; } } /* If gdb has been unlocked, refresh pointers */ /** @todo Check if we can do it more efficient, eg. vol_ArefToAttribute */ if (fetched) { np = NULL; op = NULL; continue; } } break; } while (1); } else { /* Lookup by attribute reference. */ do { op = vol_OidToObject(&lsts, cp->aref.Objid, gdb_mLo_global, vol_mTrans_all, cvol_eHint_none); if (op == NULL) { lsts = GDH__NOSUCHOBJ; break; } rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ if (op->g.flags.b.isAliasServer) cp->aref.Objid = op->g.oid; /* This is a not to ugly fix, but it should be removed, LW. It's done to make Leif-Göran Hansson happier. I.e. it makes the linksup program work. */ cp->aref.Objid = op->g.oid; vp = pool_Address(NULL, gdbroot->pool, op->l.vr); np = hash_Search(&lsts, gdbroot->nid_ht, &vp->g.nid); if (np == NULL) { op = NULL; break; } ccp = NULL; equal = 1; /* Get cached class if needed */ if (!op->u.c.flags.b.classChecked || !op->u.c.flags.b.classEqual) { ap = vol_ArefToAttribute(&lsts, &attribute, &cp->aref, gdb_mLo_global, vol_mTrans_all); if (ap == NULL) break; ccp = cmvolc_GetCachedClass(&lsts, np, vp, ap, &equal, &fetched, NULL); if (EVEN(lsts)) { np = NULL; op = NULL; break; } if (fetched) { rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ } if (equal) { if (cp->cclass != pool_cNRef) { ccp = pool_Address(NULL, gdbroot->pool, cp->cclass); if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "cached class address"); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; } ccp = NULL; } else { ccr = pool_ItemReference(NULL, gdbroot->pool, ccp); if (ccr == pool_cNRef) errh_Bugcheck(GDH__WEIRD, "cache class address to reference"); if (ccr != cp->cclass) { if (cp->cclass != pool_cNRef) { gdb_sCclass *cc2p = pool_Address(NULL, gdbroot->pool, cp->cclass); cmvolc_UnlockClass(NULL, cc2p); } cmvolc_LockClass(NULL, ccp); cp->cclass = ccr; } } /* If gdb has been unlocked, refresh pointers */ /** @todo Check if we can do it more efficient, eg. vol_ArefToAttribute */ if (fetched) { np = NULL; op = NULL; continue; } } break; } while (1); } } while (0); /* There is a risk that the client has disappeared after these calls (can result in a cache lookup). Verify that it still exists... */ rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp == cp) { /* OK, it exists! */ cp->sts = lsts; if (op != NULL) { if (gdbroot->db->log.b.sub) errh_Info("Test client %s", op->g.f.name.orig); vp = pool_Address(NULL, gdbroot->pool, op->l.vr); np = pool_Address(NULL, gdbroot->pool, vp->l.nr); if (!equal) { ccpLocked = ccp; rarp = ndc_NarefToRaref(sts, ap, arp, ccp, &ridx, &cp->raref, &equal, NULL, ccpLocked, vp, np ); if (rarp == NULL || equal) { if (ccp->flags.b.cacheLock) cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; if (rarp == NULL) np = gdbroot->no_node; } else { if (!ccp->flags.b.rnConv) { ndc_sRemoteToNative *tbl; gdb_sClass *c = hash_Search(sts, gdbroot->cid_ht, &ccp->key.cid); if (c == NULL) errh_Bugcheck(GDH__WEIRD, "can't get class"); tbl = pool_Alloc(sts, gdbroot->pool, sizeof(*tbl) * c->acount); ndc_UpdateRemoteToNativeTable(sts, tbl, c->acount, c, ccp, np->nid); if (ODD(*sts)) { ccp->rnConv = pool_Reference(NULL, gdbroot->pool, tbl); ccp->flags.b.rnConv = 1; } else { pool_Free(NULL, gdbroot->pool, tbl); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; np = gdbroot->no_node; } } } } /* not equal class versions */ } else { np = gdbroot->no_node; } } return np; }
void subc_ActivateList ( pool_sQlink *lh, pwr_tObjid oid ) { pwr_tStatus sts; tree_sTable *add; #if 0 tree_sTable *remove; sRemove *rep; #endif net_sSubSpec *specp; qcom_sQid tgt; pool_sQlink *my_lh; pwr_tUInt32 my_subc_lc; gdb_sNode *np; gdb_sNode *old_np; sub_sClient *cp; pool_sQlink *cl; sAdd *aep; /* Test each client. If existing object, fill in nid field and move the client to the appropriate nodes's subc_lh list. Turn on timeouts. Put request in subadd message buffer. We must do it all in one pass, since a user can come in during a cache query for a later subcli and cancel the subscription for an earlier subcli. */ add = tree_CreateTable(&sts, sizeof(pwr_tNodeId), offsetof(sAdd, nid), sizeof(sAdd), 10, tree_Comp_nid); #if 0 remove = tree_CreateTable(&sts, sizeof(pwr_tNodeId), offsetof(sRemove, nid), sizeof(sRemove), 10, tree_eComp_nid); #endif /* Move all objects to a new, temporary root */ my_lh = pool_Qalloc(NULL, gdbroot->pool); my_subc_lc = 0; for (cl = pool_Qsucc(NULL, gdbroot->pool, lh); cl != lh;) { cp = pool_Qitem(cl, sub_sClient, subc_ll); cl = pool_Qsucc(NULL, gdbroot->pool, cl); if (cdh_ObjidIsNull(oid) || cdh_ObjidIsEqual(oid, cp->aref.Objid)) { pool_Qremove(NULL, gdbroot->pool, &cp->subc_ll); pool_QinsertPred(NULL, gdbroot->pool, &cp->subc_ll, my_lh); my_subc_lc++; } } /* Now start testing clients from 'my_lh', and move them to other lists Make sure the clients are still there after the test. */ for (cl = pool_Qsucc(NULL, gdbroot->pool, my_lh); cl != my_lh; ) { cp = pool_Qitem(cl, sub_sClient, subc_ll); cl = pool_Qsucc(NULL, gdbroot->pool, cl); np = testClient(&sts, cp); /* If an error is returned the client doesn't exist anymore. Some other user removed it while TestSubcli had the database unlocked. Just go on with the next client... */ if (np == NULL) continue; /* Move the client to the list for the node where the object resides. nid = pwr_cNNodeId is used for all objects we don't know. */ old_np = hash_Search(&sts, gdbroot->nid_ht, &cp->nid); if (old_np == NULL) errh_Bugcheck(GDH__WEIRD, ""); pool_Qremove(NULL, gdbroot->pool, &cp->subc_ll); old_np->subc_lc--; pool_QinsertPred(NULL, gdbroot->pool, &cp->subc_ll, &np->subc_lh); np->subc_lc++; cp->nid = np->nid; /* If the object's nid changed, then take the appropriate actions. */ if (np != old_np) { if (np->nid != pwr_cNNodeId) { /* Object is known. */ activateTimeoutWatch(cp); aep = tree_Insert(&sts, add, &np->nid); if (aep == NULL) errh_Bugcheck(GDH__WEIRD, ""); if (aep->msg == NULL) { aep->cnt = MIN(my_subc_lc, net_cSubMaxAdd); aep->msg = malloc(sizeof(net_sSubAdd) + sizeof(net_sSubSpec) * aep->cnt); aep->msg->count = 0; } /* If there was no message allocated */ specp = &aep->msg->spec[aep->msg->count]; specp->sid = cp->sid; specp->dt = cp->dt; specp->sub_by_name = cp->sub_by_name; specp->aref = cp->cclass != pool_cNRef ? cp->raref : cp->aref; if (++aep->msg->count >= aep->cnt) { /* The message buffer is full and must be sent. */ tgt = np->handler; pwr_Assert(tgt.nid != pwr_cNNodeId); gdb_Unlock; net_Put(NULL, &tgt, aep->msg, net_eMsg_subAdd, 0, pwr_Offset(aep->msg, spec[aep->msg->count]), 0); gdb_Lock; aep->msg->count = 0; } } else { /* The object became unknown... */ cancelTimeoutWatch(cp); subc_SetOld(cp); /* Data gets old immediately */ #if 0 /** @todo Maybe we should unlock the cached class? */ if (cp->cclass != pwr_cNRefId) { ccp = pool_Address(NULL, gdbroot->pool, cp->cclass); if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "Cached class address"); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pwr_cNRefId; } #endif #if 0 if (old_np->nid != pwr_cNNodeId) { rep = tree_Insert(&sts, remove, &old_np->nid); if (rep == NULL) errh_Bugcheck(GDH__WEIRD, ""); if (rep->msg == NULL) { rep->nid = old_np->nid; rep->cnt = MIN(my_subc_lc, net_cSubMaxRemove); rep->msg = malloc(sizeof(net_sSubRemove) + sizeof(rep->msg->sid[0]) * rep->cnt); rep->msg->count = 0; } rep->msg->sid[rep->msg->count++] = cp->sid; if (rep->msg->count >= net_cSubMaxRemove) { np = hash_Search(&sts, gdbroot->nid_ht, &old_np->nid); if (np == NULL) errh_Bugcheck(sts, ""); tgt.nid = rep->nid; pwr_Assert(tgt.nid != pwr_cNNodeId); gdb_Unlock; net_Put(NULL, &tgt, rep->msg, net_eMsg_subRemove, 0, pwr_Offset(rep->msg, sid[rep->msg->count]), 0); gdb_Lock; rep->msg->count = 0; } } #endif } } } pool_Free(NULL, gdbroot->pool, my_lh); /* Now walk through the addmsg & remmsg and send all unsent messages. */ gdb_Unlock; #if 0 for (rep = tree_Minimum(remove); rep != NULL; rep = tree_Successor(remove, rep)) { if (rep->msg != NULL) { if (rep->msg->count > 0) { tgt.nid = rep->nid; pwr_Assert(tgt.nid != pwr_cNNodeId); net_Put(NULL, &tgt, rep->msg, net_eMsg_subRemove, 0, pwr_Offset(rep->msg, sid[rep->msg->count]), 0); } free(rep->msg); } } #endif for (aep = tree_Minimum(&sts, add); aep != NULL; aep = tree_Successor(&sts, add, aep)) { if (aep->msg != NULL) { if (aep->msg->count > 0) { np = hash_Search(&sts, gdbroot->nid_ht, &aep->nid); if (np == NULL) errh_Bugcheck(GDH__WEIRD, ""); tgt = np->handler; pwr_Assert(tgt.nid != pwr_cNNodeId); net_Put(NULL, &tgt, aep->msg, net_eMsg_subAdd, 0, pwr_Offset(aep->msg, spec[aep->msg->count]), 0); } free(aep->msg); } } gdb_Lock; tree_DeleteTable(&sts, add); #if 0 tree_DeleteTable(remove); #endif }
void subc_CancelList ( pool_sQlink *lh ) { qcom_sQid tgt; #if 0 tree_sTable *remove; sRemove *rep; gdb_sNode *np; #endif pwr_tNodeId nid; pwr_tSubid sid; sub_sClient *cp; pool_sQlink *cl; gdb_AssumeLocked; tgt.qix = net_cProcHandler; #if 0 remove = tree_CreateTable(sizeof(pwr_tNodeId), offsetof(sRemove, nid), sizeof(sRemove), 10, tree_eComp_nid, NULL); #endif for (cl = pool_Qsucc(NULL, gdbroot->pool, lh); cl != lh;) { cp = pool_Qitem(cl, sub_sClient, subc_ll); cl = pool_Qsucc(NULL, gdbroot->pool, cl); cancelTimeoutWatch(cp); /* Get rid of the client, make it invalid for other references that might happen when we are unlocked But first: save nid and sid which we need further down. */ nid = cp->nid; sid = cp->sid; deleteClient(cp); #if 0 if (nid != pwr_cNNodeId) { rep = tree_Insert(remove, &nid); if (rep == NULL) errh_Bugcheck(GDH__WEIRD, ""); if (rep->msg == NULL) { np = hash_Search(NULL, gdbroot->nid_ht, &nid); if (np == NULL) errh_Bugcheck(GDH__WEIRD, ""); rep->cnt = net_cSubMaxRemove; rep->msg = malloc(sizeof(net_sSubRemove) + sizeof(rep->msg->sid[0]) * rep->cnt); rep->msg->count = 0; } rep->msg->sid[rep->msg->count++] = sid; if (rep->msg->count >= net_cSubMaxRemove) { tgt.nid = rep->nid; gdb_Unlock; net_Put(NULL, &tgt, rep->msg, net_eMsg_subRemove, 0, pwr_Offset(rep->msg, sid[rep->msg->count]), 0); gdb_Lock; rep->msg->count = 0; } } /* Remote */ #endif } /* For all clients in list */ #if 0 /* Now send all unsent messages. */ gdb_Unlock; for (rep = tree_Minimum(remove); rep != NULL; rep = tree_Successor(remove, rep)) { if (rep->msg != NULL) { if (rep->msg->count > 0) { tgt.nid = rep->nid; net_Put(NULL, &tgt, rep->msg, net_eMsg_subRemove, 0, pwr_Offset(rep->msg, sid[rep->msg->count]), 0); } free(rep->msg); } } gdb_Lock; tree_DeleteTable(remove); #endif }
static pool_sQlink * findEntry ( pwr_tStatus *sts, pool_sQlink **bp, /* Return pointer to bucket. */ hash_sTable *htp, const void *keyp ) { pwr_tUInt32 key; /* key transformation value */ pwr_tBoolean found; pwr_tUInt32 depth; hash_sGtable *ghtp; pool_sQlink *lh; pool_sQlink *il; char *ip; ghtp = htp->ghtp; switch (ghtp->key_type) { case hash_eKey_oid: { pwr_tObjid *valp = (pwr_tObjid *) keyp; key = (valp->oix + ((valp->vid * 127) ^ (valp->vid * 131))) % ghtp->size; } break; case hash_eKey_int32: { pwr_tUInt32 val = *(pwr_tUInt32 *) keyp; key = ((val * 127) ^ (val * 131)) % ghtp->size; } break; case hash_eKey_family: { pwr_tUInt32 val = ((cdh_sFamily *) keyp)->name.pack.key; pwr_tObjid *valp = &(((cdh_sFamily *) keyp)->poid); key = (((val * 127) ^ (val * 131)) ^ ((valp->oix * 127) ^ (valp->oix * 131)) ^ ((valp->vid * 127) ^ (valp->vid * 131))) % ghtp->size; } break; case hash_eKey_objName: { pwr_tUInt32 val = ((cdh_sObjName *) keyp)->pack.key; key = ((val * 127) ^ (val * 131)) % ghtp->size; } break; case hash_eKey_memcmp: { const char *s = keyp; pwr_tUInt32 val = 0; int i = ghtp->key_size; for (s = keyp; i > 0; s++, i--) val += val*3 + *s; key = val % ghtp->size; } break; case hash_eKey_strncmp: { const char *s = keyp; pwr_tUInt32 val = 0; int i = ghtp->key_size; for (s = keyp; *s != '\0' && i > 0; s++, i--) val += val*3 + *s; key = val % ghtp->size; } break; case hash_eKey_uint16: { pwr_tUInt32 val = *(pwr_tUInt16 *) keyp; key = ((val * 127) ^ (val * 131)) % ghtp->size; } break; case hash_eKey_user: if (htp->xform_f != NULL) key = htp->xform_f(keyp, ghtp->size); else errh_Bugcheck(HASH__BUGCHECK, ""); break; default: errh_Bugcheck(HASH__BUGCHECK, ""); } ghtp->xforms++; /* Walk the chain starting in this pht entry */ found = NO; lh = htp->tp + key; /* NOTE: Pointer arithmetic */ depth = 0; for (il = pool_Qsucc(sts, htp->php, lh); il != lh; il = pool_Qsucc(sts, htp->php, il)) { ip = (char *) il - ghtp->link_offset; depth++; ghtp->comps++; switch (ghtp->key_type) { case hash_eKey_oid: { pwr_tObjid *xkey = (pwr_tObjid *) (ip + ghtp->key_offset); pwr_tObjid *ykey = (pwr_tObjid *) keyp; found = (xkey->oix == ykey->oix && xkey->vid == ykey->vid); } break; case hash_eKey_int32: { pwr_tUInt32 *xkey = (pwr_tUInt32 *) (ip + ghtp->key_offset); pwr_tUInt32 *ykey = (pwr_tUInt32 *) keyp; found = *xkey == *ykey; } break; case hash_eKey_family: { cdh_sFamily *xkey = (cdh_sFamily *) (ip + ghtp->key_offset); cdh_sFamily *ykey = (cdh_sFamily *) keyp; found = (xkey->name.pack.key == ykey->name.pack.key && xkey->poid.oix == ykey->poid.oix && xkey->poid.vid == ykey->poid.vid && strcmp(xkey->name.norm, ykey->name.norm) == 0); } break; case hash_eKey_objName: { cdh_sObjName *xkey = (cdh_sObjName *) (ip + ghtp->key_offset); cdh_sObjName *ykey = (cdh_sObjName *) keyp; found = (xkey->pack.key == ykey->pack.key && strcmp(xkey->norm, ykey->norm) == 0); } break; case hash_eKey_memcmp: found = memcmp(ip + ghtp->key_offset, keyp, ghtp->key_size) == 0; break; case hash_eKey_strncmp: found = strncmp(ip + ghtp->key_offset, keyp, ghtp->key_size) == 0; break; case hash_eKey_uint16: { pwr_tUInt16 *xkey = (pwr_tUInt16 *) (ip + ghtp->key_offset); pwr_tUInt16 *ykey = (pwr_tUInt16 *) keyp; found = *xkey == *ykey; } case hash_eKey_user: if (htp->comp_f != NULL) found = htp->comp_f(keyp, ip); else errh_Bugcheck(HASH__BUGCHECK, ""); break; default: errh_Bugcheck(HASH__BUGCHECK, ""); } if (found) break; } if (depth > ghtp->max_depth) ghtp->max_depth = depth; if (bp != NULL) *bp = (void *)(lh); if (!found) { ghtp->no_finds++; pwr_Return(NULL, sts, HASH__NOTFOUND); } ghtp->finds++; pwr_Return(il, sts, HASH__SUCCESS); }
static void respondObject ( qcom_sGet *get, gdb_sObject *op, pwr_tInt32 lcount, pwr_tInt32 rcount ) { pwr_tStatus sts; qcom_sPut put; gdb_sObject *pop; net_sObjectR *rsp; net_sGobject *gop; net_sGobject *go[net_cObjectMaxCount]; pwr_tUInt32 count; pwr_tUInt32 pcount; pwr_tUInt32 size; pwr_tInt32 i; pool_sQlink *sol; gdb_sObject *sop; gdb_AssumeLocked; /* The parents must be first in the message, so the receiver can link the cache objects. They must be in top-down-order. */ pop = op; pcount = 0; count = 0; while (pop->g.oid.oix != pwr_cNObjectIx && count < net_cObjectMaxCount - 1) { pop = pool_Address(NULL, gdbroot->pool, pop->l.por); go[count++] = &pop->g; } pcount = count; pop = pool_Address(NULL, gdbroot->pool, op->l.por); if (pop != NULL) { /* Left siblings. (At most lcount of them.) */ for ( i = 0, sol = pool_Qpred(NULL, gdbroot->pool, &op->u.n.sib_ll); i < lcount && sol != &pop->u.n.sib_lh && count < net_cObjectMaxCount - 1; i++, sol = pool_Qpred(NULL, gdbroot->pool, sol) ) { sop = pool_Qitem(sol, gdb_sObject, u.n.sib_ll); go[count++] = &sop->g; } /* Right siblings. (At most rcount of them.) */ for ( i = 0, sol = pool_Qsucc(NULL, gdbroot->pool, &op->u.n.sib_ll); i < rcount && sol != &pop->u.n.sib_lh && count < net_cObjectMaxCount - 1; i++, sol = pool_Qsucc(NULL, gdbroot->pool, sol) ) { sop = pool_Qitem(sol, gdb_sObject, u.n.sib_ll); go[count++] = &sop->g; } } /* Build response message. */ size = sizeof(net_sObjectR) + count * sizeof(net_sGobject); rsp = net_Alloc(&sts, &put, size, net_eMsg_objectR); if (rsp == NULL) { printf("NETH: could not allocate pams buffer for Cache send response, sts: %d\n", sts); respondError(get, op->g.oid, sts); return; } gop = &rsp->g[0]; /* Copy parent objects. */ for (i = pcount - 1; i >= 0; i--) *gop++ = *(go[i]); /* Copy target object. */ *gop++ = op->g; /* Copy sibling objects. */ for (i = pcount; i < count; i++) *gop++ = *(go[i]); rsp->sts = sts; rsp->oid = op->g.oid; rsp->count = count + 1; if (!net_Reply(&sts, get, &put, 0)) errh_Bugcheck(sts, "net_Reply"); }
static gdb_sLocal * mapLocalDb ( pwr_tStatus *sts ) { #if defined OS_LYNX || defined OS_LINUX pthread_mutexattr_t mattr; #endif gdb_AssumeLocked; if (gdbroot->db->version != gdb_cVersion) pwr_Return(NULL, sts, GDH__REVLEVEL); #ifdef OS_ELN ELN$CREATE_MUTEX(gdbroot->thread_lock, NULL); #elif defined(OS_LINUX) || defined(OS_LYNX) && !defined(PWR_LYNX_30) pthread_mutexattr_init(&mattr); if (pthread_mutex_init(&gdbroot->thread_lock, &mattr) == -1) { perror("mapLocalDb: pthread_mutex_init, "); pwr_Return(NULL, sts, GDB__MUTEXINIT); } #elif defined OS_LYNX pthread_mutexattr_create(&mattr); if (pthread_mutex_init(&gdbroot->thread_lock, mattr) == -1) { perror("mapLocalDb: pthread_mutex_init, "); pwr_Return(NULL, sts, GDB__MUTEXINIT); } #endif /* Map hash tables. */ gdbroot->oid_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.oid_ht, &gdbroot->db->h.oid_ht, NULL, NULL); if (gdbroot->oid_ht == NULL) errh_Bugcheck(*sts, "initiating oid hash table"); gdbroot->vid_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.vid_ht, &gdbroot->db->h.vid_ht, NULL, NULL); if (gdbroot->vid_ht == NULL) errh_Bugcheck(*sts, "initiating vid hash table"); gdbroot->vn_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.vn_ht, &gdbroot->db->h.vn_ht, NULL, NULL); if (gdbroot->vn_ht == NULL) errh_Bugcheck(*sts, "initiating vn hash table"); gdbroot->nid_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.nid_ht, &gdbroot->db->h.nid_ht, NULL, NULL); if (gdbroot->nid_ht == NULL) errh_Bugcheck(*sts, "initiating nid hash table"); gdbroot->cid_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.cid_ht, &gdbroot->db->h.cid_ht, NULL, NULL); if (gdbroot->cid_ht == NULL) errh_Bugcheck(*sts, "initiating cid hash table"); gdbroot->tid_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.tid_ht, &gdbroot->db->h.tid_ht, NULL, NULL); if (gdbroot->tid_ht == NULL) errh_Bugcheck(*sts, "initiating tid hash table"); gdbroot->family_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.family_ht, &gdbroot->db->h.family_ht, NULL, NULL); if (gdbroot->family_ht == NULL) errh_Bugcheck(*sts, "initiating family hash table"); gdbroot->ms_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.ms_ht, &gdbroot->db->h.ms_ht, NULL, NULL); if (gdbroot->ms_ht == NULL) errh_Bugcheck(*sts, "initiating mount server hash table"); gdbroot->as_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.as_ht, &gdbroot->db->h.as_ht, NULL, NULL); if (gdbroot->as_ht == NULL) errh_Bugcheck(*sts, "initiating alias server hash table"); gdbroot->subc_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.subc_ht, &gdbroot->db->h.subc_ht, NULL, NULL); if (gdbroot->subc_ht == NULL) errh_Bugcheck(*sts, "initiating subscription client hash table"); gdbroot->subs_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.subs_ht, &gdbroot->db->h.subs_ht, NULL, NULL); if (gdbroot->subs_ht == NULL) errh_Bugcheck(*sts, "initiating subscription server hash table"); gdbroot->sans_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.sans_ht, &gdbroot->db->h.sans_ht, NULL, NULL); if (gdbroot->sans_ht == NULL) errh_Bugcheck(*sts, "initiating subscribed alarm notification server hash table"); gdbroot->ccvol_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.ccvol_ht, &gdbroot->db->h.ccvol_ht, NULL, NULL); if (gdbroot->ccvol_ht == NULL) errh_Bugcheck(*sts, "initiating cached class volume hash table"); gdbroot->cclass_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.cclass_ht, &gdbroot->db->h.cclass_ht, NULL, NULL); if (gdbroot->cclass_ht == NULL) errh_Bugcheck(*sts, "initiating cached class hash table"); gdbroot->sc_ht = hash_Create(sts, gdbroot->pool, &gdbroot->h.sc_ht, &gdbroot->db->h.sc_ht, NULL, NULL); if (gdbroot->sc_ht == NULL) errh_Bugcheck(*sts, "initiating sub class object hash table"); gdbroot->catt_tt = ptree_Create(sts, gdbroot->pool, &gdbroot->t.catt_tt, &gdbroot->db->t.catt_tt, compCatt); if (gdbroot->catt_tt == NULL) errh_Bugcheck(*sts, "initiating class attribute tree table"); if (offsetof(sub_sClient, sid) != offsetof(sub_sServer, sid)) errh_Bugcheck(GDH__WEIRD, "offset id: client - server"); if (offsetof(sub_sClient, sid) != offsetof(dl_sLink, dlid)) errh_Bugcheck(GDH__WEIRD, "offset id: client - dlink"); if (offsetof(sub_sClient, subc_htl) != offsetof(sub_sServer, subs_htl)) errh_Bugcheck(GDH__WEIRD, "offset htl: client - server"); if (offsetof(sub_sClient, subc_htl) != offsetof(dl_sLink, subc_htl)) errh_Bugcheck(GDH__WEIRD, "offset htl: client - dlink"); if ((offsetof(gdb_sNobject, flags) - offsetof(gdb_sNobject, cid_ll)) != (offsetof(gdb_sScObject, flags) - offsetof(gdb_sScObject, cid_ll))) errh_Bugcheck(GDH__WEIRD, "offset between cid_ll and flags in gdb_sNobject and gdb_sScObject"); if (gdb_mNo_isSc != gdb_mSc_isSc) errh_Bugcheck(GDH__WEIRD, "gdb_mNo_isSubClass != gdb_mSc_isSubClass"); return gdbroot; }