📄 dbvol.cxx
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <getopt.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <disk/DiskNode.hxx>#include <disk/PagePot.hxx>#include <erosimg/App.hxx>#include <erosimg/Parse.hxx>#include <erosimg/ExecImage.hxx>#include <erosimg/Volume.hxx>#include <erosimg/StringPool.hxx>extern void PrintDiskKey(const DiskKey&);class App App("dbvol");Volume vol;const char* targname;const char* sysmap;uint16_tip_cksum(uint16_t *buf, int len){ uint16_t cksum=0; typedef char * caddr_t; if ((uint32_t)buf & 0x01) { cksum=(*(uint8_t *)buf)<<8; buf=(uint16_t *)((caddr_t)buf+1); len--; } while (len>1) { cksum+=*buf++; if (cksum & 0x10000) cksum=(cksum & 0xFFFF)+1; len-=2; } if (len) { cksum+=*(uint8_t *)buf; if (cksum & 0x10000) cksum=(cksum & 0xFFFF)+1; } return ~cksum;}intProcessCmd(){ char buf[1024]; if (isatty(0)) fputs("dbvol> ", stdout); if (fgets(buf, 1024, stdin) == 0) return 0; buf[1023] = 0; Parse::TrimLine(buf); const char* rest = buf; InternedString fileName; OID oid; uint32_t w; if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "n") && Parse::MatchOIDVal(rest, oid) && Parse::MatchEOL(rest) ) { DiskNode node; if (vol.ReadNode(oid, node) ) { Diag::printf("Node OID="); Diag::print(node.oid); Diag::printf(" allocCount="); Diag::print(node.allocCount); Diag::printf(" callCount="); Diag::print(node.callCount); Diag::printf(" cksum=0x%04x\n", ip_cksum((uint16_t*)&node, sizeof(DiskNode))); for (unsigned int i = 0; i < EROS_NODE_SIZE; i++) { Diag::printf(" [%02d] ",i); PrintDiskKey(node[i]); Diag::printf("\n"); } Diag::printf("\n"); } } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "rn") && Parse::MatchOIDVal(rest, oid) && Parse::MatchEOL(rest) ) { DiskNode node; if ( vol.ReadNode(oid, node) ) { uint32_t *wpNode = (uint32_t *) &node; uint32_t nWords = sizeof(DiskNode) / 4; Diag::printf("Node OID="); Diag::print(node.oid); Diag::printf(" allocCount="); Diag::print(node.allocCount); Diag::printf(" callCount="); Diag::print(node.callCount); Diag::printf(" cksum=0x%04x\n", ip_cksum((uint16_t*)&node, sizeof(DiskNode))); for (uint32_t i = 0; i < nWords;) { for (uint32_t j = 0; (j < 4) && (i < nWords); j++, i++) Diag::printf(" 0x%08x", wpNode[i]); Diag::printf("\n"); } } } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "p") && Parse::MatchOIDVal(rest, oid) && Parse::MatchEOL(rest) ) { uint8_t buf[EROS_PAGE_SIZE]; Volume::VolPagePot pinfo; vol.GetPagePotInfo(oid, pinfo); Diag::printf("Page OID="); Diag::print(oid); Diag::printf(" tag=%d allocCount=", pinfo.type); Diag::print(pinfo.count); Diag::printf("\n"); if ( vol.ReadDataPage(oid, buf) ) { uint8_t *bufp = buf; for (int i = 0; i < 8; i++) { Diag::printf(" +0x%04x ", i * 16); for (int j = 0; j < 16; j++) { Diag::printf("%02x ", *bufp); bufp++; } Diag::printf("\n"); } Diag::printf("...\n"); Diag::printf("\n"); } } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "p") && Parse::MatchOIDVal(rest, oid) && Parse::Match(rest, ",") && Parse::MatchWord(rest, w) && Parse::MatchEOL(rest) ) { uint8_t buf[EROS_PAGE_SIZE]; Volume::VolPagePot pinfo; vol.GetPagePotInfo(oid, pinfo); Diag::printf("Page OID="); Diag::print(oid); Diag::printf(" tag=%d allocCount=", pinfo.type); Diag::print(pinfo.count); Diag::printf("\n"); if ( vol.ReadDataPage(oid, buf) ) {#if 0 Diag::printf(" cksum=0x%04x\n", ip_cksum((uint16_t*)buf, EROS_PAGE_SIZE)); #endif w &= ~0xfu; /* round down to mult of 16 */ uint8_t *bufp = buf; bufp += w; for (int i = 0; i < 8; i++) { Diag::printf(" +0x%04x ", w + (i * 16)); for (int j = 0; j < 16; j++) { if ((size_t)(bufp - buf) >= EROS_PAGE_SIZE) continue; Diag::printf("%02x ", *bufp); bufp++; } Diag::printf("\n"); } Diag::printf("...\n"); Diag::printf("\n"); } } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "lp") && Parse::MatchOIDVal(rest, oid) && Parse::MatchEOL(rest) ) { uint8_t buf[EROS_PAGE_SIZE]; vol.ReadLogPage(oid, buf); Diag::printf("Log Page "); Diag::print(oid); Diag::printf(" cksum=0x%04x\n", ip_cksum((uint16_t*)buf, EROS_PAGE_SIZE)); Diag::printf("\n"); uint8_t *bufp = buf; for (int i = 0; i < 8; i++) { Diag::printf(" +0x%04x ", i * 16); for (int j = 0; j < 16; j++) { Diag::printf("%02x ", *bufp); bufp++; } Diag::printf("\n"); } Diag::printf("...\n"); Diag::printf("\n"); } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "v") && Parse::MatchEOL(rest) ) { extern void PrintVolHdr(Volume&); PrintVolHdr(vol); } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "c") && Parse::MatchEOL(rest) ) { extern void PrintCkptDir(Volume&); PrintCkptDir(vol); } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "d") && Parse::MatchEOL(rest) ) { extern void PrintDivTable(Volume&); PrintDivTable(vol); } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "r") && Parse::MatchEOL(rest) ) { extern void PrintRsrvDir(Volume&); PrintRsrvDir(vol); } else if (Parse::MatchStart(rest, buf) && Parse::MatchKeyword(rest, "kernel") && Parse::MatchFileName(rest, fileName) && Parse::MatchEOL(rest) ) { ExecImage kernelImage; if ( !kernelImage.SetImage(fileName) ) { Diag::error(1, "Couldn't load kernel image\n"); return 1; } if (kernelImage.NumRegions() != 1) { Diag::error(1, "%s: kernel image improperly linked. Use '-n'!\n", fileName.str()); return 1; } for (int i = 0; i < vol.MaxDiv(); i++) { const Division& d = vol.GetDivision(i); if (d.type == dt_Kernel) vol.WriteKernelImage(i, kernelImage); } }#ifdef DEAD_BAD_MAP /* bad maps are a thing of the past */ else if (Parse::MatchKeyword(rest, "b") && Parse::MatchEOL(rest) ) { int i; if (vol.MaxBadEnt()) Diag::printf("From To\n"); else Diag::printf("Badmap Empty\n"); for (i = 0; i < vol.MaxBadEnt(); i++) { const BadEnt& be = vol.GetBadEnt(i); Diag::printf("%-8d ==> %-8d\n", be.badSec, be.goodSec); } }#endif else if ( ( Parse::MatchKeyword(rest, "h") || Parse::Match(rest, "?") ) && Parse::MatchEOL(rest) ) { Diag::printf("dbvol commands:\n"); Diag::printf(" n <oid> - print out a node\n"); Diag::printf(" rn <oid> - print out a node as raw words\n"); Diag::printf(" cp <oid> - print out a cappage page\n"); Diag::printf(" p <oid> - print out a page\n"); Diag::printf(" lp <loc> - print out a log page\n"); Diag::printf(" c - print out the ckpt directory\n"); Diag::printf(" v - print out the volume header\n"); Diag::printf(" d - print out the division table\n"); Diag::printf(" r - print out the rsrv table\n");#ifdef DEAD_BAD_MAP Diag::printf(" b - print out the bad block table\n");#endif Diag::printf(" kernel - install new kernel on existing volume\n"); Diag::printf(" h/? - display this summary\n"); Diag::printf("\n"); } else if (Parse::MatchKeyword(rest, "q") && Parse::MatchEOL(rest) ) return 0; return 1;}int main(int argc, char *argv[]){ int c; extern int optind;#if 0 extern char *optarg;#endif int opterr = 0; while ((c = getopt(argc, argv, "")) != -1) { switch(c) { default: opterr++; } } /* remaining arguments describe node and/or page space divisions */ argc -= optind; argv += optind; if (argc != 1) opterr++; if (opterr) Diag::fatal(1, "Usage: dbvol file\n"); targname = *argv; if ( !vol.Open(targname, false) ) Diag::fatal(1, "Could not open \"%s\"\n", targname); while ( ProcessCmd() ) ; vol.Close(); App.Exit();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -