[9] | 1 | /* SB - Copyright 1982 by Ken Harrenstien, SRI International
|
---|
| 2 | * This software is quasi-public; it may be used freely with
|
---|
| 3 | * like software, but may NOT be sold or made part of licensed
|
---|
| 4 | * products without permission of the author. In all cases
|
---|
| 5 | * the source code and any modifications thereto must remain
|
---|
| 6 | * available to any user.
|
---|
| 7 | *
|
---|
| 8 | * This is part of the SB library package.
|
---|
| 9 | * Any software using the SB library must likewise be made
|
---|
| 10 | * quasi-public, with freely available sources.
|
---|
| 11 | */
|
---|
| 12 |
|
---|
| 13 | #define PRINT /* Include printout stuff */
|
---|
| 14 |
|
---|
| 15 | #include "sb.h"
|
---|
| 16 | #include <stdio.h>
|
---|
| 17 |
|
---|
| 18 | extern struct smblk *sbm_nfl;
|
---|
| 19 | extern struct smblk *sbm_list;
|
---|
| 20 | extern struct sdblk *sbx_nfl;
|
---|
| 21 |
|
---|
| 22 | #ifdef PRINT
|
---|
| 23 | #define PRF(stmt) {if(p) stmt;}
|
---|
| 24 | #define PRFBUG(str,stmt) {if(p) stmt;else return(str);}
|
---|
| 25 | #define PRFBAD(str,stmt) {if(p) stmt; return(str);}
|
---|
| 26 | #else
|
---|
| 27 | #define PRF(stmt) ;
|
---|
| 28 | #define PRFBUG(str,stmt) return(str);
|
---|
| 29 | #define PRFBAD(str,stmt) return(str);
|
---|
| 30 | #endif
|
---|
| 31 |
|
---|
| 32 | #ifndef NPTRS
|
---|
| 33 | #define NPTRS (1000) /* Catch loops of period less than this. */
|
---|
| 34 | #endif
|
---|
| 35 |
|
---|
| 36 | int sbe_dec = 0; /* Set nonzero to use decimal printout */
|
---|
| 37 |
|
---|
| 38 | struct ptab {
|
---|
| 39 | int pt_pflag; /* Printflag value */
|
---|
| 40 | char *pt_err; /* Error string return */
|
---|
| 41 | int pt_xerr; /* Error index return */
|
---|
| 42 | int pt_hidx; /* Highest freelist entry */
|
---|
| 43 | int pt_nsto; /* # entries stored in table */
|
---|
| 44 | int pt_cnt; /* # of entry store attempts */
|
---|
| 45 | struct smblk *pt_tab[NPTRS];
|
---|
| 46 | };
|
---|
| 47 |
|
---|
| 48 | _PROTOTYPE( char *sbe_sdtab, (struct ptab *pt, int p, int phys) );
|
---|
| 49 | _PROTOTYPE( char *sbe_schk, (struct sdblk *sd, struct ptab *pt) );
|
---|
| 50 | _PROTOTYPE( int sbe_tbent, (struct ptab *pt, struct smblk *sm) );
|
---|
| 51 |
|
---|
| 52 | #define PTF_PRF 01 /* Do printout stuff */
|
---|
| 53 | #define PTF_OVFERR 02 /* Complain if table overflows */
|
---|
| 54 | #define PTF_SDPHYS 04 /* Follow SD phys links (else logical links) */
|
---|
| 55 |
|
---|
| 56 | struct flgt {
|
---|
| 57 | int flg_bit;
|
---|
| 58 | int flg_chr;
|
---|
| 59 | };
|
---|
| 60 |
|
---|
| 61 | _PROTOTYPE( char *sbe_fstr, (int flags, struct flgt *fp) );
|
---|
| 62 |
|
---|
| 63 | char *sbe_mvfy(), *sbe_mfl(), *sbe_mlst(); /* SBM */
|
---|
| 64 | char *sbe_sbvfy(), *sbe_sbs(); /* SBBUF */
|
---|
| 65 | char *sbe_svfy(), *sbe_sdlist(), *sbe_sdtab(), *sbe_schk(); /* SD */
|
---|
| 66 | char *sbe_fstr(); /* Misc utility */
|
---|
| 67 | |
---|
| 68 |
|
---|
| 69 |
|
---|
| 70 | /* SBE_MEM() - Print out memory usage list
|
---|
| 71 | */
|
---|
| 72 | sbe_mem()
|
---|
| 73 | {
|
---|
| 74 | printf("\nMemory Usage:\n");
|
---|
| 75 | printf("\tsbm_nfl : %6o\n",sbm_nfl);
|
---|
| 76 | printf("\tsbm_list: %6o\n",sbm_list);
|
---|
| 77 | printf("\tsmblk nodes are %o bytes long.\n",sizeof (struct smblk));
|
---|
| 78 |
|
---|
| 79 | sbe_mlst(1); /* Scan mem list, printing stuff. */
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | /* SBE_MVFY() - Verify memory allocation structures
|
---|
| 83 | * Returns error message (0 if no errors found).
|
---|
| 84 | */
|
---|
| 85 | char *
|
---|
| 86 | sbe_mvfy()
|
---|
| 87 | { register char *res;
|
---|
| 88 |
|
---|
| 89 | if((res = sbe_mfl(0))
|
---|
| 90 | || (res = sbe_mlst(0)))
|
---|
| 91 | return(res);
|
---|
| 92 | return(0);
|
---|
| 93 | }
|
---|
| 94 | |
---|
| 95 |
|
---|
| 96 | /* SBM Debugging Routines */
|
---|
| 97 |
|
---|
| 98 | struct flgt smflgtab[] = {
|
---|
| 99 | SM_USE, 'U',
|
---|
| 100 | SM_NXM, 'N',
|
---|
| 101 | SM_EXT, 'E',
|
---|
| 102 | SM_MNODS,'M',
|
---|
| 103 | SM_DNODS,'D',
|
---|
| 104 | 0,0
|
---|
| 105 | };
|
---|
| 106 |
|
---|
| 107 | static char smfhelp[] = "U-Used, N-NXM, E-External, M-SMnodes, D-SDnodes";
|
---|
| 108 | static char smhdline[] = "\
|
---|
| 109 | SM: back smaddr smlen smuse smflags";
|
---|
| 110 |
|
---|
| 111 | /* SBE_MFL(printflag) - Verify/Print memory freelist
|
---|
| 112 | * Returns error message (0 if no errors found).
|
---|
| 113 | */
|
---|
| 114 | char *
|
---|
| 115 | sbe_mfl(p)
|
---|
| 116 | int p;
|
---|
| 117 | { register struct smblk *sm;
|
---|
| 118 | register int i;
|
---|
| 119 | struct ptab smtab; /* For loop detection */
|
---|
| 120 |
|
---|
| 121 | PRF(printf("Tracing SM node freelist --\n"))
|
---|
| 122 | PRF(printf(" Maximum loop detection size is %d.", NPTRS))
|
---|
| 123 | if((sm = sbm_nfl) == 0)
|
---|
| 124 | { PRF(printf("\n\tNo list.\n"))
|
---|
| 125 | return(0); /* Null freelist is ok */
|
---|
| 126 | }
|
---|
| 127 | smtab.pt_pflag = p ? PTF_PRF : 0;
|
---|
| 128 | smtab.pt_nsto = smtab.pt_cnt = 0;
|
---|
| 129 | i = 0; /* Print 8 addrs/line */
|
---|
| 130 | for(; sm; sm = sm->smforw)
|
---|
| 131 | {
|
---|
| 132 | PRF(printf("%s%7o->", (i==0 ? "\n " : ""), sm))
|
---|
| 133 | if(++i >= 8) i = 0;
|
---|
| 134 | if(sbe_tbent(&smtab, sm) < 0) /* If hit loop, stop */
|
---|
| 135 | PRFBAD("SM freelist loop",
|
---|
| 136 | printf("\nLOOP - %o seen as node %d!!\n",
|
---|
| 137 | sm, smtab.pt_xerr))
|
---|
| 138 | if(sm->smflags)
|
---|
| 139 | { PRF((i = 0, printf("\nFreelist node has flags:\n")))
|
---|
| 140 | PRFBUG("Free SM flagged", sbe_smp(sm, 0))
|
---|
| 141 | }
|
---|
| 142 | }
|
---|
| 143 | PRF(printf("\nEnd - %d nodes on SM freelist.\n", smtab.pt_cnt))
|
---|
| 144 | return(0);
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | /* SBE_MLST(printflag) - Verify/Print allocated memory list.
|
---|
| 148 | * Returns error message (0 if no errors found).
|
---|
| 149 | */
|
---|
| 150 | char *
|
---|
| 151 | sbe_mlst(p)
|
---|
| 152 | int p;
|
---|
| 153 | { register struct smblk *sm, *smf, *smb;
|
---|
| 154 | char *nextaddr;
|
---|
| 155 | int i;
|
---|
| 156 | struct ptab smtab; /* For loop detection */
|
---|
| 157 |
|
---|
| 158 | PRF(printf("Tracing mem list -- \n"))
|
---|
| 159 | if((sm = sbm_list) == 0)
|
---|
| 160 | { PRF(printf("\tNo list?!\n"))
|
---|
| 161 | if(sbm_nfl) /* Ensure rest are 0 too */
|
---|
| 162 | return("No mem list?!!");
|
---|
| 163 | return(0);
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | smtab.pt_pflag = p;
|
---|
| 167 | smtab.pt_cnt = smtab.pt_nsto = 0;
|
---|
| 168 | smb = 0;
|
---|
| 169 | PRF(printf(" Flags: %s\n%s\n", smfhelp, smhdline))
|
---|
| 170 | for(; sm; sm = smf)
|
---|
| 171 | { PRF(printf(" %6o: ",sm))
|
---|
| 172 | if(sbe_tbent(&smtab, sm) < 0)
|
---|
| 173 | PRFBAD("Loop in mem list!!",
|
---|
| 174 | printf("LOOP - seen as node %d!!\n", smtab.pt_xerr))
|
---|
| 175 |
|
---|
| 176 | if(sm->smback == smb)
|
---|
| 177 | PRF(printf("^ ")) /* Back ptr OK */
|
---|
| 178 |
|
---|
| 179 | else PRFBUG("Bad back ptr!",
|
---|
| 180 | printf("%6o BAD Backptr!!\n\t ",sm->smback))
|
---|
| 181 |
|
---|
| 182 | if((sm->smflags&0377)!= SM_NID)
|
---|
| 183 | PRFBUG("SM: bad node ID",
|
---|
| 184 | printf("BAD - no node ID!\n\t "))
|
---|
| 185 | PRF(printf((sm->smflags&SM_USE) ? " " : "FREE "))
|
---|
| 186 | if(sm->smlen == 0)
|
---|
| 187 | PRFBUG("SM: len 0",
|
---|
| 188 | printf("Zero-length area!"))
|
---|
| 189 | if((sm->smflags&SM_USE)==0
|
---|
| 190 | && rndrem(sm->smaddr - sbm_lowaddr))
|
---|
| 191 | PRFBUG("Bad free-mem block",
|
---|
| 192 | printf("Bad free-mem block"))
|
---|
| 193 | PRF(sbe_smp(sm, 1)) /* Print out rest of info */
|
---|
| 194 |
|
---|
| 195 | if(nextaddr != sm->smaddr
|
---|
| 196 | && smtab.pt_cnt != 1) /* 1st time needs init */
|
---|
| 197 | { PRFBUG("Alignment error!",
|
---|
| 198 | printf("\t BAD!! %6o expected; ",nextaddr))
|
---|
| 199 | #if !(MINIX)
|
---|
| 200 | PRF((i = sm->smaddr - nextaddr) > 0
|
---|
| 201 | ? printf("%d skipped.\n",i)
|
---|
| 202 | : printf("%d overlapped.\n",-i))
|
---|
| 203 | #endif
|
---|
| 204 | }
|
---|
| 205 | nextaddr = sm->smaddr + sm->smlen;
|
---|
| 206 | smf = sm->smforw;
|
---|
| 207 | smb = sm; /* Save ptr to back */
|
---|
| 208 | }
|
---|
| 209 | PRF(printf("End = %6o\n",nextaddr))
|
---|
| 210 | return(0);
|
---|
| 211 | }
|
---|
| 212 |
|
---|
| 213 | #ifdef PRINT
|
---|
| 214 | sbe_smp(sm,type)
|
---|
| 215 | register struct smblk *sm;
|
---|
| 216 | int type;
|
---|
| 217 | {
|
---|
| 218 | if(type==0)
|
---|
| 219 | printf(" %6o: %s ", sm,
|
---|
| 220 | ((sm->smflags&SM_USE) ? " " : "FREE"));
|
---|
| 221 | printf("%6o: ", sm->smaddr);
|
---|
| 222 | printf((sbe_dec ? "%5d. %5d." : "%6o %6o"), sm->smlen, sm->smuse);
|
---|
| 223 | printf(" %7o = %s\n", sm->smflags, sbe_fstr(sm->smflags, smflgtab));
|
---|
| 224 | }
|
---|
| 225 | #endif /*PRINT*/
|
---|
| 226 | |
---|
| 227 |
|
---|
| 228 | /* SD (SBSTR) debugging routines */
|
---|
| 229 |
|
---|
| 230 | struct flgt sdflgtab[] = {
|
---|
| 231 | SD_LOCK, 'L',
|
---|
| 232 | SD_LCK2, 'T',
|
---|
| 233 | SD_MOD, '*',
|
---|
| 234 | 0,0
|
---|
| 235 | };
|
---|
| 236 |
|
---|
| 237 | static char sdfhelp[] = "\
|
---|
| 238 | <f> flags: *-MOD (disk outofdate), L-LOCK, T-LCK2 (temp)";
|
---|
| 239 | static char sdhdline[] = "\
|
---|
| 240 | <f> SD: slforw slback sdflgs sdforw sdback sdmem sdfile sdaddr sdlen";
|
---|
| 241 |
|
---|
| 242 |
|
---|
| 243 | /* SBE_SFL(printflag) - Verify/Print SD freelist
|
---|
| 244 | * Returns error message (0 if no errors found).
|
---|
| 245 | */
|
---|
| 246 | char *
|
---|
| 247 | sbe_sfl(p)
|
---|
| 248 | int p;
|
---|
| 249 | { register struct sdblk *sd;
|
---|
| 250 | register int i;
|
---|
| 251 | struct ptab sdtab; /* For loop detection */
|
---|
| 252 |
|
---|
| 253 | PRF(printf("Tracing SDBLK node freelist --\n"))
|
---|
| 254 | PRF(printf(" Maximum loop detection size is %d.", NPTRS))
|
---|
| 255 | if((sd = sbx_nfl) == 0)
|
---|
| 256 | { PRF(printf("\n\tNo list.\n"))
|
---|
| 257 | return(0); /* Null freelist is ok */
|
---|
| 258 | }
|
---|
| 259 | sdtab.pt_pflag = p ? PTF_PRF : 0;
|
---|
| 260 | sdtab.pt_nsto = sdtab.pt_cnt = 0;
|
---|
| 261 | i = 0; /* Print 8 addrs/line */
|
---|
| 262 | for(; sd; sd = sd->slforw)
|
---|
| 263 | {
|
---|
| 264 | PRF(printf("%s%7o->", (i==0 ? "\n " : ""), sd))
|
---|
| 265 | if(++i >= 8) i = 0;
|
---|
| 266 | if(sbe_tbent(&sdtab, sd) < 0) /* If hit loop, stop */
|
---|
| 267 | PRFBAD("SD freelist loop",
|
---|
| 268 | printf("\nLOOP - %o seen as node %d!!",
|
---|
| 269 | sd, sdtab.pt_xerr))
|
---|
| 270 | if(sd->sdflags)
|
---|
| 271 | { PRF((i = 0, printf("\nFreelist node has flags:\n")))
|
---|
| 272 | PRFBUG("Free SD flagged", sbe_psd(sd))
|
---|
| 273 | }
|
---|
| 274 | }
|
---|
| 275 | PRF(printf("\nEnd - %d nodes on SD freelist.\n", sdtab.pt_cnt))
|
---|
| 276 | return(0);
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 |
|
---|
| 280 |
|
---|
| 281 | /* SBE_SDS() - Print out all sdblk data stuff
|
---|
| 282 | */
|
---|
| 283 | sbe_sds()
|
---|
| 284 | { int sbe_psd();
|
---|
| 285 |
|
---|
| 286 | printf("Printout of all in-use SDBLKs:\n");
|
---|
| 287 | printf(" %s\n", sdfhelp);
|
---|
| 288 | printf("%s\n", sdhdline);
|
---|
| 289 | sbm_nfor(SM_DNODS,sizeof(struct sdblk),sbe_psd,0);
|
---|
| 290 | printf("\n");
|
---|
| 291 | }
|
---|
| 292 |
|
---|
| 293 | /* SBE_PSD - Auxiliary for invocation by SBE_SDS above. */
|
---|
| 294 | sbe_psd(sd)
|
---|
| 295 | register struct sdblk *sd;
|
---|
| 296 | { register int flags;
|
---|
| 297 |
|
---|
| 298 | flags = sd->sdflags;
|
---|
| 299 | printf("%c%c%c",
|
---|
| 300 | ((flags&SD_MOD) ? '*' : ' '),
|
---|
| 301 | ((flags&SD_LOCK) ? 'L' : ' '),
|
---|
| 302 | ((flags&SD_LCK2) ? 'T' : ' '));
|
---|
| 303 |
|
---|
| 304 | printf(" %7o: %6o %6o %6o %6o %6o %6o %6o %7lo %5ld.\n", sd,
|
---|
| 305 | sd->slforw, sd->slback, sd->sdflags,
|
---|
| 306 | sd->sdforw, sd->sdback, sd->sdmem,
|
---|
| 307 | sd->sdfile, sd->sdaddr, sd->sdlen);
|
---|
| 308 | return(0);
|
---|
| 309 | }
|
---|
| 310 |
|
---|
| 311 | /* SBE_SVFY() - Verify all SD blocks
|
---|
| 312 | * Returns error message (0 if no errors found).
|
---|
| 313 | */
|
---|
| 314 | char *
|
---|
| 315 | sbe_svfy()
|
---|
| 316 | { register char *res;
|
---|
| 317 | return((res = sbe_sdlist(0,0)) ? res : sbe_sdlist(0,1));
|
---|
| 318 | }
|
---|
| 319 |
|
---|
| 320 | /* SBE_SDLIST(printflag, physflag) - Verify/Print all SD blocks.
|
---|
| 321 | * Show logical lists if physflag 0
|
---|
| 322 | * Show physical lists otherwise
|
---|
| 323 | * Returns error message (0 if no errors found).
|
---|
| 324 | */
|
---|
| 325 | char *
|
---|
| 326 | sbe_sdlist(p,phys)
|
---|
| 327 | int p, phys;
|
---|
| 328 | { register char *res;
|
---|
| 329 | struct ptab sdtab; /* The SDLIST table to use */
|
---|
| 330 |
|
---|
| 331 | /* First put freelist in table, then scan for all
|
---|
| 332 | * SD nodes. Each active node (not in table) gets
|
---|
| 333 | * its entire list traced forward/backward and added to table.
|
---|
| 334 | */
|
---|
| 335 | if(res = sbe_sdtab(&sdtab, p, phys)) /* Set up freelist table */
|
---|
| 336 | return(res);
|
---|
| 337 |
|
---|
| 338 | /* Freelist entered in table, now scan all SD's */
|
---|
| 339 | res = (char *)sbm_nfor(SM_DNODS,sizeof(struct sdblk),
|
---|
| 340 | sbe_schk, &sdtab);
|
---|
| 341 |
|
---|
| 342 | PRF(printf("\n"))
|
---|
| 343 | return(res);
|
---|
| 344 | }
|
---|
| 345 |
|
---|
| 346 | /* SBE_SDTAB(tableptr, printflag, physflag) - Auxiliary for SBE_SDLIST.
|
---|
| 347 | * Stuffs all freelist SDBLK addresses in table for dup detection.
|
---|
| 348 | * Returns error message (0 if no errors found).
|
---|
| 349 | */
|
---|
| 350 | char *
|
---|
| 351 | sbe_sdtab(pt, p, phys)
|
---|
| 352 | register struct ptab *pt;
|
---|
| 353 | int p, phys;
|
---|
| 354 | { register struct sdblk *sd;
|
---|
| 355 | register int res;
|
---|
| 356 |
|
---|
| 357 | pt->pt_pflag = (p ? PTF_PRF : 0) | (phys ? PTF_SDPHYS : 0)
|
---|
| 358 | | PTF_OVFERR;
|
---|
| 359 | pt->pt_cnt = pt->pt_nsto = 0; /* Initialize */
|
---|
| 360 |
|
---|
| 361 | /* Stick freelist in table */
|
---|
| 362 | for(sd = sbx_nfl; sd; sd = sd->slforw)
|
---|
| 363 | { if(sbe_tbent(pt, sd) < 0)
|
---|
| 364 | { if(pt->pt_xerr < 0)
|
---|
| 365 | PRFBAD("SD freelist too long",
|
---|
| 366 | printf("SD freelist too long (%d)\n",
|
---|
| 367 | NPTRS))
|
---|
| 368 | PRFBAD("SD freelist loop",
|
---|
| 369 | printf("SD freelist loop at %o\n", pt->pt_xerr))
|
---|
| 370 | }
|
---|
| 371 |
|
---|
| 372 | if(sd->sdflags)
|
---|
| 373 | {
|
---|
| 374 | PRF(printf("Bad free SD, non-zero flag:\n"))
|
---|
| 375 | PRFBUG("Free SD flagged", sbe_psd(sd))
|
---|
| 376 | }
|
---|
| 377 | }
|
---|
| 378 | pt->pt_hidx = pt->pt_nsto; /* Set idx of 1st non-FL entry */
|
---|
| 379 | return(0);
|
---|
| 380 | }
|
---|
| 381 | |
---|
| 382 |
|
---|
| 383 | /* SBE_SCHK(SDptr, tableptr) - Auxiliary for SBE_SDLIST.
|
---|
| 384 | * If SD not already in table, verifies or prints
|
---|
| 385 | * the complete physical or logical list it's on, and enters all
|
---|
| 386 | * of its SDs into table (to prevent doing it again).
|
---|
| 387 | * Returns 0 if no errors, else error string.
|
---|
| 388 | ** There is a problem when the table overflows. The tbent routine
|
---|
| 389 | ** wants to add it (wrapping around at bottom) in that case, because
|
---|
| 390 | ** that still helps detect loops. But this routine wants to reset
|
---|
| 391 | ** the table back (after scanning to head of list) and once it starts
|
---|
| 392 | ** scanning forward again it will fail, because some of the SDs are
|
---|
| 393 | ** still in the table due to the wraparound! Thus PTF_OVFERR is always
|
---|
| 394 | ** set, in order to at least give the right error message.
|
---|
| 395 | */
|
---|
| 396 | char *
|
---|
| 397 | sbe_schk(sd, pt)
|
---|
| 398 | register struct sdblk *sd;
|
---|
| 399 | struct ptab *pt;
|
---|
| 400 | { register struct sdblk *sdx;
|
---|
| 401 | register struct smblk *sm;
|
---|
| 402 | struct sbfile *savfile;
|
---|
| 403 | chroff lastaddr;
|
---|
| 404 | int p, res, savidx, phys;
|
---|
| 405 |
|
---|
| 406 | phys = pt->pt_pflag&PTF_SDPHYS; /* Set up physflag */
|
---|
| 407 | if(phys && (sd->sdfile == 0)) /* Ignore non-phys stuff if phys */
|
---|
| 408 | return(0);
|
---|
| 409 | p = pt->pt_pflag&PTF_PRF; /* Set up printflag */
|
---|
| 410 | savidx = pt->pt_nsto; /* Remember initial extent of table */
|
---|
| 411 |
|
---|
| 412 | if(sbe_tbent(pt, sd) < 0)
|
---|
| 413 | { if(pt->pt_xerr >= 0) /* OK if already in table */
|
---|
| 414 | return(0);
|
---|
| 415 | PRFBAD("Too many SDs",
|
---|
| 416 | printf("Too many SDs for table (%d)\n", NPTRS))
|
---|
| 417 | }
|
---|
| 418 |
|
---|
| 419 | /* Now search backward for start of list */
|
---|
| 420 | while(sdx = (phys ? sd->sdback : sd->slback))
|
---|
| 421 | if(sbe_tbent(pt,sdx) >= 0)
|
---|
| 422 | sd = sdx;
|
---|
| 423 | else break;
|
---|
| 424 | if(sdx)
|
---|
| 425 | { if(pt->pt_xerr < 0) /* Table error? */
|
---|
| 426 | PRFBAD("Too many SDs",
|
---|
| 427 | printf("Too many SDs for table (%d)\n",NPTRS))
|
---|
| 428 | PRF(printf("Backlist loop!! Dup'd node:%s\n",
|
---|
| 429 | (pt->pt_xerr < pt->pt_hidx) ?
|
---|
| 430 | "(on freelist!)" : "" ))
|
---|
| 431 | PRFBUG((phys ? "Phys SD loop" : "SD loop"), sbe_psd(sdx))
|
---|
| 432 | }
|
---|
| 433 | /* Reset table to flush nodes backed over */
|
---|
| 434 | pt->pt_cnt = pt->pt_nsto = savidx;
|
---|
| 435 |
|
---|
| 436 | /* SD now points to start of list. Begin stepping thru list... */
|
---|
| 437 | PRF(printf("---- %sList started: ", (phys ? "Phys " : "")))
|
---|
| 438 | if(phys)
|
---|
| 439 | { savfile = sd->sdfile;
|
---|
| 440 | PRF(printf(" SF: %o, fd= %d, ln= %ld\n",
|
---|
| 441 | savfile,savfile->sffd,savfile->sflen))
|
---|
| 442 | if(savfile->sfptr1 != sd)
|
---|
| 443 | PRFBUG("SFPTR1 bad",
|
---|
| 444 | printf(" BAD!! Sfptr1 %o doesn't match SD %o!!\n",
|
---|
| 445 | savfile->sfptr1, sd))
|
---|
| 446 | lastaddr = 0;
|
---|
| 447 | }
|
---|
| 448 | else PRF(printf("\n"))
|
---|
| 449 |
|
---|
| 450 | PRF(printf("%s\n", sdhdline))
|
---|
| 451 | for(sdx = 0; sd; (sdx = sd, sd = (phys ? sd->sdforw : sd->slforw)))
|
---|
| 452 | {
|
---|
| 453 | PRF(sbe_psd(sd)) /* Print it out */
|
---|
| 454 | if(sdx != (phys ? sd->sdback : sd->slback))
|
---|
| 455 | { if(phys)
|
---|
| 456 | PRFBUG("PSD bad sdback",printf("\tBad phys backptr\n"))
|
---|
| 457 | else
|
---|
| 458 | PRFBUG("SD bad slback",printf("\tBad backptr\n"))
|
---|
| 459 | }
|
---|
| 460 |
|
---|
| 461 | if((sd->sdflags&0377) != SD_NID)
|
---|
| 462 | PRFBUG("Bad SD node ID", printf("\tBad node ID!\n"))
|
---|
| 463 |
|
---|
| 464 |
|
---|
| 465 | if(sd->sdfile && (sd->sdlen < 0 || sd->sdaddr < 0))
|
---|
| 466 | PRFBUG("SD: neg len/addr",
|
---|
| 467 | printf("\tNeg disk len/addr\n"))
|
---|
| 468 | if(phys) goto dophys;
|
---|
| 469 |
|
---|
| 470 | /* Do special stuff for logical list */
|
---|
| 471 | if(sm = sd->sdmem)
|
---|
| 472 | { if((sm->smflags&0377) != SM_NID)
|
---|
| 473 | PRFBUG("SD: bad SM",
|
---|
| 474 | printf("\nBad SMBLK ptr\n"))
|
---|
| 475 | if((sd->sdflags&SD_MOD)==0
|
---|
| 476 | && sd->sdlen != sm->smuse)
|
---|
| 477 | PRFBUG("SD != SM",
|
---|
| 478 | printf("\tBad SMBLK? Len conflict\n"))
|
---|
| 479 | if(sm->smlen < sm->smuse)
|
---|
| 480 | PRFBUG("SD: SM len < use",
|
---|
| 481 | printf("\tBad SMBLK, len < use\n"))
|
---|
| 482 | }
|
---|
| 483 | goto doboth; /* Skip phys stuff */
|
---|
| 484 |
|
---|
| 485 | /* Do special stuff for phys list */
|
---|
| 486 | dophys: if(sd->sdfile != savfile)
|
---|
| 487 | PRFBUG("SD: bad sdfile",
|
---|
| 488 | printf("\tBad sdfile ptr! Shd be %o\n",
|
---|
| 489 | savfile))
|
---|
| 490 | if(sd->sdaddr < lastaddr)
|
---|
| 491 | PRFBUG("SD addr out of order",
|
---|
| 492 | printf("\tBad disk addr, not in order!\n"))
|
---|
| 493 | lastaddr = sd->sdaddr;
|
---|
| 494 | /* Done with special phys stuff */
|
---|
| 495 |
|
---|
| 496 | doboth: if(sbe_tbent(pt, sd) < 0)
|
---|
| 497 | { if(pt->pt_xerr < 0)
|
---|
| 498 | PRFBAD("Too many SDs",
|
---|
| 499 | printf("Too many SDs for table (%d)\n",NPTRS))
|
---|
| 500 |
|
---|
| 501 | PRFBUG("SD loop",
|
---|
| 502 | printf("\tLOOP!! This SD already seen%s.\n",
|
---|
| 503 | (pt->pt_xerr < pt->pt_hidx) ?
|
---|
| 504 | " (on freelist!)" : "" ))
|
---|
| 505 | break;
|
---|
| 506 | }
|
---|
| 507 | }
|
---|
| 508 | PRF(printf("-----------\n"))
|
---|
| 509 | return(0);
|
---|
| 510 | }
|
---|
| 511 | |
---|
| 512 |
|
---|
| 513 | /* SBE_DSK(SFptr) - Print out disk usage list for specific file
|
---|
| 514 | */
|
---|
| 515 |
|
---|
| 516 | sbe_dsk(sfp)
|
---|
| 517 | SBFILE *sfp;
|
---|
| 518 | {
|
---|
| 519 | printf("SBFILE printout not coded: %o\n",sfp);
|
---|
| 520 | }
|
---|
| 521 | |
---|
| 522 |
|
---|
| 523 | /* SBBUF structure debugging routines */
|
---|
| 524 |
|
---|
| 525 | struct flgt sbflgtab[] = {
|
---|
| 526 | SB_OVW, 'O',
|
---|
| 527 | SB_WRIT,'W',
|
---|
| 528 | 0,0
|
---|
| 529 | };
|
---|
| 530 | static char sbfhelp[] = "O-Overwrite, W-Write";
|
---|
| 531 |
|
---|
| 532 | /* SBE_SBVFY(SBptr) - Verify a SB-string.
|
---|
| 533 | * Returns error message (0 if no errors found).
|
---|
| 534 | */
|
---|
| 535 | char *
|
---|
| 536 | sbe_sbvfy(sbp)
|
---|
| 537 | SBBUF *sbp;
|
---|
| 538 | { return(sbe_sbs(sbp,0));
|
---|
| 539 | }
|
---|
| 540 |
|
---|
| 541 | /* SBE_SBS(SBptr, printflag) - Verify/Print SBSTR data stuff
|
---|
| 542 | * Returns error message (0 if no errors found).
|
---|
| 543 | */
|
---|
| 544 | char *
|
---|
| 545 | sbe_sbs(sbp,p)
|
---|
| 546 | SBBUF *sbp;
|
---|
| 547 | int p;
|
---|
| 548 | { register SBBUF *sb;
|
---|
| 549 | register struct smblk *sm;
|
---|
| 550 | register struct sdblk *sd;
|
---|
| 551 |
|
---|
| 552 | sb = sbp;
|
---|
| 553 | PRF(printf("SBSTR %o: ",sb))
|
---|
| 554 | if(sb == 0)
|
---|
| 555 | PRFBUG(0,printf("Zero pointer???\n"))
|
---|
| 556 |
|
---|
| 557 | /* First print out cryptic summary in case pointers bomb
|
---|
| 558 | * out farther on. */
|
---|
| 559 | PRF(printf(" (io,cur,r,w,f,.,+ = %o,%o,%d,%d,%o,%lo,%lo)\n",
|
---|
| 560 | sb->sbiop, sb->sbcur, sb->sbrleft, sb->sbwleft,
|
---|
| 561 | sb->sbflags, sb->sbdot, sb->sboff))
|
---|
| 562 |
|
---|
| 563 | PRF(printf(" sbflags %5o = %s (%s)\n",
|
---|
| 564 | sb->sbflags, sbe_fstr(sb->sbflags,sbflgtab),
|
---|
| 565 | sbfhelp))
|
---|
| 566 |
|
---|
| 567 | if(sd = sb->sbcur) /* Okay, now try getting pointers */
|
---|
| 568 | sm = sd->sdmem;
|
---|
| 569 | else sm = 0;
|
---|
| 570 |
|
---|
| 571 | PRF(printf(" sbcur %6o",sd))
|
---|
| 572 | if(sd)
|
---|
| 573 | {
|
---|
| 574 | PRF(printf("\n %s\n ", sdhdline))
|
---|
| 575 | PRF(sbe_psd(sd))
|
---|
| 576 |
|
---|
| 577 | if((sd->sdflags&0377) != SD_NID)
|
---|
| 578 | PRFBUG("SBCUR not SD?",printf(" BAD SDBLK ID!! \n"))
|
---|
| 579 | if(sm)
|
---|
| 580 | {
|
---|
| 581 | PRF(printf(" %s\n ", smhdline))
|
---|
| 582 | PRF(sbe_smp(sm,0))
|
---|
| 583 | if((sm->smflags&0377) != SM_NID)
|
---|
| 584 | PRFBUG("SBCUR has bad SM",
|
---|
| 585 | printf(" BAD SMBLK ID!!\n"))
|
---|
| 586 | }
|
---|
| 587 | }
|
---|
| 588 |
|
---|
| 589 |
|
---|
| 590 | PRF(printf(" sbiop %6o",sb->sbiop))
|
---|
| 591 | if(sb->sbiop)
|
---|
| 592 | { if(!sm || sb->sbiop < sm->smaddr
|
---|
| 593 | || sb->sbiop > (sm->smaddr + sm->smlen))
|
---|
| 594 | PRFBUG("Bad SBIOP", printf(" BAD"))
|
---|
| 595 | }
|
---|
| 596 | else if(sb->sbrleft > 0 || sb->sbwleft > 0)
|
---|
| 597 | PRFBUG("Bad SBIOP/cnts", printf(" BAD"))
|
---|
| 598 | PRF(printf("\n"))
|
---|
| 599 |
|
---|
| 600 | PRF(printf(" sbrleft %5o = %5d.",sb->sbrleft, sb->sbrleft))
|
---|
| 601 | if(sb->sbrleft
|
---|
| 602 | && ( !sm
|
---|
| 603 | || sb->sbwleft
|
---|
| 604 | || (sb->sbflags&SB_WRIT)
|
---|
| 605 | || (sb->sbrleft != (sm->smuse - (sb->sbiop - sm->smaddr)))
|
---|
| 606 | ))
|
---|
| 607 | PRFBUG("Bad sbrleft", printf(" BAD"))
|
---|
| 608 | PRF(printf("\n"))
|
---|
| 609 |
|
---|
| 610 | PRF(printf(" sbwleft %5o = %5d.", sb->sbwleft, sb->sbwleft))
|
---|
| 611 | if(sb->sbwleft
|
---|
| 612 | && ( !sm
|
---|
| 613 | || (sb->sbflags&SB_WRIT) == 0
|
---|
| 614 | || (sb->sbwleft > (sm->smlen - (sb->sbiop - sm->smaddr)))
|
---|
| 615 | ))
|
---|
| 616 | PRFBUG("Bad sbwleft", printf(" BAD"))
|
---|
| 617 | PRF(printf("\n"))
|
---|
| 618 |
|
---|
| 619 | PRF(printf(" sbdot %7lo = %7ld.", sb->sbdot, sb->sbdot))
|
---|
| 620 | if(sb->sbdot < 0)
|
---|
| 621 | PRFBUG("Bad sbdot", printf(" BAD"))
|
---|
| 622 |
|
---|
| 623 | PRF(printf("\n sboff %7lo = %7ld.\n", sb->sboff, sb->sboff))
|
---|
| 624 | PRF(printf(" I/O ptr loc: %ld.\n\n", sb_tell(sb)))
|
---|
| 625 |
|
---|
| 626 | return(0);
|
---|
| 627 | }
|
---|
| 628 | |
---|
| 629 |
|
---|
| 630 | /* SBE_TBENT() - Auxiliary to add and check entries to a pointer table.
|
---|
| 631 | * Note we assume here that smblk ptrs are used, although sdblks
|
---|
| 632 | * can also be hacked. This wins as long as the two kinds of ptrs
|
---|
| 633 | * are basically identical (saves horrible casting problems).
|
---|
| 634 | * Returns index # if successful (between 0 and NPTRS-1 inclusive).
|
---|
| 635 | * Otherwise an error (-1), with relevant info in pt_xerr:
|
---|
| 636 | * -1 if out of room and flag set making it an error
|
---|
| 637 | * 0-n if entry already existed.
|
---|
| 638 | */
|
---|
| 639 | sbe_tbent(pt, sm)
|
---|
| 640 | register struct ptab *pt;
|
---|
| 641 | struct smblk *sm;
|
---|
| 642 | { register struct smblk **smt;
|
---|
| 643 | register int i;
|
---|
| 644 | int p;
|
---|
| 645 |
|
---|
| 646 | p = pt->pt_pflag&PTF_PRF; /* Set up print flag */
|
---|
| 647 | smt = &(pt->pt_tab[0]);
|
---|
| 648 | if(i = pt->pt_nsto)
|
---|
| 649 | { do {
|
---|
| 650 | if(sm == *smt++)
|
---|
| 651 | { pt->pt_xerr = pt->pt_nsto - i;
|
---|
| 652 | return(-1);
|
---|
| 653 | }
|
---|
| 654 | } while(--i);
|
---|
| 655 | --smt;
|
---|
| 656 | }
|
---|
| 657 |
|
---|
| 658 | i = pt->pt_cnt++;
|
---|
| 659 | if(++(pt->pt_nsto) > NPTRS)
|
---|
| 660 | { if(pt->pt_pflag&PTF_OVFERR)
|
---|
| 661 | { pt->pt_err = "Ptrtab overflow";
|
---|
| 662 | pt->pt_xerr = -1;
|
---|
| 663 | return(-1);
|
---|
| 664 | }
|
---|
| 665 | pt->pt_nsto = NPTRS;
|
---|
| 666 | i %= NPTRS;
|
---|
| 667 | }
|
---|
| 668 | pt->pt_tab[i] = sm;
|
---|
| 669 | return(i);
|
---|
| 670 | }
|
---|
| 671 |
|
---|
| 672 | /* SBE_FSTR(flags, flagtab) - Auxiliary to convert flag word to a string
|
---|
| 673 | * and return pointer to it. Handy for printfs.
|
---|
| 674 | */
|
---|
| 675 | char *
|
---|
| 676 | sbe_fstr(flags, fp)
|
---|
| 677 | register int flags;
|
---|
| 678 | register struct flgt *fp;
|
---|
| 679 | { static char retstr[17]; /* Max of 16 flags */
|
---|
| 680 | register char *cp;
|
---|
| 681 | cp = retstr;
|
---|
| 682 | for(; fp->flg_bit; ++fp)
|
---|
| 683 | *cp++ = (fp->flg_bit&flags) ? fp->flg_chr : ' ';
|
---|
| 684 | *cp = 0;
|
---|
| 685 | return(retstr);
|
---|
| 686 | }
|
---|