summaryrefslogtreecommitdiffstats
path: root/main.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'main.cxx')
-rw-r--r--main.cxx109
1 files changed, 72 insertions, 37 deletions
diff --git a/main.cxx b/main.cxx
index 890f65bc..1ac5dd5a 100644
--- a/main.cxx
+++ b/main.cxx
@@ -108,10 +108,13 @@ usage (systemtap_session& s, int exitcode)
<< " " << s.kernel_build_tree << endl
<< " -m MODULE set probe module name, instead of " << endl
<< " " << s.module_name << endl
- << " -o FILE send script output to file, instead of stdout" << endl
+ << " -o FILE send script output to file, instead of stdout. This supports" << endl
+ << " strftime(3) formats for FILE" << endl
<< " -c CMD start the probes, run CMD, and exit when it finishes" << endl
<< " -x PID sets target() to PID" << endl
- << " -F load module and start probes, then detach" << endl
+ << " -F run as on-file flight recorder with -o." << endl
+ << " run as on-memory flight recorder without -o." << endl
+ << " -S size[,n] set maximum of the size and the number of files." << endl
<< " -d OBJECT add unwind/symbol data for OBJECT file";
if (s.unwindsym_modules.size() == 0)
clog << endl;
@@ -287,14 +290,9 @@ int pending_interrupts;
extern "C"
void handle_interrupt (int sig)
{
- if (pending_interrupts == 0)
- kill (0, sig); // Forward signals to child processes if any.
-
+ kill_stap_spawn(sig);
pending_interrupts ++;
- // NB: the "2" below is intended to skip the effect of the self-induced
- // deferred signal coming from the kill() above.
-
- if (pending_interrupts > 2) // XXX: should be configurable? time-based?
+ if (pending_interrupts > 1) // XXX: should be configurable? time-based?
{
char msg[] = "Too many interrupts received, exiting.\n";
int rc = write (2, msg, sizeof(msg)-1);
@@ -318,7 +316,7 @@ setup_signals (sighandler_t handler)
sigaddset (&sa.sa_mask, SIGINT);
sigaddset (&sa.sa_mask, SIGTERM);
}
- sa.sa_flags = 0;
+ sa.sa_flags = SA_RESTART;
sigaction (SIGHUP, &sa, NULL);
sigaction (SIGPIPE, &sa, NULL);
@@ -326,6 +324,34 @@ setup_signals (sighandler_t handler)
sigaction (SIGTERM, &sa, NULL);
}
+void
+setup_kernel_release (systemtap_session &s, const char* kstr) {
+ if (kstr[0] == '/') // fully specified path
+ {
+ s.kernel_build_tree = kstr;
+ string version_file_name = s.kernel_build_tree + "/include/config/kernel.release";
+ // The file include/config/kernel.release within the
+ // build tree is used to pull out the version information
+ ifstream version_file (version_file_name.c_str());
+ if (version_file.fail ())
+ {
+ cerr << "Missing " << version_file_name << endl;
+ exit(1);
+ }
+ else
+ {
+ char c;
+ s.kernel_release = "";
+ while (version_file.get(c) && c != '\n')
+ s.kernel_release.push_back(c);
+ }
+ }
+ else
+ {
+ s.kernel_release = string (kstr);
+ s.kernel_build_tree = "/lib/modules/" + s.kernel_release + "/build";
+ }
+}
int
main (int argc, char * const argv [])
@@ -375,6 +401,15 @@ main (int argc, char * const argv [])
s.ignore_vmlinux = false;
s.ignore_dwarf = false;
s.load_only = false;
+ s.skip_badvars = false;
+
+ // Location of our signing certificate.
+ // If we're root, use the database in SYSCONFDIR, otherwise
+ // use the one in our $HOME directory. */
+ if (geteuid() == 0)
+ s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
+ else
+ s.cert_db_path = getenv("HOME") + string ("/.systemtap/ssl/server");
const char* s_p = getenv ("SYSTEMTAP_TAPSET");
if (s_p != NULL)
@@ -425,6 +460,12 @@ main (int argc, char * const argv [])
if (s_tc != NULL)
s.tapset_compile_coverage = true;
+ const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
+ if (s_kr != NULL) {
+ setup_kernel_release(s, s_kr);
+ }
+
+
while (true)
{
int long_opt;
@@ -444,7 +485,7 @@ main (int argc, char * const argv [])
{ "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS },
{ NULL, 0, NULL, 0 }
};
- int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:F",
+ int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:FS:",
long_options, NULL);
if (grc < 0)
break;
@@ -559,31 +600,7 @@ main (int argc, char * const argv [])
break;
case 'r':
- if (optarg[0] == '/') // fully specified path
- {
- s.kernel_build_tree = optarg;
- string version_file_name = s.kernel_build_tree + "/include/config/kernel.release";
- // The file include/config/kernel.release within the
- // build tree is used to pull out the version information
- ifstream version_file (version_file_name.c_str());
- if (version_file.fail ())
- {
- cerr << "Missing " << version_file_name << endl;
- usage (s, 1);
- }
- else
- {
- char c;
- s.kernel_release = "";
- while (version_file.get(c) && c != '\n')
- s.kernel_release.push_back(c);
- }
- }
- else
- {
- s.kernel_release = string (optarg);
- s.kernel_build_tree = "/lib/modules/" + s.kernel_release + "/build";
- }
+ setup_kernel_release(s, optarg);
break;
case 'k':
@@ -628,6 +645,10 @@ main (int argc, char * const argv [])
s.macros.push_back (string (optarg));
break;
+ case 'S':
+ s.size_option = string (optarg);
+ break;
+
case 'q':
s.tapset_compile_coverage = true;
break;
@@ -1121,6 +1142,20 @@ main (int argc, char * const argv [])
if (copy_file(module_src_path.c_str(), module_dest_path.c_str()) != 0)
cerr << "Copy failed (\"" << module_src_path << "\" to \""
<< module_dest_path << "\"): " << strerror(errno) << endl;
+
+#if HAVE_NSS
+ // Save the signature as well.
+ assert (! s.cert_db_path.empty());
+ module_src_path += ".sgn";
+ module_dest_path += ".sgn";
+
+ if (s.verbose > 1)
+ clog << "Copying " << module_src_path << " to "
+ << module_dest_path << endl;
+ if (copy_file(module_src_path.c_str(), module_dest_path.c_str()) != 0)
+ cerr << "Copy failed (\"" << module_src_path << "\" to \""
+ << module_dest_path << "\"): " << strerror(errno) << endl;
+#endif
}
}
@@ -1178,7 +1213,7 @@ pass_5:
string cleanupcmd = "rm -rf ";
cleanupcmd += s.tmpdir;
if (s.verbose>1) clog << "Running " << cleanupcmd << endl;
- int status = system (cleanupcmd.c_str());
+ int status = stap_system (cleanupcmd.c_str());
if (status != 0 && s.verbose>1)
clog << "Cleanup command failed, status: " << status << endl;
}