diff options
author | Dave Brolley <brolley@redhat.com> | 2009-09-17 20:35:41 -0400 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-09-17 20:35:41 -0400 |
commit | 8afee8bbf045e858dae186d40653293c99dbbcdd (patch) | |
tree | d170c0b3e060f8534ecbd2783074b4838dcf812c | |
parent | 8150f846586bb04d05f51e4f17e86c00347cb7b6 (diff) | |
download | systemtap-steved-8afee8bbf045e858dae186d40653293c99dbbcdd.tar.gz systemtap-steved-8afee8bbf045e858dae186d40653293c99dbbcdd.tar.xz systemtap-steved-8afee8bbf045e858dae186d40653293c99dbbcdd.zip |
Check for unprivileged options conflicts on the server side.
Gneral work on options in the client and server.
-rw-r--r-- | main.cxx | 46 | ||||
-rwxr-xr-x | stap-client | 137 | ||||
-rwxr-xr-x | stap-server | 100 |
3 files changed, 174 insertions, 109 deletions
@@ -381,42 +381,6 @@ checkOptions (systemtap_session &s) cerr << "You can't specify -g and --unprivileged together." << endl; optionsConflict = true; } - if (s.include_path.size () > 1) - { - cerr << "You can't specify -I and --unprivileged together." << endl; - optionsConflict = true; - } - if (s.runtime_path != string(PKGDATADIR) + "/runtime") - { - cerr << "You can't use -R to specify an alternate runtime path when --unprivileged is specified." << endl; - optionsConflict = true; - } - if (s.kernel_build_tree.substr(0, 13) != "/lib/modules/") - { - cerr << "You can't use -r to specify a kernel release which is not installed when --unprivileged is specified." << endl; - optionsConflict = true; - } - if (! s.macros.empty ()) - { - cerr << "You can't specify -D and --unprivileged together." << endl; - optionsConflict = true; - } - - if (getenv ("SYSTEMTAP_TAPSET")) - { - cerr << "The environment variable SYSTEMTAP_TAPSET can not be defined when --unprivileged is specified." << endl; - optionsConflict = true; - } - if (getenv ("SYSTEMTAP_RUNTIME")) - { - cerr << "The environment variable SYSTEMTAP_RUNTIME can not be defined when --unprivileged is specified." << endl; - optionsConflict = true; - } - if (getenv ("SYSTEMTAP_DEBUGINFO_PATH")) - { - cerr << "The environment variable SYSTEMTAP_DEBUGINFO_PATH can not be defined when --unprivileged is specified." << endl; - optionsConflict = true; - } } if (!s.kernel_symtab_path.empty()) @@ -621,17 +585,17 @@ main (int argc, char * const argv []) break; case 'p': - if (s.listing_mode) - { - cerr << "Listing (-l) mode implies pass 2." << endl; - usage (s, 1); - } s.last_pass = (int)strtoul(optarg, &num_endptr, 10); if (*num_endptr != '\0' || s.last_pass < 1 || s.last_pass > 5) { cerr << "Invalid pass number (should be 1-5)." << endl; usage (s, 1); } + if (s.listing_mode && s.last_pass != 2) + { + cerr << "Listing (-l) mode implies pass 2." << endl; + usage (s, 1); + } break; case 'I': diff --git a/stap-client b/stap-client index 449d4a3d..3f2eb0a1 100755 --- a/stap-client +++ b/stap-client @@ -58,6 +58,11 @@ function initialization { v_level=0 keep_temps=0 b_specified=0 + m_name= + module_name=stap_$$ + uname_r="`uname -r`" + uname_v="`uname -v`" + uname_m="`uname -m`" # Default variable settings find_all= @@ -81,6 +86,7 @@ function parse_options { cmdline= cmdline1= cmdline2= + while test $# != 0 do advance_p=0 @@ -128,13 +134,11 @@ function parse_options { fi if test $dash_seen = 0; then # The dash has not been seen. This is either the script file - # name, a long argument or an argument to be passed to the probe module. + # name or an argument to be passed to the probe module. # If this is the first time, and -e has not been specified, # then it could be the name of the script file. - if test "X$second_char" = "X-"; then - cmdline2="$cmdline2 $first_token" - elif test "X$e_script" = "X" -a "X$script_file" = "X"; then - script_file=$first_token + if test "X$e_script" = "X" -a "X$script_file" = "X"; then + script_file="$first_token" cmdline1="$cmdline2" cmdline2= elif test "$first_char" != "'"; then @@ -149,9 +153,17 @@ function parse_options { # We are at the start of an option. Look at the first character. case $first_char in + a) + get_arg $first_token $2 + cmdline2="${cmdline2}s '$stap_arg'" + ;; b) b_specified=1 ;; + B) + get_arg $first_token $2 + cmdline2="${cmdline2}s '$stap_arg'" + ;; c) get_arg $first_token "$2" process_c "$stap_arg" @@ -174,6 +186,12 @@ function parse_options { l) get_arg $first_token $2 cmdline2="${cmdline2}l '$stap_arg'" + p_phase=2 + ;; + L) + get_arg $first_token $2 + cmdline2="${cmdline2}l '$stap_arg'" + p_phase=2 ;; m) get_arg $first_token $2 @@ -189,7 +207,7 @@ function parse_options { ;; r) get_arg $first_token $2 - cmdline2="${cmdline2}r '$stap_arg'" + process_r $stap_arg ;; R) get_arg $first_token $2 @@ -199,6 +217,10 @@ function parse_options { get_arg $first_token $2 cmdline2="${cmdline2}s '$stap_arg'" ;; + S) + get_arg $first_token $2 + cmdline2="${cmdline2}s '$stap_arg'" + ;; v) v_level=$(($v_level + 1)) ;; @@ -234,13 +256,13 @@ function parse_options { if test "X$script_file" != "X"; then local local_name if test "$script_file" != "-"; then - local_name=`generate_client_temp_name $script_file` + local_name=`generate_client_temp_name "$script_file"` else - local_name=$script_file + local_name="$script_file" fi - cmdline="$cmdline1 script/$local_name $cmdline2" + cmdline="$cmdline1 'script/$local_name' $cmdline2" else - cmdline="$cmdline1 $cmdline2" + cmdline="$cmdline2" fi # Processing based on final options settings @@ -323,8 +345,8 @@ function process_e { if test "X$e_script" = "X"; then e_script="$1" if test "X$script_file" != "X"; then - cmdline1="$cmdline1 $script_file $cmdline2" - cmdline2= + cmdline2="$cmdline1 '$script_file' $cmdline2" + cmdline1= script_file= fi fi @@ -344,6 +366,7 @@ function process_I { # # Process the -m flag. function process_m { + module_name="$1" m_name="$1" cmdline2="${cmdline2}m '$1'" } @@ -364,6 +387,33 @@ function process_p { cmdline2="${cmdline2}p '$1'" } +# function: process_r ARGUMENT +# +# Process the -r flag. +function process_r { + local first_char=`expr "$1" : '\(.\).*'` + + if test "$first_char" = "/"; then # fully specified path + kernel_build_tree=$1 + version_file_name="$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 + release=`cat $version_file_name 2>/dev/null` + if test "X$release" = "X"; then + fatal "Missing $version_file_name" + return + fi + else + # kernel release specified directly + release=$1 + fi + + if test "X$release" != "X$uname_r"; then + uname_r=$release + find_all="--all" + fi +} + # function: process_R ARGUMENT # # Process the -R flag. @@ -379,10 +429,11 @@ function process_R { # tree to be sent to the server. function include_file_or_directory { # Add a symbolic link of the named file or directory to our temporary directory - local local_name=`generate_client_temp_name $2` - mkdir -p $tmpdir_client/$1/`dirname $local_name` || \ - fatal "Could not create $tmpdir_client/$1/`dirname $local_name`" - ln -s /$local_name $tmpdir_client/$1/$local_name || \ + local local_name=`generate_client_temp_name "$2"` + local local_dirname=`dirname "$local_name"` + mkdir -p "$tmpdir_client/$1/$local_dirname" || \ + fatal "Could not create $tmpdir_client/$1/$local_dirname" + ln -s "/$local_name" "$tmpdir_client/$1/$local_name" || \ fatal "Could not link $tmpdir_client/$1/$local_name to /$local_name" echo "$local_name" } @@ -413,9 +464,9 @@ function create_request { if test "$script_file" = "-"; then mkdir -p $tmpdir_client/script || \ fatal "Cannot create temporary directory " $tmpdir_client/script - cat > $tmpdir_client/script/$script_file + cat > "$tmpdir_client/script/$script_file" else - include_file_or_directory script $script_file > /dev/null + include_file_or_directory script "$script_file" > /dev/null fi fi @@ -428,11 +479,7 @@ function create_request { # # Generate the client's sysinfo and echo it to stdout function client_sysinfo { - if test "X$sysinfo_client" = "X"; then - # Add some info from uname - sysinfo_client="`uname -rvm`" - fi - echo "$sysinfo_client" + echo "$uname_r $uname_v $uname_m" } # function: package_request @@ -507,8 +554,9 @@ 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=$tmpdir_server/$tmpdir_stap # Make sure we own the systemtap temp directory if we are root. - test $EUID = 0 && chown $EUID:$EUID $tmpdir_server/$tmpdir_stap + test $EUID = 0 && chown $EUID:$EUID $tmpdir_stap fi fi } @@ -632,6 +680,10 @@ function choose_server { fatal "Server port not provided by avahi" fi + # Does the server build for the kernel release that we want? + release=`expr "$remain" : ".sysinfo=\\\([^ ]*\\\).*"` + test "X$release" != "X$uname_r" && continue + ssl_db=`send_receive $name $port` test "X$ssl_db" != "X" && echo $ssl_db && return done @@ -696,16 +748,27 @@ function process_response { cd $tmpdir_server rc=`cat rc` - # Copy the module to the current directory, if -m was specified - if test "X$m_name" != "X"; then - if test -f $tmpdir_stap/$m_name.ko; then - cp $tmpdir_stap/$m_name.ko $wd - else + if test $p_phase -ge 4; then + if test -f $tmpdir_stap/*.ko; then + if test $p_phase = 4 -o "X$m_name" != "X"; then + cp -p $tmpdir_stap/*.ko $wd/$module_name.ko + test -f $tmpdir_stap/*.sgn && cp -p $tmpdir_stap/*.sgn $wd/$module_name.ko.sgn + else + module_name=`ls $tmpdir_stap/*.ko` + module_name=`expr "$module_name" : '\(.*\)\.ko'` + fi + elif test "X$script_file" != "X" -o "X$e_script" != "X"; then stream_output - fatal "module $tmpdir_stap/$m_name.ko does not exist" + fatal "no module returned by the server" fi fi + # Change the name of the temp directory and module name in stdout and stderr + sed -i "s,stap_[0-9]\+,$module_name,g" $tmpdir_server/stdout + sed -i "s,stap_[0-9]\+,$module_name,g" $tmpdir_server/stderr + sed -i "s,into \".*$module_name,into \"$module_name,g" $tmpdir_server/stdout + sed -i "s,into \".*$module_name,into \"$module_name,g" $tmpdir_server/stderr + # Output stdout and stderr as directed stream_output } @@ -738,12 +801,6 @@ function maybe_call_staprun { return fi - # There should be a module. - local mod_name=`ls $tmpdir_stap | grep '.ko$'` - if test "X$mod_name" = "X"; then - fatal "No module was found in $tmpdir_stap" - fi - if test $p_phase = 5; then test $v_level -gt 0 && echo "Pass 5: starting run." >&2 @@ -765,13 +822,15 @@ function maybe_call_staprun { staprun_opts="$staprun_opts -o $stdout_redirection" fi + # Run it from our original working directory + cd $wd + # Run it in the background and wait for it. This # way any signals sent to us can be caught. if test $v_level -ge 2; then - echo "running `which staprun` $staprun_opts $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'`" >&2 + echo "running `which staprun` $staprun_opts $module_name.ko" >&2 fi - eval `staprun_PATH` "$staprun_opts" \ - $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'` + eval `staprun_PATH` "$staprun_opts" $module_name.ko rc=$? # Wait until the job actually disappears so that its output is complete. diff --git a/stap-server b/stap-server index f9ccde04..98b54d96 100755 --- a/stap-server +++ b/stap-server @@ -32,6 +32,7 @@ function initialization { p_phase=5 keep_temps=0 unprivileged=0 + stap_options= # Request file name. zip_client=$1 @@ -135,19 +136,9 @@ function server_sysinfo { # # Make sure that systemtap as described by SYSINFO1 and SYSINFO2 are compaible function check_compatibility { - # Compatibility is irrelevant if the request is not for phase 5 activity. - test $p_phase -lt 5 && return - - # TODO: This needs work - # - Make sure the linux kernel matches exactly - local sysinfo1=$1 - local sysinfo2=$2 - - if test "$sysinfo1" != "$sysinfo2"; then - error "System configuration mismatch" - error " client: $sysinfo1" - fatal " server: $sysinfo2" - fi + # Compatibility is irrelevant. The client can choose any server + # it sees fit + return } # function: read_data_file PREFIX @@ -182,6 +173,13 @@ function read_data_file { # Examine the command line. We need not do much checking, but we do need to # parse all options in order to discover the ones we're interested in. function parse_options { + # We need to know in advance if --unprivileged was specified. + all_options="$@"" " + token=`expr "$all_options" : '.* \(--unprivileged\) .*'` + if test "X$token" = "X--unprivileged"; then + unprivileged=1 + fi + while test $# != 0 do advance_p=0 @@ -190,13 +188,6 @@ function parse_options { # Start of a new token. first_token=$1 - # Handle the --unprivileged option. - if test "X$first_token" = "X--unprivileged"; then - unprivileged=1 - shift - continue - fi - # Process the option. until test $advance_p != 0 do @@ -205,7 +196,16 @@ function parse_options { if test $dash_seen = 0; then if test "$first_char" = "-"; then if test "$first_token" != "-"; then - # It's not a lone dash, so it's an option. Remove the dash. + # It's not a lone dash, so it's an option. + # Is it a long option (i.e. --option)? + second_char=`expr "$first_token" : '.\(.\).*'` + if test "X$second_char" = "X-"; then + advance_p=$(($advance_p + 1)) + stap_options="$stap_options $first_token" + break + fi + # It's not a lone dash, or a long option, so it's a short option string. + # Remove the dash. first_token=`expr "$first_token" : '-\(.*\)'` dash_seen=1 first_char=`expr "$first_token" : '\(.\).*'` @@ -217,7 +217,12 @@ function parse_options { # If this is the first time, and -e has not been specified, # then it could be the name of the script file. if test "X$e_script" = "X" -a "X$script_file" = "X"; then - script_file=$first_token + script_file="$first_token" + fi + if test "$first_char" != "'"; then + stap_options="$stap_options '$first_token'" + else + stap_options="$stap_options $first_token" fi advance_p=$(($advance_p + 1)) break @@ -226,46 +231,83 @@ function parse_options { # We are at the start of an option. Look at the first character. case $first_char in - c) - get_arg $first_token "$2" + a) + get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" + ;; + B) + get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" + ;; + d) + get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" ;; D) get_arg $first_token $2 + if test $unprivileged = 1; then + fatal "You can't specify -D and --unprivileged together." + else + stap_options="$stap_options -$first_char $stap_arg" + fi ;; e) get_arg $first_token "$2" + stap_options="$stap_options -$first_char '$stap_arg'" process_e "$stap_arg" ;; I) get_arg $first_token $2 + if test $unprivileged = 1; then + fatal "You can't specify -I and --unprivileged together." + else + stap_options="$stap_options -$first_char $stap_arg" + fi ;; k) keep_temps=1 ;; l) get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" + process_p 2 + ;; + L) + get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" + process_p 2 ;; m) get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" ;; o) get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" ;; p) get_arg $first_token $2 process_p $stap_arg ;; - r) - get_arg $first_token $2 - ;; R) get_arg $first_token $2 + if test $unprivileged = 1; then + fatal "You can't specify -R and --unprivileged together." + else + stap_options="$stap_options -$first_char $stap_arg" + fi ;; s) get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" + ;; + S) + get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" ;; x) get_arg $first_token $2 + stap_options="$stap_options -$first_char $stap_arg" ;; *) # An unknown flag. Ignore it. @@ -274,6 +316,7 @@ function parse_options { if test $advance_p = 0; then # Just another flag character. Consume it. + stap_options="$stap_options -$first_char" first_token=`expr "$first_token" : '.\(.*\)'` if test "X$first_token" = "X"; then advance_p=$(($advance_p + 1)) @@ -302,7 +345,6 @@ function get_arg { advance_p=$(($advance_p + 1)) first=$1 fi - stap_arg="$first" advance_p=$(($advance_p + 1)) } @@ -340,7 +382,7 @@ function call_stap { server_p_phase=$p_phase fi - eval ${stap_exec_prefix}stap "$cmdline" -k -p $server_p_phase \ + eval ${stap_exec_prefix}stap "$stap_options" -k -p $server_p_phase \ >> $tmpdir_server/stdout \ 2>> $tmpdir_server/stderr |