]> sourceware.org Git - systemtap.git/commitdiff
remote: Allow prefixing lines with the host index
authorJosh Stone <jistone@redhat.com>
Wed, 27 Apr 2011 22:23:05 +0000 (15:23 -0700)
committerJosh Stone <jistone@redhat.com>
Wed, 27 Apr 2011 22:23:05 +0000 (15:23 -0700)
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.

remote.cxx
remote.h
session.cxx
session.h

index 5395b15d35c3be2354855c9cd00577948bf89589..13a7b7681b17ba65c5cfcf75b8dce32207e617f5 100644 (file)
@@ -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 <<string.
+                              cout.write(buf, rc);
+                              continue;
+                            }
                         }
                     }
                   close();
@@ -805,8 +821,11 @@ remote::run(const vector<remote*>& 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;
     }
index bc294b834046b72a02436a6f4e5b6142c720d704..b71bad01c6f559e2b0132788ed9ddaf29412f00c 100644 (file)
--- 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) {}
 
index 2d8a3d08b163195ed4a00e1abf46d81d67be5a74..ca2e63ce8bb0f0a853bb6e5504f510dbe523df95 100644 (file)
@@ -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;
index e8bb75f4c656ecb90ff8d33a561f2ffe0fba4176..eb70fe0807c8b1295de78d23156e5fed52516d60 100644 (file)
--- a/session.h
+++ b/session.h
@@ -209,6 +209,7 @@ public:
 
   // Remote execution
   std::vector<std::string> remote_uris;
+  bool use_remote_prefix;
   typedef std::map<std::pair<std::string, std::string>, systemtap_session*> session_map_t;
   session_map_t subsessions;
   systemtap_session* clone(const std::string& arch, const std::string& release);
This page took 0.038452 seconds and 5 git commands to generate.