From: Josh Stone Date: Wed, 27 Apr 2011 22:23:05 +0000 (-0700) Subject: remote: Allow prefixing lines with the host index X-Git-Tag: release-1.5~84 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=756cfd496a2c1dcae30914b05c5cdf6a10ca4671;p=systemtap.git remote: Allow prefixing lines with the host index When --remote-prefix is given, each line from remote scripts will be prefixed with "N: ", where N is the index of that host among all the --remote options on the command line. * remote.h (class remote): Add an optional prefix string. * remote.cxx (remote::run): Set the prefix if desired. (stapsh::handle_poll): When using prefixes, read data line-wise. * session.cxx (systemtap_session): Add bool use_remote_prefix. (systemtap_session::parse_cmdline): Set it with --remote-prefix. --- diff --git a/remote.cxx b/remote.cxx index 5395b15d3..13a7b7681 100644 --- a/remote.cxx +++ b/remote.cxx @@ -135,13 +135,29 @@ class stapsh : public remote { { if (fds[i].revents & POLLIN) { - // XXX should we do line-buffering? char buf[4096]; - size_t rc = fread(buf, 1, sizeof(buf), OUT); - if (rc > 0) + if (!prefix.empty()) { - cout.write(buf, rc); - continue; + // If we have a line prefix, then read lines one at a + // time and copy out with the prefix. + errno = 0; + while (fgets(buf, sizeof(buf), OUT)) + cout << prefix << buf; + if (errno == EAGAIN) + continue; + } + else + { + // Otherwise read an entire block of data at once. + size_t rc = fread(buf, 1, sizeof(buf), OUT); + if (rc > 0) + { + // NB: The buf could contain binary data, + // including \0, so write as a block instead of + // the usual <& remotes) for (unsigned i = 0; i < remotes.size() && !pending_interrupts; ++i) { - remotes[i]->s->verbose = remotes[i]->s->perpass_verbose[4]; - rc = remotes[i]->prepare(); + remote *r = remotes[i]; + r->s->verbose = r->s->perpass_verbose[4]; + if (r->s->use_remote_prefix) + r->prefix = lex_cast(i) + ": "; + rc = r->prepare(); if (rc) return rc; } diff --git a/remote.h b/remote.h index bc294b834..b71bad01c 100644 --- a/remote.h +++ b/remote.h @@ -29,6 +29,7 @@ class remote { protected: systemtap_session* s; + std::string prefix; remote(systemtap_session& s): s(&s) {} diff --git a/session.cxx b/session.cxx index 2d8a3d08b..ca2e63ce8 100644 --- a/session.cxx +++ b/session.cxx @@ -133,6 +133,7 @@ systemtap_session::systemtap_session (): server_cache = NULL; use_server_on_error = false; try_server_status = try_server_unset; + use_remote_prefix = false; systemtap_v_check = false; /* adding in the XDG_DATA_DIRS variable path, @@ -288,6 +289,7 @@ systemtap_session::systemtap_session (const systemtap_session& other, server_cache = NULL; use_server_on_error = other.use_server_on_error; try_server_status = other.try_server_status; + use_remote_prefix = other.use_remote_prefix; systemtap_v_check = other.systemtap_v_check; include_path = other.include_path; @@ -491,7 +493,10 @@ systemtap_session::usage (int exitcode) #endif " --remote=HOSTNAME\n" " run pass 5 on the specified ssh host.\n" - " may be repeated for targeting multiple hosts.", compatible.c_str()) << endl + " may be repeated for targeting multiple hosts.\n" + " --remote-prefix\n" + " prefix each line of remote output with a host index." + , compatible.c_str()) << endl ; time_t now; @@ -537,6 +542,7 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) #define LONG_OPT_CHECK_VERSION 21 #define LONG_OPT_USE_SERVER_ON_ERROR 22 #define LONG_OPT_VERSION 23 +#define LONG_OPT_REMOTE_PREFIX 24 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page static struct option long_options[] = { { "kelf", 0, &long_opt, LONG_OPT_KELF }, @@ -566,6 +572,7 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) { "use-server-on-error", 2, &long_opt, LONG_OPT_USE_SERVER_ON_ERROR }, { "all-modules", 0, &long_opt, LONG_OPT_ALL_MODULES }, { "remote", 1, &long_opt, LONG_OPT_REMOTE }, + { "remote-prefix", 0, &long_opt, LONG_OPT_REMOTE_PREFIX }, { "check-version", 0, &long_opt, LONG_OPT_CHECK_VERSION }, { "version", 0, &long_opt, LONG_OPT_VERSION }, { NULL, 0, NULL, 0 } @@ -1015,6 +1022,15 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) remote_uris.push_back(optarg); break; + case LONG_OPT_REMOTE_PREFIX: + if (client_options) { + cerr << _F("ERROR: %s is invalid with %s", "--remote-prefix", "--client-options") << endl; + return 1; + } + + use_remote_prefix = true; + break; + case LONG_OPT_CHECK_VERSION: push_server_opt = true; systemtap_v_check = true; diff --git a/session.h b/session.h index e8bb75f4c..eb70fe080 100644 --- a/session.h +++ b/session.h @@ -209,6 +209,7 @@ public: // Remote execution std::vector remote_uris; + bool use_remote_prefix; typedef std::map, systemtap_session*> session_map_t; session_map_t subsessions; systemtap_session* clone(const std::string& arch, const std::string& release);