Beispiel #1
0
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);
  }
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
      }
    }
  }
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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");
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);

}
Beispiel #10
0
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;
}
Beispiel #11
0
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;

}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
/**
 * 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);

}
Beispiel #19
0
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;
}
Beispiel #20
0
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)));
}
Beispiel #21
0
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;
}
Beispiel #22
0
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);
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
0
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
}
Beispiel #27
0
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
}
Beispiel #28
0
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);
}
Beispiel #29
0
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");
}
Beispiel #30
0
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;  
}