diff --git a/client/tarantool/tc.c b/client/tarantool/tc.c index eb5402618a2c31d5800ab4c53078f3ae1a730471..7942e24f05b31dbc1cc2e73ca85092dcc2d00bd8 100644 --- a/client/tarantool/tc.c +++ b/client/tarantool/tc.c @@ -38,6 +38,7 @@ #include <connector/c/include/tarantool/tnt.h> #include <connector/c/include/tarantool/tnt_net.h> #include <connector/c/include/tarantool/tnt_sql.h> +#include <connector/c/include/tarantool/tnt_iter.h> #include <connector/c/include/tarantool/tnt_xlog.h> #include "client/tarantool/tc_opt.h" @@ -79,6 +80,42 @@ void tc_error(char *fmt, ...) { tc_printf("error: %s\n", msg); exit(1); } +static int get_admin_port(void) +{ + char *e = NULL; + tc_query("call box.dostring('return box.cfg.admin_port')", &e); + struct tnt_iter i, it, ifl; + tnt_iter_reply(&i, tc.net); + struct tnt_reply *r = TNT_IREPLY_PTR(&i); + if (!tnt_next(&i)) { + tnt_iter_free(&i); + } + if (tnt_error(tc.net) != TNT_EOK) { + tc_error(tc_query_error("%s ERROR, %s", + tc_query_op(r), + tnt_strerror(tc.net))); + } else if (r->code != 0) { + tc_error(tc_query_error("%s ERROR, %s (%s)", + tc_query_op(r), ((r->error) ? r->error : ""), + tnt_strerror(tc.net))); + } + tnt_iter_list(&it, TNT_REPLY_LIST(r)); + if (!tnt_next(&it)) { + tnt_iter_free(&it); + tnt_iter_free(&i); + } + struct tnt_tuple *tu = TNT_ILIST_TUPLE(&it); + tnt_iter(&ifl, tu); + if (!tnt_next(&ifl)) { goto end; } + int port = *((uint32_t* )TNT_IFIELD_DATA(&ifl)); +end: + tnt_iter_free(&ifl); + tnt_iter_free(&it); + tnt_iter_free(&i); + if (e != NULL) + free(e); + return port; +} static void tc_connect(void) { @@ -98,6 +135,8 @@ static void tc_connect(void) /* connecting to server */ if (tnt_connect(tc.net) == -1) tc_error("%s", tnt_strerror(tc.net)); + if (tc.opt.port_admin == 0) + tc.opt.port_admin = get_admin_port(); } static int get_primary_port(void) @@ -125,6 +164,17 @@ static void tc_connect_admin(void) tc.opt.port = get_primary_port(); } +static void tc_connect_both(void) +{ + if (!tc.opt.port && tc.opt.port_admin) { + tc_connect_admin(); + tc_connect(); + } else { + tc_connect(); + tc_connect_admin(); + } +} + static void tc_validate(void) { tc.opt.xlog_printer = tc_print_getxlogcb(tc.opt.format); @@ -165,13 +215,11 @@ int main(int argc, char *argv[]) rc = tc_store_play(); break; case TC_OPT_CMD: - tc_connect_admin(); - tc_connect(); + tc_connect_both(); rc = tc_cli_cmdv(); break; case TC_OPT_INTERACTIVE: - tc_connect_admin(); - tc_connect(); + tc_connect_both(); rc = tc_cli(); break; } diff --git a/client/tarantool/tc_opt.c b/client/tarantool/tc_opt.c index c0096a275caf313d3acaa3e4fa7a65ade1dfec5a..87ce93755ad315c42c3b24893c19595e3d2c6d92 100644 --- a/client/tarantool/tc_opt.c +++ b/client/tarantool/tc_opt.c @@ -37,7 +37,6 @@ #define TC_DEFAULT_HOST "localhost" -#define TC_DEFAULT_PORT_ADMIN 33015 /* supported cli options */ static const void *tc_options_def = gopt_start( @@ -120,7 +119,7 @@ enum tc_opt_mode tc_opt_init(struct tc_opt *opt, int argc, char **argv) opt->port = atoi(arg); /* server admin port */ - opt->port_admin = TC_DEFAULT_PORT_ADMIN; + opt->port_admin = 0; if (gopt_arg(tc_options, 'a', &arg)) opt->port_admin = atoi(arg); diff --git a/client/tarantool/tc_query.c b/client/tarantool/tc_query.c index 98ce487e5188725605d8f7f1b26761157348eb65..16909a8b1740ceea706a7f6626df60687d717e41 100644 --- a/client/tarantool/tc_query.c +++ b/client/tarantool/tc_query.c @@ -60,7 +60,7 @@ char *tc_query_type(uint32_t type) { return "Unknown"; } -static char *tc_query_op(struct tnt_reply *r) { +char *tc_query_op(struct tnt_reply *r) { return tc_query_type(r->op); } @@ -73,7 +73,7 @@ int tc_query_printer(struct tnt_reply *r, void *ptr, char **e) { return 0; } -static char *tc_query_error(char *fmt, ...) { +char *tc_query_error(char *fmt, ...) { char msg[256]; va_list args; va_start(args, fmt); diff --git a/client/tarantool/tc_query.h b/client/tarantool/tc_query.h index a3708379e5ba24f375ba3b8eeed7e5b08968d28a..2189022f2c75e1231f69f04ddac7c887725f4610 100644 --- a/client/tarantool/tc_query.h +++ b/client/tarantool/tc_query.h @@ -41,4 +41,8 @@ int tc_query(char *q, char **e); int tc_query_admin_printer(char *r, char **e); int tc_query_admin(char *q, tc_query_admin_t cb, char **e); + +char *tc_query_error(char *fmt, ...); +char *tc_query_op(struct tnt_reply *r); + #endif /* TC_QUERY_H_INCLUDED */