Commit a245f597 authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.1

into serg.mylan:/usr/home/serg/Abk/m51

parents 6f160532 9479462b
...@@ -880,7 +880,7 @@ int sendData(SSL& ssl, const void* buffer, int sz) ...@@ -880,7 +880,7 @@ int sendData(SSL& ssl, const void* buffer, int sz)
ssl.SetError(no_error); ssl.SetError(no_error);
ssl.verfiyHandShakeComplete(); ssl.verfiyHandShakeComplete();
if (ssl.GetError()) return 0; if (ssl.GetError()) return -1;
int sent = 0; int sent = 0;
for (;;) { for (;;) {
...@@ -891,7 +891,7 @@ int sendData(SSL& ssl, const void* buffer, int sz) ...@@ -891,7 +891,7 @@ int sendData(SSL& ssl, const void* buffer, int sz)
buildMessage(ssl, out, data); buildMessage(ssl, out, data);
ssl.Send(out.get_buffer(), out.get_size()); ssl.Send(out.get_buffer(), out.get_size());
if (ssl.GetError()) return 0; if (ssl.GetError()) return -1;
sent += len; sent += len;
if (sent == sz) break; if (sent == sz) break;
} }
...@@ -918,14 +918,14 @@ int receiveData(SSL& ssl, Data& data) ...@@ -918,14 +918,14 @@ int receiveData(SSL& ssl, Data& data)
ssl.SetError(no_error); ssl.SetError(no_error);
ssl.verfiyHandShakeComplete(); ssl.verfiyHandShakeComplete();
if (ssl.GetError()) return 0; if (ssl.GetError()) return -1;
if (!ssl.bufferedData()) if (!ssl.bufferedData())
processReply(ssl); processReply(ssl);
ssl.fillData(data); ssl.fillData(data);
ssl.useLog().ShowData(data.get_length()); ssl.useLog().ShowData(data.get_length());
if (ssl.GetError()) return 0; if (ssl.GetError()) return -1;
if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) { if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) {
ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
......
...@@ -113,13 +113,22 @@ uint Socket::get_ready() const ...@@ -113,13 +113,22 @@ uint Socket::get_ready() const
uint Socket::send(const byte* buf, unsigned int sz, int flags) const uint Socket::send(const byte* buf, unsigned int sz, int flags) const
{ {
const byte* pos = buf;
const byte* end = pos + sz;
assert(socket_ != INVALID_SOCKET); assert(socket_ != INVALID_SOCKET);
int sent = ::send(socket_, reinterpret_cast<const char *>(buf), sz, flags);
while (pos != end) {
int sent = ::send(socket_, reinterpret_cast<const char *>(pos),
static_cast<int>(end - pos), flags);
if (sent == -1) if (sent == -1)
return 0; return 0;
return sent; pos += sent;
}
return sz;
} }
......
...@@ -1842,5 +1842,29 @@ a b ...@@ -1842,5 +1842,29 @@ a b
select * from t1 where b like 'abc' or b like 'abc'; select * from t1 where b like 'abc' or b like 'abc';
a b a b
3 abc 3 abc
drop table t1;
create table t1 ( fname varchar(255), lname varchar(255) )
engine=ndbcluster;
insert into t1 values ("Young","Foo");
set engine_condition_pushdown = 0;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
fname lname
Young Foo
set engine_condition_pushdown = 1;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
fname lname
Young Foo
insert into t1 values ("aaa", "aaa");
insert into t1 values ("bbb", "bbb");
insert into t1 values ("ccc", "ccc");
insert into t1 values ("ddd", "ddd");
set engine_condition_pushdown = 0;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
fname lname
Young Foo
set engine_condition_pushdown = 1;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
fname lname
Young Foo
set engine_condition_pushdown = @old_ecpd; set engine_condition_pushdown = @old_ecpd;
DROP TABLE t1,t2,t3,t4,t5; DROP TABLE t1,t2,t3,t4,t5;
...@@ -1397,3 +1397,14 @@ c1 ...@@ -1397,3 +1397,14 @@ c1
9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999
drop table t1; drop table t1;
create table t1 (i int, j int);
insert into t1 values (1,1), (1,2), (2,3), (2,4);
select i, count(distinct j) from t1 group by i;
i count(distinct j)
1 2
2 2
select i+0.0 as i2, count(distinct j) from t1 group by i2;
i2 count(distinct j)
1.0 2
2.0 2
drop table t1;
...@@ -620,3 +620,32 @@ ERROR HY000: There is no 'no-such-user'@'localhost' registered ...@@ -620,3 +620,32 @@ ERROR HY000: There is no 'no-such-user'@'localhost' registered
DROP VIEW v; DROP VIEW v;
DROP TABLE t1; DROP TABLE t1;
USE test; USE test;
CREATE USER mysqltest_db1@localhost identified by 'PWD';
GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION;
CREATE SCHEMA mysqltest_db1 ;
USE mysqltest_db1 ;
CREATE TABLE t1 (f1 INTEGER);
CREATE VIEW view1 AS
SELECT * FROM t1;
SHOW CREATE VIEW view1;
View Create View
view1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1`
CREATE VIEW view2 AS
SELECT * FROM view1;
# Here comes a suspicious warning
SHOW CREATE VIEW view2;
View Create View
view2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1`
# But the view view2 is usable
SELECT * FROM view2;
f1
CREATE VIEW view3 AS
SELECT * FROM view2;
SELECT * from view3;
f1
DROP VIEW mysqltest_db1.view3;
DROP VIEW mysqltest_db1.view2;
DROP VIEW mysqltest_db1.view1;
DROP TABLE mysqltest_db1.t1;
DROP SCHEMA mysqltest_db1;
DROP USER mysqltest_db1@localhost;
...@@ -1686,5 +1686,27 @@ select * from t1 where b like 'ab' or b like 'ab'; ...@@ -1686,5 +1686,27 @@ select * from t1 where b like 'ab' or b like 'ab';
select * from t1 where b like 'abc'; select * from t1 where b like 'abc';
select * from t1 where b like 'abc' or b like 'abc'; select * from t1 where b like 'abc' or b like 'abc';
# bug#20406 (maybe same as bug#17421 -1, not seen on 32-bit x86)
drop table t1;
create table t1 ( fname varchar(255), lname varchar(255) )
engine=ndbcluster;
insert into t1 values ("Young","Foo");
set engine_condition_pushdown = 0;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
set engine_condition_pushdown = 1;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
# make sure optimizer does not do some crazy shortcut
insert into t1 values ("aaa", "aaa");
insert into t1 values ("bbb", "bbb");
insert into t1 values ("ccc", "ccc");
insert into t1 values ("ddd", "ddd");
set engine_condition_pushdown = 0;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
set engine_condition_pushdown = 1;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
set engine_condition_pushdown = @old_ecpd; set engine_condition_pushdown = @old_ecpd;
DROP TABLE t1,t2,t3,t4,t5; DROP TABLE t1,t2,t3,t4,t5;
...@@ -1095,3 +1095,12 @@ insert into t1 values( ...@@ -1095,3 +1095,12 @@ insert into t1 values(
insert into t1 values(1e100); insert into t1 values(1e100);
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Bug#19667 group by a decimal expression yields wrong result
#
create table t1 (i int, j int);
insert into t1 values (1,1), (1,2), (2,3), (2,4);
select i, count(distinct j) from t1 group by i;
select i+0.0 as i2, count(distinct j) from t1 group by i2;
drop table t1;
...@@ -813,3 +813,42 @@ SELECT * FROM v; ...@@ -813,3 +813,42 @@ SELECT * FROM v;
DROP VIEW v; DROP VIEW v;
DROP TABLE t1; DROP TABLE t1;
USE test; USE test;
#
# Bug#20363: Create view on just created view is now denied
#
eval CREATE USER mysqltest_db1@localhost identified by 'PWD';
eval GRANT ALL ON mysqltest_db1.* TO mysqltest_db1@localhost WITH GRANT OPTION;
# The session with the non root user is needed.
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
connect (session1,localhost,mysqltest_db1,PWD,test);
CREATE SCHEMA mysqltest_db1 ;
USE mysqltest_db1 ;
CREATE TABLE t1 (f1 INTEGER);
CREATE VIEW view1 AS
SELECT * FROM t1;
SHOW CREATE VIEW view1;
CREATE VIEW view2 AS
SELECT * FROM view1;
--echo # Here comes a suspicious warning
SHOW CREATE VIEW view2;
--echo # But the view view2 is usable
SELECT * FROM view2;
CREATE VIEW view3 AS
SELECT * FROM view2;
SELECT * from view3;
connection default;
DROP VIEW mysqltest_db1.view3;
DROP VIEW mysqltest_db1.view2;
DROP VIEW mysqltest_db1.view1;
DROP TABLE mysqltest_db1.t1;
DROP SCHEMA mysqltest_db1;
DROP USER mysqltest_db1@localhost;
...@@ -408,6 +408,19 @@ ...@@ -408,6 +408,19 @@
} }
# #
# BUG#19940: NDB sends uninitialized parts of field buffers across the wire.
# This is "works as designed"; the uninitialized part is not used at the
# other end (but Valgrind cannot see this).
#
{
bug19940
Memcheck:Param
socketcall.sendto(msg)
fun:send
fun:_ZN15TCP_Transporter6doSendEv
fun:_ZN19TransporterRegistry11performSendEv
fun:_ZN19TransporterRegistry14forceSendCheckEi
}
# Warning when printing stack trace (to suppress some not needed warnings) # Warning when printing stack trace (to suppress some not needed warnings)
# #
......
...@@ -132,7 +132,7 @@ bool Cached_item_decimal::cmp() ...@@ -132,7 +132,7 @@ bool Cached_item_decimal::cmp()
{ {
my_decimal tmp; my_decimal tmp;
my_decimal *ptmp= item->val_decimal(&tmp); my_decimal *ptmp= item->val_decimal(&tmp);
if (null_value != item->null_value || my_decimal_cmp(&value, ptmp) == 0) if (null_value != item->null_value || my_decimal_cmp(&value, ptmp))
{ {
null_value= item->null_value; null_value= item->null_value;
my_decimal2decimal(ptmp, &value); my_decimal2decimal(ptmp, &value);
......
...@@ -5201,7 +5201,14 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) ...@@ -5201,7 +5201,14 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
if (all_tables->security_ctx) if (all_tables->security_ctx)
thd->security_ctx= all_tables->security_ctx; thd->security_ctx= all_tables->security_ctx;
if (check_access(thd, privilege, all_tables->db, const char *db_name;
if ((all_tables->view || all_tables->field_translation) &&
!all_tables->schema_table)
db_name= all_tables->view_db.str;
else
db_name= all_tables->db;
if (check_access(thd, privilege, db_name,
&all_tables->grant.privilege, 0, 0, &all_tables->grant.privilege, 0, 0,
test(all_tables->schema_table))) test(all_tables->schema_table)))
goto deny; goto deny;
......
...@@ -5009,6 +5009,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5009,6 +5009,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
old_db_type= table->s->db_type; old_db_type= table->s->db_type;
if (!create_info->db_type) if (!create_info->db_type)
{ {
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->part_info && if (table->part_info &&
create_info->used_fields & HA_CREATE_USED_ENGINE) create_info->used_fields & HA_CREATE_USED_ENGINE)
{ {
...@@ -5022,6 +5023,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5022,6 +5023,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
create_info->db_type= table->part_info->default_engine_type; create_info->db_type= table->part_info->default_engine_type;
} }
else else
#endif
create_info->db_type= old_db_type; create_info->db_type= old_db_type;
} }
......
...@@ -699,6 +699,28 @@ extern "C" { ...@@ -699,6 +699,28 @@ extern "C" {
int ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, int ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes,
const int * node_list, int abort); const int * node_list, int abort);
/**
* Stops cluster nodes
*
* @param handle Management handle.
* @param no_of_nodes Number of database nodes to stop<br>
* -1: All database and management nodes<br>
* 0: All database nodes in cluster<br>
* n: Stop the <var>n</var> node(s) specified in
* the array node_list
* @param node_list List of node IDs of database nodes to be stopped
* @param abort Don't perform graceful stop,
* but rather stop immediately
* @param disconnect Returns true if you need to disconnect to apply
* the stop command (e.g. stopping the mgm server
* that handle is connected to)
*
* @return Number of nodes stopped (-1 on error).
*/
int ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes,
const int * node_list, int abort, int *disconnect);
/** /**
* Restart database nodes * Restart database nodes
* *
...@@ -738,6 +760,31 @@ extern "C" { ...@@ -738,6 +760,31 @@ extern "C" {
const int * node_list, int initial, const int * node_list, int initial,
int nostart, int abort); int nostart, int abort);
/**
* Restart nodes
*
* @param handle Management handle.
* @param no_of_nodes Number of database nodes to be restarted:<br>
* 0: Restart all database nodes in the cluster<br>
* n: Restart the <var>n</var> node(s) specified in the
* array node_list
* @param node_list List of node IDs of database nodes to be restarted
* @param initial Remove filesystem from restarting node(s)
* @param nostart Don't actually start node(s) but leave them
* waiting for start command
* @param abort Don't perform graceful restart,
* but rather restart immediately
* @param disconnect Returns true if mgmapi client must disconnect from
* server to apply the requested operation. (e.g.
* restart the management server)
*
*
* @return Number of nodes stopped (-1 on error).
*/
int ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes,
const int * node_list, int initial,
int nostart, int abort, int *disconnect);
/** /**
* Start database nodes * Start database nodes
* *
...@@ -1018,6 +1065,16 @@ extern "C" { ...@@ -1018,6 +1065,16 @@ extern "C" {
*/ */
Uint32 ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle); Uint32 ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle);
/**
* Get the version of the mgm server we're talking to.
* Designed to allow switching of protocol depending on version
* so that new clients can speak to old servers in a compat mode
*/
int ndb_mgm_get_version(NdbMgmHandle handle,
int *major, int *minor, int* build,
int len, char* str);
/** /**
* Config iterator * Config iterator
*/ */
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <mgmapi_debug.h> #include <mgmapi_debug.h>
#include "mgmapi_configuration.hpp" #include "mgmapi_configuration.hpp"
#include <socket_io.h> #include <socket_io.h>
#include <version.h>
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <SocketServer.hpp> #include <SocketServer.hpp>
...@@ -103,6 +104,9 @@ struct ndb_mgm_handle { ...@@ -103,6 +104,9 @@ struct ndb_mgm_handle {
#endif #endif
FILE *errstream; FILE *errstream;
char *m_name; char *m_name;
int mgmd_version_major;
int mgmd_version_minor;
int mgmd_version_build;
}; };
#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s) #define SET_ERROR(h, e, s) setError(h, e, __LINE__, s)
...@@ -174,6 +178,10 @@ ndb_mgm_create_handle() ...@@ -174,6 +178,10 @@ ndb_mgm_create_handle()
h->logfile = 0; h->logfile = 0;
#endif #endif
h->mgmd_version_major= -1;
h->mgmd_version_minor= -1;
h->mgmd_version_build= -1;
DBUG_PRINT("info", ("handle=0x%x", (UintPtr)h)); DBUG_PRINT("info", ("handle=0x%x", (UintPtr)h));
DBUG_RETURN(h); DBUG_RETURN(h);
} }
...@@ -367,8 +375,9 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, ...@@ -367,8 +375,9 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
* Print some info about why the parser returns NULL * Print some info about why the parser returns NULL
*/ */
fprintf(handle->errstream, fprintf(handle->errstream,
"Error in mgm protocol parser. cmd: >%s< status: %d curr: %d\n", "Error in mgm protocol parser. cmd: >%s< status: %d curr: %s\n",
cmd, (Uint32)ctx.m_status, ctx.m_currentToken); cmd, (Uint32)ctx.m_status,
(ctx.m_currentToken)?ctx.m_currentToken:"NULL");
DBUG_PRINT("info",("ctx.status: %d, ctx.m_currentToken: %s", DBUG_PRINT("info",("ctx.status: %d, ctx.m_currentToken: %s",
ctx.m_status, ctx.m_currentToken)); ctx.m_status, ctx.m_currentToken));
} }
...@@ -684,7 +693,11 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -684,7 +693,11 @@ ndb_mgm_get_status(NdbMgmHandle handle)
out.println(""); out.println("");
char buf[1024]; char buf[1024];
in.gets(buf, sizeof(buf)); if(!in.gets(buf, sizeof(buf)))
{
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
return NULL;
}
if(buf[strlen(buf)-1] == '\n') if(buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0'; buf[strlen(buf)-1] = '\0';
...@@ -693,7 +706,11 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -693,7 +706,11 @@ ndb_mgm_get_status(NdbMgmHandle handle)
return NULL; return NULL;
} }
in.gets(buf, sizeof(buf)); if(!in.gets(buf, sizeof(buf)))
{
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
return NULL;
}
if(buf[strlen(buf)-1] == '\n') if(buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0'; buf[strlen(buf)-1] = '\0';
...@@ -716,6 +733,13 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -716,6 +733,13 @@ ndb_mgm_get_status(NdbMgmHandle handle)
malloc(sizeof(ndb_mgm_cluster_state)+ malloc(sizeof(ndb_mgm_cluster_state)+
noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#"))); noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
if(!state)
{
SET_ERROR(handle, NDB_MGM_OUT_OF_MEMORY,
"Allocating ndb_mgm_cluster_state");
return NULL;
}
state->no_of_nodes= noOfNodes; state->no_of_nodes= noOfNodes;
ndb_mgm_node_state * ptr = &state->node_states[0]; ndb_mgm_node_state * ptr = &state->node_states[0];
int nodeId = 0; int nodeId = 0;
...@@ -725,7 +749,13 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -725,7 +749,13 @@ ndb_mgm_get_status(NdbMgmHandle handle)
} }
i = -1; ptr--; i = -1; ptr--;
for(; i<noOfNodes; ){ for(; i<noOfNodes; ){
in.gets(buf, sizeof(buf)); if(!in.gets(buf, sizeof(buf)))
{
free(state);
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY,
"Probably disconnected");
return NULL;
}
tmp.assign(buf); tmp.assign(buf);
if(tmp.trim() == ""){ if(tmp.trim() == ""){
...@@ -835,37 +865,81 @@ ndb_mgm_stop(NdbMgmHandle handle, int no_of_nodes, const int * node_list) ...@@ -835,37 +865,81 @@ ndb_mgm_stop(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
return ndb_mgm_stop2(handle, no_of_nodes, node_list, 0); return ndb_mgm_stop2(handle, no_of_nodes, node_list, 0);
} }
extern "C" extern "C"
int int
ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int abort) int abort)
{ {
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop2"); int disconnect;
const ParserRow<ParserDummy> stop_reply[] = { return ndb_mgm_stop3(handle, no_of_nodes, node_list, abort, &disconnect);
}
extern "C"
int
ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int abort, int *disconnect)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop3");
const ParserRow<ParserDummy> stop_reply_v1[] = {
MGM_CMD("stop reply", NULL, ""),
MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
MGM_ARG("result", String, Mandatory, "Error message"),
MGM_END()
};
const ParserRow<ParserDummy> stop_reply_v2[] = {
MGM_CMD("stop reply", NULL, ""), MGM_CMD("stop reply", NULL, ""),
MGM_ARG("stopped", Int, Optional, "No of stopped nodes"), MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
MGM_ARG("result", String, Mandatory, "Error message"), MGM_ARG("result", String, Mandatory, "Error message"),
MGM_ARG("disconnect", Int, Mandatory, "Need to disconnect"),
MGM_END() MGM_END()
}; };
CHECK_HANDLE(handle, -1); CHECK_HANDLE(handle, -1);
CHECK_CONNECTED(handle, -1); CHECK_CONNECTED(handle, -1);
if(no_of_nodes < 0){ if(handle->mgmd_version_build==-1)
{
char verstr[50];
if(!ndb_mgm_get_version(handle,
&(handle->mgmd_version_major),
&(handle->mgmd_version_minor),
&(handle->mgmd_version_build),
sizeof(verstr),
verstr))
{
return -1;
}
}
int use_v2= ((handle->mgmd_version_major==5)
&& (
(handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
||(handle->mgmd_version_minor>1)
)
)
|| (handle->mgmd_version_major>5);
if(no_of_nodes < -1){
SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES, SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES,
"Negative number of nodes requested to stop"); "Negative number of nodes requested to stop");
return -1; return -1;
} }
Uint32 stoppedNoOfNodes = 0; Uint32 stoppedNoOfNodes = 0;
if(no_of_nodes == 0){ if(no_of_nodes <= 0){
/** /**
* All database nodes should be stopped * All nodes should be stopped (all or just db)
*/ */
Properties args; Properties args;
args.put("abort", abort); args.put("abort", abort);
if(use_v2)
args.put("stop", (no_of_nodes==-1)?"mgm,db":"db");
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, stop_reply, "stop all", &args); if(use_v2)
reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args);
else
reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(reply, -1);
if(!reply->get("stopped", &stoppedNoOfNodes)){ if(!reply->get("stopped", &stoppedNoOfNodes)){
...@@ -874,6 +948,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -874,6 +948,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
delete reply; delete reply;
return -1; return -1;
} }
if(use_v2)
reply->get("disconnect", (Uint32*)disconnect);
else
*disconnect= 0;
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
if(strcmp(result.c_str(), "Ok") != 0) { if(strcmp(result.c_str(), "Ok") != 0) {
...@@ -899,7 +977,11 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -899,7 +977,11 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
args.put("abort", abort); args.put("abort", abort);
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, stop_reply, "stop", &args); if(use_v2)
reply = ndb_mgm_call(handle, stop_reply_v2, "stop v2", &args);
else
reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args);
CHECK_REPLY(reply, stoppedNoOfNodes); CHECK_REPLY(reply, stoppedNoOfNodes);
if(!reply->get("stopped", &stoppedNoOfNodes)){ if(!reply->get("stopped", &stoppedNoOfNodes)){
SET_ERROR(handle, NDB_MGM_STOP_FAILED, SET_ERROR(handle, NDB_MGM_STOP_FAILED,
...@@ -907,6 +989,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -907,6 +989,10 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
delete reply; delete reply;
return -1; return -1;
} }
if(use_v2)
reply->get("disconnect", (Uint32*)disconnect);
else
*disconnect= 0;
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
if(strcmp(result.c_str(), "Ok") != 0) { if(strcmp(result.c_str(), "Ok") != 0) {
...@@ -918,22 +1004,71 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -918,22 +1004,71 @@ ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
return stoppedNoOfNodes; return stoppedNoOfNodes;
} }
extern "C"
int
ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart");
return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0);
}
extern "C" extern "C"
int int
ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int initial, int nostart, int abort) int initial, int nostart, int abort)
{ {
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart2"); int disconnect;
return ndb_mgm_restart3(handle, no_of_nodes, node_list, initial, nostart,
abort, &disconnect);
}
extern "C"
int
ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
int initial, int nostart, int abort, int *disconnect)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart3");
Uint32 restarted = 0; Uint32 restarted = 0;
const ParserRow<ParserDummy> restart_reply[] = { const ParserRow<ParserDummy> restart_reply_v1[] = {
MGM_CMD("restart reply", NULL, ""), MGM_CMD("restart reply", NULL, ""),
MGM_ARG("result", String, Mandatory, "Error message"), MGM_ARG("result", String, Mandatory, "Error message"),
MGM_ARG("restarted", Int, Optional, "No of restarted nodes"), MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
MGM_END() MGM_END()
}; };
const ParserRow<ParserDummy> restart_reply_v2[] = {
MGM_CMD("restart reply", NULL, ""),
MGM_ARG("result", String, Mandatory, "Error message"),
MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
MGM_ARG("disconnect", Int, Optional, "Disconnect to apply"),
MGM_END()
};
CHECK_HANDLE(handle, -1); CHECK_HANDLE(handle, -1);
CHECK_CONNECTED(handle, -1); CHECK_CONNECTED(handle, -1);
if(handle->mgmd_version_build==-1)
{
char verstr[50];
if(!ndb_mgm_get_version(handle,
&(handle->mgmd_version_major),
&(handle->mgmd_version_minor),
&(handle->mgmd_version_build),
sizeof(verstr),
verstr))
{
return -1;
}
}
int use_v2= ((handle->mgmd_version_major==5)
&& (
(handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
||(handle->mgmd_version_minor>1)
)
)
|| (handle->mgmd_version_major>5);
if(no_of_nodes < 0){ if(no_of_nodes < 0){
SET_ERROR(handle, NDB_MGM_RESTART_FAILED, SET_ERROR(handle, NDB_MGM_RESTART_FAILED,
"Restart requested of negative number of nodes"); "Restart requested of negative number of nodes");
...@@ -948,7 +1083,7 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -948,7 +1083,7 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
const Properties *reply; const Properties *reply;
const int timeout = handle->read_timeout; const int timeout = handle->read_timeout;
handle->read_timeout= 5*60*1000; // 5 minutes handle->read_timeout= 5*60*1000; // 5 minutes
reply = ndb_mgm_call(handle, restart_reply, "restart all", &args); reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args);
handle->read_timeout= timeout; handle->read_timeout= timeout;
CHECK_REPLY(reply, -1); CHECK_REPLY(reply, -1);
...@@ -984,7 +1119,10 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -984,7 +1119,10 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
const Properties *reply; const Properties *reply;
const int timeout = handle->read_timeout; const int timeout = handle->read_timeout;
handle->read_timeout= 5*60*1000; // 5 minutes handle->read_timeout= 5*60*1000; // 5 minutes
reply = ndb_mgm_call(handle, restart_reply, "restart node", &args); if(use_v2)
reply = ndb_mgm_call(handle, restart_reply_v2, "restart node v2", &args);
else
reply = ndb_mgm_call(handle, restart_reply_v1, "restart node", &args);
handle->read_timeout= timeout; handle->read_timeout= timeout;
if(reply != NULL) { if(reply != NULL) {
BaseString result; BaseString result;
...@@ -995,20 +1133,16 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -995,20 +1133,16 @@ ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
return -1; return -1;
} }
reply->get("restarted", &restarted); reply->get("restarted", &restarted);
if(use_v2)
reply->get("disconnect", (Uint32*)disconnect);
else
*disconnect= 0;
delete reply; delete reply;
} }
return restarted; return restarted;
} }
extern "C"
int
ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list)
{
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart");
return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0);
}
static const char *clusterlog_severity_names[]= static const char *clusterlog_severity_names[]=
{ "enabled", "debug", "info", "warning", "error", "critical", "alert" }; { "enabled", "debug", "info", "warning", "error", "critical", "alert" };
...@@ -2340,4 +2474,56 @@ int ndb_mgm_end_session(NdbMgmHandle handle) ...@@ -2340,4 +2474,56 @@ int ndb_mgm_end_session(NdbMgmHandle handle)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
extern "C"
int ndb_mgm_get_version(NdbMgmHandle handle,
int *major, int *minor, int *build, int len, char* str)
{
DBUG_ENTER("ndb_mgm_get_version");
CHECK_HANDLE(handle, 0);
CHECK_CONNECTED(handle, 0);
Properties args;
const ParserRow<ParserDummy> reply[]= {
MGM_CMD("version", NULL, ""),
MGM_ARG("id", Int, Mandatory, "ID"),
MGM_ARG("major", Int, Mandatory, "Major"),
MGM_ARG("minor", Int, Mandatory, "Minor"),
MGM_ARG("string", String, Mandatory, "String"),
MGM_END()
};
const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get version", &args);
CHECK_REPLY(prop, 0);
Uint32 id;
if(!prop->get("id",&id)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
*build= getBuild(id);
if(!prop->get("major",(Uint32*)major)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
if(!prop->get("minor",(Uint32*)minor)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
BaseString result;
if(!prop->get("string", result)){
fprintf(handle->errstream, "Unable to get value\n");
return 0;
}
strncpy(str, result.c_str(), len);
delete prop;
DBUG_RETURN(1);
}
template class Vector<const ParserRow<ParserDummy>*>; template class Vector<const ParserRow<ParserDummy>*>;
...@@ -155,6 +155,7 @@ private: ...@@ -155,6 +155,7 @@ private:
NdbMgmHandle m_mgmsrv; NdbMgmHandle m_mgmsrv;
NdbMgmHandle m_mgmsrv2; NdbMgmHandle m_mgmsrv2;
const char *m_constr;
bool m_connected; bool m_connected;
int m_verbose; int m_verbose;
int try_reconnect; int try_reconnect;
...@@ -335,22 +336,7 @@ convert(const char* s, int& val) { ...@@ -335,22 +336,7 @@ convert(const char* s, int& val) {
CommandInterpreter::CommandInterpreter(const char *_host,int verbose) CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
: m_verbose(verbose) : m_verbose(verbose)
{ {
m_mgmsrv = ndb_mgm_create_handle(); m_constr= _host;
if(m_mgmsrv == NULL) {
ndbout_c("Cannot create handle to management server.");
exit(-1);
}
m_mgmsrv2 = ndb_mgm_create_handle();
if(m_mgmsrv2 == NULL) {
ndbout_c("Cannot create 2:nd handle to management server.");
exit(-1);
}
if (ndb_mgm_set_connectstring(m_mgmsrv, _host))
{
printError();
exit(-1);
}
m_connected= false; m_connected= false;
m_event_thread= 0; m_event_thread= 0;
try_reconnect = 0; try_reconnect = 0;
...@@ -362,8 +348,6 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose) ...@@ -362,8 +348,6 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
CommandInterpreter::~CommandInterpreter() CommandInterpreter::~CommandInterpreter()
{ {
disconnect(); disconnect();
ndb_mgm_destroy_handle(&m_mgmsrv);
ndb_mgm_destroy_handle(&m_mgmsrv2);
} }
static bool static bool
...@@ -385,15 +369,14 @@ emptyString(const char* s) ...@@ -385,15 +369,14 @@ emptyString(const char* s)
void void
CommandInterpreter::printError() CommandInterpreter::printError()
{ {
if (ndb_mgm_check_connection(m_mgmsrv))
{
m_connected= false;
disconnect();
}
ndbout_c("* %5d: %s", ndbout_c("* %5d: %s",
ndb_mgm_get_latest_error(m_mgmsrv), ndb_mgm_get_latest_error(m_mgmsrv),
ndb_mgm_get_latest_error_msg(m_mgmsrv)); ndb_mgm_get_latest_error_msg(m_mgmsrv));
ndbout_c("* %s", ndb_mgm_get_latest_error_desc(m_mgmsrv)); ndbout_c("* %s", ndb_mgm_get_latest_error_desc(m_mgmsrv));
if (ndb_mgm_check_connection(m_mgmsrv))
{
disconnect();
}
} }
//***************************************************************************** //*****************************************************************************
...@@ -440,10 +423,30 @@ bool ...@@ -440,10 +423,30 @@ bool
CommandInterpreter::connect() CommandInterpreter::connect()
{ {
DBUG_ENTER("CommandInterpreter::connect"); DBUG_ENTER("CommandInterpreter::connect");
if(!m_connected)
{ if(m_connected)
if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1)) DBUG_RETURN(m_connected);
m_mgmsrv = ndb_mgm_create_handle();
if(m_mgmsrv == NULL) {
ndbout_c("Cannot create handle to management server.");
exit(-1);
}
m_mgmsrv2 = ndb_mgm_create_handle();
if(m_mgmsrv2 == NULL) {
ndbout_c("Cannot create 2:nd handle to management server.");
exit(-1);
}
if (ndb_mgm_set_connectstring(m_mgmsrv, m_constr))
{ {
printError();
exit(-1);
}
if(ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1))
DBUG_RETURN(m_connected); // couldn't connect, always false
const char *host= ndb_mgm_get_connected_host(m_mgmsrv); const char *host= ndb_mgm_get_connected_host(m_mgmsrv);
unsigned port= ndb_mgm_get_connected_port(m_mgmsrv); unsigned port= ndb_mgm_get_connected_port(m_mgmsrv);
BaseString constr; BaseString constr;
...@@ -507,8 +510,7 @@ CommandInterpreter::connect() ...@@ -507,8 +510,7 @@ CommandInterpreter::connect()
printf("Connected to Management Server at: %s:%d\n", printf("Connected to Management Server at: %s:%d\n",
host, port); host, port);
} }
}
}
DBUG_RETURN(m_connected); DBUG_RETURN(m_connected);
} }
...@@ -516,20 +518,18 @@ bool ...@@ -516,20 +518,18 @@ bool
CommandInterpreter::disconnect() CommandInterpreter::disconnect()
{ {
DBUG_ENTER("CommandInterpreter::disconnect"); DBUG_ENTER("CommandInterpreter::disconnect");
if (m_event_thread) { if (m_event_thread) {
void *res; void *res;
do_event_thread= 0; do_event_thread= 0;
NdbThread_WaitFor(m_event_thread, &res); NdbThread_WaitFor(m_event_thread, &res);
NdbThread_Destroy(&m_event_thread); NdbThread_Destroy(&m_event_thread);
m_event_thread= 0; m_event_thread= 0;
ndb_mgm_disconnect(m_mgmsrv2); ndb_mgm_destroy_handle(&m_mgmsrv2);
} }
if (m_connected) if (m_connected)
{ {
if (ndb_mgm_disconnect(m_mgmsrv) == -1) { ndb_mgm_destroy_handle(&m_mgmsrv);
ndbout_c("Could not disconnect from management server");
printError();
}
m_connected= false; m_connected= false;
} }
DBUG_RETURN(true); DBUG_RETURN(true);
...@@ -985,7 +985,8 @@ CommandInterpreter::executeShutdown(char* parameters) ...@@ -985,7 +985,8 @@ CommandInterpreter::executeShutdown(char* parameters)
NdbAutoPtr<char> ap1((char*)state); NdbAutoPtr<char> ap1((char*)state);
int result = 0; int result = 0;
result = ndb_mgm_stop(m_mgmsrv, 0, 0); int need_disconnect;
result = ndb_mgm_stop3(m_mgmsrv, -1, 0, 0, &need_disconnect);
if (result < 0) { if (result < 0) {
ndbout << "Shutdown of NDB Cluster node(s) failed." << endl; ndbout << "Shutdown of NDB Cluster node(s) failed." << endl;
printError(); printError();
...@@ -994,28 +995,11 @@ CommandInterpreter::executeShutdown(char* parameters) ...@@ -994,28 +995,11 @@ CommandInterpreter::executeShutdown(char* parameters)
ndbout << result << " NDB Cluster node(s) have shutdown." << endl; ndbout << result << " NDB Cluster node(s) have shutdown." << endl;
int mgm_id= 0; if(need_disconnect) {
mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv); ndbout << "Disconnecting to allow management server to shutdown."
if (mgm_id == 0)
{
ndbout << "Unable to locate management server, "
<< "shutdown manually with <id> STOP"
<< endl; << endl;
return 1;
}
result = ndb_mgm_stop(m_mgmsrv, 1, &mgm_id);
if (result <= 0) {
ndbout << "Shutdown of NDB Cluster management server failed." << endl;
printError();
if (result == 0)
return 1;
return result;
}
m_connected= false;
disconnect(); disconnect();
ndbout << "NDB Cluster management server shutdown." << endl; }
return 0; return 0;
} }
...@@ -1237,12 +1221,7 @@ CommandInterpreter::executeConnect(char* parameters) ...@@ -1237,12 +1221,7 @@ CommandInterpreter::executeConnect(char* parameters)
{ {
disconnect(); disconnect();
if (!emptyString(parameters)) { if (!emptyString(parameters)) {
if (ndb_mgm_set_connectstring(m_mgmsrv, m_constr= BaseString(parameters).trim().c_str();
BaseString(parameters).trim().c_str()))
{
printError();
return;
}
} }
connect(); connect();
} }
...@@ -1407,6 +1386,7 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list, ...@@ -1407,6 +1386,7 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
unsigned command_pos, unsigned command_pos,
int *node_ids, int no_of_nodes) int *node_ids, int no_of_nodes)
{ {
int need_disconnect;
int abort= 0; int abort= 0;
for (; command_pos < command_list.size(); command_pos++) for (; command_pos < command_list.size(); command_pos++)
{ {
...@@ -1421,7 +1401,8 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list, ...@@ -1421,7 +1401,8 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
return; return;
} }
int result= ndb_mgm_stop2(m_mgmsrv, no_of_nodes, node_ids, abort); int result= ndb_mgm_stop3(m_mgmsrv, no_of_nodes, node_ids, abort,
&need_disconnect);
if (result < 0) if (result < 0)
{ {
ndbout_c("Shutdown failed."); ndbout_c("Shutdown failed.");
...@@ -1439,6 +1420,13 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list, ...@@ -1439,6 +1420,13 @@ CommandInterpreter::executeStop(Vector<BaseString> &command_list,
ndbout_c(" has shutdown."); ndbout_c(" has shutdown.");
} }
} }
if(need_disconnect)
{
ndbout << "Disconnecting to allow Management Server to shutdown" << endl;
disconnect();
}
} }
void void
...@@ -1529,6 +1517,7 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, ...@@ -1529,6 +1517,7 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
int nostart= 0; int nostart= 0;
int initialstart= 0; int initialstart= 0;
int abort= 0; int abort= 0;
int need_disconnect= 0;
for (; command_pos < command_list.size(); command_pos++) for (; command_pos < command_list.size(); command_pos++)
{ {
...@@ -1553,8 +1542,8 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, ...@@ -1553,8 +1542,8 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
return; return;
} }
result= ndb_mgm_restart2(m_mgmsrv, no_of_nodes, node_ids, result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids,
initialstart, nostart, abort); initialstart, nostart, abort, &need_disconnect);
if (result <= 0) { if (result <= 0) {
ndbout_c("Restart failed."); ndbout_c("Restart failed.");
...@@ -1571,6 +1560,8 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, ...@@ -1571,6 +1560,8 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
ndbout << " " << node_ids[i]; ndbout << " " << node_ids[i];
ndbout_c(" is being restarted"); ndbout_c(" is being restarted");
} }
if(need_disconnect)
disconnect();
} }
} }
......
...@@ -60,9 +60,6 @@ ...@@ -60,9 +60,6 @@
#include <SignalSender.hpp> #include <SignalSender.hpp>
extern bool g_StopServer;
extern bool g_RestartServer;
//#define MGM_SRV_DEBUG //#define MGM_SRV_DEBUG
#ifdef MGM_SRV_DEBUG #ifdef MGM_SRV_DEBUG
#define DEBUG(x) do ndbout << x << endl; while(0) #define DEBUG(x) do ndbout << x << endl; while(0)
...@@ -937,6 +934,13 @@ int MgmtSrvr::sendStopMgmd(NodeId nodeId, ...@@ -937,6 +934,13 @@ int MgmtSrvr::sendStopMgmd(NodeId nodeId,
* client connection to that mgmd and stop it that way. * client connection to that mgmd and stop it that way.
* This allows us to stop mgm servers when there isn't any real * This allows us to stop mgm servers when there isn't any real
* distributed communication up. * distributed communication up.
*
* node_ids.size()==0 means to stop all DB nodes.
* MGM nodes will *NOT* be stopped.
*
* If we work out we should be stopping or restarting ourselves,
* we return <0 in stopSelf for restart, >0 for stop
* and 0 for do nothing.
*/ */
int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
...@@ -946,7 +950,8 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, ...@@ -946,7 +950,8 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
bool stop, bool stop,
bool restart, bool restart,
bool nostart, bool nostart,
bool initialStart) bool initialStart,
int* stopSelf)
{ {
int error = 0; int error = 0;
DBUG_ENTER("MgmtSrvr::sendSTOP_REQ"); DBUG_ENTER("MgmtSrvr::sendSTOP_REQ");
...@@ -995,12 +1000,13 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, ...@@ -995,12 +1000,13 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
NodeId nodeId= 0; NodeId nodeId= 0;
int use_master_node= 0; int use_master_node= 0;
int do_send= 0; int do_send= 0;
int do_stop_self= 0; *stopSelf= 0;
NdbNodeBitmask nodes_to_stop; NdbNodeBitmask nodes_to_stop;
{ {
for (unsigned i= 0; i < node_ids.size(); i++) for (unsigned i= 0; i < node_ids.size(); i++)
{ {
nodeId= node_ids[i]; nodeId= node_ids[i];
ndbout << "asked to stop " << nodeId << endl;
if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM) if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM)
nodes_to_stop.set(nodeId); nodes_to_stop.set(nodeId);
else if (nodeId != getOwnNodeId()) else if (nodeId != getOwnNodeId())
...@@ -1011,7 +1017,11 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, ...@@ -1011,7 +1017,11 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
stoppedNodes.set(nodeId); stoppedNodes.set(nodeId);
} }
else else
do_stop_self= 1;; {
ndbout << "which is me" << endl;
*stopSelf= (restart)? -1 : 1;
stoppedNodes.set(nodeId);
}
} }
} }
int no_of_nodes_to_stop= nodes_to_stop.count(); int no_of_nodes_to_stop= nodes_to_stop.count();
...@@ -1044,14 +1054,6 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, ...@@ -1044,14 +1054,6 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
nodes.set(nodeId); nodes.set(nodeId);
} }
} }
nodeId= 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM))
{
if(nodeId==getOwnNodeId())
continue;
if(sendStopMgmd(nodeId, abort, stop, restart, nostart, initialStart)==0)
stoppedNodes.set(nodeId);
}
} }
// now wait for the replies // now wait for the replies
...@@ -1143,11 +1145,9 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, ...@@ -1143,11 +1145,9 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
DBUG_RETURN(SEND_OR_RECEIVE_FAILED); DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
} }
} }
if (!error && do_stop_self) if (error && *stopSelf)
{ {
if (restart) *stopSelf= 0;
g_RestartServer= true;
g_StopServer= true;
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -1157,7 +1157,7 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, ...@@ -1157,7 +1157,7 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
*/ */
int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids, int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids,
int *stopCount, bool abort) int *stopCount, bool abort, int* stopSelf)
{ {
if (!abort) if (!abort)
{ {
...@@ -1179,20 +1179,46 @@ int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids, ...@@ -1179,20 +1179,46 @@ int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids,
false, false,
false, false,
false, false,
false); false,
stopSelf);
if (stopCount) if (stopCount)
*stopCount= nodes.count(); *stopCount= nodes.count();
return ret; return ret;
} }
int MgmtSrvr::shutdownMGM(int *stopCount, bool abort, int *stopSelf)
{
NodeId nodeId = 0;
int error;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM))
{
if(nodeId==getOwnNodeId())
continue;
error= sendStopMgmd(nodeId, abort, true, false,
false, false);
if (error == 0)
*stopCount++;
}
*stopSelf= 1;
*stopCount++;
return 0;
}
/* /*
* Perform system shutdown * Perform DB nodes shutdown.
* MGM servers are left in their current state
*/ */
int MgmtSrvr::stop(int * stopCount, bool abort) int MgmtSrvr::shutdownDB(int * stopCount, bool abort)
{ {
NodeBitmask nodes; NodeBitmask nodes;
Vector<NodeId> node_ids; Vector<NodeId> node_ids;
int tmp;
int ret = sendSTOP_REQ(node_ids, int ret = sendSTOP_REQ(node_ids,
nodes, nodes,
0, 0,
...@@ -1200,7 +1226,8 @@ int MgmtSrvr::stop(int * stopCount, bool abort) ...@@ -1200,7 +1226,8 @@ int MgmtSrvr::stop(int * stopCount, bool abort)
true, true,
false, false,
false, false,
false); false,
&tmp);
if (stopCount) if (stopCount)
*stopCount = nodes.count(); *stopCount = nodes.count();
return ret; return ret;
...@@ -1225,6 +1252,7 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) ...@@ -1225,6 +1252,7 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
} }
NodeBitmask nodes; NodeBitmask nodes;
Vector<NodeId> node_ids; Vector<NodeId> node_ids;
int stopSelf;
int ret = sendSTOP_REQ(node_ids, int ret = sendSTOP_REQ(node_ids,
nodes, nodes,
singleUserNodeId, singleUserNodeId,
...@@ -1232,7 +1260,8 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) ...@@ -1232,7 +1260,8 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
false, false,
false, false,
false, false,
false); false,
&stopSelf);
if (stopCount) if (stopCount)
*stopCount = nodes.count(); *stopCount = nodes.count();
return ret; return ret;
...@@ -1244,7 +1273,8 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) ...@@ -1244,7 +1273,8 @@ int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids, int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids,
int * stopCount, bool nostart, int * stopCount, bool nostart,
bool initialStart, bool abort) bool initialStart, bool abort,
int *stopSelf)
{ {
NodeBitmask nodes; NodeBitmask nodes;
int ret= sendSTOP_REQ(node_ids, int ret= sendSTOP_REQ(node_ids,
...@@ -1254,7 +1284,8 @@ int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids, ...@@ -1254,7 +1284,8 @@ int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids,
false, false,
true, true,
true, true,
initialStart); initialStart,
stopSelf);
if (ret) if (ret)
return ret; return ret;
...@@ -1297,14 +1328,16 @@ int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids, ...@@ -1297,14 +1328,16 @@ int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids,
} }
/* /*
* Perform system restart * Perform restart of all DB nodes
*/ */
int MgmtSrvr::restart(bool nostart, bool initialStart, int MgmtSrvr::restartDB(bool nostart, bool initialStart,
bool abort, int * stopCount ) bool abort, int * stopCount)
{ {
NodeBitmask nodes; NodeBitmask nodes;
Vector<NodeId> node_ids; Vector<NodeId> node_ids;
int tmp;
int ret = sendSTOP_REQ(node_ids, int ret = sendSTOP_REQ(node_ids,
nodes, nodes,
0, 0,
...@@ -1312,7 +1345,8 @@ int MgmtSrvr::restart(bool nostart, bool initialStart, ...@@ -1312,7 +1345,8 @@ int MgmtSrvr::restart(bool nostart, bool initialStart,
true, true,
true, true,
true, true,
initialStart); initialStart,
&tmp);
if (ret) if (ret)
return ret; return ret;
......
...@@ -255,12 +255,15 @@ public: ...@@ -255,12 +255,15 @@ public:
* @param processId: Id of the DB process to stop * @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus: * @return 0 if succeeded, otherwise: as stated above, plus:
*/ */
int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort); int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort,
int *stopSelf);
int shutdownMGM(int *stopCount, bool abort, int *stopSelf);
/** /**
* Stop the system * shutdown the DB nodes
*/ */
int stop(int * cnt = 0, bool abort = false); int shutdownDB(int * cnt = 0, bool abort = false);
/** /**
* print version info about a node * print version info about a node
...@@ -294,12 +297,12 @@ public: ...@@ -294,12 +297,12 @@ public:
*/ */
int restartNodes(const Vector<NodeId> &node_ids, int restartNodes(const Vector<NodeId> &node_ids,
int *stopCount, bool nostart, int *stopCount, bool nostart,
bool initialStart, bool abort); bool initialStart, bool abort, int *stopSelf);
/** /**
* Restart the system * Restart all DB nodes
*/ */
int restart(bool nostart, bool initialStart, int restartDB(bool nostart, bool initialStart,
bool abort = false, bool abort = false,
int * stopCount = 0); int * stopCount = 0);
...@@ -500,7 +503,8 @@ private: ...@@ -500,7 +503,8 @@ private:
bool stop, bool stop,
bool restart, bool restart,
bool nostart, bool nostart,
bool initialStart); bool initialStart,
int *stopSelf);
/** /**
* Check if it is possible to send a signal to a (DB) process * Check if it is possible to send a signal to a (DB) process
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <base64.h> #include <base64.h>
extern bool g_StopServer; extern bool g_StopServer;
extern bool g_RestartServer;
extern EventLogger g_eventLogger; extern EventLogger g_eventLogger;
static const unsigned int MAX_READ_TIMEOUT = 1000 ; static const unsigned int MAX_READ_TIMEOUT = 1000 ;
...@@ -144,7 +145,13 @@ ParserRow<MgmApiSession> commands[] = { ...@@ -144,7 +145,13 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""), MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""),
MGM_CMD("restart node", &MgmApiSession::restart, ""), MGM_CMD("restart node", &MgmApiSession::restart_v1, ""),
MGM_ARG("node", String, Mandatory, "Nodes to restart"),
MGM_ARG("initialstart", Int, Optional, "Initial start"),
MGM_ARG("nostart", Int, Optional, "No start"),
MGM_ARG("abort", Int, Optional, "Abort"),
MGM_CMD("restart node v2", &MgmApiSession::restart_v2, ""),
MGM_ARG("node", String, Mandatory, "Nodes to restart"), MGM_ARG("node", String, Mandatory, "Nodes to restart"),
MGM_ARG("initialstart", Int, Optional, "Initial start"), MGM_ARG("initialstart", Int, Optional, "Initial start"),
MGM_ARG("nostart", Int, Optional, "No start"), MGM_ARG("nostart", Int, Optional, "No start"),
...@@ -185,12 +192,17 @@ ParserRow<MgmApiSession> commands[] = { ...@@ -185,12 +192,17 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""), MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""),
MGM_ARG("id", Int, Mandatory, "Backup id"), MGM_ARG("id", Int, Mandatory, "Backup id"),
MGM_CMD("stop", &MgmApiSession::stop, ""), MGM_CMD("stop", &MgmApiSession::stop_v1, ""),
MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_CMD("stop v2", &MgmApiSession::stop_v2, ""),
MGM_ARG("node", String, Mandatory, "Node"), MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("abort", Int, Mandatory, "Node"), MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_CMD("stop all", &MgmApiSession::stopAll, ""), MGM_CMD("stop all", &MgmApiSession::stopAll, ""),
MGM_ARG("abort", Int, Mandatory, "Node"), MGM_ARG("abort", Int, Mandatory, "Node"),
MGM_ARG("stop", String, Optional, "MGM/DB or both"),
MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""), MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""),
MGM_ARG("nodeId", Int, Mandatory, "Node"), MGM_ARG("nodeId", Int, Mandatory, "Node"),
...@@ -276,6 +288,7 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock) ...@@ -276,6 +288,7 @@ MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock)
m_output = new SocketOutputStream(sock); m_output = new SocketOutputStream(sock);
m_parser = new Parser_t(commands, *m_input, true, true, true); m_parser = new Parser_t(commands, *m_input, true, true, true);
m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv); m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
m_stopSelf= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -295,6 +308,10 @@ MgmApiSession::~MgmApiSession() ...@@ -295,6 +308,10 @@ MgmApiSession::~MgmApiSession()
NDB_CLOSE_SOCKET(m_socket); NDB_CLOSE_SOCKET(m_socket);
m_socket= NDB_INVALID_SOCKET; m_socket= NDB_INVALID_SOCKET;
} }
if(m_stopSelf < 0)
g_RestartServer= true;
if(m_stopSelf)
g_StopServer= true;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -875,8 +892,19 @@ MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &, ...@@ -875,8 +892,19 @@ MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &,
} }
void void
MgmApiSession::restart(Parser<MgmApiSession>::Context &, MgmApiSession::restart_v1(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
restart(args,1);
}
void
MgmApiSession::restart_v2(Parser<MgmApiSession>::Context &,
Properties const &args) {
restart(args,2);
}
void
MgmApiSession::restart(Properties const &args, int version) {
Uint32 Uint32
nostart = 0, nostart = 0,
initialstart = 0, initialstart = 0,
...@@ -901,7 +929,8 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &, ...@@ -901,7 +929,8 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &,
&restarted, &restarted,
nostart != 0, nostart != 0,
initialstart != 0, initialstart != 0,
abort != 0); abort != 0,
&m_stopSelf);
m_output->println("restart reply"); m_output->println("restart reply");
if(result != 0){ if(result != 0){
...@@ -909,6 +938,8 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &, ...@@ -909,6 +938,8 @@ MgmApiSession::restart(Parser<MgmApiSession>::Context &,
} else } else
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("restarted: %d", restarted); m_output->println("restarted: %d", restarted);
if(version>1)
m_output->println("disconnect: %d", (m_stopSelf)?1:0);
m_output->println(""); m_output->println("");
} }
...@@ -925,7 +956,7 @@ MgmApiSession::restartAll(Parser<MgmApiSession>::Context &, ...@@ -925,7 +956,7 @@ MgmApiSession::restartAll(Parser<MgmApiSession>::Context &,
args.get("nostart", &nostart); args.get("nostart", &nostart);
int count = 0; int count = 0;
int result = m_mgmsrv.restart(nostart, initialstart, abort, &count); int result = m_mgmsrv.restartDB(nostart, initialstart, abort, &count);
m_output->println("restart reply"); m_output->println("restart reply");
if(result != 0) if(result != 0)
...@@ -1018,8 +1049,19 @@ MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &, ...@@ -1018,8 +1049,19 @@ MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &,
} }
void void
MgmApiSession::stop(Parser<MgmApiSession>::Context &, MgmApiSession::stop_v1(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
stop(args,1);
}
void
MgmApiSession::stop_v2(Parser<MgmApiSession>::Context &,
Properties const &args) {
stop(args,2);
}
void
MgmApiSession::stop(Properties const &args, int version) {
Uint32 abort; Uint32 abort;
char *nodes_str; char *nodes_str;
Vector<NodeId> nodes; Vector<NodeId> nodes;
...@@ -1044,7 +1086,7 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &, ...@@ -1044,7 +1086,7 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
int stopped= 0; int stopped= 0;
int result= 0; int result= 0;
if (nodes.size()) if (nodes.size())
result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0); result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0, &m_stopSelf);
m_output->println("stop reply"); m_output->println("stop reply");
if(result != 0) if(result != 0)
...@@ -1052,25 +1094,41 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &, ...@@ -1052,25 +1094,41 @@ MgmApiSession::stop(Parser<MgmApiSession>::Context &,
else else
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("stopped: %d", stopped); m_output->println("stopped: %d", stopped);
if(version>1)
m_output->println("disconnect: %d", (m_stopSelf)?1:0);
m_output->println(""); m_output->println("");
} }
void void
MgmApiSession::stopAll(Parser<MgmApiSession>::Context &, MgmApiSession::stopAll(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
int stopped = 0; int stopped[2] = {0,0};
Uint32 abort; Uint32 abort;
args.get("abort", &abort); args.get("abort", &abort);
int result = m_mgmsrv.stop(&stopped, abort != 0); BaseString stop;
const char* tostop= "db";
int ver=1;
if (args.get("stop", stop))
{
tostop= stop.c_str();
ver= 2;
}
int result= 0;
if(strstr(tostop,"db"))
result= m_mgmsrv.shutdownDB(&stopped[0], abort != 0);
if(!result && strstr(tostop,"mgm"))
result= m_mgmsrv.shutdownMGM(&stopped[1], abort!=0, &m_stopSelf);
m_output->println("stop reply"); m_output->println("stop reply");
if(result != 0) if(result != 0)
m_output->println("result: %s", get_error_text(result)); m_output->println("result: %s", get_error_text(result));
else else
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("stopped: %d", stopped); m_output->println("stopped: %d", stopped[0]+stopped[1]);
if(ver >1)
m_output->println("disconnect: %d", (m_stopSelf)?1:0);
m_output->println(""); m_output->println("");
} }
......
...@@ -41,6 +41,7 @@ private: ...@@ -41,6 +41,7 @@ private:
Parser_t *m_parser; Parser_t *m_parser;
MgmtSrvr::Allocated_resources *m_allocated_resources; MgmtSrvr::Allocated_resources *m_allocated_resources;
char m_err_str[1024]; char m_err_str[1024];
int m_stopSelf; // -1 is restart, 0 do nothing, 1 stop
void getConfig_common(Parser_t::Context &ctx, void getConfig_common(Parser_t::Context &ctx,
const class Properties &args, const class Properties &args,
...@@ -62,7 +63,9 @@ public: ...@@ -62,7 +63,9 @@ public:
void getVersion(Parser_t::Context &ctx, const class Properties &args); void getVersion(Parser_t::Context &ctx, const class Properties &args);
void getStatus(Parser_t::Context &ctx, const class Properties &args); void getStatus(Parser_t::Context &ctx, const class Properties &args);
void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args); void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args);
void restart(Parser_t::Context &ctx, const class Properties &args); void restart(const class Properties &args, int version);
void restart_v1(Parser_t::Context &ctx, const class Properties &args);
void restart_v2(Parser_t::Context &ctx, const class Properties &args);
void restartAll(Parser_t::Context &ctx, const class Properties &args); void restartAll(Parser_t::Context &ctx, const class Properties &args);
void insertError(Parser_t::Context &ctx, const class Properties &args); void insertError(Parser_t::Context &ctx, const class Properties &args);
void setTrace(Parser_t::Context &ctx, const class Properties &args); void setTrace(Parser_t::Context &ctx, const class Properties &args);
...@@ -74,7 +77,9 @@ public: ...@@ -74,7 +77,9 @@ public:
void abortBackup(Parser_t::Context &ctx, const class Properties &args); void abortBackup(Parser_t::Context &ctx, const class Properties &args);
void enterSingleUser(Parser_t::Context &ctx, const class Properties &args); void enterSingleUser(Parser_t::Context &ctx, const class Properties &args);
void exitSingleUser(Parser_t::Context &ctx, const class Properties &args); void exitSingleUser(Parser_t::Context &ctx, const class Properties &args);
void stop(Parser_t::Context &ctx, const class Properties &args); void stop_v1(Parser_t::Context &ctx, const class Properties &args);
void stop_v2(Parser_t::Context &ctx, const class Properties &args);
void stop(const class Properties &args, int version);
void stopAll(Parser_t::Context &ctx, const class Properties &args); void stopAll(Parser_t::Context &ctx, const class Properties &args);
void start(Parser_t::Context &ctx, const class Properties &args); void start(Parser_t::Context &ctx, const class Properties &args);
void startAll(Parser_t::Context &ctx, const class Properties &args); void startAll(Parser_t::Context &ctx, const class Properties &args);
......
@echo off @echo off
del cmakecache.txt if exist cmakecache.txt del cmakecache.txt
copy win\vs71cache.txt cmakecache.txt copy win\vs71cache.txt cmakecache.txt
cmake -G "Visual Studio 7 .NET 2003" cmake -G "Visual Studio 7 .NET 2003"
copy cmakecache.txt win\vs71cache.txt copy cmakecache.txt win\vs71cache.txt
......
@echo off @echo off
del cmakecache.txt if exist cmakecache.txt del cmakecache.txt
copy win\vs8cache.txt cmakecache.txt copy win\vs8cache.txt cmakecache.txt
cmake -G "Visual Studio 8 2005" cmake -G "Visual Studio 8 2005"
copy cmakecache.txt win\vs8cache.txt copy cmakecache.txt win\vs8cache.txt
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment