Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
905db498
Commit
905db498
authored
Nov 29, 2004
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1
into poseidon.ndb.mysql.com:/home/tomas/mysql-4.1-clean
parents
bd6634ad
3d3ad211
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
295 additions
and
194 deletions
+295
-194
ndb/include/kernel/signaldata/BackupImpl.hpp
ndb/include/kernel/signaldata/BackupImpl.hpp
+9
-9
ndb/include/kernel/signaldata/BackupSignalData.hpp
ndb/include/kernel/signaldata/BackupSignalData.hpp
+14
-13
ndb/include/ndbapi/ndberror.h
ndb/include/ndbapi/ndberror.h
+2
-1
ndb/src/kernel/blocks/backup/Backup.cpp
ndb/src/kernel/blocks/backup/Backup.cpp
+7
-0
ndb/src/kernel/blocks/backup/Backup.hpp
ndb/src/kernel/blocks/backup/Backup.hpp
+1
-0
ndb/src/kernel/blocks/backup/BackupInit.cpp
ndb/src/kernel/blocks/backup/BackupInit.cpp
+1
-0
ndb/src/mgmclient/CommandInterpreter.cpp
ndb/src/mgmclient/CommandInterpreter.cpp
+127
-109
ndb/src/mgmclient/main.cpp
ndb/src/mgmclient/main.cpp
+17
-6
ndb/src/mgmclient/ndb_mgmclient.hpp
ndb/src/mgmclient/ndb_mgmclient.hpp
+2
-2
ndb/src/mgmsrv/CommandInterpreter.cpp
ndb/src/mgmsrv/CommandInterpreter.cpp
+27
-20
ndb/src/mgmsrv/CommandInterpreter.hpp
ndb/src/mgmsrv/CommandInterpreter.hpp
+3
-0
ndb/src/mgmsrv/MgmtSrvr.cpp
ndb/src/mgmsrv/MgmtSrvr.cpp
+11
-16
ndb/src/mgmsrv/MgmtSrvr.hpp
ndb/src/mgmsrv/MgmtSrvr.hpp
+1
-1
ndb/src/mgmsrv/Services.cpp
ndb/src/mgmsrv/Services.cpp
+17
-17
ndb/src/mgmsrv/Services.hpp
ndb/src/mgmsrv/Services.hpp
+3
-0
ndb/src/ndbapi/ndberror.c
ndb/src/ndbapi/ndberror.c
+53
-0
No files found.
ndb/include/kernel/signaldata/BackupImpl.hpp
View file @
905db498
...
...
@@ -78,15 +78,15 @@ public:
STATIC_CONST
(
SignalLength
=
3
);
enum
ErrorCode
{
Undefined
=
20
0
,
FailedToAllocateBuffers
=
20
2
,
FailedToSetupFsBuffers
=
20
3
,
FailedToAllocateTables
=
20
4
,
FailedInsertFileHeader
=
20
5
,
FailedInsertTableList
=
20
6
,
FailedAllocateTableMem
=
20
7
,
FailedToAllocateFileRecord
=
20
8
,
FailedToAllocateAttributeRecord
=
20
9
Undefined
=
134
0
,
FailedToAllocateBuffers
=
134
2
,
FailedToSetupFsBuffers
=
134
3
,
FailedToAllocateTables
=
134
4
,
FailedInsertFileHeader
=
134
5
,
FailedInsertTableList
=
134
6
,
FailedAllocateTableMem
=
134
7
,
FailedToAllocateFileRecord
=
134
8
,
FailedToAllocateAttributeRecord
=
134
9
};
private:
Uint32
backupId
;
...
...
ndb/include/kernel/signaldata/BackupSignalData.hpp
View file @
905db498
...
...
@@ -119,12 +119,13 @@ public:
private:
enum
ErrorCodes
{
Undefined
=
100
,
IAmNotMaster
=
101
,
OutOfBackupRecord
=
102
,
OutOfResources
=
103
,
SequenceFailure
=
104
,
BackupDefinitionNotImplemented
=
105
Undefined
=
1300
,
IAmNotMaster
=
1301
,
OutOfBackupRecord
=
1302
,
OutOfResources
=
1303
,
SequenceFailure
=
1304
,
BackupDefinitionNotImplemented
=
1305
,
CannotBackupDiskless
=
1306
};
Uint32
senderData
;
Uint32
errorCode
;
...
...
@@ -232,13 +233,13 @@ public:
STATIC_CONST
(
SignalLength
=
3
);
enum
RequestType
{
ClientAbort
=
1
,
BackupComplete
=
2
,
BackupFailure
=
3
,
// General backup failure coordinator -> slave
LogBufferFull
=
4
,
// slave -> coordinator
FileOrScanError
=
5
,
// slave -> coordinator
BackupFailureDueToNodeFail
=
6
,
// slave -> slave
OkToClean
=
7
// master -> slave
ClientAbort
=
1
321
,
BackupComplete
=
132
2
,
BackupFailure
=
132
3
,
// General backup failure coordinator -> slave
LogBufferFull
=
132
4
,
// slave -> coordinator
FileOrScanError
=
132
5
,
// slave -> coordinator
BackupFailureDueToNodeFail
=
132
6
,
// slave -> slave
OkToClean
=
132
7
// master -> slave
};
private:
Uint32
requestType
;
...
...
ndb/include/ndbapi/ndberror.h
View file @
905db498
...
...
@@ -46,7 +46,8 @@ typedef enum
ndberror_cl_internal_error
=
12
,
ndberror_cl_function_not_implemented
=
13
,
ndberror_cl_unknown_error_code
=
14
,
ndberror_cl_node_shutdown
=
15
ndberror_cl_node_shutdown
=
15
,
ndberror_cl_configuration
=
16
}
ndberror_classification_enum
;
...
...
ndb/src/kernel/blocks/backup/Backup.cpp
View file @
905db498
...
...
@@ -863,6 +863,13 @@ Backup::execBACKUP_REQ(Signal* signal)
sendBackupRef
(
senderRef
,
signal
,
senderData
,
BackupRef
::
IAmNotMaster
);
return
;
}
//if
if
(
m_diskless
)
{
sendBackupRef
(
senderRef
,
signal
,
senderData
,
BackupRef
::
CannotBackupDiskless
);
return
;
}
if
(
dataLen32
!=
0
)
{
jam
();
...
...
ndb/src/kernel/blocks/backup/Backup.hpp
View file @
905db498
...
...
@@ -526,6 +526,7 @@ public:
NdbNodeBitmask
c_aliveNodes
;
DLList
<
BackupRecord
>
c_backups
;
Config
c_defaults
;
Uint32
m_diskless
;
STATIC_CONST
(
NO_OF_PAGES_META_FILE
=
2
);
...
...
ndb/src/kernel/blocks/backup/BackupInit.cpp
View file @
905db498
...
...
@@ -42,6 +42,7 @@ Backup::Backup(const Configuration & conf) :
ndbrequire
(
p
!=
0
);
Uint32
noBackups
=
0
,
noTables
=
0
,
noAttribs
=
0
;
ndbrequire
(
!
ndb_mgm_get_int_parameter
(
p
,
CFG_DB_DISCLESS
,
&
m_diskless
));
ndb_mgm_get_int_parameter
(
p
,
CFG_DB_PARALLEL_BACKUPS
,
&
noBackups
);
ndbrequire
(
!
ndb_mgm_get_int_parameter
(
p
,
CFG_DB_NO_TABLES
,
&
noTables
));
ndbrequire
(
!
ndb_mgm_get_int_parameter
(
p
,
CFG_DB_NO_ATTRIBUTES
,
&
noAttribs
));
...
...
ndb/src/mgmclient/CommandInterpreter.cpp
View file @
905db498
...
...
@@ -54,10 +54,11 @@ class CommandInterpreter {
*
* @return true until quit/bye/exit has been typed
*/
int
execute
(
const
char
*
_line
,
int
_try_reconnect
=-
1
);
int
execute
(
const
char
*
_line
,
int
_try_reconnect
=-
1
,
int
*
error
=
0
);
private:
void
printError
();
int
execute_impl
(
const
char
*
_line
);
/**
* Analyse the command line, after the first token.
...
...
@@ -121,7 +122,7 @@ class CommandInterpreter {
void
executeStatus
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeEventReporting
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeDumpState
(
int
processId
,
const
char
*
parameters
,
bool
all
);
void
executeStartBackup
(
char
*
parameters
);
int
executeStartBackup
(
char
*
parameters
);
void
executeAbortBackup
(
char
*
parameters
);
void
executeRep
(
char
*
parameters
);
...
...
@@ -156,6 +157,7 @@ class CommandInterpreter {
bool
connected
;
int
m_verbose
;
int
try_reconnect
;
int
m_error
;
#ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle
m_repserver
;
const
char
*
rep_host
;
...
...
@@ -179,9 +181,9 @@ Ndb_mgmclient::~Ndb_mgmclient()
{
delete
m_cmd
;
}
int
Ndb_mgmclient
::
execute
(
const
char
*
_line
,
int
_try_reconnect
)
int
Ndb_mgmclient
::
execute
(
const
char
*
_line
,
int
_try_reconnect
,
int
*
error
)
{
return
m_cmd
->
execute
(
_line
,
_try_reconnect
);
return
m_cmd
->
execute
(
_line
,
_try_reconnect
,
error
);
}
int
Ndb_mgmclient
::
disconnect
()
...
...
@@ -227,7 +229,7 @@ extern "C" {
#include <util/InputStream.hpp>
#include <util/OutputStream.hpp>
int
Ndb_mgmclient
::
execute
(
int
argc
,
char
**
argv
,
int
_try_reconnect
)
int
Ndb_mgmclient
::
execute
(
int
argc
,
char
**
argv
,
int
_try_reconnect
,
int
*
error
)
{
if
(
argc
<=
0
)
return
0
;
...
...
@@ -236,7 +238,7 @@ int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect)
{
_line
.
appfmt
(
" %s"
,
argv
[
i
]);
}
return
m_cmd
->
execute
(
_line
.
c_str
(),
_try_reconnect
);
return
m_cmd
->
execute
(
_line
.
c_str
(),
_try_reconnect
,
error
);
}
/*****************************************************************************
...
...
@@ -277,7 +279,7 @@ static const char* helpText =
"REP CONNECT <host:port> Connect to REP server on host:port
\n
"
#endif
"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server
\n
"
"CONNECT
Connect to management server (reconnect if already connected)
\n
"
"CONNECT
[<connectstring>]
Connect to management server (reconnect if already connected)
\n
"
"QUIT Quit management client
\n
"
;
...
...
@@ -469,13 +471,24 @@ CommandInterpreter::disconnect()
//*****************************************************************************
int
CommandInterpreter
::
execute
(
const
char
*
_line
,
int
_try_reconnect
)
CommandInterpreter
::
execute
(
const
char
*
_line
,
int
_try_reconnect
,
int
*
error
)
{
DBUG_ENTER
(
"CommandInterpreter::execute"
);
DBUG_PRINT
(
"info"
,(
"line=
\"
%s
\"
"
,
_line
));
if
(
_try_reconnect
>=
0
)
try_reconnect
=
_try_reconnect
;
int
result
=
execute_impl
(
_line
);
if
(
error
)
*
error
=
m_error
;
return
result
;
}
int
CommandInterpreter
::
execute_impl
(
const
char
*
_line
)
{
DBUG_ENTER
(
"CommandInterpreter::execute_impl"
);
DBUG_PRINT
(
"enter"
,(
"line=
\"
%s
\"
"
,
_line
));
m_error
=
0
;
char
*
line
;
if
(
_line
==
NULL
)
{
// ndbout << endl;
...
...
@@ -488,20 +501,16 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
DBUG_RETURN
(
true
);
}
for
(
unsigned
int
i
=
0
;
i
<
strlen
(
line
);
++
i
)
{
line
[
i
]
=
toupper
(
line
[
i
]);
}
// if there is anything in the line proceed
char
*
firstToken
=
strtok
(
line
,
" "
);
char
*
allAfterFirstToken
=
strtok
(
NULL
,
""
);
if
(
strcmp
(
firstToken
,
"HELP"
)
==
0
||
strcmp
(
firstToken
,
"?"
)
==
0
)
{
if
(
strc
asec
mp
(
firstToken
,
"HELP"
)
==
0
||
strc
asec
mp
(
firstToken
,
"?"
)
==
0
)
{
executeHelp
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"CONNECT"
)
==
0
)
{
else
if
(
strc
asec
mp
(
firstToken
,
"CONNECT"
)
==
0
)
{
executeConnect
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
...
...
@@ -509,61 +518,61 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
if
(
!
connect
())
DBUG_RETURN
(
true
);
if
(
strcmp
(
firstToken
,
"SHOW"
)
==
0
)
{
if
(
strc
asec
mp
(
firstToken
,
"SHOW"
)
==
0
)
{
executeShow
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"SHUTDOWN"
)
==
0
)
{
else
if
(
strc
asec
mp
(
firstToken
,
"SHUTDOWN"
)
==
0
)
{
executeShutdown
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"CLUSTERLOG"
)
==
0
){
else
if
(
strc
asec
mp
(
firstToken
,
"CLUSTERLOG"
)
==
0
){
executeClusterLog
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"START"
)
==
0
&&
else
if
(
strc
asec
mp
(
firstToken
,
"START"
)
==
0
&&
allAfterFirstToken
!=
NULL
&&
strncmp
(
allAfterFirstToken
,
"BACKUP"
,
sizeof
(
"BACKUP"
)
-
1
)
==
0
){
executeStartBackup
(
allAfterFirstToken
);
strnc
asec
mp
(
allAfterFirstToken
,
"BACKUP"
,
sizeof
(
"BACKUP"
)
-
1
)
==
0
){
m_error
=
executeStartBackup
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"ABORT"
)
==
0
&&
else
if
(
strc
asec
mp
(
firstToken
,
"ABORT"
)
==
0
&&
allAfterFirstToken
!=
NULL
&&
strncmp
(
allAfterFirstToken
,
"BACKUP"
,
sizeof
(
"BACKUP"
)
-
1
)
==
0
){
strnc
asec
mp
(
allAfterFirstToken
,
"BACKUP"
,
sizeof
(
"BACKUP"
)
-
1
)
==
0
){
executeAbortBackup
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"PURGE"
)
==
0
)
{
else
if
(
strc
asec
mp
(
firstToken
,
"PURGE"
)
==
0
)
{
executePurge
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
#ifdef HAVE_GLOBAL_REPLICATION
else
if
(
strcmp
(
firstToken
,
"REPLICATION"
)
==
0
||
strcmp
(
firstToken
,
"REP"
)
==
0
)
{
else
if
(
strc
asec
mp
(
firstToken
,
"REPLICATION"
)
==
0
||
strc
asec
mp
(
firstToken
,
"REP"
)
==
0
)
{
executeRep
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
#endif // HAVE_GLOBAL_REPLICATION
else
if
(
strcmp
(
firstToken
,
"ENTER"
)
==
0
&&
else
if
(
strc
asec
mp
(
firstToken
,
"ENTER"
)
==
0
&&
allAfterFirstToken
!=
NULL
&&
strncmp
(
allAfterFirstToken
,
"SINGLE USER MODE "
,
strnc
asec
mp
(
allAfterFirstToken
,
"SINGLE USER MODE "
,
sizeof
(
"SINGLE USER MODE"
)
-
1
)
==
0
){
executeEnterSingleUser
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"EXIT"
)
==
0
&&
else
if
(
strc
asec
mp
(
firstToken
,
"EXIT"
)
==
0
&&
allAfterFirstToken
!=
NULL
&&
strncmp
(
allAfterFirstToken
,
"SINGLE USER MODE "
,
strnc
asec
mp
(
allAfterFirstToken
,
"SINGLE USER MODE "
,
sizeof
(
"SINGLE USER MODE"
)
-
1
)
==
0
){
executeExitSingleUser
(
allAfterFirstToken
);
DBUG_RETURN
(
true
);
}
else
if
(
strcmp
(
firstToken
,
"ALL"
)
==
0
)
{
else
if
(
strc
asec
mp
(
firstToken
,
"ALL"
)
==
0
)
{
analyseAfterFirstToken
(
-
1
,
allAfterFirstToken
);
}
else
if
((
strcmp
(
firstToken
,
"QUIT"
)
==
0
||
strcmp
(
firstToken
,
"EXIT"
)
==
0
||
strcmp
(
firstToken
,
"BYE"
)
==
0
)
&&
else
if
((
strc
asec
mp
(
firstToken
,
"QUIT"
)
==
0
||
strc
asec
mp
(
firstToken
,
"EXIT"
)
==
0
||
strc
asec
mp
(
firstToken
,
"BYE"
)
==
0
)
&&
allAfterFirstToken
==
NULL
){
DBUG_RETURN
(
false
);
}
else
{
...
...
@@ -573,12 +582,12 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
int
nodeId
;
if
(
!
convert
(
firstToken
,
nodeId
))
{
ndbout
<<
"Invalid command: "
<<
line
<<
endl
;
ndbout
<<
"Invalid command: "
<<
_
line
<<
endl
;
ndbout
<<
"Type HELP for help."
<<
endl
<<
endl
;
DBUG_RETURN
(
true
);
}
if
(
nodeId
<
0
)
{
if
(
nodeId
<
=
0
)
{
ndbout
<<
"Invalid node ID: "
<<
firstToken
<<
"."
<<
endl
;
DBUG_RETURN
(
true
);
}
...
...
@@ -639,7 +648,7 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
ExecuteFunction
fun
=
0
;
const
char
*
command
=
0
;
for
(
int
i
=
0
;
i
<
tmpSize
;
i
++
){
if
(
strcmp
(
secondToken
,
commands
[
i
].
command
)
==
0
){
if
(
strc
asec
mp
(
secondToken
,
commands
[
i
].
command
)
==
0
){
fun
=
commands
[
i
].
executeFunction
;
command
=
commands
[
i
].
command
;
break
;
...
...
@@ -655,7 +664,7 @@ CommandInterpreter::analyseAfterFirstToken(int processId,
if
(
processId
==
-
1
){
executeForAll
(
command
,
fun
,
allAfterSecondToken
);
}
else
{
if
(
strcmp
(
command
,
"STATUS"
)
!=
0
)
if
(
strc
asec
mp
(
command
,
"STATUS"
)
!=
0
)
ndbout_c
(
"Executing %s on node %d."
,
command
,
processId
);
(
this
->*
fun
)(
processId
,
allAfterSecondToken
,
false
);
ndbout
<<
endl
;
...
...
@@ -705,10 +714,10 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
const
char
*
allAfterSecondToken
)
{
int
nodeId
=
0
;
if
(
strcmp
(
cmd
,
"STOP"
)
==
0
)
{
if
(
strc
asec
mp
(
cmd
,
"STOP"
)
==
0
)
{
ndbout_c
(
"Executing STOP on all nodes."
);
(
this
->*
fun
)(
nodeId
,
allAfterSecondToken
,
true
);
}
else
if
(
strcmp
(
cmd
,
"RESTART"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
cmd
,
"RESTART"
)
==
0
)
{
ndbout_c
(
"Executing RESTART on all nodes."
);
ndbout_c
(
"Starting shutdown. This may take a while. Please wait..."
);
(
this
->*
fun
)(
nodeId
,
allAfterSecondToken
,
true
);
...
...
@@ -723,7 +732,7 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
}
NdbAutoPtr
<
char
>
ap1
((
char
*
)
cl
);
while
(
get_next_nodeid
(
cl
,
&
nodeId
,
NDB_MGM_NODE_TYPE_NDB
))
{
if
(
strcmp
(
cmd
,
"STATUS"
)
!=
0
)
if
(
strc
asec
mp
(
cmd
,
"STATUS"
)
!=
0
)
ndbout_c
(
"Executing %s on node %d."
,
cmd
,
nodeId
);
(
this
->*
fun
)(
nodeId
,
allAfterSecondToken
,
true
);
ndbout
<<
endl
;
...
...
@@ -751,7 +760,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
firstTokenAfterLog
[
i
]
=
toupper
(
firstTokenAfterLog
[
i
]);
}
if
(
strcmp
(
firstTokenAfterLog
,
"BLOCK"
)
!=
0
)
{
if
(
strc
asec
mp
(
firstTokenAfterLog
,
"BLOCK"
)
!=
0
)
{
ndbout
<<
"Unexpected value: "
<<
firstTokenAfterLog
<<
". Expected BLOCK."
<<
endl
;
return
false
;
...
...
@@ -764,7 +773,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
}
char
*
secondTokenAfterLog
=
strtok
(
allAfterFirstToken
,
" "
);
if
(
strcmp
(
secondTokenAfterLog
,
"="
)
!=
0
)
{
if
(
strc
asec
mp
(
secondTokenAfterLog
,
"="
)
!=
0
)
{
ndbout
<<
"Unexpected value: "
<<
secondTokenAfterLog
<<
". Expected =."
<<
endl
;
return
false
;
...
...
@@ -772,7 +781,7 @@ CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
char
*
blockName
=
strtok
(
NULL
,
" "
);
bool
all
=
false
;
if
(
blockName
!=
NULL
&&
(
strcmp
(
blockName
,
"ALL"
)
==
0
))
{
if
(
blockName
!=
NULL
&&
(
strc
asec
mp
(
blockName
,
"ALL"
)
==
0
))
{
all
=
true
;
}
while
(
blockName
!=
NULL
)
{
...
...
@@ -823,15 +832,15 @@ CommandInterpreter::executeHelp(char* parameters)
ndbout
<<
"<level> = "
<<
"0 - 15"
<<
endl
;
ndbout
<<
"<id> = "
<<
"ALL | Any database node id"
<<
endl
;
ndbout
<<
endl
;
}
else
if
(
strcmp
(
parameters
,
"SHOW"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
parameters
,
"SHOW"
)
==
0
)
{
ndbout
<<
helpTextShow
;
#ifdef HAVE_GLOBAL_REPLICATION
}
else
if
(
strcmp
(
parameters
,
"REPLICATION"
)
==
0
||
strcmp
(
parameters
,
"REP"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
parameters
,
"REPLICATION"
)
==
0
||
strc
asec
mp
(
parameters
,
"REP"
)
==
0
)
{
ndbout
<<
helpTextRep
;
#endif // HAVE_GLOBAL_REPLICATION
#ifdef VM_TRACE // DEBUG ONLY
}
else
if
(
strcmp
(
parameters
,
"DEBUG"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
parameters
,
"DEBUG"
)
==
0
)
{
ndbout
<<
helpTextDebug
;
#endif
}
else
{
...
...
@@ -939,7 +948,7 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it,
const
char
*
hostname
=
node_state
->
connect_address
;
if
(
hostname
==
0
||
strlen
(
hostname
)
==
0
||
strcmp
(
hostname
,
"0.0.0.0"
)
==
0
)
||
strc
asec
mp
(
hostname
,
"0.0.0.0"
)
==
0
)
ndbout
<<
" "
;
else
ndbout
<<
"
\t
@"
<<
hostname
;
...
...
@@ -984,9 +993,9 @@ CommandInterpreter::executePurge(char* parameters)
break
;
char
*
firstToken
=
strtok
(
parameters
,
" "
);
char
*
nextToken
=
strtok
(
NULL
,
"
\0
"
);
if
(
strcmp
(
firstToken
,
"STALE"
)
==
0
&&
if
(
strc
asec
mp
(
firstToken
,
"STALE"
)
==
0
&&
nextToken
&&
strcmp
(
nextToken
,
"SESSIONS"
)
==
0
)
{
strc
asec
mp
(
nextToken
,
"SESSIONS"
)
==
0
)
{
command_ok
=
1
;
break
;
}
...
...
@@ -1086,17 +1095,17 @@ CommandInterpreter::executeShow(char* parameters)
print_nodes
(
state
,
it
,
"mysqld"
,
api_nodes
,
NDB_MGM_NODE_TYPE_API
,
0
);
// ndbout << helpTextShow;
return
;
}
else
if
(
strcmp
(
parameters
,
"PROPERTIES"
)
==
0
||
strcmp
(
parameters
,
"PROP"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
parameters
,
"PROPERTIES"
)
==
0
||
strc
asec
mp
(
parameters
,
"PROP"
)
==
0
)
{
ndbout
<<
"SHOW PROPERTIES is not yet implemented."
<<
endl
;
// ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */
}
else
if
(
strcmp
(
parameters
,
"CONFIGURATION"
)
==
0
||
strcmp
(
parameters
,
"CONFIG"
)
==
0
){
}
else
if
(
strc
asec
mp
(
parameters
,
"CONFIGURATION"
)
==
0
||
strc
asec
mp
(
parameters
,
"CONFIG"
)
==
0
){
ndbout
<<
"SHOW CONFIGURATION is not yet implemented."
<<
endl
;
//nbout << "_mgmtSrvr.getConfig()->printConfigFile();" << endl; /* XXX */
}
else
if
(
strcmp
(
parameters
,
"PARAMETERS"
)
==
0
||
strcmp
(
parameters
,
"PARAMS"
)
==
0
||
strcmp
(
parameters
,
"PARAM"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
parameters
,
"PARAMETERS"
)
==
0
||
strc
asec
mp
(
parameters
,
"PARAMS"
)
==
0
||
strc
asec
mp
(
parameters
,
"PARAM"
)
==
0
)
{
ndbout
<<
"SHOW PARAMETERS is not yet implemented."
<<
endl
;
// ndbout << "_mgmtSrvr.getConfig()->getConfigInfo()->print();"
// << endl; /* XXX */
...
...
@@ -1109,6 +1118,14 @@ void
CommandInterpreter
::
executeConnect
(
char
*
parameters
)
{
disconnect
();
if
(
!
emptyString
(
parameters
))
{
if
(
ndb_mgm_set_connectstring
(
m_mgmsrv
,
BaseString
(
parameters
).
trim
().
c_str
()))
{
printError
();
return
;
}
}
connect
();
}
...
...
@@ -1132,7 +1149,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG FILTER
********************/
if
(
strcmp
(
item
,
"FILTER"
)
==
0
)
{
if
(
strc
asec
mp
(
item
,
"FILTER"
)
==
0
)
{
item
=
strtok_r
(
NULL
,
" "
,
&
tmpPtr
);
if
(
item
==
NULL
)
{
...
...
@@ -1141,21 +1158,21 @@ CommandInterpreter::executeClusterLog(char* parameters)
while
(
item
!=
NULL
)
{
snprintf
(
name
,
sizeof
(
name
),
item
);
if
(
strcmp
(
item
,
"ALL"
)
==
0
)
{
if
(
strc
asec
mp
(
item
,
"ALL"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_ALL
;
}
else
if
(
strcmp
(
item
,
"ALERT"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"ALERT"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_ALERT
;
}
else
if
(
strcmp
(
item
,
"CRITICAL"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"CRITICAL"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_CRITICAL
;
}
else
if
(
strcmp
(
item
,
"ERROR"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"ERROR"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_ERROR
;
}
else
if
(
strcmp
(
item
,
"WARNING"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"WARNING"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_WARNING
;
}
else
if
(
strcmp
(
item
,
"INFO"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"INFO"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_INFO
;
}
else
if
(
strcmp
(
item
,
"DEBUG"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"DEBUG"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_DEBUG
;
}
else
if
(
strcmp
(
item
,
"OFF"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"OFF"
)
==
0
)
{
severity
=
NDB_MGM_CLUSTERLOG_OFF
;
}
else
{
isOk
=
false
;
...
...
@@ -1168,17 +1185,17 @@ CommandInterpreter::executeClusterLog(char* parameters)
ndbout
<<
"Missing argument(s)."
<<
endl
;
}
else
if
(
isOk
)
{
if
(
ndb_mgm_filter_clusterlog
(
m_mgmsrv
,
severity
,
NULL
))
{
if
(
strc
mp
(
name
,
"ALL"
)
==
0
||
strcmp
(
name
,
"all
"
)
==
0
)
{
if
(
strc
asecmp
(
name
,
"ALL
"
)
==
0
)
{
ndbout
<<
"All severities levels enabled."
<<
endl
;
}
else
if
(
strc
mp
(
name
,
"OFF"
)
==
0
||
strcmp
(
name
,
"off
"
)
==
0
)
{
}
else
if
(
strc
asecmp
(
name
,
"OFF
"
)
==
0
)
{
ndbout
<<
"Cluster logging enabled."
<<
endl
;
}
else
{
ndbout
<<
name
<<
" events disabled."
<<
endl
;
}
}
else
{
if
(
strcmp
(
name
,
"ALL"
)
==
0
)
{
if
(
strc
asec
mp
(
name
,
"ALL"
)
==
0
)
{
ndbout
<<
"All severities levels disabled."
<<
endl
;
}
else
if
(
strcmp
(
name
,
"OFF"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
name
,
"OFF"
)
==
0
)
{
ndbout
<<
"Cluster logging disabled."
<<
endl
;
}
else
{
ndbout
<<
name
<<
" events enabled."
<<
endl
;
...
...
@@ -1191,7 +1208,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG INFO
********************/
}
else
if
(
strcmp
(
item
,
"INFO"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"INFO"
)
==
0
)
{
Uint32
*
enabled
=
ndb_mgm_get_logfilter
(
m_mgmsrv
);
if
(
enabled
==
NULL
)
{
ndbout
<<
"Couldn't get status"
<<
endl
;
...
...
@@ -1216,7 +1233,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG OFF
********************/
}
else
if
(
strcmp
(
item
,
"OFF"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"OFF"
)
==
0
)
{
Uint32
*
enabled
=
ndb_mgm_get_logfilter
(
m_mgmsrv
);
if
(
enabled
==
NULL
)
{
ndbout
<<
"Couldn't get status"
<<
endl
;
...
...
@@ -1234,7 +1251,7 @@ CommandInterpreter::executeClusterLog(char* parameters)
/********************
* CLUSTERLOG ON
********************/
}
else
if
(
strcmp
(
item
,
"ON"
)
==
0
)
{
}
else
if
(
strc
asec
mp
(
item
,
"ON"
)
==
0
)
{
Uint32
*
enabled
=
ndb_mgm_get_logfilter
(
m_mgmsrv
);
if
(
enabled
==
NULL
)
{
ndbout
<<
"Could not get status"
<<
endl
;
...
...
@@ -1358,11 +1375,11 @@ CommandInterpreter::executeRestart(int processId, const char* parameters,
char
*
tmpPtr
=
0
;
char
*
item
=
strtok_r
(
tmpString
,
" "
,
&
tmpPtr
);
while
(
item
!=
NULL
){
if
(
strcmp
(
item
,
"-N"
)
==
0
)
if
(
strc
asec
mp
(
item
,
"-N"
)
==
0
)
nostart
=
1
;
if
(
strcmp
(
item
,
"-I"
)
==
0
)
if
(
strc
asec
mp
(
item
,
"-I"
)
==
0
)
initialstart
=
1
;
if
(
strcmp
(
item
,
"-A"
)
==
0
)
if
(
strc
asec
mp
(
item
,
"-A"
)
==
0
)
abort
=
1
;
item
=
strtok_r
(
NULL
,
" "
,
&
tmpPtr
);
}
...
...
@@ -1591,7 +1608,7 @@ CommandInterpreter::executeTrace(int /*processId*/,
int result = _mgmtSrvr.setTraceNo(processId, traceNo);
if (result != 0) {
ndbout <<
_mgmtSrvr.getErrorT
ext(result) << endl;
ndbout <<
get_error_t
ext(result) << endl;
}
#endif
}
...
...
@@ -1751,7 +1768,7 @@ CommandInterpreter::executeSet(int /*processId*/,
}
}
else {
ndbout <<
_mgmtSrvr.getErrorT
ext(result) << endl;
ndbout <<
get_error_t
ext(result) << endl;
if (configBackupFileUpdated && configPrimaryFileUpdated) {
ndbout << "The configuration files are however updated and "
<< "the value will be used next time the process is restarted."
...
...
@@ -1786,7 +1803,7 @@ void CommandInterpreter::executeGetStat(int /*processId*/,
MgmtSrvr::Statistics statistics;
int result = _mgmtSrvr.getStatistics(processId, statistics);
if (result != 0) {
ndbout <<
_mgmtSrvr.getErrorT
ext(result) << endl;
ndbout <<
get_error_t
ext(result) << endl;
return;
}
#endif
...
...
@@ -1856,7 +1873,7 @@ CommandInterpreter::executeEventReporting(int processId,
/*****************************************************************************
* Backup
*****************************************************************************/
void
int
CommandInterpreter
::
executeStartBackup
(
char
*
/*parameters*/
)
{
struct
ndb_mgm_reply
reply
;
...
...
@@ -1869,7 +1886,7 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
ndbout
<<
"Start of backup failed"
<<
endl
;
printError
();
close
(
fd
);
return
;
return
result
;
}
char
*
tmp
;
...
...
@@ -1900,6 +1917,7 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
}
while
(
tmp
&&
tmp
[
0
]
!=
0
);
close
(
fd
);
return
0
;
}
void
...
...
@@ -1966,7 +1984,7 @@ CommandInterpreter::executeRep(char* parameters)
unsigned
int
repId
;
if
(
!
strcmp
(
firstToken
,
"CONNECT"
))
{
if
(
!
strc
asec
mp
(
firstToken
,
"CONNECT"
))
{
char
*
host
=
strtok
(
NULL
,
"
\0
"
);
for
(
unsigned
int
i
=
0
;
i
<
strlen
(
host
);
++
i
)
{
host
[
i
]
=
tolower
(
host
[
i
]);
...
...
@@ -2001,30 +2019,30 @@ CommandInterpreter::executeRep(char* parameters)
/********
* START
********/
if
(
!
strcmp
(
firstToken
,
"START"
))
{
if
(
!
strc
asec
mp
(
firstToken
,
"START"
))
{
unsigned
int
req
;
char
*
startType
=
strtok
(
NULL
,
"
\0
"
);
if
(
startType
==
NULL
)
{
req
=
GrepReq
::
START
;
}
else
if
(
!
strcmp
(
startType
,
"SUBSCRIPTION"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"SUBSCRIPTION"
))
{
req
=
GrepReq
::
START_SUBSCR
;
}
else
if
(
!
strcmp
(
startType
,
"METALOG"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"METALOG"
))
{
req
=
GrepReq
::
START_METALOG
;
}
else
if
(
!
strcmp
(
startType
,
"METASCAN"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"METASCAN"
))
{
req
=
GrepReq
::
START_METASCAN
;
}
else
if
(
!
strcmp
(
startType
,
"DATALOG"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"DATALOG"
))
{
req
=
GrepReq
::
START_DATALOG
;
}
else
if
(
!
strcmp
(
startType
,
"DATASCAN"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"DATASCAN"
))
{
req
=
GrepReq
::
START_DATASCAN
;
}
else
if
(
!
strcmp
(
startType
,
"REQUESTOR"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"REQUESTOR"
))
{
req
=
GrepReq
::
START_REQUESTOR
;
}
else
if
(
!
strcmp
(
startType
,
"TRANSFER"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"TRANSFER"
))
{
req
=
GrepReq
::
START_TRANSFER
;
}
else
if
(
!
strcmp
(
startType
,
"APPLY"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"APPLY"
))
{
req
=
GrepReq
::
START_APPLY
;
}
else
if
(
!
strcmp
(
startType
,
"DELETE"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"DELETE"
))
{
req
=
GrepReq
::
START_DELETE
;
}
else
{
ndbout_c
(
"Illegal argument to command 'REPLICATION START'"
);
...
...
@@ -2044,7 +2062,7 @@ CommandInterpreter::executeRep(char* parameters)
/********
* STOP
********/
if
(
!
strcmp
(
firstToken
,
"STOP"
))
{
if
(
!
strc
asec
mp
(
firstToken
,
"STOP"
))
{
unsigned
int
req
;
char
*
startType
=
strtok
(
NULL
,
" "
);
unsigned
int
epoch
=
0
;
...
...
@@ -2054,7 +2072,7 @@ CommandInterpreter::executeRep(char* parameters)
* Stop immediately
*/
req
=
GrepReq
::
STOP
;
}
else
if
(
!
strcmp
(
startType
,
"EPOCH"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"EPOCH"
))
{
char
*
strEpoch
=
strtok
(
NULL
,
"
\0
"
);
if
(
strEpoch
==
NULL
)
{
ndbout_c
(
"Epoch expected!"
);
...
...
@@ -2062,23 +2080,23 @@ CommandInterpreter::executeRep(char* parameters)
}
req
=
GrepReq
::
STOP
;
epoch
=
atoi
(
strEpoch
);
}
else
if
(
!
strcmp
(
startType
,
"SUBSCRIPTION"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"SUBSCRIPTION"
))
{
req
=
GrepReq
::
STOP_SUBSCR
;
}
else
if
(
!
strcmp
(
startType
,
"METALOG"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"METALOG"
))
{
req
=
GrepReq
::
STOP_METALOG
;
}
else
if
(
!
strcmp
(
startType
,
"METASCAN"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"METASCAN"
))
{
req
=
GrepReq
::
STOP_METASCAN
;
}
else
if
(
!
strcmp
(
startType
,
"DATALOG"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"DATALOG"
))
{
req
=
GrepReq
::
STOP_DATALOG
;
}
else
if
(
!
strcmp
(
startType
,
"DATASCAN"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"DATASCAN"
))
{
req
=
GrepReq
::
STOP_DATASCAN
;
}
else
if
(
!
strcmp
(
startType
,
"REQUESTOR"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"REQUESTOR"
))
{
req
=
GrepReq
::
STOP_REQUESTOR
;
}
else
if
(
!
strcmp
(
startType
,
"TRANSFER"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"TRANSFER"
))
{
req
=
GrepReq
::
STOP_TRANSFER
;
}
else
if
(
!
strcmp
(
startType
,
"APPLY"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"APPLY"
))
{
req
=
GrepReq
::
STOP_APPLY
;
}
else
if
(
!
strcmp
(
startType
,
"DELETE"
))
{
}
else
if
(
!
strc
asec
mp
(
startType
,
"DELETE"
))
{
req
=
GrepReq
::
STOP_DELETE
;
}
else
{
ndbout_c
(
"Illegal argument to command 'REPLICATION STOP'"
);
...
...
@@ -2097,7 +2115,7 @@ CommandInterpreter::executeRep(char* parameters)
/*********
* STATUS
*********/
if
(
!
strcmp
(
firstToken
,
"STATUS"
))
{
if
(
!
strc
asec
mp
(
firstToken
,
"STATUS"
))
{
struct
rep_state
repstate
;
int
result
=
ndb_rep_get_status
(
m_repserver
,
&
repId
,
&
reply
,
&
repstate
);
...
...
@@ -2117,7 +2135,7 @@ CommandInterpreter::executeRep(char* parameters)
/*********
* QUERY (see repapi.h for querable counters)
*********/
if
(
!
strcmp
(
firstToken
,
"QUERY"
))
{
if
(
!
strc
asec
mp
(
firstToken
,
"QUERY"
))
{
char
*
query
=
strtok
(
NULL
,
"
\0
"
);
int
queryCounter
=-
1
;
if
(
query
!=
NULL
)
{
...
...
ndb/src/mgmclient/main.cpp
View file @
905db498
...
...
@@ -60,10 +60,15 @@ static const char default_prompt[]= "ndb_mgm> ";
static
unsigned
_try_reconnect
;
static
char
*
opt_connect_str
=
0
;
static
const
char
*
prompt
=
default_prompt
;
static
char
*
opt_execute_str
=
0
;
static
struct
my_option
my_long_options
[]
=
{
NDB_STD_OPTS
(
"ndb_mgm"
),
{
"execute"
,
'e'
,
"execute command and exit"
,
(
gptr
*
)
&
opt_execute_str
,
(
gptr
*
)
&
opt_execute_str
,
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"try-reconnect"
,
't'
,
"Specify number of tries for connecting to ndb_mgmd (0 = infinite)"
,
(
gptr
*
)
&
_try_reconnect
,
(
gptr
*
)
&
_try_reconnect
,
0
,
...
...
@@ -156,19 +161,25 @@ int main(int argc, char** argv){
opt_connect_str
=
buf
;
}
if
(
!
isatty
(
0
))
if
(
!
isatty
(
0
)
||
opt_execute_str
)
{
prompt
=
0
;
}
ndbout
<<
"-- NDB Cluster -- Management Client --"
<<
endl
;
signal
(
SIGPIPE
,
handler
);
com
=
new
Ndb_mgmclient
(
opt_connect_str
,
1
);
while
(
read_and_execute
(
_try_reconnect
));
int
ret
=
0
;
if
(
!
opt_execute_str
)
{
ndbout
<<
"-- NDB Cluster -- Management Client --"
<<
endl
;
while
(
read_and_execute
(
_try_reconnect
));
}
else
{
com
->
execute
(
opt_execute_str
,
_try_reconnect
,
&
ret
);
}
delete
com
;
return
0
;
return
ret
;
}
ndb/src/mgmclient/ndb_mgmclient.hpp
View file @
905db498
...
...
@@ -23,8 +23,8 @@ class Ndb_mgmclient
public:
Ndb_mgmclient
(
const
char
*
,
int
verbose
=
0
);
~
Ndb_mgmclient
();
int
execute
(
const
char
*
_line
,
int
_try_reconnect
=-
1
);
int
execute
(
int
argc
,
char
**
argv
,
int
_try_reconnect
=-
1
);
int
execute
(
const
char
*
_line
,
int
_try_reconnect
=-
1
,
int
*
error
=
0
);
int
execute
(
int
argc
,
char
**
argv
,
int
_try_reconnect
=-
1
,
int
*
error
=
0
);
int
disconnect
();
private:
CommandInterpreter
*
m_cmd
;
...
...
ndb/src/mgmsrv/CommandInterpreter.cpp
View file @
905db498
...
...
@@ -113,6 +113,11 @@ class AutoPtr {
void
*
m_ptr
;
};
const
char
*
CommandInterpreter
::
get_error_text
(
int
err_no
)
{
return
_mgmtSrvr
.
getErrorText
(
err_no
,
m_err_str
,
sizeof
(
m_err_str
));
}
//*****************************************************************************
//*****************************************************************************
int
CommandInterpreter
::
readAndExecute
()
{
...
...
@@ -600,8 +605,9 @@ stopCallback(int nodeId, void * anyData, int errCode){
ndbout
<<
"
\n
Node "
<<
nodeId
<<
" has shutdown"
<<
endl
;
}
else
{
MgmtSrvr
*
mgm
=
(
MgmtSrvr
*
)
anyData
;
char
err_str
[
1024
];
ndbout
<<
"Node "
<<
nodeId
<<
" has not shutdown: "
<<
mgm
->
getErrorText
(
errCode
)
<<
endl
;
<<
mgm
->
getErrorText
(
errCode
,
err_str
,
sizeof
(
err_str
)
)
<<
endl
;
}
}
...
...
@@ -653,7 +659,8 @@ versionCallback(int nodeId, int version, void * anyData, int errCode){
}
else
{
MgmtSrvr
*
mgm
=
(
MgmtSrvr
*
)
anyData
;
ndbout
<<
mgm
->
getErrorText
(
errCode
)
<<
endl
;
char
err_str
[
1024
];
ndbout
<<
mgm
->
getErrorText
(
errCode
,
err_str
,
sizeof
(
err_str
))
<<
endl
;
}
}
...
...
@@ -671,7 +678,7 @@ void CommandInterpreter::executeStop(int processId,
result
=
_mgmtSrvr
.
stopNode
(
processId
,
false
,
stopCallback
,
this
);
if
(
result
!=
0
)
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
...
...
@@ -686,7 +693,7 @@ void CommandInterpreter::executeStart(int processId, const char* parameters,
int
result
=
_mgmtSrvr
.
start
(
processId
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -719,7 +726,7 @@ CommandInterpreter::executeRestart(int processId, const char* parameters,
stopCallback
,
this
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -760,7 +767,7 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters,
free
(
tmpString
);
int
result
=
_mgmtSrvr
.
dumpState
(
processId
,
pars
,
no
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -781,7 +788,7 @@ void CommandInterpreter::executeStatus(int processId,
&
status
,
&
version
,
&
startPhase
,
&
system
,
&
dynamicId
,
&
nodeGroup
,
&
connectCount
);
if
(
result
!=
0
){
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
return
;
}
...
...
@@ -875,7 +882,7 @@ void CommandInterpreter::executeLogLevel(int processId,
int result = _mgmtSrvr.setNodeLogLevel(processId, logLevel);
if (result != 0) {
ndbout <<
_mgmtSrvr.getErrorT
ext(result) << endl;
ndbout <<
get_error_t
ext(result) << endl;
}
#endif
}
...
...
@@ -913,7 +920,7 @@ void CommandInterpreter::executeError(int processId,
int
result
=
_mgmtSrvr
.
insertError
(
processId
,
errorNo
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
free
(
newpar
);
}
...
...
@@ -953,7 +960,7 @@ void CommandInterpreter::executeTrace(int processId,
int
result
=
_mgmtSrvr
.
setTraceNo
(
processId
,
traceNo
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
free
(
newpar
);
}
...
...
@@ -974,7 +981,7 @@ void CommandInterpreter::executeLog(int processId,
int
result
=
_mgmtSrvr
.
setSignalLoggingMode
(
processId
,
MgmtSrvr
::
InOut
,
blocks
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -995,7 +1002,7 @@ void CommandInterpreter::executeLogIn(int processId,
int
result
=
_mgmtSrvr
.
setSignalLoggingMode
(
processId
,
MgmtSrvr
::
In
,
blocks
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -1014,7 +1021,7 @@ void CommandInterpreter::executeLogOut(int processId,
int
result
=
_mgmtSrvr
.
setSignalLoggingMode
(
processId
,
MgmtSrvr
::
Out
,
blocks
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -1035,7 +1042,7 @@ void CommandInterpreter::executeLogOff(int processId,
int
result
=
_mgmtSrvr
.
setSignalLoggingMode
(
processId
,
MgmtSrvr
::
Off
,
blocks
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -1054,7 +1061,7 @@ void CommandInterpreter::executeTestOn(int processId,
int
result
=
_mgmtSrvr
.
startSignalTracing
(
processId
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -1073,7 +1080,7 @@ void CommandInterpreter::executeTestOff(int processId,
int
result
=
_mgmtSrvr
.
stopSignalTracing
(
processId
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
}
...
...
@@ -1126,7 +1133,7 @@ void CommandInterpreter::executeEventReporting(int processId,
ndbout_c("processId %d", processId);
int result = _mgmtSrvr.setEventReportingLevel(processId, logLevel);
if (result != 0) {
ndbout <<
_mgmtSrvr.getErrorT
ext(result) << endl;
ndbout <<
get_error_t
ext(result) << endl;
}
#endif
}
...
...
@@ -1136,7 +1143,7 @@ CommandInterpreter::executeStartBackup(char* parameters) {
Uint32
backupId
;
int
result
=
_mgmtSrvr
.
startBackup
(
backupId
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
else
{
// ndbout << "Start of backup ordered" << endl;
}
...
...
@@ -1153,7 +1160,7 @@ CommandInterpreter::executeAbortBackup(char* parameters) {
}
int
result
=
_mgmtSrvr
.
abortBackup
(
bid
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
else
{
ndbout
<<
"Abort of backup "
<<
bid
<<
" ordered"
<<
endl
;
}
...
...
@@ -1174,7 +1181,7 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) {
}
int
result
=
_mgmtSrvr
.
enterSingleUser
(
0
,
nodeId
,
0
,
0
);
if
(
result
!=
0
)
{
ndbout
<<
_mgmtSrvr
.
getErrorT
ext
(
result
)
<<
endl
;
ndbout
<<
get_error_t
ext
(
result
)
<<
endl
;
}
else
{
ndbout
<<
"Entering single user mode, granting access for node "
<<
nodeId
<<
" OK."
<<
endl
;
...
...
ndb/src/mgmsrv/CommandInterpreter.hpp
View file @
905db498
...
...
@@ -55,6 +55,9 @@ public:
int
readAndExecute
();
private:
char
m_err_str
[
1024
];
const
char
*
get_error_text
(
int
err_no
);
/**
* Read a string, and return a pointer to it.
*
...
...
ndb/src/mgmsrv/MgmtSrvr.cpp
View file @
905db498
...
...
@@ -49,6 +49,8 @@
#include <NdbAutoPtr.hpp>
#include <ndberror.h>
#include <mgmapi.h>
#include <mgmapi_configuration.hpp>
#include <mgmapi_config_parameters.h>
...
...
@@ -264,16 +266,6 @@ MgmtSrvr::isEventLogFilterEnabled(int severity)
static
ErrorItem
errorTable
[]
=
{
{
200
,
"Backup undefined error"
},
{
202
,
"Backup failed to allocate buffers (check configuration)"
},
{
203
,
"Backup failed to setup fs buffers (check configuration)"
},
{
204
,
"Backup failed to allocate tables (check configuration)"
},
{
205
,
"Backup failed to insert file header (check configuration)"
},
{
206
,
"Backup failed to insert table list (check configuration)"
},
{
207
,
"Backup failed to allocate table memory (check configuration)"
},
{
208
,
"Backup failed to allocate file record (check configuration)"
},
{
209
,
"Backup failed to allocate attribute record (check configuration)"
},
{
MgmtSrvr
::
NO_CONTACT_WITH_PROCESS
,
"No contact with the process (dead ?)."
},
{
MgmtSrvr
::
PROCESS_NOT_CONFIGURED
,
"The process is not configured."
},
{
MgmtSrvr
::
WRONG_PROCESS_TYPE
,
...
...
@@ -1856,18 +1848,21 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
//****************************************************************************
//****************************************************************************
const
char
*
MgmtSrvr
::
getErrorText
(
int
errorCode
)
const
char
*
MgmtSrvr
::
getErrorText
(
int
errorCode
,
char
*
buf
,
int
buf_sz
)
{
static
char
text
[
255
];
for
(
int
i
=
0
;
i
<
noOfErrorCodes
;
++
i
)
{
if
(
errorCode
==
errorTable
[
i
].
_errorCode
)
{
return
errorTable
[
i
].
_errorText
;
BaseString
::
snprintf
(
buf
,
buf_sz
,
errorTable
[
i
].
_errorText
);
buf
[
buf_sz
-
1
]
=
0
;
return
buf
;
}
}
BaseString
::
snprintf
(
text
,
255
,
"Unknown management server error code %d"
,
errorCode
);
return
text
;
ndb_error_string
(
errorCode
,
buf
,
buf_sz
);
buf
[
buf_sz
-
1
]
=
0
;
return
buf
;
}
void
...
...
ndb/src/mgmsrv/MgmtSrvr.hpp
View file @
905db498
...
...
@@ -466,7 +466,7 @@ public:
* @param errorCode: Error code to get a match error text for.
* @return The error text.
*/
const
char
*
getErrorText
(
int
errorCode
);
const
char
*
getErrorText
(
int
errorCode
,
char
*
buf
,
int
buf_sz
);
/**
* Get configuration
...
...
ndb/src/mgmsrv/Services.cpp
View file @
905db498
...
...
@@ -579,7 +579,7 @@ MgmApiSession::insertError(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"insert error reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -597,7 +597,7 @@ MgmApiSession::setTrace(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"set trace reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -665,7 +665,7 @@ MgmApiSession::startBackup(Parser<MgmApiSession>::Context &,
m_output->println("start backup reply");
if(result != 0)
m_output->println("result: %s(%d)",
m_mgmsrv.getErrorT
ext(result), result);
m_output->println("result: %s(%d)",
get_error_t
ext(result), result);
else{
m_output->println("result: Ok");
m_output->println("id: %d", backupId);
...
...
@@ -685,7 +685,7 @@ MgmApiSession::startBackup(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"start backup reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
{
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
"id: %d"
,
backupId
);
...
...
@@ -705,7 +705,7 @@ MgmApiSession::abortBackup(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"abort backup reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -727,7 +727,7 @@ MgmApiSession::repCommand(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"global replication reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
{
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
"id: %d"
,
repReqId
);
...
...
@@ -749,7 +749,7 @@ MgmApiSession::dumpState(Parser<MgmApiSession>::Context &,
int
result
=
m_mgmsrv
.
dumpState
(
node
,
args_str
.
c_str
());
m_output
->
println
(
"dump state reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -834,7 +834,7 @@ MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"stop signallog"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -874,7 +874,7 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"restart reply"
);
if
(
result
!=
0
){
m_output
->
println
(
"result: %d-%s"
,
result
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %d-%s"
,
result
,
get_error_t
ext
(
result
));
}
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
"restarted: %d"
,
restarted
);
...
...
@@ -898,7 +898,7 @@ MgmApiSession::restartAll(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"restart reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
"restarted: %d"
,
count
);
...
...
@@ -1029,7 +1029,7 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"stop reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
"stopped: %d"
,
stopped
);
...
...
@@ -1051,7 +1051,7 @@ MgmApiSession::stopAll(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"stop reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
"stopped: %d"
,
stopped
);
...
...
@@ -1067,7 +1067,7 @@ MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &,
int
result
=
m_mgmsrv
.
enterSingleUser
(
&
stopped
,
nodeId
);
m_output
->
println
(
"enter single user reply"
);
if
(
result
!=
0
)
{
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
}
else
{
m_output
->
println
(
"result: Ok"
);
...
...
@@ -1082,7 +1082,7 @@ MgmApiSession::exitSingleUser(Parser<MgmApiSession>::Context &,
int
result
=
m_mgmsrv
.
exitSingleUser
(
&
stopped
,
false
);
m_output
->
println
(
"exit single user reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -1100,7 +1100,7 @@ MgmApiSession::startSignalLog(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"start signallog reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -1145,7 +1145,7 @@ MgmApiSession::logSignals(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"log signals reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
@@ -1162,7 +1162,7 @@ MgmApiSession::start(Parser<MgmApiSession>::Context &,
m_output
->
println
(
"start reply"
);
if
(
result
!=
0
)
m_output
->
println
(
"result: %s"
,
m_mgmsrv
.
getErrorT
ext
(
result
));
m_output
->
println
(
"result: %s"
,
get_error_t
ext
(
result
));
else
m_output
->
println
(
"result: Ok"
);
m_output
->
println
(
""
);
...
...
ndb/src/mgmsrv/Services.hpp
View file @
905db498
...
...
@@ -39,10 +39,13 @@ private:
OutputStream
*
m_output
;
Parser_t
*
m_parser
;
MgmtSrvr
::
Allocated_resources
*
m_allocated_resources
;
char
m_err_str
[
1024
];
void
getConfig_common
(
Parser_t
::
Context
&
ctx
,
const
class
Properties
&
args
,
bool
compat
=
false
);
const
char
*
get_error_text
(
int
err_no
)
{
return
m_mgmsrv
.
getErrorText
(
err_no
,
m_err_str
,
sizeof
(
m_err_str
));
}
public:
MgmApiSession
(
class
MgmtSrvr
&
mgm
,
NDB_SOCKET_TYPE
sock
);
...
...
ndb/src/ndbapi/ndberror.c
View file @
905db498
...
...
@@ -35,6 +35,7 @@ typedef struct ErrorBundle {
#define NE ndberror_cl_none
#define AE ndberror_cl_application
#define CE ndberror_cl_configuration
#define ND ndberror_cl_no_data_found
#define CV ndberror_cl_constraint_violation
#define SE ndberror_cl_schema_error
...
...
@@ -58,6 +59,27 @@ static const char REDO_BUFFER_MSG[]=
static
const
char
*
empty_string
=
""
;
/*
* Error code ranges are reserved for respective block
*
* 200 - TC
* 300 - DIH
* 400 - LQH
* 600 - ACC
* 700 - DICT
* 800 - TUP
* 1200 - LQH
* 1300 - BACKUP
* 4000 - API
* 4100 - ""
* 4200 - ""
* 4300 - ""
* 4400 - ""
* 4500 - ""
* 4600 - ""
* 5000 - Management server
*/
static
const
ErrorBundle
ErrorCodes
[]
=
{
...
...
@@ -303,6 +325,36 @@ ErrorBundle ErrorCodes[] = {
*/
{
4003
,
NI
,
"Function not implemented yet"
},
/**
* Backup error codes
*/
{
1300
,
IE
,
"Undefined error"
},
{
1301
,
IE
,
"Backup issued to not master (reissue command to master)"
},
{
1302
,
IE
,
"Out of backup record"
},
{
1303
,
IS
,
"Out of resources"
},
{
1304
,
IE
,
"Sequence failure"
},
{
1305
,
IE
,
"Backup definition not implemented"
},
{
1306
,
AE
,
"Backup not supported in diskless mode (change Diskless)"
},
{
1321
,
IE
,
"Backup aborted by application"
},
{
1322
,
IE
,
"Backup already completed"
},
{
1323
,
IE
,
"1323"
},
{
1324
,
IE
,
"Backup log buffer full"
},
{
1325
,
IE
,
"File or scan error"
},
{
1326
,
IE
,
"Backup abortet due to node failure"
},
{
1327
,
IE
,
"1327"
},
{
1340
,
IE
,
"Backup undefined error"
},
{
1342
,
AE
,
"Backup failed to allocate buffers (check configuration)"
},
{
1343
,
AE
,
"Backup failed to setup fs buffers (check configuration)"
},
{
1344
,
AE
,
"Backup failed to allocate tables (check configuration)"
},
{
1345
,
AE
,
"Backup failed to insert file header (check configuration)"
},
{
1346
,
AE
,
"Backup failed to insert table list (check configuration)"
},
{
1347
,
AE
,
"Backup failed to allocate table memory (check configuration)"
},
{
1348
,
AE
,
"Backup failed to allocate file record (check configuration)"
},
{
1349
,
AE
,
"Backup failed to allocate attribute record (check configuration)"
},
/**
* Still uncategorized
*/
...
...
@@ -467,6 +519,7 @@ const
ErrorStatusClassification
StatusClassificationMapping
[]
=
{
{
ST_S
,
NE
,
"No error"
},
{
ST_P
,
AE
,
"Application error"
},
{
ST_P
,
CE
,
"Configuration or application error"
},
{
ST_P
,
ND
,
"No data found"
},
{
ST_P
,
CV
,
"Constraint violation"
},
{
ST_P
,
SE
,
"Schema error"
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment