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; }
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; }
hash_sTable * hash_Create ( pwr_tStatus *sts, pool_sHead *php, hash_sTable *htp, hash_sGtable *ghtp, pwr_tBoolean (*comp_f) (const void *, void *), /* Key comparison routine */ pwr_tUInt32 (*xform_f) (const void *, size_t) /* Key transformation routine */ ) { pwr_tUInt32 i; pool_sQlink *lh; memset(htp, 0, sizeof(*htp)); htp->php = php; ghtp->inits++; if (!ghtp->flags.b.created) { ghtp->size = nextPrime(ghtp->size); ghtp->table = pool_RefAlloc(sts, php, sizeof(hash_sEntry) * ghtp->size); if (ghtp->table == pool_cNRef) return NULL; htp->tp = pool_Address(sts, php, ghtp->table); if (htp->tp == NULL) return NULL; for (i = 0, lh = htp->tp; i < ghtp->size; i++, lh++) pool_Qinit(sts, php, lh); ghtp->flags.b.created = 1; } else { htp->tp = pool_Address(sts, php, ghtp->table); } htp->ghtp = ghtp; htp->comp_f = comp_f; htp->xform_f = xform_f; pwr_Return(htp, sts, HASH__SUCCESS); }
gdb_sVolume * gdb_AddVolume ( pwr_tStatus *sts, pwr_tVolumeId vid, pwr_tBitMask flags ) { gdb_sVolume *vp; gdb_AssumeLocked; vp = hash_Search(sts, gdbroot->vid_ht, &vid); if (vp != NULL) { if (flags & gdb_mAdd_failIfAdded) pwr_Return(NULL, sts, GDB__DUPLADD); else pwr_Return(vp, sts, GDB__ALRADD); } vp = pool_Alloc(sts, gdbroot->pool, sizeof(*vp)); if (vp == NULL) return NULL; vp->g.vid = vid; vp->g.oid.vid = vid; pool_Qinit(NULL, gdbroot->pool, &vp->l.vid_htl); pool_Qinit(NULL, gdbroot->pool, &vp->l.vn_htl); pool_Qinit(NULL, gdbroot->pool, &vp->l.vol_ll); pool_Qinit(NULL, gdbroot->pool, &vp->l.own_ll); pool_Qinit(NULL, gdbroot->pool, &vp->l.obj_lh); pool_Qinit(NULL, gdbroot->pool, &vp->l.volms_lh); hash_Insert(sts, gdbroot->vid_ht, vp); vp->l.flags.b.inVidTable = 1; pool_QinsertPred(sts, gdbroot->pool, &vp->l.vol_ll, &gdbroot->db->vol_lh); vp->l.flags.b.inVolList = 1; return vp; }
gdb_sVolume * cvolcm_ConnectVolume ( pwr_tStatus *sts, gdb_sVolume *vp, net_sGvolume *gvp, gdb_sNode *np ) { gdb_sTouchQ *tqp; gdb_sVolume *ovp; gdb_AssumeLocked; if (vp->g.nid != pwr_cNNodeId && vp->g.nid != np->nid) { errh_Error("Volume %s (%s) is loaded from another node.\nCurrent: %s, new: %s", vp->g.name.orig, cdh_VolumeIdToString(NULL, vp->g.vid, 1, 0), cdh_NodeIdToString(NULL, vp->g.nid, 1, 0), cdh_NodeIdToString(NULL, np->nid, 1, 0)); return NULL; } vp->g = *gvp; pwr_Assert(vp->g.nid != pwr_cNNodeId); vp->l.nr = pool_Reference(NULL, gdbroot->pool, np); /* Add volume name to hash table. */ ovp = hash_Search(NULL, gdbroot->vn_ht, &vp->g.name); if (ovp != NULL) { if (ovp != vp) { errh_Warning("Volume name allready exist: %s, vid: %x\n", vp->g.name.orig, vp->g.vid); hash_Remove(NULL, gdbroot->vn_ht, ovp); ovp = hash_Insert(sts, gdbroot->vn_ht, vp); pwr_Assert(ovp == vp); } } else { ovp = hash_Insert(sts, gdbroot->vn_ht, vp); pwr_Assert(ovp == vp); } vp->l.flags.b.inVnTable = 1; pwr_Assert(!vp->l.flags.b.inOwnList); pool_QinsertPred(sts, gdbroot->pool, &vp->l.own_ll, &np->own_lh); vp->l.flags.b.inOwnList = 1; /* Initiate touch queues. */ tqp = &vp->u.c.cacheLock; pool_Qinit(NULL, gdbroot->pool, &tqp->lh); tqp->lc_max = 0; tqp->flags.b.cacheLock = 1; tqp->next = pool_cNRef; tqp = &vp->u.c.cacheVol; pool_Qinit(NULL, gdbroot->pool, &tqp->lh); #if defined OS_ELN tqp->lc_max = 100; #else tqp->lc_max = 200; #endif tqp->flags.b.cacheVol = 1; tqp->next = pool_Reference(NULL, gdbroot->pool, &np->cacheNode); vp->l.flags.b.isConnected = 1; vp->l.flags.b.isCached = 1; vp->l.flags.b.netCached = 1; vp->l.flags.b.remote = 1; return vp; }
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; }
void subcm_Data ( qcom_sGet *get ) { pwr_tStatus sts; pwr_tTime curtim; pool_tRef mr; sub_sMessage *mp; pwr_tUInt32 refcount = 0; pwr_tInt32 i; sub_sClient *cp; pool_tRef dr; net_sSubData *dp; void *adrs; gdb_sNode *np; net_sSubRemove *rp = NULL; qcom_sQid tgt; gdb_sCclass *ccp; ndc_sRemoteToNative *tbl; int rsize; time_GetTime( &curtim); gdb_AssumeUnlocked; tgt.qix = net_cProcHandler; gdb_ScopeLock { /* Allocate space for, and store the message in the pool. */ mp = pool_Alloc(&sts, gdbroot->pool, sizeof(*mp) - sizeof(mp->msg) + get->size); if (mp == NULL) break; mr = pool_ItemReference(NULL, gdbroot->pool, mp); memcpy(&mp->msg, get->data, get->size); pool_Qinit(NULL, gdbroot->pool, &mp->subm_ll); pool_QinsertPred(NULL, gdbroot->pool, &mp->subm_ll, &gdbroot->db->subm_lh); gdbroot->db->subm_lc++; np = hash_Search(&sts, gdbroot->nid_ht, &mp->msg.hdr.nid); /* Check if message is corrupt */ dp = (net_sSubData *)&mp->msg.subdata; for ( i=0; i < mp->msg.count; i++) { if ( (char *)dp > (char *)&mp->msg + get->size || (char *)dp < (char *)&mp->msg) { errh_Error( "Subscription client message corrupt"); gdb_Unlock; return; } dp = (net_sSubData *)((unsigned long)&dp->data + dp->size); } /* Walk through every entry in the message buffer. */ for ( i=0, dp = (net_sSubData *)&mp->msg.subdata, dr = mr + offsetof(sub_sMessage, msg.subdata); i < mp->msg.count; i++, dr += offsetof(net_sSubData, data) + (unsigned long)dp->size, dp = (net_sSubData *)((unsigned long)&dp->data + dp->size) ) { cp = hash_Search(&sts, gdbroot->subc_ht, &dp->sid); if (cp == NULL) { if (rp == NULL) { rp = pool_Alloc(&sts, gdbroot->pool, sizeof(*rp) + ((mp->msg.count - 1) * sizeof(rp->sid[0]))); if (rp == NULL) continue; tgt.nid = mp->msg.hdr.nid; } rp->sid[rp->count++] = dp->sid; continue; } /* If the client has an earlier reference to a message, then remove that reference. This can cause the old message to get disposed of. */ subc_RemoveFromMessage(cp); /* Now start filling in the client according to the new information we just received... */ memcpy(&cp->lastupdate, &curtim, sizeof(curtim)); cp->sts = dp->sts; cp->count++; if (ODD(dp->sts)) { cp->old = FALSE; /* There is new, fresh, real data! */ cp->submsg = mr; cp->subdata = dr; refcount++; if (1 || mp->msg.hdr.xdr) { if (cp->cclass == pool_cNRef) { gdb_sClass *classp; cdh_uTypeId cid; cid.pwr = cp->aref.Body; cid.c.bix = 0; /* To get the class id. */ classp = hash_Search(&sts, gdbroot->cid_ht, &cid.pwr); rsize = dp->size; if (classp != NULL) ndc_ConvertData(&sts, np, classp, &cp->aref, dp->data, dp->data, (pwr_tUInt32 *)&rsize, ndc_eOp_decode, cp->aref.Offset, 0); } else { cp->old = TRUE; ccp = pool_Address(&cp->sts, gdbroot->pool, cp->cclass); if (ccp != NULL) { tbl = pool_Address(&cp->sts, gdbroot->pool, ccp->rnConv); if (tbl != NULL) { rsize = dp->size; ndc_ConvertRemoteData(&cp->sts, np, ccp, &cp->raref, dp->data, dp->data, (pwr_tUInt32 *)&rsize, ndc_eOp_decode, cp->raref.Offset, 0); if (ODD(cp->sts)) cp->old = FALSE; } } } /* !!! Todo !!! Error handling. */ } /* If the userdata field contains a valid pool_tRef, then copy the data. This poolref is resolved in RTDB! */ if (cp->userdata != pool_cNRef) { adrs = pool_Address(NULL, gdbroot->rtdb, cp->userdata); if (adrs != NULL) { if (cp->cclass == pool_cNRef) memcpy(adrs, dp->data, MIN(dp->size, cp->usersize)); else if (!cp->old) { pwr_tUInt32 size = cp->usersize; pwr_tBoolean first = 1; ndc_ConvertRemoteToNativeTable(&cp->sts, ccp, tbl, &cp->raref, &cp->aref, adrs, dp->data, &size, cp->aref.Offset, 0, 0, &first, np->nid); if (EVEN(cp->sts)) cp->old = TRUE; } } } } } /* Fill in count as the # of references in the 'message' header. This is the # of references that have to be removed before the 'message' can be returned to pool. If there are no references to the 'message' just dispose it! */ if (refcount != 0) { mp->msg.count = refcount; } else { pool_Qremove(NULL, gdbroot->pool, &mp->subm_ll); gdbroot->db->subm_lc--; pool_Free(NULL, gdbroot->pool, mp); } } gdb_ScopeUnlock; if (rp != NULL) { tgt = np->handler; net_Put(NULL, &tgt, rp, net_eMsg_subRemove, 0, pwr_Offset(rp, sid[rp->count]), 0); #if 0 errh_Info("Removed %d subscriptions", rp->count - 1); #endif pool_Free(NULL, gdbroot->pool, rp); } }