From 558982c5ade8ae35156d8e6d05e117d49bfa6d45 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Sun, 29 Jun 2008 23:04:31 +0200 Subject: Add auto_free_ref to auto_free stuff; bug 6694 Also add auto_free.h to EXTRA_DIST. --- ChangeLog | 9 +++++++++ Makefile.am | 2 +- Makefile.in | 2 +- auto_free.h | 28 +++++++++++++++++++++++----- tapsets.cxx | 4 ++-- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2777fce3..d67746d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-06-29 Tim Moore + + * Makefile.am (EXTRA_DIST): Add auto_free.h. + * Makefile.in: Regenerated. + * auto_free.h (auto_free_ref): New class to free references to + pointers allocated with malloc / realloc. + * tapsets.cxx (iterate_over_srcfile_lines): Use auto_free_ref at + top level of function to free srcsp. + 2008-06-27 David Smith * tapsets.cxx (utrace_derived_probe_group::emit_module_decls): Fix diff --git a/Makefile.am b/Makefile.am index 3e5bd6c9..8333281e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -148,7 +148,7 @@ endif # Get extra libs as needed LDADD = -EXTRA_DIST = buildrun.h elaborate.h loc2c.h session.h \ +EXTRA_DIST = auto_free.h buildrun.h elaborate.h loc2c.h session.h \ parse.h staptree.h tapsets.h translate.h \ cache.h hash.h mdfour.h util.h staplog.c coveragedb.h \ testsuite systemtap.spec runtime tapset \ diff --git a/Makefile.in b/Makefile.in index 675edde2..dc039c3f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -324,7 +324,7 @@ loc2c_test_LDADD = $(stap_LDADD) # Get extra libs as needed LDADD = -EXTRA_DIST = buildrun.h elaborate.h loc2c.h session.h \ +EXTRA_DIST = auto_free.h buildrun.h elaborate.h loc2c.h session.h \ parse.h staptree.h tapsets.h translate.h \ cache.h hash.h mdfour.h util.h staplog.c coveragedb.h \ testsuite systemtap.spec runtime tapset \ diff --git a/auto_free.h b/auto_free.h index b13e7371..58290821 100644 --- a/auto_free.h +++ b/auto_free.h @@ -27,14 +27,32 @@ public: } private: // No copying allowed. - auto_free(const auto_free& af) + auto_free(const auto_free& af); + // No assignment either + auto_free& operator=(const auto_free& rhs); + void* _ptr; +}; + +// Use this to free a pointer whose value may change after the initial +// allocation e.g., be realloced. +template +class auto_free_ref +{ +public: + typedef T pointer_type; + auto_free_ref(pointer_type& ptr) : _ptr(ptr) { } - // No assignment either - auto_free& operator=(const auto_free& rhs) + ~auto_free_ref() { - return *this; + if (_ptr) + std::free(_ptr); } - void* _ptr; +private: + // No copying allowed. + auto_free_ref(const auto_free_ref& af); + // No assignment either + auto_free_ref& operator=(const auto_free_ref& rhs); + pointer_type& _ptr; }; #endif diff --git a/tapsets.cxx b/tapsets.cxx index a405cef0..c054d24c 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1184,7 +1184,8 @@ struct dwflpp size_t nsrcs = 0; dwarf_query * q = static_cast(data); int lineno = lines[0]; - + auto_free_ref free_srcsp(srcsp); + get_module_dwarf(); if (line_type == RELATIVE) @@ -1210,7 +1211,6 @@ struct dwflpp dwarf_getsrc_file (module_dwarf, srcfile, l, 0, &srcsp, &nsrcs)); - auto_free srcsp_af(srcsp); if (line_type == WILDCARD || line_type == RANGE) { Dwarf_Addr line_addr; -- cgit From ab45bf5d7fddea7f0bf0b81ea430fd3f674b549d Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 29 Jun 2008 21:08:35 -0400 Subject: point out releases/ directory; clarify optionality of elfutils bundling --- README | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README b/README index b36d7241..c0aaa8b5 100644 --- a/README +++ b/README @@ -27,18 +27,21 @@ Build steps: - Install the kernel-debuginfo, kernel-[smp-]devel, gcc and libcap-devel packages (or see below if you are building your own kernels from source). -- Download the latest elfutils snapshot (if desired): + +- If desired, download the latest elfutils snapshot to build in "bundled mode" ftp://sources.redhat.com/pub/systemtap/elfutils/elfutils-NNNN.tar.gz ftp://sources.redhat.com/pub/systemtap/elfutils/elfutils-portability.patch - Untar the snapshot in some new directory; apply patch (don't ask, long story) -- Download systemtap sources snapshot or from GIT: - ftp://sources.redhat.com/pub/systemtap/snapshots/ + +- Download systemtap sources: + http://sources.redhat.com/systemtap/ftp/releases/ + http://sources.redhat.com/systemtap/ftp/snapshots/ (or) git clone git://sources.redhat.com/git/systemtap.git (or) http://sources.redhat.com/git/systemtap.git + - Build it: - cd src - ./configure --with-elfutils=PATCHED-ELFUTILS-DIR [other autoconf options] + .../configure [--with-elfutils=PATCHED-ELFUTILS-DIR] [other autoconf options] make all check sudo make install sudo make installcheck -- cgit From b6109bf04ca3241af236179d28f9c1a32a91c485 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Mon, 30 Jun 2008 09:13:05 -0400 Subject: further clarify that elfutils need not be absolutely freshest, nor rebuilt every time --- README | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README b/README index c0aaa8b5..5fb8d408 100644 --- a/README +++ b/README @@ -28,7 +28,9 @@ Build steps: - Install the kernel-debuginfo, kernel-[smp-]devel, gcc and libcap-devel packages (or see below if you are building your own kernels from source). -- If desired, download the latest elfutils snapshot to build in "bundled mode" +- If desired, download a recent elfutils snapshot to build in "bundled mode". + If desired, build it separately one time, and install it to /usr/local. + ftp://sources.redhat.com/pub/systemtap/elfutils/elfutils-NNNN.tar.gz ftp://sources.redhat.com/pub/systemtap/elfutils/elfutils-portability.patch - Untar the snapshot in some new directory; apply patch (don't ask, long story) -- cgit From a962af3ae65f3a9d92e9ad783db92bf55f9ca523 Mon Sep 17 00:00:00 2001 From: David Smith Date: Mon, 30 Jun 2008 13:23:58 -0500 Subject: Handles "mortally wounded" threads correctly when detaching. 2008-06-30 David Smith * task_finder.c (stap_utrace_detach_ops): Removed check to see if thread has a mm (in the case where a thread isn't quite dead yet). (stap_utrace_attach): Minor error handling improvement. (__stp_utrace_attach_match_tsk): Ditto. --- runtime/ChangeLog | 8 +++++++ runtime/task_finder.c | 58 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 6da5814c..796b9cca 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +2008-06-30 David Smith + + * task_finder.c (stap_utrace_detach_ops): Removed check to see if + thread has a mm (in the case where a thread isn't quite dead + yet). + (stap_utrace_attach): Minor error handling improvement. + (__stp_utrace_attach_match_tsk): Ditto. + 2008-06-24 David Smith From: Srinivasa DS diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 07610864..021144dc 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -149,30 +149,37 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops) long error = 0; pid_t pid = 0; + // Notice we're not calling get_task_mm() in this loop. In + // every other instance when calling do_each_thread, we avoid + // tasks with no mm, because those are kernel threads. So, + // why is this function different? When a thread is in the + // process of dying, its mm gets freed. Then, later the + // thread gets in the dying state and the thread's + // UTRACE_EVENT(DEATH) event handler gets called (if any). + // + // If a thread is in this "mortally wounded" state - no mm + // but not dead - and at that moment this function is called, + // we'd miss detaching from it if we were checking to see if + // it had an mm. + rcu_read_lock(); do_each_thread(grp, tsk) { - struct mm_struct *mm; - - if (tsk->pid <= 1) + if (tsk == NULL || tsk->pid <= 1) continue; - mm = get_task_mm(tsk); - if (mm) { - mmput(mm); - engine = utrace_attach(tsk, UTRACE_ATTACH_MATCH_OPS, - ops, 0); - if (IS_ERR(engine)) { - error = -PTR_ERR(engine); - if (error != ENOENT) { - pid = tsk->pid; - goto udo_err; - } - error = 0; - } - else if (engine != NULL) { - utrace_detach(tsk, engine); - debug_task_finder_detach(); + engine = utrace_attach(tsk, UTRACE_ATTACH_MATCH_OPS, + ops, 0); + if (IS_ERR(engine)) { + error = -PTR_ERR(engine); + if (error != ENOENT) { + pid = tsk->pid; + goto udo_err; } + error = 0; + } + else if (engine != NULL) { + utrace_detach(tsk, engine); + debug_task_finder_detach(); } } while_each_thread(grp, tsk); udo_err: @@ -276,7 +283,7 @@ stap_utrace_attach(struct task_struct *tsk, int rc = 0; // Ignore init - if (tsk->pid <= 1) + if (tsk == NULL || tsk->pid <= 1) return EPERM; // Ignore threads with no mm (which are kernel threads). @@ -300,8 +307,12 @@ stap_utrace_attach(struct task_struct *tsk, rc = EFAULT; } else { - utrace_set_flags(tsk, engine, event_flags); - debug_task_finder_attach(); + rc = utrace_set_flags(tsk, engine, event_flags); + if (rc == 0) + debug_task_finder_attach(); + else + _stp_error("utrace_set_flags returned error %d on pid %d", + rc, (int)tsk->pid); } return rc; } @@ -392,7 +403,8 @@ __stp_utrace_attach_match_tsk(struct task_struct *path_tsk, char *mmpath_buf; char *mmpath; - if (path_tsk->pid <= 1 || match_tsk->pid <= 1) + if (path_tsk == NULL || path_tsk->pid <= 1 + || match_tsk == NULL || match_tsk->pid <= 1) return; /* Grab the path associated with the path_tsk. */ -- cgit From eb0ecdf035e690245c88de71b9f1bd7507856069 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Tue, 1 Jul 2008 14:45:31 -0400 Subject: Make _vfs.generic_commit_write only for kernel<=2.6.25 --- tapset/ChangeLog | 4 ++++ tapset/vfs.stp | 2 ++ testsuite/ChangeLog | 6 ++++++ testsuite/buildok/vfs_testcase.stp | 2 ++ 4 files changed, 14 insertions(+) diff --git a/tapset/ChangeLog b/tapset/ChangeLog index 0332a384..b1862324 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,7 @@ +2008-07-01 Wenji Huang + + * vfs.stp : Make _vfs.generic_commit_write only for kernel<=2.6.25 + 2008-06-26 Zhaolei * syscalls2.stp: Add sys_renameat. diff --git a/tapset/vfs.stp b/tapset/vfs.stp index 78c79051..3c38786a 100644 --- a/tapset/vfs.stp +++ b/tapset/vfs.stp @@ -898,6 +898,7 @@ probe _vfs.generic_block_bmap = kernel.function ("generic_block_bmap") get_block = $get_block } +%( kernel_v <= "2.6.25" %? probe _vfs.generic_commit_write = kernel.function ("generic_commit_write") { file = $file @@ -905,6 +906,7 @@ probe _vfs.generic_commit_write = kernel.function ("generic_commit_write") from = $from to = $to } +%) probe _vfs.block_prepare_write = kernel.function ("__block_prepare_write") { diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index eda51529..9353cc32 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,9 @@ + +2008-07-01 Wenji Huang + + * buildok/vfs_testcase.stp: Test _vfs.generic_commit_write only when + kernel<=2.6.25. + 2008-06-27 David Smith * systemtap.base/utrace_p4.exp: Added tests for 'process(PID)' diff --git a/testsuite/buildok/vfs_testcase.stp b/testsuite/buildok/vfs_testcase.stp index dc78399c..5d8dff25 100644 --- a/testsuite/buildok/vfs_testcase.stp +++ b/testsuite/buildok/vfs_testcase.stp @@ -410,6 +410,7 @@ probe _vfs.generic_block_bmap print("get_block = %p\n", get_block); } +%( kernel_v <= "2.6.25" %? probe _vfs.generic_commit_write { print("Probe hit the function: %s\n", probefunc()); @@ -417,6 +418,7 @@ probe _vfs.generic_commit_write print("page = %p\n", page); print("from = %u to=%u\n", from, to); } +%) probe _vfs.block_prepare_write { -- cgit From c0e526f077ee8cf6b1d62e02822b722d946d2648 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 1 Jul 2008 10:51:57 -0400 Subject: diagnostics improvement: print arch/mach at top if -vv --- ChangeLog | 5 +++++ main.cxx | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d67746d3..7c34f223 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-07-01 Frank Ch. Eigler + + * main.cxx (main): In -vv mode, also dump out session arch/release + values right at the top. + 2008-06-29 Tim Moore * Makefile.am (EXTRA_DIST): Add auto_free.h. diff --git a/main.cxx b/main.cxx index 58d7fa9f..eea2c7e7 100644 --- a/main.cxx +++ b/main.cxx @@ -698,7 +698,12 @@ main (int argc, char * const argv []) // arguments parsed; get down to business if (s.verbose > 1) - version (); + { + version (); + clog << "Session arch: " << s.architecture + << " release: " << s.kernel_release + << endl; + } // Create a temporary directory to build within. // Be careful with this, as "s.tmpdir" is "rm -rf"'d at the end. -- cgit From b77e6d1fc44f553e8d3ee7ec3b7e6076ad86fed6 Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 1 Jul 2008 15:16:52 -0500 Subject: Fixed __stp_get_mm_path() error return code. 2008-07-01 David Smith * task_finder.c (__stp_get_mm_path): Corrected error return code. (__stp_utrace_attach_match_tsk): Ignores ENOENT error from __stp_get_mm_path(). (stap_start_task_finder): Ditto. --- runtime/ChangeLog | 7 +++++++ runtime/task_finder.c | 18 ++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 796b9cca..f7f1a5a8 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,10 @@ +2008-07-01 David Smith + + * task_finder.c (__stp_get_mm_path): Corrected error return code. + (__stp_utrace_attach_match_tsk): Ignores ENOENT error from + __stp_get_mm_path(). + (stap_start_task_finder): Ditto. + 2008-06-30 David Smith * task_finder.c (stap_utrace_detach_ops): Removed check to see if diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 021144dc..316a9bc0 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -249,7 +249,7 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen) } else { *buf = '\0'; - rc = ERR_PTR(ENOENT); + rc = ERR_PTR(-ENOENT); } up_read(&mm->mmap_sem); return rc; @@ -428,8 +428,9 @@ __stp_utrace_attach_match_tsk(struct task_struct *path_tsk, mmput(mm); /* We're done with mm */ if (mmpath == NULL || IS_ERR(mmpath)) { int rc = -PTR_ERR(mmpath); - _stp_error("Unable to get path (error %d) for pid %d", - rc, (int)path_tsk->pid); + if (rc != ENOENT) + _stp_error("Unable to get path (error %d) for pid %d", + rc, (int)path_tsk->pid); } else { __stp_utrace_attach_match_filename(match_tsk, mmpath, @@ -952,9 +953,14 @@ stap_start_task_finder(void) mmput(mm); /* We're done with mm */ if (mmpath == NULL || IS_ERR(mmpath)) { rc = -PTR_ERR(mmpath); - _stp_error("Unable to get path (error %d) for pid %d", - rc, (int)tsk->pid); - goto stf_err; + if (rc == ENOENT) { + continue; + } + else { + _stp_error("Unable to get path (error %d) for pid %d", + rc, (int)tsk->pid); + goto stf_err; + } } /* Check the thread's exe's path/pid against our list. */ -- cgit From 92fa0578ee7cc6118487b386d9b85d8966e2771b Mon Sep 17 00:00:00 2001 From: William Cohen Date: Wed, 2 Jul 2008 14:11:37 -0400 Subject: Add para-callgraph.stp and para-callgraph.meta. --- testsuite/systemtap.examples/ChangeLog | 4 ++++ testsuite/systemtap.examples/para-callgraph.meta | 13 +++++++++++++ testsuite/systemtap.examples/para-callgraph.stp | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 testsuite/systemtap.examples/para-callgraph.meta create mode 100644 testsuite/systemtap.examples/para-callgraph.stp diff --git a/testsuite/systemtap.examples/ChangeLog b/testsuite/systemtap.examples/ChangeLog index b1c34347..c4d2c355 100644 --- a/testsuite/systemtap.examples/ChangeLog +++ b/testsuite/systemtap.examples/ChangeLog @@ -1,3 +1,7 @@ +2008-07-02 William Cohen + + * para-callgraph.stp, para-callgraph.meta: New. + 2008-06-20 William Cohen * traceio2.meta: Correct test_check and test_installcheck commands. diff --git a/testsuite/systemtap.examples/para-callgraph.meta b/testsuite/systemtap.examples/para-callgraph.meta new file mode 100644 index 00000000..3ce4b648 --- /dev/null +++ b/testsuite/systemtap.examples/para-callgraph.meta @@ -0,0 +1,13 @@ +title: Tracing Calls for Sections of Code +name: para-callgraph.stp +version: 1.0 +author: anonymous +keywords: trace callgraph +subsystem: kernel +status: production +exit: user-controlled +output: trace +scope: system-wide +description: The script takes two arguments: the first argument is the function to starts/stops the per thread call graph traces and the second argument is the list of functions to generate trace information on. The script prints out a timestap for the thread, the function name and pid, followed by entry or exit symboly and function name. +test_check: stap -p4 para-callgraph.stp sys_read "*@fs/*.c" +test_installcheck: stap para-callgraph.stp sys_read "*@fs/*.c" -c "sleep 1" diff --git a/testsuite/systemtap.examples/para-callgraph.stp b/testsuite/systemtap.examples/para-callgraph.stp new file mode 100644 index 00000000..1afb8837 --- /dev/null +++ b/testsuite/systemtap.examples/para-callgraph.stp @@ -0,0 +1,20 @@ +function trace(entry_p) { + if(tid() in trace) + printf("%s%s%s\n",thread_indent(entry_p), + (entry_p>0?"->":"<-"), + probefunc()) +} + +global trace +probe kernel.function(@1).call { + if (execname() == "stapio") next # skip our own helper process + trace[tid()] = 1 + trace(1) +} +probe kernel.function(@1).return { + trace(-1) + delete trace[tid()] +} + +probe kernel.function(@2).call { trace(1) } +probe kernel.function(@2).return { trace(-1) } -- cgit From a784d2f76cab28ae77a363185177fc8513d13e19 Mon Sep 17 00:00:00 2001 From: William Cohen Date: Wed, 2 Jul 2008 15:37:30 -0400 Subject: Add functioncallcount.meta and functioncallcount.stp. --- testsuite/systemtap.examples/ChangeLog | 4 ++++ testsuite/systemtap.examples/functioncallcount.meta | 13 +++++++++++++ testsuite/systemtap.examples/functioncallcount.stp | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 testsuite/systemtap.examples/functioncallcount.meta create mode 100644 testsuite/systemtap.examples/functioncallcount.stp diff --git a/testsuite/systemtap.examples/ChangeLog b/testsuite/systemtap.examples/ChangeLog index c4d2c355..dcaafe59 100644 --- a/testsuite/systemtap.examples/ChangeLog +++ b/testsuite/systemtap.examples/ChangeLog @@ -1,3 +1,7 @@ +2008-07-02 William Cohen + + * functioncallcount.meta, functioncallcount.stp: New. + 2008-07-02 William Cohen * para-callgraph.stp, para-callgraph.meta: New. diff --git a/testsuite/systemtap.examples/functioncallcount.meta b/testsuite/systemtap.examples/functioncallcount.meta new file mode 100644 index 00000000..4d419528 --- /dev/null +++ b/testsuite/systemtap.examples/functioncallcount.meta @@ -0,0 +1,13 @@ +title: Count Times Functions Called +name: functioncallcount.stp +version: 1.0 +author: anonymous +keywords: profiling functions +subsystem: kernel +status: production +exit: user-controlled +output: sorted-list on-exit +scope: system-wide +description: The functioncallcount.stp script takes one argument, a list of functions to probe. The script will run and count the number of times that each of the functions on the list is called. On exit the script will print a sorted list from most frequently to least frequently called function. +test_check: stap -p4 functioncallcount.stp "*@mm/*.c" +test_installcheck: stap functioncallcount.stp "*@mm/*.c" -c "sleep 1" diff --git a/testsuite/systemtap.examples/functioncallcount.stp b/testsuite/systemtap.examples/functioncallcount.stp new file mode 100644 index 00000000..e393b612 --- /dev/null +++ b/testsuite/systemtap.examples/functioncallcount.stp @@ -0,0 +1,17 @@ +# The following line command will probe all the functions +# in kernel's memory management code: +# +# stap functioncallcount.stp "*@mm/*.c" + +probe kernel.function(@1) { # probe functions listed on commandline + called[probefunc()] <<< 1 # add a count efficiently +} + +global called + +probe end { + foreach (fn in called-) # Sort by call count (in decreasing order) + # (fn+ in called) # Sort by function name + printf("%s %d\n", fn, @count(called[fn])) + exit() +} -- cgit From 66e1a139060be3caac7733ba745b225ce775ca97 Mon Sep 17 00:00:00 2001 From: Dave Brolley Date: Thu, 3 Jul 2008 13:10:44 -0400 Subject: client/server take 2. See bz6565. --- ChangeLog | 30 ++++++++++++ stap-client | 146 ++++++++++++++++++++++++++++++++++------------------------- stap-server | 113 ++++++++++++++++++++------------------------- stap-serverd | 93 +++++++++++++++++++++++++++++++++++++ 4 files changed, 256 insertions(+), 126 deletions(-) create mode 100755 stap-serverd diff --git a/ChangeLog b/ChangeLog index 7c34f223..697f4e0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2008-07-03 + + * stap-serverd: New script. + * stap-client (client_sysinfo): Client sysinfo is stripped down to + the output of `uname -r` for now. + (package_request): Don't create temporary server tar file here. + (send_request): Communication protocol simplified. Use nc to send + the tar file. + (receive_response): Communication protocol eliminated. Simply wait + for the file from the server using nc. + (unpack_response): Create temporary server tar file here. Verify the + contents of the server's response. + (find_and_connect_to_server): Obtain server address and port from + avahi-browse. + (server_fatal): New function. + (check_server_error): Call server_fatal. + * stap-server (configuration): port is now provided as an argument. + Default to port 65001. + (initialization): Don't create temp work directory here. + (receive_request): Communication protocol simplified. Receive the + request file using nc. + (unpack_request): Make temp work directory here. Verify the contents + of the request. + (server_sysinfo): New function. + (check_compatibility): Exact match required. + (package_response): Don't use -p on tar command. + (send_response): Communication protocol eliminated. Simply send the + file using nc. + (main line): Pass "$@" to configuration. + 2008-07-01 Frank Ch. Eigler * main.cxx (main): In -vv mode, also dump out session arch/release diff --git a/stap-client b/stap-client index 42402a27..515cab92 100755 --- a/stap-client +++ b/stap-client @@ -314,12 +314,8 @@ function create_request { # Generate the client's sysinfo and echo it to stdout function client_sysinfo { if test "X$sysinfo_client" = "X"; then - # Get the stap version - stap_version=`stap -V 2>&1 | grep version` - # Remove the number before the first slash - stap_version=`expr "$stap_version" : '.*version [^/]*/\([0-9./]*\).*'` # Add some info from uname - sysinfo_client="stap $stap_version `uname -sr`" + sysinfo_client="`uname -r`" fi echo $sysinfo_client } @@ -338,67 +334,50 @@ function package_request { tar -czhf $tar_client $tmpdir_client_base || \ fatal "ERROR: tar of request tree, $tmpdir_client, failed" - - tar_server=$tmpdir_env/`mktemp $tmpdir_prefix_server.tgz.XXXXXX` || \ - fatal "ERROR: cannot create temporary file " $tar_server } # function: send_request # -# Notify the server and then send $tar_client to the server as $tar_server +# Notify the server and then send $tar_client to the server # The protocol is: -# client -> "request: $tmpdir_client" -# server -> "send: $tar_server" -# client: rsync local:$tar_client server:$tar_server -# client -> "waiting:" +# client -> "request:" +# server -> "ready:" +# client -> $tar_client # # $tmpdir_client is provided on the request so that the server knows what # the tar file will expand to. function send_request { - echo "request: `basename $tmpdir_client`" >&3 + echo "request:" >&3 + # Get the server's response. read <&3 local line=$REPLY check_server_error $line - local tar_dest=`expr "$line" : 'send: \([^ ]*\)$'` - test "X$tar_dest" == "X" && \ - fatal "ERROR: destination tar file not provided" - - rsync -essh -a --delete $tar_client root@$server:$tar_dest || \ - fatal "ERROR: rsync of client request, $tar_client to $server:$tar_dest, failed" + # Check for the proper response. + test "$line" = "ready:" || \ + fatal "ERROR: server response, '$line', is incorrect" - echo "waiting:" >&3 + # Send the request file. + until nc $server $(($port + 1)) < $tar_client + do + sleep 1 + done } # function: receive_response # # Wait for a response from the server indicating the results of our request. -# The protocol is: -# server -> "sending: remote-tar-name server-tempdir-name stap-tempdir-name" -# client -> "OK" function receive_response { - read <&3 - local line=$REPLY - check_server_error $line - - tar_dest=`expr "$line" : 'sending: \([^ ]*\) [^ ]* [^ ]*$'` - test "X$tar_dest" == "X" && \ - fatal "ERROR: server response remote file is missing" - - tmpdir_server=`expr "$line" : 'sending: [^ ]* \([^ ]*\) [^ ]*$'` - test "X$tmpdir_server" == "X" && \ - fatal "ERROR: server response temp dir is missing" - - tmpdir_stap=`expr "$line" : 'sending: [^ ]* [^ ]* \([^ ]*\)$'` - test "X$tmpdir_stap" == "X" && \ - fatal "ERROR: server response stap temp dir is missing" - + # Make a place to receive the response file. + tar_server=`mktemp -t $tmpdir_prefix_client.server.tgz.XXXXXX` || \ + fatal "ERROR: cannot create temporary file " $tar_server # Retrieve the file - rsync -essh -a --delete root@$server:$tar_dest $tar_server || \ - fatal "ERROR: rsync of server response, $server:$tar_dest to $tar_server, failed" - echo "OK" >&3 + until nc $server $(($port + 1)) > $tar_server + do + sleep 1 + done } # function: unpack_response @@ -406,17 +385,45 @@ function receive_response { # Unpack the tar file received from the server and make the contents available # for printing the results and/or running 'staprun'. function unpack_response { + tmpdir_server=`mktemp -dt $tmpdir_prefix_client.server.XXXXXX` || \ + fatal "ERROR: cannot create temporary file " $tmpdir_server + # Unpack the server output directory - cd $tmpdir_client + cd $tmpdir_server tar -xzf $tar_server || \ fatal "ERROR: Unpacking of server response, $tar_server, failed" - # Create a local location for the server response. - local local_tmpdir_server_base=`basename $tar_server | sed 's,\.tgz,,'` - local local_tmpdir_server=`mktemp -dt $local_tmpdir_server_base.XXXXXX` || \ - fatal "ERROR: cannot create temporary directory " $local_tmpdir_server - - # Move the systemtap temp directory to our a local temp location, if -k + # Identify the server's request tree. The tar file should have expanded + # into a single directory named to match $tmpdir_prefix_server.?????? + # which should now be the only item in the current directory. + test "`ls | wc -l`" = 1 || \ + fatal "ERROR: Wrong number of files after expansion of server's tar file" + + tmpdir_server=`ls` + tmpdir_server=`expr "$tmpdir_server" : "\\\($tmpdir_prefix_server\\\\.......\\\)"` + + test "X$tmpdir_server" != "X" || \ + fatal "ERROR: server tar file did not expand as expected" + + # Check the contents of the expanded directory. It should contain: + # 1) a file called stdout + # 2) a file called stderr + # 3) a directory named to match stap?????? + test "`ls $tmpdir_server | wc -l`" = 3 || \ + fatal "ERROR: Wrong number of files after expansion of server's tar file" + test -f $tmpdir_server/stdout || \ + fatal "ERROR: `pwd`/$tmpdir_server/stdout does not exist or is not a regular file" + test -f $tmpdir_server/stderr || \ + fatal "ERROR: `pwd`/$tmpdir_server/stderr does not exist or is not a regular file" + + tmpdir_stap=`ls $tmpdir_server | grep stap` + tmpdir_stap=`expr "$tmpdir_stap" : "\\\(stap......\\\)"` + test "X$tmpdir_stap" = "X" && \ + fatal "ERROR: `pwd`/$tmpdir_server/stap?????? does not exist" + test -d $tmpdir_server/$tmpdir_stap || \ + fatal "ERROR: `pwd`/$tmpdir_server/$tmpdir_stap is not a directory" + + # Move the systemtap temp directory to a local temp location, if -k # was specified. if test $keep_temps = 1; then local local_tmpdir_stap=`mktemp -dt stapXXXXXX` || \ @@ -428,13 +435,17 @@ function unpack_response { sed -i "s,^Keeping temporary directory.*,Keeping temporary directory \"$local_tmpdir_stap\"," $tmpdir_server/stderr tmpdir_stap=$local_tmpdir_stap else - tmpdir_stap=$local_tmpdir_server/$tmpdir_stap + tmpdir_stap=`pwd`/$tmpdir_stap fi - # Move the extracted tree to our local location - mv $tmpdir_server/* $local_tmpdir_server + # Move the contents of the server's tmpdir down one level to the + # current directory (our local server tmpdir) + mv $tmpdir_server/* . 2>/dev/null rm -fr $tmpdir_server - tmpdir_server=$local_tmpdir_server + tmpdir_server=`pwd` + + # Make sure we own the systemtap temp directory if we are root. + test $EUID = 0 && chown $EUID:$EUID $tmpdir_stap } # function: find_and_connect_to_server @@ -443,11 +454,14 @@ function unpack_response { function find_and_connect_to_server { # Find a server server=`avahi-browse $avahi_service_tag --terminate -r 2>/dev/null | match_server` + port=`expr "$server" : '[^/]*/\(.*\)'` + server=`expr "$server" : '\([^/]*\)/.*'` + test "X$server" != "X" || \ fatal "ERROR: cannot find a server" - port=`expr "$server" : '[^/]*/\(.*\)'` - server=`expr "$server" : '\([^/]*\)/.*'` + test "X$port" != "X" || \ + fatal "ERROR: server port not provided" # Open a connection to the server if ! exec 3<> /dev/tcp/$server/$port; then @@ -500,7 +514,6 @@ function match_server { ;; txt ) sysinfo_server=`expr "$service_data" : '\[\"\([^]]*\)\"\]'` - sysinfo_server=`expr "$sysinfo_server" : '[^/]*/\(.*\)'` ;; * ) break ;; @@ -508,7 +521,6 @@ function match_server { done # It is a stap server, but is it compatible? - sysinfo_server="stap $sysinfo_server" if test "$sysinfo_server" != "`client_sysinfo`"; then continue fi @@ -534,9 +546,9 @@ function disconnect_from_server { # Write the stdout and stderr from the server to stdout and stderr respectively. function stream_output { # Output stdout and stderr as directed - cd $local_tmpdir_server - cat ${tmpdir_server}/stderr >&2 - eval cat ${tmpdir_server}/stdout $stdout_redirection + cd $tmpdir_server + cat stderr >&2 + eval cat stdout $stdout_redirection } # function: maybe_call_staprun @@ -558,7 +570,7 @@ function maybe_call_staprun { # Check the given server response for an error message. function check_server_error { echo $1 | grep -q "^ERROR:" && \ - fatal "Server:" "$@" + server_fatal "Server:" "$@" } # function: fatal [ MESSAGE ] @@ -566,6 +578,16 @@ function check_server_error { # Fatal error # Prints its arguments to stderr and exits function fatal { + echo $0: "$@" >&2 + cleanup + exit 1 +} + +# function: server_fatal [ MESSAGE ] +# +# Fatal error +# Prints its arguments to stderr and exits +function server_fatal { echo $0: "$@" >&2 cat <&3 >&2 cleanup diff --git a/stap-server b/stap-server index 1a2e7918..11d6d81d 100755 --- a/stap-server +++ b/stap-server @@ -21,6 +21,8 @@ function configuration { # Configuration tmpdir_prefix_client=stap.client tmpdir_prefix_server=stap.server + port=$1 + test "X$port" = "X" && port=65001 } # function: initialization @@ -31,54 +33,33 @@ function initialization { # Default options settings p_phase=5 keep_temps=0 - - # Make a temp directory to work in. - tmpdir_server=`mktemp -dt $tmpdir_prefix_server.XXXXXX` || \ - fatal "ERROR: cannot create temporary directory " $tmpdir_server - tmpdir_env=`dirname $tmpdir_server` } # function: receive_request # # Receive a tar file representing the request from the client: # The protocol is: -# client -> "request: $tmpdir_client" -# server -> "send: $tar_client" -# client: copies file to server:$tar_client -# client -> "waiting:" -# -# $tmpdir_client is provided on the request so that we know what -# the tar file will expand to. +# client -> "request:" +# server -> "ready:" +# client -> $tar_client function receive_request { - cd $tmpdir_server - # Request from the client is on stdin read line=$REPLY - # Extract the name of the client's temp directory. - tmpdir_client=`expr "$line" : 'request: \([^ ]*\)$'` - test "X$tmpdir_client" == "X" && \ - fatal "ERROR: client request temp dir name is missing" $tmpdir_server - tmpdir_client=$tmpdir_server/$tmpdir_client - - # Create the client's temp dir now to guarantee that it won't clash with - # any files we need to create later. - mkdir $tmpdir_client || \ - fatal "ERROR: cannot create client temp dir" $tmpdir_client + # Check to see that it is a client request + test "$line" = "request:" || \ + fatal "ERROR: client request, '$line' is incorrect" # Create a place to receive the client's tar file - tar_client=`mktemp -t $tmpdir_prefix_client.tgz.XXXXXX` || \ + tar_client=`mktemp -t $tmpdir_prefix_server.client.tgz.XXXXXX` || \ fatal "ERROR: cannot create temporary tar file " $tar_client # Request that the file be sent. - echo "send: $tar_client" + echo "ready:" - # Wait for confirmation that the tar file has arrived via rysnc - read - line=$REPLY - test "X$line" = "Xwaiting:" || \ - fatal "ERROR: client send confirmation, '$line', is incorrect" + # Receive the file. + nc -l $port < /dev/null > $tar_client } # function: unpack_request @@ -86,15 +67,31 @@ function receive_request { # Unpack the tar file received from the client and make the contents # available for use when running 'stap' function unpack_request { + # Make a temp directory to work in. + tmpdir_server=`mktemp -dt $tmpdir_prefix_server.XXXXXX` || \ + fatal "ERROR: cannot create temporary directory " $tmpdir_server + tmpdir_env=`dirname $tmpdir_server` + cd $tmpdir_server # Unpack the tar file. tar -xzf $tar_client || \ fatal "ERROR: cannot unpack tar archive $tar_client" + # Identify the client's request tree. The tar file should have expanded + # into a single directory named to match $tmpdir_prefix_client.?????? + # which should now be the only item in the current directory. + test "`ls | wc -l`" = 1 || \ + fatal "ERROR: Wrong number of files after expansion of client's tar file" + + tmpdir_client=`ls` + tmpdir_client=`expr "$tmpdir_client" : "\\\($tmpdir_prefix_client\\\\.......\\\)"` + + test "X$tmpdir_client" != "X" || \ + fatal "ERROR: client tar file did not expand as expected" + # Move the client's temp directory to a local temp location - local tmpdir_client_base=`basename $tar_client | sed 's,\.tgz,,'` - local local_tmpdir_client=`mktemp -dt $tmpdir_client_base.XXXXXX` || \ + local local_tmpdir_client=`mktemp -dt $tmpdir_prefix_server.client.XXXXXX` || \ fatal "ERROR: cannot create temporary tar file " $local_tmpdir_client mv $tmpdir_client/* $local_tmpdir_client rm -fr $tmpdir_client @@ -114,19 +111,18 @@ function check_request { client_sysinfo=`read_data_file sysinfo` test "X$client_sysinfo" != "X" || exit 1 - # Extract the client's config info. - client_name=`expr "$client_sysinfo" : 'stap [^ ]* [^ ]* \([^ ]*\).*'` - client_sysinfo=`echo $client_sysinfo | sed s,$client_name,,` - - # Extract the server's config info. - server_sysinfo=`uname -sr` - server_name=`expr "$server_sysinfo" : '[^ ]* \([^ ]*\).*'` - server_sysinfo=`echo $server_sysinfo | sed s,$server_name,,` - local stap_version=`stap -V 2>&1 | grep version` - stap_version=`expr "$stap_version" : '.*version \([0-9./]*\).*'` - server_sysinfo="stap $stap_version $server_sysinfo" + check_compatibility "$client_sysinfo" `server_sysinfo` +} - check_compatibility "$client_sysinfo" "$server_sysinfo" +# function server_sysinfo +# +# Generate the server's sysinfo and echo it to stdout +function server_sysinfo { + if test "X$sysinfo_server" = "X"; then + # Add some info from uname + sysinfo_server="`uname -r`" + fi + echo $sysinfo_server } # function check_compaibility SYSINFO1 SYSINFO2 @@ -134,10 +130,9 @@ function check_request { # Make sure that systemtap as described by SYSINFO1 and SYSINFO2 are compaible function check_compatibility { # TODO: This needs work - # - In stap version x/y, require that the y matches # - Make sure the linux kernel matches exactly - local sysinfo1=`echo $1 | sed 's,stap [^/]*/,stap ,'` - local sysinfo2=`echo $2 | sed 's,stap [^/]*/,stap ,'` + local sysinfo1=$1 + local sysinfo2=$2 if test "$sysinfo1" != "$sysinfo2"; then error "ERROR: system configuration mismatch" @@ -361,7 +356,7 @@ function package_response { chmod +r $tar_server # Generate the tar file - tar -czphf $tar_server `basename $tmpdir_server` || \ + tar -czhf $tar_server `basename $tmpdir_server` || \ fatal "ERROR: tar of $tmpdir_server failed" } @@ -370,21 +365,11 @@ function package_response { # Notify the client that $tar_server is ready and wait for the client to take # it. # The protocol is: -# server -> "sending: $tar_server $tmpdir_server $tmpdir_stap" -# client: copies file from server:$tar_server -# client -> "OK" +# server -> "sending: $tmpdir_server $tmpdir_stap" +# server -> $tar_server function send_response { - # TODO needed for rsync from client to work - chmod +r $tmpdir_server - - # Tell the client where to get it. - echo "sending: $tar_server `basename $tmpdir_server` `basename $tmpdir_stap`" - - # Wait for the confirmation - read - line=$REPLY - test $line = "OK" || \ - fatal "ERROR: client final confirmation, '$line' is incorrect" + # Now send it + nc -l $port < $tar_server > /dev/null } # function: fatal [ MESSAGE ] @@ -421,7 +406,7 @@ function cleanup { #----------------------------------------------------------------------------- # Beginning of main line execution. #----------------------------------------------------------------------------- -configuration +configuration "$@" initialization receive_request unpack_request diff --git a/stap-serverd b/stap-serverd new file mode 100755 index 00000000..2c0743c0 --- /dev/null +++ b/stap-serverd @@ -0,0 +1,93 @@ +#!/bin/bash + +# Compile server manager for systemtap +# +# Copyright (C) 2008 Red Hat Inc. +# +# This file is part of systemtap, and is free software. You can +# redistribute it and/or modify it under the terms of the GNU General +# Public License (GPL); either version 2, or (at your option) any +# later version. + +# This script publishes its presence on the network and then listens for +# incoming connections. When a connection is detected, the stap-server script +# is run to handle the request. + +# Catch ctrl-c +trap 'handle_sigint' SIGINT + +#----------------------------------------------------------------------------- +# Helper functions. +#----------------------------------------------------------------------------- +# function: initialization PORT +function initialization { + # Default settings. + tmpdir_prefix_serverd=stap.serverd + avahi_type=_stap._tcp + port=$1 + test "X$port" = "X" && port=65000 +} + +# function: advertise_presence +# +# Advertise the availability of the server on the network. +function advertise_presence { + # Build up a string representing our server's properties. + # TODO: this needs fleshing out. + + local sysinfo=`uname -r` + local txt="$sysinfo" + + # Call avahi-publish-service to advertise our presence. + avahi-publish-service "Systemtap Compile Server on `uname -n`" \ + $avahi_type $port $txt > /dev/null 2>&1 & + + echo "Systemtap Compile Server on `uname -n` listening on port $port" +} + +# function: listen +# +# Listen for and handle requests to the server. +function listen { + # Work in a temporary directory + tmpdir=`mktemp -dt $tmpdir_prefix_serverd.XXXXXX` || \ + fatal "ERROR: cannot create temporary directory " $tmpdir + cd $tmpdir + + # Create a fifo for communicating with the server + local fifo_name=$tmpdir_prefix_serverd.fifo + mknod $fifo_name p || \ + fatal "ERROR: cannot create temporary fifo " $tmpdir/$fifo_name + + # Loop forever accepting requests + while true + do + nc -l $port < $fifo_name | stap-server $((port + 1)) > $fifo_name 2>&1 + done +} + +# function: fatal [ MESSAGE ] +# +# Fatal error +# Prints its arguments to stderr and exits +function fatal { + echo "$@" >&2 + exit 1 +} + +# function: handle_sigint +# +# Terminate gracefully when SIGINT is received. +function handle_sigint { + echo "$0: received SIGINT. Exiting." + cd `dirname $tmpdir` + rm -fr $tmpdir + exit +} + +#----------------------------------------------------------------------------- +# Beginning of main line execution. +#----------------------------------------------------------------------------- +initialization "$@" +advertise_presence +listen -- cgit From 422b0781177e0755df5542e1c70e809e6f3cfe89 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 3 Jul 2008 16:00:40 -0400 Subject: ubuntu (2.6.24-16-server) kernel compatibility fix --- ChangeLog | 4 ++++ translate.cxx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 697f4e0d..7f90771b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-07-03 Frank Ch. Eigler + + * translate.cxx (translate_pass): Don't #include . + 2008-07-03 * stap-serverd: New script. diff --git a/translate.cxx b/translate.cxx index 2c1cb84c..e9dff3c7 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4530,7 +4530,7 @@ translate_pass (systemtap_session& s) s.op->newline() << "#include "; s.op->newline() << "#include "; s.op->newline() << "#include "; - s.op->newline() << "#include "; + // s.op->newline() << "#include "; s.op->newline() << "#include \"loc2c-runtime.h\" "; // XXX: old 2.6 kernel hack -- cgit