Beispiel #1
0
gdb_sMountedOn *
cvolsm_AddMountedOn (
  pwr_tStatus		*sts,
  pwr_tVolumeId		vid,
  gdb_sNode		*np
)
{
  gdb_sMountedOn	*mop;
  gdb_sVolume		*vp;

  gdb_AssumeLocked;

  vp = hash_Search(sts, gdbroot->vid_ht, &vid);
  if (vp == NULL) return NULL;   /* !!! Todo !!! error handling.  */

  mop = (gdb_sMountedOn *) pool_Alloc(NULL, gdbroot->pool, sizeof(*mop));

  mop->nid = np->nid;
  mop->nr  = pool_Reference(NULL, gdbroot->pool, np);
  mop->vid = vid;
  mop->vr  = pool_Reference(NULL, gdbroot->pool, vp);
    
  pool_QinsertSucc(NULL, gdbroot->pool, &mop->nodmo_ll, &np->nodmo_lh);
  pool_QinsertSucc(NULL, gdbroot->pool, &mop->volmo_ll, &vp->u.n.volmo_lh);

  return mop;
}
Beispiel #2
0
static san_sServer* addServer(
    pwr_tStatus* sts, gdb_sNode* np, gdb_sObject* op, net_sSanEntry* ep)
{
  san_sServer* sp;

  sp = hash_Search(NULL, gdbroot->sans_ht, &ep->sid);
  if (sp != NULL)
    return sp;

  sp = pool_Alloc(sts, gdbroot->pool, sizeof(san_sServer));
  if (sp == NULL)
    return NULL;

  sp->sane = *ep;
  sp = hash_Insert(sts, gdbroot->sans_ht, sp);
  if (sp == NULL)
    return NULL;
  /* To do !!!! This is a pool leak !!!!!! */

  if (gdbroot->is_tmon)
    sp->op = op;
  pool_QinsertPred(NULL, gdbroot->pool, &sp->sansAct_ll, &np->sansAct_lh);
  sp->flags.b.sansAct = 1;
  np->sansAct_lc++;
  np->sans_gen++;

  return checkServer(np, sp);
}
Beispiel #3
0
/**
 * Adds a remote class volume.
 */
void cvolcm_AddClassVolume(
    pwr_tStatus* sts, gdb_sNode* np, const net_sGvolume* vp)
{
  gdb_sCclassVolume *ccvp, *rp;
  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;
  }

  rp = hash_Insert(sts, gdbroot->ccvol_ht, ccvp);
  if (rp == NULL) { /* This was previously a bugcheck but obviously can occur */
    pool_Free(NULL, gdbroot->pool, ccvp);
    return;
  }

  pool_QinsertPred(NULL, gdbroot->pool, &ccvp->ccvol_ll, &np->ccvol_lh);
}
Beispiel #4
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 #5
0
pool_sQlink *
pool_Qalloc (
  pwr_tStatus		*sts,
  pool_sHead		*php
)
{
  pool_sQlink		*head;

  head = pool_Alloc(sts, php, sizeof(*head));
  
  head->flink = head->blink = head->self = ((pool_sEntry *)entryPAdd(head,-sizeof(pool_sEntry)))->next;

  return head;
}
Beispiel #6
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 #7
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 #8
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 #9
0
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;
}
Beispiel #10
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 #11
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 #12
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 #13
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 #14
0
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);
  }
}