Ejemplo n.º 1
0
void
sancm_FlushNode (
  pwr_tStatus		*status,
  gdb_sNode		*np
)
{
  pool_sQlink		*ol;
  gdb_sObject		*op;

  if (status != NULL) *status = 1;

  gdb_AssumeLocked;

  for (
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh);
    ol != &np->sancAdd_lh;
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh)
  ) {
    op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

    pwr_Assert(op->u.c.flags.b.sancAdd);
    pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
    op->u.c.flags.b.sancAdd = 0;
    pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
    pwr_Assert(np->sancAdd_lc != 0);
    np->sancAdd_lc--;
  }
  pwr_Assert(np->sancAdd_lc == 0);

  for (
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAct_lh);
    ol != &np->sancAct_lh;
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAct_lh)
  ) {
    op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

    pwr_Assert(op->u.c.flags.b.sancAct);
    pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
    op->u.c.flags.b.sancAct = 0;
    pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
    pwr_Assert(np->sancAct_lc != 0);
    np->sancAct_lc--;
  }
  pwr_Assert(np->sancAct_lc == 0);

  for (
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh);
    ol != &np->sancRem_lh;
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh)
  ) {
    op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

    pwr_Assert(op->u.c.flags.b.sancRem);
    pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
    op->u.c.flags.b.sancRem = 0;
    pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
    pwr_Assert(np->sancRem_lc != 0);
    np->sancRem_lc--;
  }
  pwr_Assert(np->sancRem_lc == 0);

  return;
}
Ejemplo n.º 2
0
void
sancm_Remove (
  pwr_tStatus		*status,
  gdb_sNode		*np
)
{
  net_sSanRemove	*rp; 
  pool_sQlink		*ol;
  gdb_sObject		*op;
  int			count;
  int			i;
  qcom_sQid		tgt;

  if (status != NULL) *status = 1;
  
  gdb_AssumeLocked;

  if (np->sancRem_lc == 0) return;

  count = MIN(np->sancRem_lc, net_cSanMaxRemove);
  rp = malloc(sizeof(net_sSanRemove) + (count - 1) * sizeof(rp->sid[0]));
  if (rp == NULL) return;

  tgt.nid = np->nid;
  tgt.qix = net_cProcHandler;

  for (
    i = 0, ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh);
    ol != &np->sancRem_lh;
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancRem_lh)
  ) {
    op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

    rp->sid[i] = op->u.c.sanid;
    i++;
    pwr_Assert(op->u.c.flags.b.sancRem);
    pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
    op->u.c.flags.b.sancRem = 0;
    pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
    pwr_Assert(np->sancRem_lc != 0);
    np->sancRem_lc--;
#if 0
    cvolc_TrimObject(op);
#endif
    if (i >= count) {
      rp->count = count;
      gdb_Unlock;
	net_Put(NULL, &tgt, rp, net_eMsg_sanRemove, 0, pwr_Offset(rp, sid[i]), 0);
      gdb_Lock;
      i = 0;
    }
  }

  pwr_Assert(np->sancRem_lc == 0);

  /* Send remaining san removes.  */

  if (i > 0) {
    rp->count = count;
    gdb_Unlock;
      net_Put(NULL, &tgt, rp, net_eMsg_sanRemove, 0, pwr_Offset(rp, sid[i]), 0);
    gdb_Lock;
  }

  free(rp);
}
Ejemplo n.º 3
0
void
sancm_Add (
  pwr_tStatus		*status,
  gdb_sNode		*np
)
{
  net_sSanAdd		*ap; 
  pool_sQlink		*ol;
  gdb_sObject		*op;
  int			count;
  int			i;
  qcom_sQid		tgt;

  if (status != NULL) *status = 1;
  
  gdb_AssumeLocked;

  if (np->sancAdd_lc == 0) return;
  count = MIN(np->sancAdd_lc, net_cSanMaxAdd);
  ap = malloc(sizeof(net_sSanAdd) + (count - 1) * sizeof(ap->sane[0]));
  if (ap == NULL) return;

  tgt.nid = np->nid;
  tgt.qix = net_cProcHandler;

  for (
    i = 0, ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh);
    ol != &np->sancAdd_lh;
    ol = pool_Qsucc(NULL, gdbroot->pool, &np->sancAdd_lh)
  ) {
    op = pool_Qitem(ol, gdb_sObject, u.c.sanc_ll);

    ap->sane[i].oid = op->g.oid;
    ap->sane[i].sid = op->u.c.sanid;
    i++;
    pwr_Assert(op->u.c.flags.b.sancAdd);
    pool_Qremove(NULL, gdbroot->pool, &op->u.c.sanc_ll);
    op->u.c.flags.b.sancAdd = 0;
    pwr_Assert((op->u.c.flags.m & gdb_mCo_inSancList) == 0);
    pwr_Assert(np->sancAdd_lc != 0);
    np->sancAdd_lc--;
    pwr_Assert(!op->u.c.flags.b.sancAct);
    pool_QinsertPred(NULL, gdbroot->pool, &op->u.c.sanc_ll, &np->sancAct_lh);
    op->u.c.flags.b.sancAct = 1;
    np->sancAct_lc++;
    if (i >= count) {
      ap->count = count;
      gdb_Unlock;
	net_Put(NULL, &tgt, ap, net_eMsg_sanAdd, 0, pwr_Offset(ap, sane[i]), 0);
      gdb_Lock;
      i = 0;
    }
  }

  pwr_Assert(np->sancAdd_lc == 0);

  /* Send remaining san entries.  */

  if (i > 0) {
    ap->count = i;
    gdb_Unlock;
      net_Put(NULL, &tgt, ap, net_eMsg_sanAdd, 0, pwr_Offset(ap, sane[i]), 0);
    gdb_Lock;
  }

  free(ap);
}
Ejemplo n.º 4
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
}
Ejemplo n.º 5
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
}
Ejemplo n.º 6
0
pwr_tBoolean
ivol_RebuildVolume (
  pwr_tStatus		*status,
  ivol_sVolume		*lv,
  const co_mFormat	*format
)
{
  gdb_sVolume		*vp = lv->vp;
  ivol_sObject		*iop;
  lst_sEntry		*iol;
  pool_sQlink		*ol;
  gdb_sObject		*op;

  pwr_dStatus(sts, status, GDH__SUCCESS);

  gdb_AssumeExcled;
  gdb_AssumeLocked;

#if 0
  // if (!vp->modified) continue;
#endif

  for (
    ol = pool_Qsucc(sts, gdbroot->pool, &vp->l.obj_lh);
    ol != &vp->l.obj_lh;
  ) {
    op = pool_Qitem(ol, gdb_sObject, l.obj_ll);
    ol = pool_Qsucc(sts, gdbroot->pool, ol);

    if (op->u.n.flags.b.swapDelete && !op->u.n.flags.b.systemCreated) {
      vol_SetAlarmLevel(sts, op, 0);/* !!! TODO Remeber to take care of move also in dvol delete and move */
      vol_SetBlockLevel(sts, op, 0);/* !!! TODO Remeber to take care of move also in dvol delete and move */
    }
  }

  /* Unlink all modified objects.  */
  for (iop = lst_Succ(NULL, &lv->upd_lh, &iol); iop != NULL; iop = lst_Succ(NULL, iol, &iol)) {
    if (!(iop->flags.m & gdb_mChange_head)) continue;
    vol_UnlinkObject(sts, vp, iop->op, iop->unlink.m);
    updateObject(lv, iop);
  }
  for (iop = lst_Succ(NULL, &lv->upd_io_lh, &iol); iop != NULL; iop = lst_Succ(NULL, iol, &iol)) {
    if (!(iop->flags.m & gdb_mChange_head)) continue;
    vol_UnlinkObject(sts, vp, iop->op, iop->unlink.m);
    updateObject(lv, iop);
  }

  for (iop = lst_Succ(NULL, &lv->cre_lh, &iol); iop != NULL; iop = lst_Succ(NULL, iol, &iol)) {
    vol_LinkObject(sts, vp, iop->op, vol_mLink_loOidTab);
  }

  for (
    ol = pool_Qsucc(sts, gdbroot->pool, &vp->l.obj_lh);
    ol != &vp->l.obj_lh;
  ) {
    op = pool_Qitem(ol, gdb_sObject, l.obj_ll);
    ol = pool_Qsucc(sts, gdbroot->pool, ol);

    if (op->u.n.flags.b.swapDelete && !op->u.n.flags.b.systemCreated) {
      vol_UnlinkObject(sts, vp, op, vol_mLink_swapDelete);
    }
  }

  /* Relink all new and modified objects.  */

  for (iop = lst_Succ(NULL, &lv->upd_lh, &iol); iop != NULL; iop = lst_Succ(NULL, iol, &iol)) {
    if (!(iop->flags.m & gdb_mChange_head)) continue;
    vol_LinkObject(sts, vp, iop->op, iop->link.m);
  }
  for (iop = lst_Succ(NULL, &lv->upd_io_lh, &iol); iop != NULL; iop = lst_Succ(NULL, iol, &iol)) {
    if (!(iop->flags.m & gdb_mChange_head)) continue;
    vol_LinkObject(sts, vp, iop->op, iop->link.m);
  }

  convFctn = dvms_GetFctns(format);

  for (iop = lst_Succ(NULL, &lv->cre_lh, &iol); iop != NULL; iop = lst_Succ(NULL, iol, &iol)) {
    vol_LinkObject(sts, vp, iop->op, vol_mLink_swapBuild);
    if (convFctn != NULL)
      decodeObject(NULL, iop->op, iop->cp, format->b.bo);
  }

  convFctn = NULL;
  

#if 0
  san_DeleteVolumeServers(sts, vp);
#endif

  return YES;
}
Ejemplo n.º 7
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);
}