Commit 9de4fa45 authored by unknown's avatar unknown
Browse files

ndb - printSchemaFile: more checks and options


ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp:
  more checks and options
parent c7853e47
Loading
Loading
Loading
Loading
+117 −51
Original line number Diff line number Diff line
#if 0
make -f Makefile -f - printSchemaFile <<'_eof_'
printSchemaFile: printSchemaFile.cpp SchemaFile.hpp
	$(CXXCOMPILE) -o $@ $@.cpp -L../../../common/util/.libs -lgeneral
ifneq ($(MYSQL_HOME),)
	ln -sf `pwd`/$@ $(MYSQL_HOME)/bin/$@
endif
_eof_
exit $?
#endif

/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
@@ -36,14 +25,19 @@ exit $?
static const char* progname = 0;
static bool allflag = false;
static bool checkonly = false;
static int xitcode = 0;
static bool equalcontents = false;
static bool okquiet = false;

static void 
usage()
{
  ndbout << "Usage " << progname
         << " [-ac]"
         << " P0.SchemaLog" << endl;  
  ndbout
    << "Usage: " << progname << " [-aceq]" << " file ..." << endl
    << "-a      print also unused slots" << endl
    << "-c      check only (return status 1 on error)" << endl
    << "-e      check also that the files have identical contents" << endl
    << "-q      no output if file is ok" << endl
    << "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl;
}

static void
@@ -57,32 +51,56 @@ fill(const char * buf, int mod)
  }
}

static void
static const char*
version(Uint32 v)
{
  static char buf[40];
  sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF);
  return buf;
}

static int
print_head(const char * filename, const SchemaFile * sf)
{
  int retcode = 0;

  if (! checkonly) {
    ndbout << "----- Schemafile: " << filename << " -----" << endl;
    ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %d.%d.%d FileSize: %d",
    ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d",
             sizeof(sf->Magic),
             sf->Magic, 
             sf->ByteOrder, 
             sf->NdbVersion >> 16,
             (sf->NdbVersion >> 8) & 0xFF,
             sf->NdbVersion & 0xFF,
             version(sf->NdbVersion),
             sf->FileSize);
  }

  if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) {
    ndbout << filename << ": invalid header magic" << endl;
    retcode = 1;
  }

  if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) {
    ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl;
    retcode = 1;
  }

static void 
print_old(const char * filename, const SchemaFile * sf)
  return retcode;
}

static int
print_old(const char * filename, const SchemaFile * sf, Uint32 sz)
{
  print_head(filename, sf);
  int retcode = 0;

  if (print_head(filename, sf) != 0)
    retcode = 1;

  for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) {
    SchemaFile::TableEntry_old te = sf->TableEntries_old[i];
    if (allflag ||
        (te.m_tableState != SchemaFile::INIT &&
         te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) {
      if (! checkonly)
        ndbout << "Table " << i << ":"
               << " State = " << te.m_tableState 
               << " version = " << te.m_tableVersion
@@ -91,18 +109,20 @@ print_old(const char * filename, const SchemaFile * sf)
               << " gcp: " << te.m_gcp << endl;
    }
  }
  return retcode;
}

static void 
static int
print(const char * filename, const SchemaFile * xsf, Uint32 sz)
{
  int retcode = 0;

  print_head(filename, xsf);
  if (print_head(filename, xsf) != 0)
    retcode = 1;

  assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE);
  if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) {
    ndbout << "***** invalid FileSize " << xsf->FileSize << endl;
    ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl;
    retcode = 1;
  }
  Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE;
@@ -111,19 +131,23 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
      ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl;
    }
    const SchemaFile * sf = &xsf[n];
    if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) {
      ndbout << filename << ": page " << n << " invalid magic" << endl;
      retcode = 1;
    }
    if (sf->FileSize != xsf->FileSize) {
      ndbout << "***** page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
      ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
      retcode = 1;
    }
    Uint32 cs = 0;
    for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++)
      cs ^= ((const Uint32*)sf)[j];
    if (cs != 0) {
      ndbout << "***** page " << n << " invalid CheckSum" << endl;
      ndbout << filename << ": page " << n << " invalid CheckSum" << endl;
      retcode = 1;
    }
    if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) {
      ndbout << "***** page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
      ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
      retcode = 1;
    }
    for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
@@ -141,31 +165,41 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
                 << " gcp: " << te.m_gcp << endl;
      }
      if (te.m_unused[0] != 0 || te.m_unused[1] != 0 || te.m_unused[2] != 0) {
        ndbout << "***** entry " << j << " garbage in m_unused[3]" << endl;
        ndbout << filename << ": entry " << j << " garbage in m_unused[3]" << endl;
        retcode = 1;
      }
    }
  }

  if (retcode != 0)
    xitcode = 1;
  else if (checkonly)
    ndbout << "ok: " << filename << endl;
  return retcode;
}

NDB_COMMAND(printSchemafile, 
	    "printSchemafile", "printSchemafile", "Prints a schemafile", 16384)
{ 
  progname = argv[0];
  int exitcode = 0;

  while (argv[1][0] == '-') {
  while (argc > 1 && argv[1][0] == '-') {
    if (strchr(argv[1], 'a') != 0)
      allflag = true;
    if (strchr(argv[1], 'c') != 0)
      checkonly = true;
    if (strchr(argv[1], 'e') != 0)
      equalcontents = true;
    if (strchr(argv[1], 'q') != 0)
      okquiet = true;
    if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) {
      usage();
      return 0;
    }
    argc--, argv++;
  }

  const char * prevfilename = 0;
  Uint32 * prevbuf = 0;
  Uint32 prevbytes = 0;

  while (argc > 1) {
    const char * filename = argv[1];
    argc--, argv++;
@@ -173,8 +207,9 @@ NDB_COMMAND(printSchemafile,
    struct stat sbuf;
    const int res = stat(filename, &sbuf);
    if (res != 0) {
      ndbout << "Could not find file: \"" << filename << "\"" << endl;
      return 1;
      ndbout << filename << ": not found errno=" << errno << endl;
      exitcode = 1;
      continue;
    }
    const Uint32 bytes = sbuf.st_size;
    
@@ -182,25 +217,56 @@ NDB_COMMAND(printSchemafile,
    
    FILE * f = fopen(filename, "rb");
    if (f == 0) {
      ndbout << "Failed to open file" << endl;
      ndbout << filename << ": open failed errno=" << errno << endl;
      delete [] buf;
      return 1;
      exitcode = 1;
      continue;
    }
    Uint32 sz = fread(buf, 1, bytes, f);
    fclose(f);
    if (sz != bytes) {
      ndbout << "Failure while reading file" << endl;
      ndbout << filename << ": read failed errno=" << errno << endl;
      delete [] buf;
      return 1;
      exitcode = 1;
      continue;
    }

    if (sz < 32) {
      ndbout << filename << ": too short (no header)" << endl;
      delete [] buf;
      exitcode = 1;
      continue;
    }

    SchemaFile* sf = (SchemaFile *)&buf[0];
    int ret;
    if (sf->NdbVersion < NDB_SF_VERSION_5_0_6)
      print_old(filename, sf);
      ret = print_old(filename, sf, sz);
    else
      print(filename, sf, sz);
    delete [] buf;
      ret = print(filename, sf, sz);

    if (ret != 0) {
      ndbout << filename << ": check failed"
             << " version=" << version(sf->NdbVersion) << endl;
      exitcode = 1;
    } else if (! okquiet) {
      ndbout << filename << ": ok"
             << " version=" << version(sf->NdbVersion) << endl;
    }

    if (equalcontents && prevfilename != 0) {
      if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) {
        ndbout << filename << ": differs from " << prevfilename << endl;
        exitcode = 1;
      }
    }

    prevfilename = filename;
    delete [] prevbuf;
    prevbuf = buf;
    prevbytes = bytes;
  }

  return xitcode;
  delete [] prevbuf;
  return exitcode;
}