Blame SOURCES/rhbz1051649.patch

f43afa
From 2512f77547e7a4b9bbfd46c01c5b2ded2c171cf3 Mon Sep 17 00:00:00 2001
f43afa
From: Jonathan Lebon <jlebon@redhat.com>
f43afa
Date: Wed, 27 Nov 2013 11:21:02 -0500
f43afa
Subject: BZ1051649: backport boot-time probing feature
f43afa
f43afa
---
f43afa
 configure.ac                         |   3 +-
f43afa
 initscript/99stap/module-setup.sh.in |  36 ++++++
f43afa
 initscript/99stap/start-staprun.sh   |  26 ++++
f43afa
 initscript/README.systemtap          | 108 ++++++++++++++--
f43afa
 initscript/config.systemtap.in       |   3 +
f43afa
 initscript/systemtap.in              | 230 +++++++++++++++++++++++++++++++++--
f43afa
 systemtap.spec                       |  39 ++++--
f43afa
 tapset-utrace.cxx                    |   9 --
f43afa
 8 files changed, 413 insertions(+), 41 deletions(-)
f43afa
 create mode 100644 initscript/99stap/module-setup.sh.in
f43afa
 create mode 100644 initscript/99stap/start-staprun.sh
f43afa
 mode change 100644 => 100755 initscript/systemtap.in
f43afa
f43afa
diff --git a/configure.ac b/configure.ac
f43afa
index 56c3b88..3d6b50b 100644
f43afa
--- a/configure.ac
f43afa
+++ b/configure.ac
f43afa
@@ -681,7 +681,8 @@ AC_CONFIG_FILES([Makefile doc/Makefile man/Makefile \
f43afa
 doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile \
f43afa
 man/stappaths.7 \
f43afa
 initscript/config.systemtap initscript/config.stap-server \
f43afa
-initscript/systemtap initscript/stap-server ])
f43afa
+initscript/systemtap initscript/stap-server \
f43afa
+initscript/99stap/module-setup.sh ])
f43afa
 AC_CONFIG_SUBDIRS(testsuite)
f43afa
 if test $enable_translator == "yes"; then
f43afa
 	AC_CONFIG_FILES([run-stap], [chmod +x run-stap])
f43afa
diff --git a/initscript/99stap/module-setup.sh.in b/initscript/99stap/module-setup.sh.in
f43afa
new file mode 100644
f43afa
index 0000000..4f4583d
f43afa
--- /dev/null
f43afa
+++ b/initscript/99stap/module-setup.sh.in
f43afa
@@ -0,0 +1,36 @@
f43afa
+#!/bin/bash
f43afa
+
f43afa
+# NB: $moddir only works in install()
f43afa
+. @prefix@/lib/dracut/modules.d/99stap/params.conf
f43afa
+
f43afa
+# Return 0 --> install stap module
f43afa
+# Return 1 --> skip stap module
f43afa
+check() {
f43afa
+   # Install it if we have early-boot scripts
f43afa
+   [ "$ONBOOT_SCRIPTS" ] && return 0
f43afa
+   return 1
f43afa
+}
f43afa
+
f43afa
+# We don't depend on anything
f43afa
+depends() {
f43afa
+   echo ""
f43afa
+}
f43afa
+
f43afa
+install() {
f43afa
+
f43afa
+   # These programs are very likely to already be included by other
f43afa
+   # dracut modules so we're really not adding any weight
f43afa
+   dracut_install bash mkdir
f43afa
+
f43afa
+   # The real payload...
f43afa
+   inst "$STAPRUN"
f43afa
+   inst "$STAPIO"
f43afa
+   for script in $ONBOOT_SCRIPTS; do
f43afa
+      inst "$CACHE_PATH/$script.ko"
f43afa
+   done
f43afa
+
f43afa
+   # start-staprun.sh will need a copy of params.conf
f43afa
+   inst_simple "$moddir/params.conf" "/etc/systemtap-params.conf"
f43afa
+   inst_hook cmdline 01 "$moddir/start-staprun.sh"
f43afa
+}
f43afa
+
f43afa
diff --git a/initscript/99stap/start-staprun.sh b/initscript/99stap/start-staprun.sh
f43afa
new file mode 100644
f43afa
index 0000000..efb4d2f
f43afa
--- /dev/null
f43afa
+++ b/initscript/99stap/start-staprun.sh
f43afa
@@ -0,0 +1,26 @@
f43afa
+#!/bin/bash
f43afa
+
f43afa
+# Inserts the SystemTap modules using staprun.
f43afa
+
f43afa
+. /etc/systemtap-params.conf
f43afa
+
f43afa
+# From here, we can access /var/run (or rather what it will link to),
f43afa
+# but because $STAT_PATH is user-configurable, we're not guaranteed that
f43afa
+# it will be /var/run.  Regardless, we can't have access to the final
f43afa
+# root so we make do and write to /var/run/systemtap anyway. The init
f43afa
+# script will take care of moving the PID files to the real directory if
f43afa
+# necessary.
f43afa
+PIDDIR=/run/systemtap
f43afa
+mkdir -p $PIDDIR
f43afa
+
f43afa
+for script in $ONBOOT_SCRIPTS; do
f43afa
+   pid=$PIDDIR/$script
f43afa
+   eval opts=\$${script}_OPT
f43afa
+   if [ $LOG_BOOT_ERR -eq 1 ]; then
f43afa
+      $STAPRUN $opts $CACHE_PATH/$script.ko 2> $PIDDIR/$script.log
f43afa
+   else
f43afa
+      $STAPRUN $opts $CACHE_PATH/$script.ko
f43afa
+   fi
f43afa
+   echo 0 > $pid
f43afa
+done
f43afa
+
f43afa
diff --git a/initscript/README.systemtap b/initscript/README.systemtap
f43afa
index d583d72..9dd1ee6 100644
f43afa
--- a/initscript/README.systemtap
f43afa
+++ b/initscript/README.systemtap
f43afa
@@ -23,8 +23,8 @@ will be useful for users who use -DRELAY_HOST and -DRELAY_GUEST.
f43afa
 ========
f43afa
 2.1 Synopsis
f43afa
 
f43afa
-/sbin/service systemtap {start|stop|restart|status|compile|cleanup} \
f43afa
-	[-r kernelrelease] [-c config] [-R] [-y] [script(s)]
f43afa
+/sbin/service systemtap {start|stop|restart|status|compile|onboot|cleanup} \
f43afa
+   [-r kernelrelease] [-o path.img] [-b] [-c config] [-R] [-y] [script(s)]
f43afa
 
f43afa
 2.2 Commands
f43afa
  You have to specify one of the below commands.
f43afa
@@ -57,9 +57,29 @@ will be useful for users who use -DRELAY_HOST and -DRELAY_GUEST.
f43afa
  Compile script(s) on the specified kernel. This command takes '-r' option
f43afa
  which specifies the release of the kernel(see 2.3.4) on which you would
f43afa
  like to compile script(s). This command asks user whether it can overwrite
f43afa
-existing caches.
f43afa
+ existing caches.
f43afa
 
f43afa
-2.2.6 cleanup
f43afa
+2.2.6 onboot
f43afa
+ Make script(s) part of the initramfs so that they are started earlier during
f43afa
+ the boot process. Only works on dracut-based systems. This command also takes
f43afa
+ the '-r' option. If '-r' is omitted, the initramfs is created for the running
f43afa
+ kernel. If '-o path.img' is given, the initramfs is created at 'path.img' (must
f43afa
+ be an absolute path).  Otherwise, defaults to '/boot/initramfs-KVER.img', where
f43afa
+ KVER is `uname -r` if the '-r' option is omitted, or the given kernel version
f43afa
+ otherwise.
f43afa
+
f43afa
+ If the output file already exists, it is overwritten, unless the -b switch is
f43afa
+ given, in which case the file is appended '.bak' rather than overwritten. Note
f43afa
+ however that if a '.bak' version already exists, it will not be overwritten.
f43afa
+
f43afa
+ If no scripts are specified on the command-line, the initramfs will be created
f43afa
+ without including any scripts at all (i.e. no extra systemtap files added).
f43afa
+
f43afa
+ Warning: do not use the stap -o option with onboot scripts because the
f43afa
+ script is started before the root filesystem is even mounted. Increase the
f43afa
+ buffer size if more space is needed.
f43afa
+
f43afa
+2.2.7 cleanup
f43afa
  Cleanup compiled script(s) from cache directory(see 3.4). This command also
f43afa
  takes '-r' option. If '-r' option is omitted, cleanup all caches for running
f43afa
  kernel. This command asks user whether it can remove caches.
f43afa
@@ -75,8 +95,8 @@ existing caches.
f43afa
 2.3.2 script(s)
f43afa
  You can specify individual scripts to the commands. If you omit to specify
f43afa
  any script, systemtap initscript will execute the command with all scripts
f43afa
- in the script directory(except 'start' and 'stop' command, see 2.2.1 and
f43afa
- 2.2.2).
f43afa
+ in the script directory (except 'start', 'stop', and 'onboot' commands, see
f43afa
+ 2.2.1, 2.2.2, and 2.2.6).
f43afa
 
f43afa
 2.3.3 -R
f43afa
  If this option is specified, systemtap initscript will try to solve
f43afa
@@ -85,11 +105,22 @@ existing caches.
f43afa
 
f43afa
 2.3.4 -r kernelrelease
f43afa
  You can specify release version of the kernel(e.g. 2.6.26.1). This option
f43afa
- is valid only with compile and cleanup commands.
f43afa
+ is valid only with compile, onboot, and cleanup commands.
f43afa
 
f43afa
 2.3.5 -y
f43afa
  Answer yes for all questions.
f43afa
 
f43afa
+2.3.6 -o path.img
f43afa
+ Specify the path of the initramfs image. Otherwise, the default is
f43afa
+ '/boot/initramfs-KVER.img', where KVER is `uname -r` if the '-r' option is
f43afa
+ omitted, or the given kernel version otherwise. This option is only valid with
f43afa
+ the onboot command.
f43afa
+
f43afa
+2.3.7 -b
f43afa
+ If present, will backup an existing initramfs image by renaming it with a
f43afa
+ '.bak' extension. Otherwise, the initramfs is overwritten without backing up.
f43afa
+ This option is only valid with the onboot command.
f43afa
+
f43afa
 2.4 Misc
f43afa
 2.4.1 Service Priority
f43afa
  Each initscript has execution priority. Since user would like to trace
f43afa
@@ -147,9 +178,16 @@ existing caches.
f43afa
  Some error and warning messages are also sent to console and syslogd (syslog
f43afa
  output is optional, because this service will start before syslog).
f43afa
 
f43afa
-3.7 Status files
f43afa
+3.6 Status files
f43afa
  /var/run/systemtap/<script-name>
f43afa
 
f43afa
+3.7 Dracut
f43afa
+ Files related to dracut/initramfs creation
f43afa
+
f43afa
+3.7.1 Dracut stap module directory
f43afa
+ /usr/lib/dracut/modules.d/99stap
f43afa
+
f43afa
+ These files permit SystemTap modules to be included in the initramfs.
f43afa
 
f43afa
 4. Configuration Format
f43afa
 =======================
f43afa
@@ -213,6 +251,14 @@ Configuration file allows us
f43afa
  option. You should check cache directory before enabling this option.
f43afa
  (default: no)
f43afa
 
f43afa
+4.1.12 LOG_BOOT_ERR
f43afa
+ Because boot-time scripts are run before the root filesystem is mounted,
f43afa
+ staprun's stderr cannot be logged to the LOG_FILE as usual (see 4.1.6).
f43afa
+ However, the log can instead be output to /var/run/systemtap/$script.log (which
f43afa
+ is accessible at boot-time) by setting LOG_BOOT_ERR to 'yes'. If STAT_PATH is
f43afa
+ different from the default, the log files will be moved there upon executing
f43afa
+ any of the initscript commands.
f43afa
+
f43afa
 4.2 Script Parameters
f43afa
 
f43afa
 4.2.1 <script-name>_OPT
f43afa
@@ -353,3 +399,49 @@ script2_REQ=script1
f43afa
  # vi /etc/systemtap/config
f43afa
  AUTOCOMPILE=no
f43afa
  ALLOW_CACHEONLY=yes
f43afa
+
f43afa
+5.9 Starting scripts during early-boot
f43afa
+ The initscript also allows you to start scripts earlier during the boot
f43afa
+ process by creating an initramfs containing the script's module. Your system
f43afa
+ must be dracut-based for this to work. Starting at this stage gives access to
f43afa
+ information otherwise very hard to obtain.
f43afa
+
f43afa
+5.9.1 Preparing the script
f43afa
+ As usual, place the script in /etc/systemtap/script.d and any configuration
f43afa
+ settings in /etc/systemtap/conf.d. (Note however that -o and -c are not
f43afa
+ supported).
f43afa
+
f43afa
+5.9.2 Adding to initramfs
f43afa
+ Simply run the command:
f43afa
+ # service systemtap onboot my_script
f43afa
+ If the script is not already compiled and cached, it will be done at this
f43afa
+ point.  A new initramfs will then be created at the default location. You can
f43afa
+ specify the '-b' option to make sure that your current initramfs is backed up.
f43afa
+ You can then restart your system. See 2.2.6 for more information regarding the
f43afa
+ onboot command.
f43afa
+
f43afa
+5.9.3 Adding to a different initramfs
f43afa
+ Rather than taking the spot of the default initramfs, you may want to create a
f43afa
+ different initramfs for a one-time boot. You can do this using the -o option:
f43afa
+ # service systemtap onboot -o /boot/special_initramfs.img
f43afa
+ Once the initramfs is created, you can change the command-line options at
f43afa
+ boot-time so that the new image is used rather than the usual one.
f43afa
+
f43afa
+5.9.4 Creating an initramfs for a different kernel
f43afa
+ Just like the compile command, you can use the -r option to specify the kernel
f43afa
+ for which you would like to create the initramfs. This is useful when you are
f43afa
+ about to upgrade and would like to prepare in advance. For example:
f43afa
+ # service systemtap onboot -r 3.12.6-200.fc19.x86_64 my_script
f43afa
+
f43afa
+5.9.5 Removing from initramfs
f43afa
+ To remove all scripts from the initramfs, you can run:
f43afa
+ # service systemtap onboot
f43afa
+ (That is, without any scripts explicitly mentioned). This will simply create
f43afa
+ a standard initramfs without any SystemTap modules inserted.
f43afa
+
f43afa
+5.9.6 Troubleshooting
f43afa
+ There can be many reasons for which the module didn't insert or did not work as
f43afa
+ expected. It may be useful to turn on dracut debugging by adding 'rdinitdebug' to
f43afa
+ the kernel command-line and checking dmesg/journalctl -ae. Also, you can
f43afa
+ capture the stderr output of staprun by setting LOG_BOOT_ERR to 'yes' (see
f43afa
+ 4.1.12).
f43afa
diff --git a/initscript/config.systemtap.in b/initscript/config.systemtap.in
f43afa
index 23068e1..9237b3b 100644
f43afa
--- a/initscript/config.systemtap.in
f43afa
+++ b/initscript/config.systemtap.in
f43afa
@@ -18,3 +18,6 @@
f43afa
 # Start these scripts by default. If omitted, all scripts are started.
f43afa
 # DEFAULT_START=
f43afa
 
f43afa
+# Log boot-time staprun stderr to /var/run/systemtap/$script.log
f43afa
+# LOG_BOOT_ERR=no
f43afa
+
f43afa
diff --git a/initscript/systemtap.in b/initscript/systemtap.in
f43afa
old mode 100644
f43afa
new mode 100755
f43afa
index c1c8854..5290f56
f43afa
--- a/initscript/systemtap.in
f43afa
+++ b/initscript/systemtap.in
f43afa
@@ -36,6 +36,11 @@ STAP=@bindir@/stap
f43afa
 STAPRUN=@bindir@/staprun
f43afa
 UNAME=/bin/uname
f43afa
 LSMOD=/sbin/lsmod
f43afa
+DRACUT=/sbin/dracut
f43afa
+
f43afa
+# Not actually used directly, but needed by
f43afa
+# stap dracut module for inclusion in initramfs
f43afa
+STAPIO=@libexecdir@/systemtap/stapio
f43afa
 
f43afa
 # Path setup
f43afa
 SCRIPT_PATH=@sysconfdir@/systemtap/script.d
f43afa
@@ -45,6 +50,9 @@ STAT_PATH=@localstatedir@/run/systemtap
f43afa
 TEMP_PATH=/tmp
f43afa
 LOG_FILE=@localstatedir@/log/systemtap.log
f43afa
 
f43afa
+# NB: this path is also used in 99stap/module-setup.sh
f43afa
+DRACUT_SRC=@prefix@/lib/dracut/modules.d/99stap/params.conf
f43afa
+
f43afa
 # FAIL unless all scripts succeeded to run
f43afa
 PASSALL=yes
f43afa
 
f43afa
@@ -60,6 +68,9 @@ DEFAULT_START=
f43afa
 # Allow cache only scripts
f43afa
 ALLOW_CACHEONLY=no
f43afa
 
f43afa
+# Log boot-time staprun stderr to /var/run/systemtap/$script.log
f43afa
+LOG_BOOT_ERR=no
f43afa
+
f43afa
 # Optional settings
f43afa
 CONFIG=@sysconfdir@/systemtap/config
f43afa
 SCRIPTS=
f43afa
@@ -68,14 +79,18 @@ OPT_RECURSIVE=
f43afa
 OPT_SCRIPTS=
f43afa
 OPTS=
f43afa
 OPT_ASSUMEYES=
f43afa
+INITRAMFS=
f43afa
+BACKUP_INITRAMFS=
f43afa
 
f43afa
 echo_usage () {
f43afa
-  echo $"Usage: $prog {start|stop|status|restart|compile|cleanup|condrestart|try-restart|reload|force-reload} [option]"
f43afa
+  echo $"Usage: $prog {start|stop|status|restart|compile|onboot|cleanup|condrestart|try-restart|reload|force-reload} [option]"
f43afa
   echo $"Options:"
f43afa
+  echo $"	-b		: backup initramfs before overwriting"
f43afa
   echo $"	-c configfile	: specify config file"
f43afa
+  echo $"	-o path.img	: specify initramfs output file"
f43afa
   echo $"	-r kernelrelease: specify kernel release version"
f43afa
   echo $"	-R 		: recursively dependency checking"
f43afa
-  echo $"	-y 		: answer yes for all questions."
f43afa
+  echo $"	-y 		: answer yes for all questions"
f43afa
   echo $"	script(s)	: specify systemtap scripts"
f43afa
 }
f43afa
 
f43afa
@@ -154,6 +169,13 @@ parse_args () { # arguments
f43afa
       -y)
f43afa
         OPT_ASSUMEYES=1
f43afa
         ;;
f43afa
+      -o)
f43afa
+        INITRAMFS=$2
f43afa
+        shift 1
f43afa
+        ;;
f43afa
+      -b)
f43afa
+        BACKUP_INITRAMFS=1
f43afa
+        ;;
f43afa
       --)
f43afa
         ;;
f43afa
       *)
f43afa
@@ -166,7 +188,7 @@ parse_args () { # arguments
f43afa
 
f43afa
 CMD=$1
f43afa
 shift 1
f43afa
-OPTS=`getopt -s bash -u -o 'r:c:Ry' -- $@`
f43afa
+OPTS=`getopt -s bash -u -o 'r:c:Ryo:b' -- $@`
f43afa
 if [ $? -ne 0 ]; then
f43afa
   slog "Error: Argument parse error: $@"
f43afa
   failure $"parse error"
f43afa
@@ -175,6 +197,11 @@ if [ $? -ne 0 ]; then
f43afa
 fi
f43afa
 parse_args $OPTS
f43afa
 
f43afa
+# Set default output file if not given as an option
f43afa
+if [ ! "$INITRAMFS" ]; then
f43afa
+  INITRAMFS=/boot/initramfs-$KRELEASE.img
f43afa
+fi
f43afa
+
f43afa
 # Include configs
f43afa
 . "$CONFIG"
f43afa
 
f43afa
@@ -188,7 +215,7 @@ check_bool $PASSALL
f43afa
 PASSALL=$?
f43afa
 check_bool $RECURSIVE
f43afa
 RECURSIVE=$?
f43afa
-if [ "$OPT_RECURSIVE" ]; then # -r option overrides RECURSIVE.
f43afa
+if [ "$OPT_RECURSIVE" ]; then # -R option overrides RECURSIVE.
f43afa
   RECURSIVE=1
f43afa
 fi
f43afa
 check_bool $AUTOCOMPILE
f43afa
@@ -198,6 +225,9 @@ CACHE_PATH="$CACHE_PATH/$KRELEASE"
f43afa
 check_bool $ALLOW_CACHEONLY
f43afa
 ALLOW_CACHEONLY=$?
f43afa
 
f43afa
+check_bool $LOG_BOOT_ERR
f43afa
+LOG_BOOT_ERR=$?
f43afa
+
f43afa
 __get_all_scripts () {
f43afa
   local s
f43afa
   if [ $ALLOW_CACHEONLY -eq 1 ]; then
f43afa
@@ -225,6 +255,29 @@ else
f43afa
   SCRIPTS="$OPT_SCRIPTS"
f43afa
 fi
f43afa
 
f43afa
+# Move over any pid files in /var/run/systemtap (from boot-time scripts)
f43afa
+# to the user-defined $STAT_PATH if it's different.
f43afa
+if [ "$STAT_PATH" != /var/run/systemtap ] && # XXX: use inodes instead?
f43afa
+   [ -d /var/run/systemtap ]; then
f43afa
+
f43afa
+   # Check if there's stuff to copy
f43afa
+  if [ "$(ls -A /var/run/systemtap)" ]; then
f43afa
+
f43afa
+    # Create target dir if it does not exist
f43afa
+    if [ ! -d "$STAT_PATH" ]; then
f43afa
+      logex mkdir -p "$STAT_PATH"
f43afa
+      if [ $? -ne 0 ]; then
f43afa
+        do_failure $"Failed to make stat directory ($STAT_PATH)"
f43afa
+        exit 1
f43afa
+      fi
f43afa
+    fi
f43afa
+
f43afa
+    cp /var/run/systemtap/* "$STAT_PATH"
f43afa
+  fi
f43afa
+
f43afa
+  rm -rf /var/run/systemtap
f43afa
+fi
f43afa
+
f43afa
 #------------------------------------------------------------------
f43afa
 # Main routine
f43afa
 #------------------------------------------------------------------
f43afa
@@ -328,10 +381,13 @@ get_compile_opts () { # opts
f43afa
   done
f43afa
 }
f43afa
 
f43afa
+# Returns 0 if something went wrong
f43afa
+# Returns 1 if in -L mode
f43afa
+# Returns 2 if in -D (daemon) mode
f43afa
 get_run_opts () { # normalized_opts
f43afa
   local opts o show mode
f43afa
   opts=`stap_getopt $*`
f43afa
-  [ $? -ne 0 ] && return 1
f43afa
+  [ $? -ne 0 ] && return 0
f43afa
   mode='-L'
f43afa
   show=0
f43afa
   for o in $opts; do
f43afa
@@ -351,6 +407,9 @@ get_run_opts () { # normalized_opts
f43afa
     esac
f43afa
   done
f43afa
   echo -n $mode
f43afa
+  [ "$mode" == "-L" ] && return 1
f43afa
+  [ "$mode" == "-D" ] && return 2
f43afa
+  return 0
f43afa
 }
f43afa
 
f43afa
 prepare_cache_dir () {
f43afa
@@ -457,7 +516,7 @@ sort_dependency () { # scripts
f43afa
 }
f43afa
 
f43afa
 start_script () { # script
f43afa
-  local tmpdir s=$1 ret count=0
f43afa
+  local tmpdir s=$1 ret count=0 mode
f43afa
   check_running $s
f43afa
   ret=$?
f43afa
   [ $ret -eq 0 ] && return 0 # already running
f43afa
@@ -472,7 +531,8 @@ start_script () { # script
f43afa
 
f43afa
   eval opts=\$${s}_OPT
f43afa
   opts=`get_run_opts $opts`
f43afa
-  [ $? -ne 0 ] && return 2
f43afa
+  mode=$?
f43afa
+  [ $mode -eq 0 ] && return 2
f43afa
 
f43afa
   clog " Starting $1 ... " -n
f43afa
   tmpdir=`mktemp -d -p "$TEMP_PATH" cache.XXXXXXXX`  # bz7097
f43afa
@@ -489,12 +549,14 @@ start_script () { # script
f43afa
   # used, staprun detaches from the terminal and *then* prints the new
f43afa
   # pid.  So, it is possible to check the ./pid file before it has
f43afa
   # been written.  To avoid this, wait a bit (if necessary).
f43afa
-  while [ $count -lt 10 ]; do
f43afa
-    # when the file exists and has a size > 0, quit
f43afa
-    [ -s ./pid ] && break
f43afa
-    sleep 1
f43afa
-    count=`expr $count + 1`
f43afa
-  done
f43afa
+  if [ $mode -eq 2 ]; then
f43afa
+    while [ $count -lt 10 ]; do
f43afa
+      # when the file exists and has a size > 0, quit
f43afa
+      [ -s ./pid ] && break
f43afa
+      sleep 1
f43afa
+      count=`expr $count + 1`
f43afa
+    done
f43afa
+  fi
f43afa
 
f43afa
   [ x`cat ./pid` = x ] && echo 0 > ./pid
f43afa
   if [ $ret -eq 0 ]; then
f43afa
@@ -674,6 +736,142 @@ compile () {
f43afa
   return 0
f43afa
 }
f43afa
 
f43afa
+# Writes info to $DRACUT_SRC, which the stap dracut module will source
f43afa
+# Includes all needed info such as location of stap/staprun, which
f43afa
+# scripts to insert, and their options
f43afa
+update_dracut() { # scripts
f43afa
+  local s opts
f43afa
+
f43afa
+  if [ -f "$DRACUT_SRC" ]; then
f43afa
+    rm -f "$DRACUT_SRC"
f43afa
+  fi
f43afa
+
f43afa
+  echo      "STAPRUN=\"$STAPRUN\""      >> "$DRACUT_SRC"
f43afa
+  echo       "STAPIO=\"$STAPIO\""       >> "$DRACUT_SRC"
f43afa
+  echo   "CACHE_PATH=\"$CACHE_PATH\""   >> "$DRACUT_SRC"
f43afa
+  echo    "STAT_PATH=\"$STAT_PATH\""    >> "$DRACUT_SRC"
f43afa
+  echo     "KRELEASE=\"$KRELEASE\""     >> "$DRACUT_SRC"
f43afa
+  echo "LOG_BOOT_ERR=\"$LOG_BOOT_ERR\"" >> "$DRACUT_SRC"
f43afa
+
f43afa
+  echo -n "ONBOOT_SCRIPTS=\"" >> "$DRACUT_SRC"
f43afa
+  for s in $*; do
f43afa
+    echo -n "$s " >> "$DRACUT_SRC"
f43afa
+  done
f43afa
+  echo "\"" >> "$DRACUT_SRC"
f43afa
+
f43afa
+  for s in $*; do
f43afa
+    eval opts=\$${s}_OPT
f43afa
+    opts=`get_run_opts $opts`
f43afa
+    [ $? -eq 0 ] && return 1
f43afa
+    echo -n "$s" >> "$DRACUT_SRC"
f43afa
+    echo "_OPT=\"$opts\"" >> "$DRACUT_SRC"
f43afa
+  done
f43afa
+}
f43afa
+
f43afa
+backup_initramfs() {
f43afa
+  # does target file exist?
f43afa
+  if [ -f "$INITRAMFS" ]; then
f43afa
+    # don't overwrite an existing backup
f43afa
+    if [ ! -f "$INITRAMFS.bak" ]; then
f43afa
+      mv "$INITRAMFS" "$INITRAMFS.bak"
f43afa
+      clog "Renamed $INITRAMFS"
f43afa
+      clog "     to $INITRAMFS.bak"
f43afa
+      RESTORE_INITRAMFS_ON_FAIL=1
f43afa
+    else
f43afa
+      clog "Backup already exists: $INITRAMFS.bak"
f43afa
+    fi
f43afa
+  fi
f43afa
+}
f43afa
+
f43afa
+onboot () {
f43afa
+  local s ret ss
f43afa
+  if [ ! -f "$DRACUT" ]; then
f43afa
+    clog "Could not find $DRACUT" -n
f43afa
+    do_failure "$DRACUT not found"
f43afa
+    clog
f43afa
+    clog "The system must be dracut-based to use this feature"
f43afa
+    clog "If it is located elsewhere, modify the \$DRACUT parameter" -n
f43afa
+    return 1
f43afa
+  fi
f43afa
+  if [ ! -d "$(dirname $DRACUT_SRC)" ]; then
f43afa
+    clog "Could not find dracut module" -n
f43afa
+    do_failure "SystemTap dracut module $(dirname $DRACUT_SRC) not found"
f43afa
+    return 1
f43afa
+  fi
f43afa
+  prepare_cache_dir
f43afa
+  if [ $? -ne 0 ]; then
f43afa
+    do_failure "Failed to make cache directory ($CACHE_PATH)"
f43afa
+    return 1
f43afa
+  fi
f43afa
+  # NB: we use OPT_SCRIPTS, not SCRIPTS because we want
f43afa
+  # no scripts passed to mean building a virgin initramfs
f43afa
+  for s in $OPT_SCRIPTS; do
f43afa
+    compile_script $s check
f43afa
+    ret=$?
f43afa
+    [ $ret -ne 0 ] && might_fail "Could not compile $s ($ret)"
f43afa
+    eval opts=\$${s}_OPT
f43afa
+    opts=`get_run_opts $opts`
f43afa
+    mode=$?
f43afa
+    clog " Checking options $s ... " -n
f43afa
+    [ $mode -eq 0 ] && might_fail "Bad runtime options for script $s"
f43afa
+    [ $mode -eq 2 ] && might_fail "Unsupported option -o in script $s"
f43afa
+    if [ $ret -eq 0 ] && [ $mode -eq 1 ]; then
f43afa
+      ss="$ss$s "
f43afa
+      clog "done"
f43afa
+    fi
f43afa
+  done
f43afa
+  # User specified script(s) but they were all skipped
f43afa
+  if [ -n "$OPT_SCRIPTS" ] && [ -z "$ss" ]; then
f43afa
+    do_failure "No scripts left to operate on"
f43afa
+    return 1
f43afa
+  fi
f43afa
+  if [ ! "$ss" ]; then
f43afa
+    clog " Creating initramfs without scripts ... " -n
f43afa
+  else
f43afa
+    clog " Creating initramfs with $ss... " -n
f43afa
+  fi
f43afa
+  update_dracut $ss
f43afa
+  if [ $? -ne 0 ]; then
f43afa
+    do_failure "Call to update_dracut failed. Bad opts?"
f43afa
+    return 1
f43afa
+  fi
f43afa
+  if [ "$BACKUP_INITRAMFS" ]; then
f43afa
+    backup_initramfs
f43afa
+  fi
f43afa
+  dir=`dirname $INITRAMFS` && TMPINITRAMFS=`mktemp --tmpdir=$dir`
f43afa
+  if [ $? -ne 0 ]; then
f43afa
+    do_failure "Failed to make temporary file in $dir"
f43afa
+    return 1
f43afa
+  fi
f43afa
+  out=$($DRACUT --force $TMPINITRAMFS $KRELEASE 2>&1)
f43afa
+  # dracut will report success even if some modules (e.g. stap) failed
f43afa
+  # to install some files, so we need to be a bit more involved in
f43afa
+  # checking for errors
f43afa
+  if [ $? -ne 0 ] || [[ "$out" == *ERROR* ]]; then
f43afa
+    do_failure "The initramfs creation is unsuccessful"
f43afa
+    if [ -f /var/log/dracut.log ]; then
f43afa
+      do_failure "See /var/log/dracut.log for more info"
f43afa
+    else
f43afa
+      do_failure "See dracut log for more info"
f43afa
+    fi
f43afa
+    echo # We need a new line
f43afa
+    if [ -f "$TMPINITRAMFS" ]; then
f43afa
+      rm "$TMPINITRAMFS"
f43afa
+    fi
f43afa
+    # Put back the initramfs if we moved it (if we didn't move it, then
f43afa
+    # whatever initramfs they used to boot in is still there)
f43afa
+    if [ "$RESTORE_INITRAMFS_ON_FAIL" ]; then
f43afa
+      mv "$INITRAMFS.bak" "$INITRAMFS"
f43afa
+      clog "Renamed $INITRAMFS.bak"
f43afa
+      clog "     to $INITRAMFS"
f43afa
+    fi
f43afa
+    return 1
f43afa
+  fi
f43afa
+  mv "$TMPINITRAMFS" "$INITRAMFS"
f43afa
+  might_success "initramfs created"
f43afa
+  return 0
f43afa
+}
f43afa
+
f43afa
 # Cleanup caches
f43afa
 cleanup () {
f43afa
   local s ss ret
f43afa
@@ -731,6 +929,10 @@ case $CMD in
f43afa
   compile
f43afa
   RETVAL=$?
f43afa
   ;;
f43afa
+  onboot)
f43afa
+  onboot
f43afa
+  RETVAL=$?
f43afa
+  ;;
f43afa
   cleanup)
f43afa
   cleanup
f43afa
   RETVAL=$?
f43afa
@@ -748,3 +950,5 @@ esac
f43afa
 
f43afa
 echo
f43afa
 exit $RETVAL
f43afa
+
f43afa
+# vim: sw=2 ts=8
f43afa
diff --git a/systemtap.spec b/systemtap.spec
f43afa
index 39d22ca..6cd5853 100644
f43afa
--- a/systemtap.spec
f43afa
+++ b/systemtap.spec
f43afa
@@ -32,6 +32,7 @@
f43afa
 # don't want to build runtime-virthost for f18 or RHEL5/6
f43afa
 %{!?with_virthost: %global with_virthost 0%{?fedora} >= 19 || 0%{?rhel} >= 7}
f43afa
 %{!?with_virtguest: %global with_virtguest 1}
f43afa
+%{!?with_dracut: %global with_dracut 0%{?fedora} >= 19 || 0%{?rhel} >= 7}
f43afa
 
f43afa
 %if 0%{?fedora} >= 18 || 0%{?rhel} >= 6
f43afa
    %define initdir %{_initddir}
f43afa
@@ -47,6 +48,9 @@
f43afa
    %endif
f43afa
 %endif
f43afa
 
f43afa
+%define dracutlibdir %{_prefix}/lib/dracut
f43afa
+%define dracutstap %{dracutlibdir}/modules.d/99stap
f43afa
+
f43afa
 Name: systemtap
f43afa
 Version: 2.4
f43afa
 Release: 1%{?dist}
f43afa
@@ -60,7 +64,7 @@ Release: 1%{?dist}
f43afa
 # systemtap-devel        /usr/bin/stap, runtime, tapset, req:kernel-devel
f43afa
 # systemtap-runtime      /usr/bin/staprun, /usr/bin/stapsh, /usr/bin/stapdyn
f43afa
 # systemtap-client       /usr/bin/stap, samples, docs, tapset(bonus), req:-runtime
f43afa
-# systemtap-initscript   /etc/init.d/systemtap, req:systemtap
f43afa
+# systemtap-initscript   /etc/init.d/systemtap, dracut module, req:systemtap
f43afa
 # systemtap-sdt-devel    /usr/include/sys/sdt.h /usr/bin/dtrace
f43afa
 # systemtap-testsuite    /usr/share/systemtap/testsuite*, req:systemtap, req:sdt-devel
f43afa
 # systemtap-runtime-java libHelperSDT.so, HelperSDT.jar, stapbm, req:-runtime
f43afa
@@ -245,7 +249,9 @@ Requires(preun): initscripts
f43afa
 Requires(postun): initscripts
f43afa
 
f43afa
 %description initscript
f43afa
-Sysvinit scripts to launch selected systemtap scripts at system startup.
f43afa
+This package includes a SysVinit script to launch selected systemtap
f43afa
+scripts at system startup, along with a dracut module for early
f43afa
+boot-time probing if supported.
f43afa
 
f43afa
 
f43afa
 %package sdt-devel
f43afa
@@ -545,6 +551,13 @@ done
f43afa
    %endif
f43afa
 %endif
f43afa
 
f43afa
+%if %{with_dracut}
f43afa
+   mkdir -p $RPM_BUILD_ROOT%{dracutstap}
f43afa
+   install -p -m 755 initscript/99stap/module-setup.sh $RPM_BUILD_ROOT%{dracutstap}
f43afa
+   install -p -m 755 initscript/99stap/start-staprun.sh $RPM_BUILD_ROOT%{dracutstap}
f43afa
+   touch $RPM_BUILD_ROOT%{dracutstap}/params.conf
f43afa
+%endif
f43afa
+
f43afa
 %clean
f43afa
 rm -rf ${RPM_BUILD_ROOT}
f43afa
 
f43afa
@@ -615,7 +628,7 @@ if [ $1 = 0 ] ; then
f43afa
        /bin/systemctl stop stap-server.service >/dev/null 2>&1 || :
f43afa
     %else
f43afa
         /sbin/service stap-server stop >/dev/null 2>&1
f43afa
-    	/sbin/chkconfig --del stap-server
f43afa
+        /sbin/chkconfig --del stap-server
f43afa
     %endif
f43afa
 fi
f43afa
 exit 0
f43afa
@@ -625,7 +638,7 @@ exit 0
f43afa
 # If so, restart the service if it's running
f43afa
 if [ "$1" -ge "1" ] ; then
f43afa
     %if %{with_systemd}
f43afa
-    	/bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
f43afa
+        /bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
f43afa
     %else
f43afa
         /sbin/service stap-server condrestart >/dev/null 2>&1 || :
f43afa
     %endif
f43afa
@@ -634,8 +647,7 @@ exit 0
f43afa
 
f43afa
 %post initscript
f43afa
 %if %{with_systemd}
f43afa
-    /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
f43afa
-     /bin/systemd-tmpfiles --create >/dev/null 2>&1 || :
f43afa
+    /bin/systemctl enable systemtap.service >/dev/null 2>&1 || :
f43afa
 %else
f43afa
     /sbin/chkconfig --add systemtap
f43afa
 %endif
f43afa
@@ -646,11 +658,11 @@ exit 0
f43afa
 # just removing the old package on upgrade.
f43afa
 if [ $1 = 0 ] ; then
f43afa
     %if %{with_systemd}
f43afa
-    	/bin/systemctl --no-reload disable stap-server.service >/dev/null 2>&1 || :
f43afa
-	/bin/systemctl stop stap-server.service >/dev/null 2>&1 || :
f43afa
+        /bin/systemctl --no-reload disable systemtap.service >/dev/null 2>&1 || :
f43afa
+        /bin/systemctl stop systemtap.service >/dev/null 2>&1 || :
f43afa
     %else
f43afa
         /sbin/service systemtap stop >/dev/null 2>&1
f43afa
-    	/sbin/chkconfig --del systemtap
f43afa
+        /sbin/chkconfig --del systemtap
f43afa
     %endif
f43afa
 fi
f43afa
 exit 0
f43afa
@@ -660,7 +672,7 @@ exit 0
f43afa
 # If so, restart the service if it's running
f43afa
 if [ "$1" -ge "1" ] ; then
f43afa
     %if %{with_systemd}
f43afa
-        /bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
f43afa
+        /bin/systemctl condrestart systemtap.service >/dev/null 2>&1 || :
f43afa
     %else
f43afa
         /sbin/service systemtap condrestart >/dev/null 2>&1 || :
f43afa
     %endif
f43afa
@@ -917,6 +929,10 @@ done
f43afa
 %dir %{_localstatedir}/cache/systemtap
f43afa
 %ghost %{_localstatedir}/run/systemtap
f43afa
 %doc initscript/README.systemtap
f43afa
+%if %{with_dracut}
f43afa
+   %dir %{dracutstap}
f43afa
+   %{dracutstap}/*
f43afa
+%endif
f43afa
 
f43afa
 
f43afa
 %files sdt-devel
f43afa
@@ -970,6 +986,9 @@ done
f43afa
 #   http://sourceware.org/systemtap/wiki/SystemTapReleases
f43afa
 
f43afa
 %changelog
f43afa
+* Mon Jan 06 2014 Jonathan Lebon <jlebon@redhat.com>
f43afa
+- Added dracut module to initscript package
f43afa
+
f43afa
 * Wed Nov 06 2013 Frank Ch. Eigler <fche@redhat.com> - 2.4-1
f43afa
 - Upstream release.
f43afa
 
f43afa
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
f43afa
index 05491f3..d0f90ea 100644
f43afa
--- a/tapset-utrace.cxx
f43afa
+++ b/tapset-utrace.cxx
f43afa
@@ -700,15 +700,6 @@ struct utrace_builder: public derived_probe_builder
f43afa
         sess.unwindsym_modules.insert (path);
f43afa
         path_tgt = path_remove_sysroot(sess, path);
f43afa
       }
f43afa
-    else if (has_pid)
f43afa
-      {
f43afa
-	// We can't probe 'init' (pid 1).  XXX: where does this limitation come from?
f43afa
-	if (pid < 2)
f43afa
-	  throw SEMANTIC_ERROR (_("process pid must be greater than 1"),
f43afa
-				location->components.front()->tok);
f43afa
-
f43afa
-        // XXX: could we use /proc/$pid/exe in unwindsym_modules and elsewhere?
f43afa
-      }
f43afa
 
f43afa
     finished_results.push_back(new utrace_derived_probe(sess, base, location,
f43afa
 							has_path, path_tgt, pid,
f43afa
-- 
f43afa
1.8.3.1
f43afa