1 /*
2    Copyright (c) 2003, 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 #include <ndb_global.h>
26 #include <ndbd_exit_codes.h>
27 
28 typedef struct ErrStruct {
29    int faultId;
30    ndbd_exit_classification classification;
31    const char* text;
32 } ErrStruct;
33 
34 /**
35  * Shorter names in table below
36  */
37 
38 #define XST_S ndbd_exit_st_success
39 #define XST_U ndbd_exit_st_unknown
40 #define XST_P ndbd_exit_st_permanent
41 #define XST_R ndbd_exit_st_temporary
42 #define XST_I ndbd_exit_st_filesystem_error
43 
44 #define XNE ndbd_exit_cl_none
45 #define XUE ndbd_exit_cl_unknown
46 #define XIE ndbd_exit_cl_internal_error
47 #define XCE ndbd_exit_cl_configuration_error
48 #define XAE ndbd_exit_cl_arbitration_error
49 #define XRE ndbd_exit_cl_restart_error
50 #define XCR ndbd_exit_cl_resource_configuration_error
51 #define XFF ndbd_exit_cl_filesystem_full_error
52 #define XFI ndbd_exit_cl_filesystem_inconsistency_error
53 #define XFL ndbd_exit_cl_filesystem_limit
54 
55 static const ErrStruct errArray[] =
56 {
57    {NDBD_EXIT_GENERIC, XRE, "Generic error"},
58    {NDBD_EXIT_PRGERR, XIE, "Assertion"},
59    {NDBD_EXIT_NODE_NOT_IN_CONFIG, XCE,
60     "node id in the configuration has the wrong type, (i.e. not an NDB node)"},
61    {NDBD_EXIT_SYSTEM_ERROR, XIE,
62     "System error, node killed during node restart by other node"},
63    {NDBD_EXIT_INDEX_NOTINRANGE, XIE, "Array index out of range"},
64    {NDBD_EXIT_ARBIT_SHUTDOWN, XAE, "Node lost connection to other nodes and "
65     "can not form a unpartitioned cluster, please investigate if there are "
66     "error(s) on other node(s)"},
67    {NDBD_EXIT_PARTITIONED_SHUTDOWN, XAE, "Partitioned cluster detected. "
68     "Please check if cluster is already running"},
69    {NDBD_EXIT_NODE_DECLARED_DEAD, XAE,
70     "Node declared dead. See error log for details"},
71    {NDBD_EXIT_POINTER_NOTINRANGE, XIE, "Pointer too large"},
72    {NDBD_EXIT_SR_OTHERNODEFAILED, XRE, "Another node failed during system "
73     "restart, please investigate error(s) on other node(s)"},
74    {NDBD_EXIT_NODE_NOT_DEAD, XRE, "Internal node state conflict, "
75     "most probably resolved by restarting node again"},
76    {NDBD_EXIT_SR_REDOLOG, XFI, "Error while reading the REDO log"},
77    {NDBD_EXIT_SR_SCHEMAFILE, XFI, "Error while reading the schema file"},
78    /* Currently unused? */
79    {2311, XIE, "Conflict when selecting restart type"},
80    {NDBD_EXIT_NO_MORE_UNDOLOG, XCR,
81     "No more free UNDO log, increase UndoIndexBuffer"},
82    {NDBD_EXIT_SR_UNDOLOG, XFI,
83     "Error while reading the datapages and UNDO log"},
84    {NDBD_EXIT_SINGLE_USER_MODE, XRE, "Data node is not allowed to get added "
85     "to the cluster while it is in single user mode"},
86    {NDBD_EXIT_MEMALLOC, XCE, "Memory allocation failure, "
87     "please decrease some configuration parameters"},
88    {NDBD_EXIT_BLOCK_JBUFCONGESTION, XIE, "Job buffer congestion"},
89    {NDBD_EXIT_TIME_QUEUE_ZERO, XIE, "Error in zero time queue"},
90    {NDBD_EXIT_TIME_QUEUE_SHORT, XIE, "Error in short time queue"},
91    {NDBD_EXIT_TIME_QUEUE_LONG, XIE, "Error in long time queue"},
92    {NDBD_EXIT_TIME_QUEUE_DELAY, XIE, "Error in time queue, too long delay"},
93    {NDBD_EXIT_TIME_QUEUE_INDEX, XIE, "Time queue index out of range"},
94    {NDBD_EXIT_BLOCK_BNR_ZERO, XIE, "Send signal error"},
95    {NDBD_EXIT_WRONG_PRIO_LEVEL, XIE, "Wrong priority level when sending signal"},
96    {NDBD_EXIT_NDBREQUIRE, XIE, "Internal program error (failed ndbrequire)"},
97    {NDBD_EXIT_NDBASSERT, XIE, "Internal program error (failed ndbassert)"},
98    {NDBD_EXIT_ERROR_INSERT, XNE, "Error insert executed" },
99    /* this error message is complemented by additional info when generated */
100    {NDBD_EXIT_INVALID_CONFIG, XCE,
101     "Invalid configuration received from Management Server"},
102 
103    {NDBD_EXIT_RESOURCE_ALLOC_ERROR, XCE,
104     "Resource allocation error, please review the configuration"},
105 
106    {NDBD_EXIT_NO_MORE_REDOLOG, XCR,
107     "Fatal error due to end of REDO log. Increase NoOfFragmentLogFiles or FragmentLogFileSize" },
108 
109    /* this error message is complemented by additional info when
110       generated, such as signal, and text
111    */
112    {NDBD_EXIT_OS_SIGNAL_RECEIVED, XIE, "Error OS signal received"},
113 
114    {NDBD_EXIT_SR_RESTARTCONFLICT, XRE,
115     "Partial system restart causing conflicting file systems"},
116 
117    /* VM */
118    {NDBD_EXIT_OUT_OF_LONG_SIGNAL_MEMORY,    XCR,
119     "Signal lost, out of long signal memory, please increase LongMessageBuffer"},
120    {NDBD_EXIT_WATCHDOG_TERMINATE, XIE, "WatchDog terminate, internal error "
121     "or massive overload on the machine running this node"},
122    {NDBD_EXIT_SIGNAL_LOST_SEND_BUFFER_FULL, XCR,
123     "Signal lost, out of send buffer memory, please increase SendBufferMemory or lower the load"},
124    {NDBD_EXIT_SIGNAL_LOST,    XIE, "Signal lost (unknown reason)"},
125    {NDBD_EXIT_ILLEGAL_SIGNAL, XIE,
126     "Illegal signal (version mismatch a possibility)"},
127    {NDBD_EXIT_CONNECTION_SETUP_FAILED, XCE, "Connection setup failed"},
128 
129    /* Ndbcntr */
130    {NDBD_EXIT_RESTART_TIMEOUT, XCE,
131     "Total restart time too long, consider increasing StartFailureTimeout "
132     "or investigate error(s) on other node(s)"},
133    {NDBD_EXIT_RESTART_DURING_SHUTDOWN, XRE,
134     "Node started while node shutdown in progress. "
135     "Please wait until shutdown complete before starting node"},
136 
137    /* DIH */
138    {NDBD_EXIT_MAX_CRASHED_REPLICAS, XFL,
139     "Too many crashed replicas (8 consecutive node restart failures)"},
140    {NDBD_EXIT_MASTER_FAILURE_DURING_NR, XRE,
141     "Unhandled master failure during node restart"},
142    {NDBD_EXIT_LOST_NODE_GROUP, XAE,
143     "All nodes in a node group are unavailable"},
144    {NDBD_EXIT_NO_RESTORABLE_REPLICA, XFI,
145     "Unable to find a restorable replica"},
146 
147    /* ACC */
148    {NDBD_EXIT_SR_OUT_OF_INDEXMEMORY, XCR,
149     "Out of index memory during system restart, please increase IndexMemory"},
150 
151    /* TUP */
152    {NDBD_EXIT_SR_OUT_OF_DATAMEMORY, XCR,
153     "Out of data memory during system restart, please increase DataMemory"},
154 
155    /* LQH */
156    {NDBD_EXIT_LCP_SCAN_WATCHDOG_FAIL, XIE,
157     "LCP fragment scan watchdog detected a problem.  Please report a bug."},
158 
159    /* Ndbfs error messages */
160    /* Most codes will have additional info, such as OS error code */
161    {NDBD_EXIT_AFS_NOPATH,       XIE, "No file system path"},
162    {2802,                       XIE, "Channel is full"},
163    {2803,                       XIE, "No more threads"},
164    {NDBD_EXIT_AFS_PARAMETER,    XIE, "Bad parameter"},
165    {NDBD_EXIT_AFS_INVALIDPATH,  XCE, "Illegal file system path"},
166    {NDBD_EXIT_AFS_MAXOPEN,      XCR,
167     "Max number of open files exceeded, please increase MaxNoOfOpenFiles"},
168    {NDBD_EXIT_AFS_ALREADY_OPEN, XIE, "File has already been opened"},
169 
170    {NDBD_EXIT_AFS_ENVIRONMENT           , XIE, "Environment error using file"},
171    {NDBD_EXIT_AFS_TEMP_NO_ACCESS        , XIE, "Temporary on access to file"},
172    {NDBD_EXIT_AFS_DISK_FULL             , XFF, "The file system is full"},
173    {NDBD_EXIT_AFS_PERMISSION_DENIED     , XCE, "Received permission denied for file"},
174    {NDBD_EXIT_AFS_INVALID_PARAM         , XCE, "Invalid parameter for file"},
175    {NDBD_EXIT_AFS_UNKNOWN               , XIE, "Unknown file system error"},
176    {NDBD_EXIT_AFS_NO_MORE_RESOURCES     , XIE,
177     "System reports no more file system resources"},
178    {NDBD_EXIT_AFS_NO_SUCH_FILE          , XFI, "File not found"},
179    {NDBD_EXIT_AFS_READ_UNDERFLOW        , XFI, "Read underflow"},
180 
181    {NDBD_EXIT_INVALID_LCP_FILE, XFI, "Invalid LCP" },
182    {NDBD_EXIT_INSUFFICENT_NODES, XRE, "Insufficent nodes for system restart" },
183 
184    {NDBD_EXIT_UNSUPPORTED_VERSION, XRE, "Unsupported version" },
185 
186    {NDBD_EXIT_RESTORE_SCHEMA, XCR, "Failure to restore schema" },
187 
188    {NDBD_EXIT_GRACEFUL_SHUTDOWN_ERROR, XNE,
189     "Graceful shutdown not 100% possible due to mixed ndbd versions" },
190 
191    /* Sentinel */
192    {0, XUE,
193     "No message slogan found (please report a bug if you get this error code)"}
194 };
195 
196 typedef struct StatusExitMessage {
197   ndbd_exit_status status;
198   const char * message;
199 } StatusExitMessage;
200 
201 typedef struct StatusExitClassification {
202   ndbd_exit_status status;
203   ndbd_exit_classification classification;
204   const char * message;
205 } StatusExitClassification;
206 
207 /**
208  * Mapping between classification and status
209  */
210 static
211 const
212 StatusExitMessage StatusExitMessageMapping[] = {
213   { XST_S, "Success"},
214   { XST_U ,"Unknown"},
215   { XST_P, "Permanent error, external action needed"},
216   { XST_R, "Temporary error, restart node"},
217   { XST_I, "Ndbd file system error, restart node initial"}
218 };
219 
220 static
221 const
222 int NbExitStatus = sizeof(StatusExitMessageMapping)/sizeof(StatusExitMessage);
223 
224 static
225 const
226 StatusExitClassification StatusExitClassificationMapping[] = {
227   { XST_S, XNE, "No error"},
228   { XST_U, XUE, "Unknown"},
229   { XST_R, XIE, "Internal error, programming error or missing error message, "
230                 "please report a bug"},
231   { XST_P, XCE, "Configuration error"},
232   { XST_R, XAE, "Arbitration error"},
233   { XST_R, XRE, "Restart error"},
234   { XST_P, XCR, "Resource configuration error"},
235   { XST_P, XFF, "File system full"},
236   { XST_I, XFI, "Ndbd file system inconsistency error, please report a bug"},
237   { XST_I, XFL, "Ndbd file system limit exceeded"}
238 };
239 
240 static const int NbExitClassification =
241 sizeof(StatusExitClassificationMapping)/sizeof(StatusExitClassification);
242 
ndbd_exit_message(int faultId,ndbd_exit_classification * cl)243 const char *ndbd_exit_message(int faultId, ndbd_exit_classification *cl)
244 {
245   int i = 0;
246   while (errArray[i].faultId != faultId && errArray[i].faultId != 0)
247     i++;
248   *cl = errArray[i].classification;
249   return errArray[i].text;
250 }
251 
252 static const char* empty_xstring = "";
253 
254 const
ndbd_exit_classification_message(ndbd_exit_classification classification,ndbd_exit_status * status)255 char *ndbd_exit_classification_message(ndbd_exit_classification classification,
256                                      ndbd_exit_status *status)
257 {
258   int i;
259   for (i= 0; i < NbExitClassification; i++)
260   {
261     if (StatusExitClassificationMapping[i].classification == classification)
262     {
263       *status = StatusExitClassificationMapping[i].status;
264       return StatusExitClassificationMapping[i].message;
265     }
266   }
267   *status = XST_U;
268   return empty_xstring;
269 }
270 
ndbd_exit_status_message(ndbd_exit_status status)271 const char *ndbd_exit_status_message(ndbd_exit_status status)
272 {
273   int i;
274   for (i= 0; i < NbExitStatus; i++)
275     if (StatusExitMessageMapping[i].status == status)
276       return StatusExitMessageMapping[i].message;
277   return empty_xstring;
278 }
279 
ndbd_exit_string(int err_no,char * str,unsigned int size)280 int ndbd_exit_string(int err_no, char *str, unsigned int size)
281 {
282   size_t len;
283 
284   ndbd_exit_classification cl;
285   ndbd_exit_status st;
286   const char *msg = ndbd_exit_message(err_no, &cl);
287   if (msg[0] != '\0' && cl != XUE)
288   {
289     const char *cl_msg = ndbd_exit_classification_message(cl, &st);
290     const char *st_msg = ndbd_exit_status_message(st);
291 
292     len = my_snprintf(str, size-1, "%s: %s: %s", msg, st_msg, cl_msg);
293     str[size-1]= '\0';
294 
295     return (int)len;
296   }
297   return -1;
298 }
299