]> sourceware.org Git - systemtap.git/commitdiff
Improved handling of uprobes.ko by compile-server and client.
authorDave Brolley <brolley@redhat.com>
Thu, 25 Nov 2010 16:11:36 +0000 (11:11 -0500)
committerDave Brolley <brolley@redhat.com>
Thu, 25 Nov 2010 16:11:36 +0000 (11:11 -0500)
- Server now returns uprobes.ko to client when required.
- New optional argument to staprun's -u option to specify the location
  of uprobes module.
- Client uses new argument of -u to specify uprobes.ko returned by
  the server.
- staprun still prefers already-loaded uprobes, built-in uprobes and
  kernel-built uprobes over the one returned by the server.
- staprun verifies the signature of the uprobes module for unprivileged
  users.

buildrun.cxx
csclient.cxx
runtime/staprun/common.c
runtime/staprun/staprun.c
runtime/staprun/staprun.h
session.cxx
session.h
stap-server-connect.c

index 1abec3fe19e65fd0ff29220c601dac08f8201518..9eb177ba6eded3d95fd134cd0d3206a22b519f26 100644 (file)
@@ -441,7 +441,7 @@ run_pass (systemtap_session& s)
     staprun_cmd += "-b " + lex_cast(s.buffer_size) + " ";
 
   if (s.need_uprobes)
-    staprun_cmd += "-u ";
+    staprun_cmd += "-u" + s.uprobes_path + " ";
 
   if (s.load_only)
     staprun_cmd += (s.output_file.empty() ? "-L " : "-D ");
index a1a512bbf1931871a53fc879c51d999f29f0ce99..846353d5060d8aa5c35a1183f54d0dedaf5544d4 100644 (file)
@@ -808,6 +808,13 @@ compile_server_client::process_response ()
                  s.module_name = components.back ();
                  s.module_name.erase(s.module_name.size() - 3);
                }
+
+             // If a uprobes.ko module was returned, then make note of it.
+             if (file_exists (s.tmpdir + "/server/uprobes.ko"))
+               {
+                 s.need_uprobes = true;
+                 s.uprobes_path = s.tmpdir + "/server/uprobes.ko";
+               }
            }
        }
       else if (s.have_script)
index d3550fb4ddade4d93615be16b18a38b771074e45..6ecf0d574a4ba5e22cc97ade1778bff5fd3f61a8 100644 (file)
@@ -7,7 +7,7 @@
  * Public License (GPL); either version 2, or (at your option) any
  * later version.
  *
- * Copyright (C) 2007 Red Hat Inc.
+ * Copyright (C) 2007, 2010 Red Hat Inc.
  */
 
 #include "staprun.h"
@@ -27,6 +27,7 @@ int attach_mod;
 int delete_mod;
 int load_only;
 int need_uprobes;
+const char *uprobes_path = NULL;
 int daemon_mode;
 off_t fsize_max;
 int fnum_max;
@@ -113,10 +114,12 @@ void parse_args(int argc, char **argv)
        fsize_max = 0;
        fnum_max = 0;
 
-       while ((c = getopt(argc, argv, "ALuvb:t:dc:o:x:S:D")) != EOF) {
+       while ((c = getopt(argc, argv, "ALu::vb:t:dc:o:x:S:D")) != EOF) {
                switch (c) {
                case 'u':
                        need_uprobes = 1;
+                       if (optarg)
+                         uprobes_path = strdup (optarg);
                        break;
                case 'v':
                        verbose++;
index 54b238941b34ab46810f7c58c3430bb4f4415f7f..2b9ad9e380bdc56e381430e69e016724e6c41414 100644 (file)
@@ -130,10 +130,14 @@ static int enable_uprobes(void)
        if (run_as(0, 0, 0, argv[0], argv) == 0)
                return 0;
 
+       /* Try the specified module or the one from the runtime.  */
+       if (uprobes_path)
+         snprintf (runtimeko, sizeof(runtimeko), "%s", uprobes_path);
+       else
+         snprintf (runtimeko, sizeof(runtimeko), "%s/uprobes/uprobes.ko",
+                   (getenv("SYSTEMTAP_RUNTIME") ?: PKGDATADIR "/runtime"));
+       dbug(2, "Inserting uprobes module from %s.\n", runtimeko);
        /* This module may be signed, so use insert_module to load it.  */
-       snprintf (runtimeko, sizeof(runtimeko), "%s/uprobes/uprobes.ko",
-                 (getenv("SYSTEMTAP_RUNTIME") ?: PKGDATADIR "/runtime"));
-       dbug(2, "Inserting uprobes module from SystemTap runtime %s.\n", runtimeko);
        argv[0] = NULL;
        if (insert_module(runtimeko, NULL, argv, assert_uprobes_module_permissions) == 0)
                return 0;
index 252c9ed50db2761f714f63dbd8c6290aefd0ab5f..64c8bc2b6016f90ea9337311a64b9c730d96e494 100644 (file)
@@ -190,6 +190,7 @@ extern int attach_mod;
 extern int delete_mod;
 extern int load_only;
 extern int need_uprobes;
+extern const char *uprobes_path;
 extern int daemon_mode;
 extern off_t fsize_max;
 extern int fnum_max;
index 526ccaa31b536622b9981a4d32ec1f3ecd086d8b..9fc8816b95c66f4e8fc9bb6cae40f9b9abe403f6 100644 (file)
@@ -138,6 +138,7 @@ systemtap_session::systemtap_session ():
   poison_cache = false;
   tapset_compile_coverage = false;
   need_uprobes = false;
+  uprobes_path = "";
   consult_symtab = false;
   ignore_vmlinux = false;
   ignore_dwarf = false;
@@ -1032,38 +1033,6 @@ systemtap_session::parse_kernel_config ()
   return 0;
 }
 
-int
-systemtap_session::parse_kernel_exports ()
-{
-  string kernel_exports_file = kernel_build_tree + "/Module.symvers";
-  struct stat st;
-  int rc = stat(kernel_exports_file.c_str(), &st);
-  if (rc != 0)
-    {
-       clog << "Checking \"" << kernel_exports_file << "\" failed: " << strerror(errno) << endl
-            << "Ensure kernel development headers & makefiles are installed." << endl;
-       return rc;
-    }
-
-  ifstream kef (kernel_exports_file.c_str());
-  string line;
-  while (getline (kef, line))
-    {
-      vector<string> tokens;
-      tokenize (line, tokens, "\t");
-      if (tokens.size() == 4 &&
-          tokens[2] == "vmlinux" &&
-          tokens[3].substr(0,13) == string("EXPORT_SYMBOL"))
-        kernel_exports.insert (tokens[1]);
-    }
-  if (verbose > 2)
-    clog << "Parsed kernel \"" << kernel_exports_file << "\", number of vmlinux exports: " << kernel_exports.size() << endl;
-  
-  kef.close();
-  return 0;
-}
-
-
 void systemtap_session::insert_loaded_modules()
 {
   char line[1024];
index 361ec03ca055a5d6176331081537cc1443586488..6981c6415bd8025eb8f79ee318b19025a0ae47af 100644 (file)
--- a/session.h
+++ b/session.h
@@ -83,7 +83,6 @@ struct systemtap_session
   // to be cleared in the systemtap_session ctor (session.cxx).
   void setup_kernel_release (const char* kstr);
   int parse_kernel_config ();
-  int parse_kernel_exports ();
   void insert_loaded_modules ();
 
   // command line parsing
@@ -142,6 +141,7 @@ struct systemtap_session
   bool prologue_searching;
   bool tapset_compile_coverage;
   bool need_uprobes;
+  std::string uprobes_path;
   bool load_only; // flight recorder mode
   bool omit_werror;
   bool unprivileged;
index d9409ebe92f7f044456963d837187b0fdf32fc04..46c4ba1683929c2d54fe27d3b235219d32858c24 100644 (file)
@@ -382,6 +382,7 @@ static void handleRequest (const char* requestDirName, const char* responseDirNa
   char stapstdout[PATH_MAX];
   char stapstderr[PATH_MAX];
   char staprc[PATH_MAX];
+  char stapsymvers[PATH_MAX];
 #define MAXSTAPARGC 1000 /* sorry, too lazy to dynamically allocate */
   char* stapargv[MAXSTAPARGC];
   int stapargc=0;
@@ -391,6 +392,7 @@ static void handleRequest (const char* requestDirName, const char* responseDirNa
   FILE* f;
   int unprivileged = 0;
   int stapargv_freestart = 0;
+  struct stat st;
 
   stapargv[stapargc++] = getenv ("SYSTEMTAP_STAP") ?: STAP_PREFIX "/bin/stap";
 
@@ -578,9 +580,35 @@ static void handleRequest (const char* requestDirName, const char* responseDirNa
                     errWarn("stap-sign-module");
                 }
             }
-        }
 
-      /* XXX: What about uprobes.ko? */
+         /* If uprobes.ko is required, then we need to return it to the client.
+            uprobes.ko was requires if the file "Module.symvers" is not empty in
+            the temp directory.  */
+         snprintf (stapsymvers, PATH_MAX, "%s/Module.symvers", new_staptmpdir);
+         rc = stat (stapsymvers, & st);
+         if (rc == 0 && st.st_size != 0)
+           {
+             /* uprobes.ko is required. Link to it from the response directory.  */
+             char *lnargv[10];
+             lnargv[0] = "/bin/ln";
+             lnargv[1] = "-s";
+             lnargv[2] = PKGDATADIR "/runtime/uprobes/uprobes.ko";
+             lnargv[3] = (char*)responseDirName;
+             lnargv[4] = NULL;
+             rc = spawn_and_wait (lnargv, NULL, NULL, NULL, NULL);
+             if (rc != PR_SUCCESS)
+               errWarn("stap uprobes.ko link");
+
+             /* In unprivileged mode, we need to return the signature as well. */
+             if (unprivileged) 
+               {
+                 lnargv[2] = PKGDATADIR "/runtime/uprobes/uprobes.ko.sgn";
+                 rc = spawn_and_wait (lnargv, NULL, NULL, NULL, NULL);
+                 if (rc != PR_SUCCESS)
+                   errWarn("stap uprobes.ko.sgn link");
+               }
+           }
+        }
     }
 
   /* Free up all the arg string copies.  Note that the first few were alloc'd
@@ -949,15 +977,6 @@ server_main(unsigned short port, SECKEYPrivateKey *privKey)
   if (prStatus != PR_SUCCESS)
     exitErr("PR_SetSocketOption");
 
-#if 0
-  /* This cipher is not on by default. The Acceptance test
-   * would like it to be. Turn this cipher on.
-   */
-  secStatus = SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE);
-  if (secStatus != SECSuccess)
-    exitErr("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5");
-#endif
-
   /* Configure the network connection. */
   addr.inet.family = PR_AF_INET;
   addr.inet.ip    = PR_INADDR_ANY;
This page took 0.044615 seconds and 5 git commands to generate.