diff --git a/include/recovery.h b/include/recovery.h index d19acc32477ab7cfa61d801367896379a7176cfe..8228b4d104096dda93a9f649a9c8e5e0a0fc40c2 100644 --- a/include/recovery.h +++ b/include/recovery.h @@ -67,12 +67,15 @@ wait_lsn_clear(struct wait_lsn *wait_lsn) struct wal_writer; struct wal_watcher; +enum { REMOTE_SOURCE_MAXLEN = 32 }; + /** Master connection */ struct remote { struct sockaddr_in addr; struct fiber *reader; uint64_t cookie; ev_tstamp recovery_lag, recovery_last_update_tstamp; + char source[REMOTE_SOURCE_MAXLEN]; }; enum wal_mode { WAL_NONE = 0, WAL_WRITE, WAL_FSYNC, WAL_FSYNC_DELAY, WAL_MODE_MAX }; diff --git a/include/tarantool.h b/include/tarantool.h index a32850acf2e7ec8c319df578f1fe377079e217f7..e3cba7b0eac42e4769427e4638282baea2fa2823 100644 --- a/include/tarantool.h +++ b/include/tarantool.h @@ -45,6 +45,7 @@ extern char *cfg_filename_fullpath; extern bool booting; extern char *binary_filename; extern char *custom_proc_title; +extern char status[]; int reload_cfg(struct tbuf *out); void show_cfg(struct tbuf *out); int snapshot(void); @@ -52,10 +53,8 @@ const char *tarantool_version(void); double tarantool_uptime(void); void tarantool_free(void); -char **init_set_proc_title(int argc, char **argv); -void free_proc_title(int argc, char **argv); -void set_proc_title(const char *format, ...); -void title(const char *fmt, ...); +void __attribute__((format (printf, 2, 3))) +title(const char *role, const char *fmt, ...); #define DEFAULT_CFG_FILENAME "tarantool.cfg" #define DEFAULT_CFG SYSCONF_DIR "/" DEFAULT_CFG_FILENAME diff --git a/src/box/box.cc b/src/box/box.cc index 008635cc24ae62c5fcc6b1dcc3bf87dfa4cd59e7..fd0ad87c8e4e2c186f8ddc08d54dbc99f8c9204f 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -60,8 +60,6 @@ static void process_rw(struct port *port, box_process_func box_process = process_ro; box_process_func box_process_ro = process_ro; -static char status[64] = "unknown"; - static int stat_base; struct box_snap_row { @@ -192,19 +190,12 @@ box_enter_master_or_replica_mode(struct tarantool_cfg *conf) recovery_wait_lsn(recovery_state, recovery_state->lsn); recovery_follow_remote(recovery_state, conf->replication_source); - - snprintf(status, sizeof(status), "replica/%s%s", - conf->replication_source, custom_proc_title); - title("replica/%s%s", conf->replication_source, - custom_proc_title); } else { box_process = process_rw; memcached_start_expire(); - snprintf(status, sizeof(status), "primary%s", - custom_proc_title); - title("primary%s", custom_proc_title); + title("primary", NULL); say_info("I am primary"); } @@ -326,7 +317,7 @@ box_free(void) void box_init(bool init_storage) { - title("loading"); + title("loading", NULL); /* initialization spaces */ space_init(); @@ -355,13 +346,11 @@ box_init(bool init_storage) say_info("building secondary indexes"); build_secondary_indexes(); - title("orphan"); + title("orphan", NULL); if (cfg.local_hot_standby) { say_info("starting local hot standby"); recovery_follow_local(recovery_state, cfg.wal_dir_rescan_delay); - snprintf(status, sizeof(status), "hot_standby%s", - custom_proc_title); - title("hot_standby%s", custom_proc_title); + title("hot_standby", NULL); } } diff --git a/src/replica.cc b/src/replica.cc index b4acbb7744c372eab532d7efd5e29a35d3005e4b..d4ce43956f972f210dfaeb83a492bd645ba19bbd 100644 --- a/src/replica.cc +++ b/src/replica.cc @@ -36,6 +36,7 @@ #include "fiber.h" #include "pickle.h" #include "coio_buf.h" +#include "tarantool.h" static void remote_apply_row(struct recovery_state *r, const char *row, uint32_t rowlne); @@ -103,11 +104,15 @@ pull_from_remote(va_list ap) try { fiber_setcancellable(true); if (! evio_is_active(&coio)) { + title("replica", "%s/%s", r->remote->source, + "connecting"); if (iobuf == NULL) iobuf = iobuf_new(fiber_name(fiber)); remote_connect(&coio, &r->remote->addr, r->confirmed_lsn + 1, &err); warning_said = false; + title("replica", "%s/%s", r->remote->source, + "connected"); } err = "can't read row"; uint32_t rowlen; @@ -123,10 +128,12 @@ pull_from_remote(va_list ap) iobuf_gc(iobuf); fiber_gc(); } catch (const FiberCancelException& e) { + title("replica", "%s/%s", r->remote->source, "failed"); iobuf_delete(iobuf); evio_close(&coio); throw; } catch (const Exception& e) { + title("replica", "%s/%s", r->remote->source, "failed"); e.log(); if (! warning_said) { if (err != NULL) @@ -190,6 +197,7 @@ recovery_follow_remote(struct recovery_state *r, const char *addr) remote.addr.sin_port = htons(port); memcpy(&remote.cookie, &remote.addr, MIN(sizeof(remote.cookie), sizeof(remote.addr))); remote.reader = f; + snprintf(remote.source, sizeof(remote.source), "%s", addr); r->remote = &remote; fiber_call(f, r); } diff --git a/src/replication.cc b/src/replication.cc index 53d896adf434bc52b5d67e69ea69fb1088c1d88d..071eba7c109e898e2f296f88cd6e089a4bb79a2d 100644 --- a/src/replication.cc +++ b/src/replication.cc @@ -299,12 +299,10 @@ replication_send_socket(ev_io *watcher, int events __attribute__((unused))) static void spawner_init(int sock) { - char name[FIBER_NAME_MAXLEN]; struct sigaction sa; - snprintf(name, sizeof(name), "spawner%s", custom_proc_title); - fiber_set_name(fiber, name); - set_proc_title(name); + title("spawner", NULL); + fiber_set_name(fiber, status); /* init replicator process context */ spawner.sock = sock; @@ -609,7 +607,6 @@ replication_relay_send_row(void *param, const char *row, uint32_t rowlen) static void replication_relay_loop(int client_sock) { - char name[FIBER_NAME_MAXLEN]; struct sigaction sa; int64_t lsn; ssize_t r; @@ -621,9 +618,8 @@ replication_relay_loop(int client_sock) struct sockaddr_in peer; socklen_t addrlen = sizeof(peer); getpeername(client_sock, ((struct sockaddr*)&peer), &addrlen); - snprintf(name, sizeof(name), "relay/%s", sio_strfaddr(&peer)); - fiber_set_name(fiber, name); - set_proc_title("%s%s", name, custom_proc_title); + title("relay", "%s", sio_strfaddr(&peer)); + fiber_set_name(fiber, status); /* init signals */ memset(&sa, 0, sizeof(sa)); diff --git a/src/tarantool.cc b/src/tarantool.cc index f04e4eafcf94f47da8e3ea2e25a23bf2f58d81f0..24f0520ed687b394c216b4d52221c4314d9ff4a1 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -77,6 +77,7 @@ const char *cfg_filename = NULL; char *cfg_filename_fullpath = NULL; char *binary_filename; char *custom_proc_title; +char status[64] = "unknown"; char **main_argv; int main_argc; static void *main_opt = NULL; @@ -90,6 +91,13 @@ uint32_t snapshot_version = 0; extern const void *opt_def; +/* defined in third_party/proctitle.c */ +extern "C" { +char **init_set_proc_title(int argc, char **argv); +void free_proc_title(int argc, char **argv); +void set_proc_title(const char *format, ...); +} /* extern "C" */ + static int core_check_config(struct tarantool_cfg *conf) { @@ -102,14 +110,26 @@ core_check_config(struct tarantool_cfg *conf) } void -title(const char *fmt, ...) +title(const char *role, const char *fmt, ...) { + (void) role; + va_list ap; char buf[128], *bufptr = buf, *bufend = buf + sizeof(buf); - - va_start(ap, fmt); - bufptr += vsnprintf(bufptr, bufend - bufptr, fmt, ap); - va_end(ap); + char *statusptr = status, *statusend = status + sizeof(status); + statusptr += snprintf(statusptr, statusend - statusptr, "%s", role); + bufptr += snprintf(bufptr, bufend - bufptr, "%s%s", role, + custom_proc_title); + + if (fmt != NULL) { + const char *s = statusptr; + statusptr += snprintf(statusptr, statusend - statusptr, "/"); + va_start(ap, fmt); + statusptr += vsnprintf(statusptr, statusend - statusptr, + fmt, ap); + va_end(ap); + bufptr += snprintf(bufptr, bufend - bufptr, "%s", s); + } int ports[] = { cfg.primary_port, cfg.secondary_port, cfg.memcached_port, cfg.admin_port, @@ -341,8 +361,8 @@ snapshot(void) salloc_protect(); - fiber_set_name(fiber, "dumper"); - set_proc_title("dumper (%" PRIu32 ")", getppid()); + title("dumper", "%" PRIu32, getppid()); + fiber_set_name(fiber, status); /* * Safety: make sure we don't double-write diff --git a/test/replication/status.result b/test/replication/status.result new file mode 100644 index 0000000000000000000000000000000000000000..dbde422651c9a2cfcc7cf081472dd40b13ed257c --- /dev/null +++ b/test/replication/status.result @@ -0,0 +1,2 @@ +True +True diff --git a/test/replication/status.test b/test/replication/status.test new file mode 100644 index 0000000000000000000000000000000000000000..759078c4f06190281ffdda0b5c0f64217b48db82 --- /dev/null +++ b/test/replication/status.test @@ -0,0 +1,28 @@ +# encoding: tarantool +import os +import time +import re +from lib.tarantool_server import TarantoolServer + +# replica server +replica = TarantoolServer() +replica.deploy("replication/cfg/replica.cfg", + replica.find_exe(self.args.builddir), + os.path.join(self.args.vardir, "replica")) + +replica.get_param("lsn") + +status = replica.admin.execute_no_reconnect("lua box.info.status", True) +print(re.search(r'replica/.*/(connecting|connected)\n', status) != None) + +server.stop() +status = replica.admin.execute_no_reconnect("lua box.info.status", True) +print(re.search(r'replica/.*/(connecting|failed)\n', status) != None) + +# Cleanup. +replica.stop() +replica.cleanup(True) + +server.deploy(self.suite_ini["config"]) + +# vim: syntax=python