1 /*
2    Copyright (c) 2005, 2021, Oracle and/or its affiliates.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 
26 #include <ndb_global.h>
27 
28 #include <NdbMain.h>
29 #include <NdbOut.hpp>
30 #include "Sysfile.hpp"
31 
32 #define JAM_FILE_ID 358
33 
34 
35 static int g_all = 0;
36 
37 void
usage(const char * prg)38 usage(const char * prg){
39   ndbout << "Usage " << prg
40 	 << " P[0-1].sysfile" << endl;
41 }
42 
43 struct NSString {
44   Sysfile::ActiveStatus NodeStatus;
45   const char * desc;
46 };
47 
48 static const
49 NSString NodeStatusStrings[] = {
50   { Sysfile::NS_Active,                 "Active         " },
51   { Sysfile::NS_ActiveMissed_1,         "Active missed 1" },
52   { Sysfile::NS_ActiveMissed_2,         "Active missed 2" },
53   { Sysfile::NS_ActiveMissed_3,         "Active missed 3" },
54   { Sysfile::NS_NotActive_NotTakenOver, "Not active     " },
55   { Sysfile::NS_TakeOver,               "Take over      " },
56   { Sysfile::NS_NotActive_TakenOver,    "Taken over     " },
57   { Sysfile::NS_NotDefined,             "Not defined    " }
58   ,{ Sysfile::NS_Configured,            "Configured     " }
59 };
60 
61 const
getNSString(Uint32 ns)62 char * getNSString(Uint32 ns){
63   for(Uint32 i = 0; i<(sizeof(NodeStatusStrings)/sizeof(NSString)); i++)
64     if((Uint32)NodeStatusStrings[i].NodeStatus == ns)
65       return NodeStatusStrings[i].desc;
66   return "<Unknown state>";
67 }
68 
69 void
fill(const char * buf,int mod)70 fill(const char * buf, int mod){
71   int len = (int)(strlen(buf)+1);
72   ndbout << buf << " ";
73   while((len % mod) != 0){
74     ndbout << " ";
75     len++;
76   }
77 }
78 
79 void
print(const char * filename,const Sysfile * sysfile)80 print(const char * filename, const Sysfile * sysfile){
81   char buf[255];
82   ndbout << "----- Sysfile: " << filename
83 	 << " seq: " << hex << sysfile->m_restart_seq
84 	 << " -----" << endl;
85   ndbout << "Initial start ongoing: "
86 	 << Sysfile::getInitialStartOngoing(sysfile->systemRestartBits)
87 	 << ", ";
88 
89   ndbout << "Restart Ongoing: "
90 	 << Sysfile::getRestartOngoing(sysfile->systemRestartBits)
91 	 << ", ";
92 
93   ndbout << "LCP Ongoing: "
94 	 << Sysfile::getLCPOngoing(sysfile->systemRestartBits)
95 	 << endl;
96 
97 
98   ndbout << "-- Global Checkpoint Identities: --" << endl;
99   sprintf(buf, "keepGCI = %u", sysfile->keepGCI);
100   fill(buf, 40);
101   ndbout << " -- Tail of REDO log" << endl;
102 
103   sprintf(buf, "oldestRestorableGCI = %u", sysfile->oldestRestorableGCI);
104   fill(buf, 40);
105   ndbout << " -- " << endl;
106 
107   sprintf(buf, "newestRestorableGCI = %u", sysfile->newestRestorableGCI);
108   fill(buf, 40);
109   ndbout << " -- " << endl;
110 
111   sprintf(buf, "latestLCP = %u", sysfile->latestLCP_ID);
112   fill(buf, 40);
113   ndbout << " -- " << endl;
114 
115   ndbout << "-- Node status: --" << endl;
116   for(int i = 1; i < MAX_NDB_NODES; i++){
117     if(g_all || Sysfile::getNodeStatus(i, sysfile->nodeStatus) !=Sysfile::NS_NotDefined){
118       sprintf(buf,
119 	      "Node %.2d -- %s GCP: %d, NodeGroup: %d, TakeOverNode: %d, "
120 	      "LCP Ongoing: %s",
121 	      i,
122 	      getNSString(Sysfile::getNodeStatus(i,sysfile->nodeStatus)),
123 	      sysfile->lastCompletedGCI[i],
124 	      Sysfile::getNodeGroup(i, sysfile->nodeGroups),
125 	      Sysfile::getTakeOverNode(i, sysfile->takeOver),
126 	      BitmaskImpl::get(NdbNodeBitmask::Size,
127 			       sysfile->lcpActive, i) != 0 ? "yes" : "no");
128       ndbout << buf << endl;
129     }
130   }
131 }
132 
133 NDB_COMMAND(printSysfile,
134 	    "printSysfile", "printSysfile", "Prints a sysfile", 16384){
135   ndb_init();
136   if(argc < 2){
137     usage(argv[0]);
138     return 0;
139   }
140 
141   for(int i = 1; i<argc; i++){
142     const char * filename = argv[i];
143 
144     if (strcmp(filename, "--all") == 0)
145     {
146       g_all = 1;
147       continue;
148     }
149 
150     struct stat sbuf;
151 
152     if(stat(filename, &sbuf) != 0)
153     {
154       ndbout << "Could not find file: \"" << filename << "\"" << endl;
155       continue;
156     }
157     const Uint32 bytes = sbuf.st_size;
158 
159     Uint32 * buf = new Uint32[bytes/4+1];
160 
161     FILE * f = fopen(filename, "rb");
162     if(f == 0){
163       ndbout << "Failed to open file" << endl;
164       delete [] buf;
165       continue;
166     }
167     Uint32 sz = (Uint32)fread(buf, 1, bytes, f);
168     fclose(f);
169     if(sz != bytes){
170       ndbout << "Failure while reading file" << endl;
171       delete [] buf;
172       continue;
173     }
174 
175     print(filename, (Sysfile *)&buf[0]);
176     delete [] buf;
177     continue;
178   }
179   return 0;
180 }
181