/* ******************************************************************************* * Copyright (c) 1996 Martin Poole * ******************************************************************************* ** ** WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! ** ** Any changes to be made to this file should first be checked with ** mplib1 source control for library integrity. ** ** mplib1 source control can be reached at mplib1@quatermass.co.uk ** * * System : * Subsystem : * Module : * $Source: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/bpo_val_list.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:37 $ * $Revision: 1.2 $ * Purpose : * ******************************************************************************* * * Change History * * Originally derived from V1.2 of sh_diag_i.c * * $Log: bpo_val_list.c,v $ * Revision 1.2 2002/10/07 09:37:37 mpoole * Initial checkin of mplib1-3.1.0 * * Revision 1.1 2002/10/07 09:36:54 mpoole * Initial checkin of mplib1-3.1.0 * * * * ******************************************************************************* */ #ident "$Header: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/bpo_val_list.c,v 1.2 2002/10/07 09:37:37 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #ifdef INCLUDE_GETOPT #include #endif #include #include #include #include #include #include #include #include #include #include #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ #define GENOFF(a,b) (off_t)((char *)a-(char *)b) static int (*v_func)(FILE *,const char *,...)=NULL; static FILE *v_fh=NULL; static int list_has_problems=0; /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ int node_list_header( int (*p_func)(FILE *,const char *,...), FILE *fh ) { int rv=1; if (p_func) rv = (* p_func)( fh, "Address lno_me Forward Backward List Item Name\n" ); return(rv); } int node_list_details( void *base, bpo_Node_t *bnp, int (*p_func)(FILE *,const char *,...), FILE *fh ) { int rv=1; if (p_func) rv = (*p_func)( fh, "%08lx(%08lx) %08lx %08lx %08lx %08lx <%s>\n", GENOFF(bnp,base), bnp->lno_me, bnp->lno_Succ, bnp->lno_Pred, bnp->lno_List, bnp->lno_Item, (bnp->lno_Name)? (char *)base + bnp->lno_Name : "" ); return(rv); } static int node_details( void *vp, bpo_Node_t *bnp, int dbg_lev, int error_level ) { if (error_level==0 && dbg_lev==0) node_list_header( v_func, v_fh ); if (dbg_lev==0) node_list_details( vp, bnp, v_func, v_fh ); return(error_level+1); } static int Walk_Forwards( void *vp, bpo_List_t *blp, bpo_Node_t *bnp, int depth ) { off_t as_should; bpo_Node_t *nnp; int rv=0; /* check the various aspects of this node */ as_should = (off_t)((char *)bnp - (char *)vp); /* does the node have a valid 'me' value */ if (bnp->lno_me != as_should) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (* v_func)( v_fh, " ^ vs ^ Bad lno_me\n" ); list_has_problems++; } /* Is the Node actually in the list it's meant to be in? */ if (bnp->lno_List != blp->lno_me) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (* v_func)(v_fh, " node is not in list %08lx(%08lx)\n", GENOFF(blp,vp), blp->lno_me ); list_has_problems++; } if (bnp->lno_Succ) { /* the next node pointed to should point back to us */ nnp = GRPTR(bnp,bnp->lno_Succ); if (nnp->lno_Pred != bnp->lno_me) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (* v_func)( v_fh, " successor does not point back to us\n" ); node_list_details( vp, nnp, v_func, v_fh ); list_has_problems++; } /* Time to recurse for the next node */ if (rv == 0) rv += Walk_Forwards( vp, blp, nnp, depth+1 ); }else { /* well in theory, this is the tail node in the list structure, so check it */ if (bnp != &blp->lno_Tail) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (* v_func)( v_fh, " node with no successor is not tail node %08lx(%08lx)\n", GENOFF(&blp->lno_Tail,vp), blp->lno_Tail.lno_me ); list_has_problems++; } } if (depth) { /* check back link */ nnp = GRPTR(bnp,bnp->lno_Pred); if (nnp->lno_Succ != bnp->lno_me) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (*v_func)( v_fh, " predecessor does not point to me %08lx -> %08lx\n", GENOFF(nnp,vp), nnp->lno_Succ ); list_has_problems++; } } return(rv); } static int Walk_Backwards( void *vp, bpo_List_t *blp, bpo_Node_t *bnp, int depth ) { off_t as_should; bpo_Node_t *nnp; int rv=0; /* check the various aspects of this node */ as_should = (off_t)((char *)bnp - (char *)vp); if (0) node_list_details( vp, bnp, v_func, v_fh ); /* does the node have a valid 'me' value */ if (bnp->lno_me != as_should) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (* v_func)( v_fh, " ^ vs ^ Bad lno_me\n" ); list_has_problems++; } /* Is the Node actually in the list it's meant to be in? */ if (bnp->lno_List != blp->lno_me) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (*v_func)( v_fh, " node is not in list %08lx(%08lx)\n", GENOFF(blp,vp), blp->lno_me ); list_has_problems++; } if (bnp->lno_Pred) { /* the next node pointed to should point back to us */ nnp = GRPTR(bnp,bnp->lno_Pred); if (nnp->lno_Succ != bnp->lno_me) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (*v_func)( v_fh, " predecessor does not point to me %08lx -> %08lx\n", GENOFF(nnp,vp), nnp->lno_Pred ); list_has_problems++; } /* Time to recurse for the next node */ if (rv == 0) rv += Walk_Backwards( vp, blp, nnp, depth+1 ); }else { /* well in theory, this is the tail node in the list structure, so check it */ if (bnp != &blp->lno_Head) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (*v_func)( v_fh, " node with no predecessor is not head node %08lx(%08lx)\n", GENOFF(&blp->lno_Head,vp), blp->lno_Head.lno_me ); list_has_problems++; } } if (depth) { /* check forw link */ nnp = GRPTR(bnp,bnp->lno_Succ); if (nnp->lno_Pred != bnp->lno_me) { rv = node_details( vp, bnp, 0, rv ); if (v_func) (*v_func)( v_fh, " successor does not point back to us\n" ); node_list_details( vp, nnp, v_func, v_fh ); list_has_problems++; } } return(rv); } int bpo_List_Chk( bpo_List_t *rlp, int (*p_func)(FILE *,const char *,...), FILE *fh ) { int rv=0; void *vp; v_func = p_func; v_fh = fh; list_has_problems=0; vp = Get_SODB_Base( rlp ); if(vp) { if ( (rlp->lno_me != ((char *)rlp - (char *)vp) ) || (rlp->lno_Head.lno_me != ((char *)(&rlp->lno_Head) - (char *)vp) ) || (rlp->lno_Tail.lno_me != ((char *)(&rlp->lno_Tail) - (char *)vp) ) || (rlp->lno_Head.lno_List != rlp->lno_me) || (rlp->lno_Tail.lno_List != rlp->lno_me) ) { if (v_func) (*v_func)( v_fh, "list header does not contain correct offset\n" ); list_has_problems++; } else { bpo_pid_Lock( &rlp->lno_Pid_Lock ); /* list_top_fix( vp, rlp );*/ rv = Walk_Forwards( vp, rlp, &rlp->lno_Head, 0 ); if (rv) rv = Walk_Backwards( vp, rlp, &rlp->lno_Tail, 0 ); bpo_pid_Unlock( &rlp->lno_Pid_Lock ); } }else { if (v_func) (* v_func)( v_fh, "list is not is shared block\n" ); list_has_problems++; } return(list_has_problems); } /* -- End of File -- */