diff --git a/SOURCES/rhbz1020207.patch b/SOURCES/rhbz1020207.patch
new file mode 100644
index 0000000..54489d3
--- /dev/null
+++ b/SOURCES/rhbz1020207.patch
@@ -0,0 +1,87 @@
+From 9b1d74f9a9d606f1e483690afae0a4a8207c76db Mon Sep 17 00:00:00 2001
+From: David Smith <dsmith@redhat.com>
+Date: Fri, 7 Feb 2014 10:27:14 -0600
+Subject: [PATCH] Remove the transport's unused "dropped" file.
+
+* runtime/transport/relay_v2.c: Unless _STP_USE_DROPPED_FILE is defined,
+  don't bother creating the unused "dropped" file.
+---
+ runtime/transport/relay_v2.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/runtime/transport/relay_v2.c b/runtime/transport/relay_v2.c
+index 6c9815d..97e02f9 100644
+--- a/runtime/transport/relay_v2.c
++++ b/runtime/transport/relay_v2.c
+@@ -43,8 +43,10 @@
+ struct _stp_relay_data_type {
+ 	struct rchan *rchan;
+ 	atomic_t /* enum _stp_transport_state */ transport_state;
++#ifdef _STP_USE_DROPPED_FILE
+ 	struct dentry *dropped_file;
+ 	atomic_t dropped;
++#endif
+ 	atomic_t wakeup;
+ 	struct timer_list timer;
+ 	int overwrite_flag;
+@@ -160,6 +162,7 @@ static void _stp_transport_data_fs_overwrite(int overwrite)
+ 	_stp_relay_data.overwrite_flag = overwrite;
+ }
+ 
++#ifdef _STP_USE_DROPPED_FILE
+ static int __stp_relay_dropped_open(struct inode *inode, struct file *filp)
+ {
+ 	return 0;
+@@ -181,6 +184,7 @@ static struct file_operations __stp_relay_dropped_fops = {
+ 	.open =		__stp_relay_dropped_open,
+ 	.read =		__stp_relay_dropped_read,
+ };
++#endif
+ 
+ /*
+  * Keep track of how many times we encountered a full subbuffer, to aid
+@@ -193,7 +197,9 @@ static int __stp_relay_subbuf_start_callback(struct rchan_buf *buf,
+ 	if (_stp_relay_data.overwrite_flag || !relay_buf_full(buf))
+ 		return 1;
+ 
++#ifdef _STP_USE_DROPPED_FILE
+ 	atomic_inc(&_stp_relay_data.dropped);
++#endif
+ 	return 0;
+ }
+ 
+@@ -270,8 +276,10 @@ static void _stp_transport_data_fs_stop(void)
+ static void _stp_transport_data_fs_close(void)
+ {
+ 	_stp_transport_data_fs_stop();
++#ifdef _STP_USE_DROPPED_FILE
+ 	if (_stp_relay_data.dropped_file)
+ 		debugfs_remove(_stp_relay_data.dropped_file);
++#endif
+ 	if (_stp_relay_data.rchan) {
+ 		relay_close(_stp_relay_data.rchan);
+ 		_stp_relay_data.rchan = NULL;
+@@ -286,9 +294,11 @@ static int _stp_transport_data_fs_init(void)
+ 
+ 	atomic_set(&_stp_relay_data.transport_state, STP_TRANSPORT_STOPPED);
+ 	_stp_relay_data.overwrite_flag = 0;
++	_stp_relay_data.rchan = NULL;
++
++#ifdef _STP_USE_DROPPED_FILE
+ 	atomic_set(&_stp_relay_data.dropped, 0);
+ 	_stp_relay_data.dropped_file = NULL;
+-	_stp_relay_data.rchan = NULL;
+ 
+ 	/* Create "dropped" file. */
+ 	_stp_relay_data.dropped_file
+@@ -306,6 +316,7 @@ static int _stp_transport_data_fs_init(void)
+ 
+ 	_stp_relay_data.dropped_file->d_inode->i_uid = KUIDT_INIT(_stp_uid);
+ 	_stp_relay_data.dropped_file->d_inode->i_gid = KGIDT_INIT(_stp_gid);
++#endif
+ 
+ 	/* Create "trace" file. */
+ 	npages = _stp_subbuf_size * _stp_nsubbufs;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1035752.patch b/SOURCES/rhbz1035752.patch
new file mode 100644
index 0000000..4d06bad
--- /dev/null
+++ b/SOURCES/rhbz1035752.patch
@@ -0,0 +1,108 @@
+From 735972b4c681efeff3c4137816cb913174a839be Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Mon, 2 Dec 2013 11:17:05 -0500
+Subject: [PATCH 1/2] Resolves: #1035752
+
+Upstream commit e7d52b3.
+---
+ csclient.cxx     |  2 +-
+ stap-serverd.cxx | 34 ++++++++++++++++++----------------
+ 2 files changed, 19 insertions(+), 17 deletions(-)
+
+diff --git a/csclient.cxx b/csclient.cxx
+index cce5428..4cfeb08 100644
+--- a/csclient.cxx
++++ b/csclient.cxx
+@@ -829,7 +829,7 @@ compile_server_client::passes_0_4 ()
+            << TIMESPRINT
+            << endl;
+     }
+-  if (rc)
++  if (rc && !s.listing_mode)
+     {
+       clog << _("Passes: via server failed.  Try again with another '-v' option.") << endl;
+     }
+diff --git a/stap-serverd.cxx b/stap-serverd.cxx
+index 53a8d3a..035d06c 100644
+--- a/stap-serverd.cxx
++++ b/stap-serverd.cxx
+@@ -63,7 +63,7 @@ extern "C" {
+ using namespace std;
+ 
+ static void cleanup ();
+-static PRStatus spawn_and_wait (const vector<string> &argv,
++static PRStatus spawn_and_wait (const vector<string> &argv, int *result,
+                                 const char* fd0, const char* fd1, const char* fd2,
+ 				const char *pwd, const vector<string>& envVec = vector<string> ());
+ 
+@@ -1234,18 +1234,19 @@ handleRequest (const string &requestDirName, const string &responseDirName, stri
+   get_stap_locale (staplang, envVec, stapstderr, &client_version);
+ 
+   /* All ready, let's run the translator! */
+-  rc = spawn_and_wait(stapargv, "/dev/null", stapstdout.c_str (), stapstderr.c_str (),
+-		      requestDirName.c_str (), envVec);
++  int staprc;
++  rc = spawn_and_wait(stapargv, &staprc, "/dev/null", stapstdout.c_str (),
++                      stapstderr.c_str (), requestDirName.c_str (), envVec);
++  if (rc != PR_SUCCESS)
++    {
++      server_error(_("Failed spawning translator"));
++      return;
++    }
+ 
+   /* Save the RC */
+-  string staprc = responseDirName + "/rc";
+-  f = fopen(staprc.c_str (), "w");
+-  if (f) 
+-    {
+-      /* best effort basis */
+-      fprintf(f, "%d", rc);
+-      fclose(f);
+-    }
++  ofstream ofs((responseDirName + "/rc").c_str());
++  ofs << staprc;
++  ofs.close();
+ 
+   // In unprivileged modes, if we have a module built, we need to sign the sucker.
+   privilege_t privilege = getRequestedPrivilege (stapargv);
+@@ -1316,7 +1317,7 @@ handleRequest (const string &requestDirName, const string &responseDirName, stri
+ /* A front end for stap_spawn that handles stdin, stdout, stderr, switches to a working
+    directory and returns overall success or failure. */
+ static PRStatus
+-spawn_and_wait (const vector<string> &argv,
++spawn_and_wait (const vector<string> &argv, int *spawnrc,
+ 		const char* fd0, const char* fd1, const char* fd2,
+ 		const char *pwd, const vector<string>& envVec)
+ { 
+@@ -1380,8 +1381,8 @@ spawn_and_wait (const vector<string> &argv,
+       return PR_FAILURE;
+     }
+ 
+-  rc = stap_waitpid (0, pid);
+-  if (rc == -1)
++  *spawnrc = stap_waitpid (0, pid);
++  if (*spawnrc == -1)
+     {
+       server_error (_("Error in waitpid"));
+       return PR_FAILURE;
+@@ -1540,14 +1541,15 @@ handle_connection (void *arg)
+   handleRequest(requestDirName, responseDirName, stapstderr);
+ 
+   /* Zip the response. */
++  int ziprc;
+   argv.clear ();
+   argv.push_back ("zip");
+   argv.push_back ("-q");
+   argv.push_back ("-r");
+   argv.push_back (responseFileName);
+   argv.push_back (".");
+-  rc = spawn_and_wait (argv, NULL, NULL, NULL, responseDirName);
+-  if (rc != PR_SUCCESS)
++  rc = spawn_and_wait (argv, &ziprc, NULL, NULL, NULL, responseDirName);
++  if (rc != PR_SUCCESS || ziprc != 0)
+     {
+       server_error (_("Unable to compress server response"));
+       goto cleanup;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1035850.patch b/SOURCES/rhbz1035850.patch
new file mode 100644
index 0000000..a56047a
--- /dev/null
+++ b/SOURCES/rhbz1035850.patch
@@ -0,0 +1,122 @@
+From 10632b637aa12614e36ef83c7762bd44bef80716 Mon Sep 17 00:00:00 2001
+From: David Smith <dsmith@redhat.com>
+Date: Tue, 3 Dec 2013 10:52:37 -0600
+Subject: [PATCH 2/2] Resolves: #1035850
+
+Upstream commit f112949.
+---
+ testsuite/systemtap.examples/process/pfiles.stp | 54 +++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+diff --git a/testsuite/systemtap.examples/process/pfiles.stp b/testsuite/systemtap.examples/process/pfiles.stp
+index 6f5a834..b2bdbd8 100755
+--- a/testsuite/systemtap.examples/process/pfiles.stp
++++ b/testsuite/systemtap.examples/process/pfiles.stp
+@@ -77,6 +77,10 @@
+ #include <net/sock.h>
+ #include <linux/un.h>
+ #include <linux/tcp.h>
++#ifdef CONFIG_USER_NS
++#include <linux/user_namespace.h>
++#include <linux/uidgid.h>
++#endif
+ %}
+ 
+ function task_valid_file_handle:long (task:long, fd:long) %{ /* pure */
+@@ -199,6 +203,9 @@ function task_file_handle_uid:long (task:long, fd:long) %{ /* pure */
+ 	struct task_struct *p = (struct task_struct *)((long)STAP_ARG_task);
+ 	struct files_struct *files;
+ 	struct file *filp;
++#ifdef CONFIG_USER_NS
++	struct user_namespace *ns = NULL;
++#endif
+ 
+ 	rcu_read_lock();
+ 	if ((files = kread(&p->files)) &&
+@@ -207,7 +214,25 @@ function task_file_handle_uid:long (task:long, fd:long) %{ /* pure */
+ 		/* git commit d76b0d9b */
+ 		const struct cred *cred;
+ 		if ((cred = kread(&filp->f_cred))) {
++#ifdef CONFIG_USER_NS
++			ns = get_user_ns(task_cred_xxx(p, user_ns));
++			if (ns) {
++				// We call kderef_buffer() here to
++				// ensure the memory at the kuid_t
++				// location is valid to read. We can't
++				// use kderef()/kread(), since they
++				// only handle data with a size of 1,
++				// 2, 4, or 8 bytes.
++				kderef_buffer(NULL,  &cred->fsuid,
++					      sizeof(kuid_t));
++				STAP_RETVALUE = from_kuid(ns, cred->fsuid);
++			}
++			else
++				STAP_RETVALUE = -1;
++
++#else	/* ! CONFIG_USER_NS */
+ 			STAP_RETVALUE = kread(&cred->fsuid);
++#endif	/* ! CONFIG_USER_NS */
+ 		}
+ #else
+ 		STAP_RETVALUE = kread(&filp->f_uid);
+@@ -215,6 +240,10 @@ function task_file_handle_uid:long (task:long, fd:long) %{ /* pure */
+ 	}
+ 
+ 	CATCH_DEREF_FAULT();
++#ifdef CONFIG_USER_NS
++	if (ns)
++		put_user_ns(ns);
++#endif
+ 	rcu_read_unlock();
+ %}
+ 
+@@ -222,6 +251,9 @@ function task_file_handle_gid:long (task:long, fd:long) %{ /* pure */
+ 	struct task_struct *p = (struct task_struct *)((long)STAP_ARG_task);
+ 	struct files_struct *files;
+ 	struct file *filp;
++#ifdef CONFIG_USER_NS
++	struct user_namespace *ns = NULL;
++#endif
+ 
+ 	rcu_read_lock();
+ 	if ((files = kread(&p->files)) &&
+@@ -230,7 +262,25 @@ function task_file_handle_gid:long (task:long, fd:long) %{ /* pure */
+ 		/* git commit d76b0d9b */
+ 		const struct cred *cred;
+ 		if ((cred = kread(&filp->f_cred))) {
++#ifdef CONFIG_USER_NS
++			ns = get_user_ns(task_cred_xxx(p, user_ns));
++			if (ns) {
++				// We call kderef_buffer() here to
++				// ensure the memory at the kgid_t
++				// location is valid to read. We can't
++				// use kderef()/kread(), since they
++				// only handle data with a size of 1,
++				// 2, 4, or 8 bytes.
++				kderef_buffer(NULL,  &cred->fsgid,
++					      sizeof(kgid_t));
++				STAP_RETVALUE = from_kgid(ns, cred->fsgid);
++			}
++			else
++				STAP_RETVALUE = -1;
++
++#else	/* ! CONFIG_USER_NS */
+ 			STAP_RETVALUE = kread(&cred->fsgid);
++#endif	/* ! CONFIG_USER_NS */
+ 		}
+ #else
+ 		STAP_RETVALUE = kread(&filp->f_gid);
+@@ -238,6 +288,10 @@ function task_file_handle_gid:long (task:long, fd:long) %{ /* pure */
+ 	}
+ 
+ 	CATCH_DEREF_FAULT();
++#ifdef CONFIG_USER_NS
++	if (ns)
++		put_user_ns(ns);
++#endif
+ 	rcu_read_unlock();
+ %}
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1044429.patch b/SOURCES/rhbz1044429.patch
new file mode 100644
index 0000000..910b98d
--- /dev/null
+++ b/SOURCES/rhbz1044429.patch
@@ -0,0 +1,1278 @@
+From 94b9fcc03560b36932405727759a5621966cd212 Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Fri, 13 Dec 2013 16:37:57 -0500
+Subject: BZ1044429: fix client.exp and improve client/server
+
+---
+ csclient.cxx                                      | 342 ++++++++++++----------
+ csclient.h                                        |   4 +-
+ nsscommon.cxx                                     |  11 +-
+ testsuite/lib/systemtap.exp                       |   1 +
+ testsuite/systemtap.server/client.exp             | 333 ++++++++++-----------
+ testsuite/systemtap.server/server_args.exp        |  17 +-
+ testsuite/systemtap.server/server_concurrency.exp |   4 +-
+ 7 files changed, 373 insertions(+), 339 deletions(-)
+
+diff --git a/csclient.cxx b/csclient.cxx
+index cce5428..568cc8f 100644
+--- a/csclient.cxx
++++ b/csclient.cxx
+@@ -1,6 +1,6 @@
+ /*
+  Compile server client functions
+- Copyright (C) 2010-2013 Red Hat Inc.
++ Copyright (C) 2010-2014 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
+@@ -88,66 +88,71 @@ nsscommon_error (const char *msg, int logit __attribute ((unused)))
+ // Information about compile servers.
+ struct compile_server_info
+ {
+-  compile_server_info ()
++  compile_server_info () : port(0), fully_specified(false)
+   {
+     memset (& address, 0, sizeof (address));
+   }
+ 
+   string host_name;
+   PRNetAddr address;
++  unsigned short port;
++  bool fully_specified;
+   string version;
+   string sysinfo;
+   string certinfo;
+ 
+   bool empty () const
+   {
+-    return this->host_name.empty () && ! this->hasAddress ();
++    return this->host_name.empty () && ! this->hasAddress () && certinfo.empty ();
+   }
+   bool hasAddress () const
+   {
+     return this->address.raw.family != 0;
+   }
+-  unsigned short port () const
+-  {
+-    if (this->address.raw.family == PR_AF_INET)
+-      return ntohs (this->address.inet.port);
+-    if (this->address.raw.family == PR_AF_INET6)
+-      return ntohs (this->address.ipv6.port);
+-    return 0;
+-  }
+-  unsigned short setPort (unsigned short port)
++  unsigned short setAddressPort (unsigned short port)
+   {
+     if (this->address.raw.family == PR_AF_INET)
+       return this->address.inet.port = htons (port);
+     if (this->address.raw.family == PR_AF_INET6)
+       return this->address.ipv6.port = htons (port);
++    assert (0);
+     return 0;
+   }
++  bool isComplete () const
++  {
++    return this->hasAddress () && port != 0;
++  }
+ 
+   bool operator== (const compile_server_info &that) const
+   {
+-    // If both ip addressed are not set, then the host names must match, otherwise
+-    // the addresses must match.
+-    if (! this->hasAddress() || ! that.hasAddress())
++    // If one item or the other has only a name, and possibly a port specified,
++    // then allow a match by name and port only. This is so that the user can specify
++    // names which are returned by avahi, but are not dns resolvable.
++    // Otherwise, we will ignore the host_name.
++    if ((! this->hasAddress() && this->version.empty () &&
++	 this->sysinfo.empty () && this->certinfo.empty ()) ||
++	(! that.hasAddress() && that.version.empty () &&
++	 that.sysinfo.empty () && that.certinfo.empty ()))
+       {
+ 	if (this->host_name != that.host_name)
+ 	  return false;
+       }
+-    else if (this->address != that.address)
+-      return false;
+ 
+     // Compare the other fields only if they have both been set.
+-    if (this->port() != 0 && that.port() != 0 &&
+-	this->port() != that.port())
++    if (this->hasAddress() && that.hasAddress() &&
++	this->address != that.address)
++      return false;
++    if (this->port != 0 && that.port != 0 &&
++        this->port != that.port)
+       return false;
+     if (! this->version.empty () && ! that.version.empty () &&
+-	this->version != that.version)
++        this->version != that.version)
+       return false;
+     if (! this->sysinfo.empty () && ! that.sysinfo.empty () &&
+-	this->sysinfo != that.sysinfo)
++        this->sysinfo != that.sysinfo)
+       return false;
+     if (! this->certinfo.empty () && ! that.certinfo.empty () &&
+-	this->certinfo != that.certinfo)
++        this->certinfo != that.certinfo)
+       return false;
+ 
+     return true; // They are equal
+@@ -179,6 +184,14 @@ preferred_order (vector<compile_server_info> &servers)
+   sort (servers.begin (), servers.end ());
+ }
+ 
++struct resolved_host
++{
++  string host_name;
++  PRNetAddr address;
++  resolved_host(string chost_name, PRNetAddr caddress):
++    host_name(chost_name), address(caddress) {}
++};
++
+ struct compile_server_cache
+ {
+   vector<compile_server_info> default_servers;
+@@ -187,7 +200,7 @@ struct compile_server_cache
+   vector<compile_server_info> signing_servers;
+   vector<compile_server_info> online_servers;
+   vector<compile_server_info> all_servers;
+-  map<string,vector<compile_server_info> > resolved_servers;
++  map<string,vector<resolved_host> > resolved_hosts;
+ };
+ 
+ // For filtering queries.
+@@ -234,7 +247,7 @@ static void resolve_host (systemtap_session& s, compile_server_info &server, vec
+ // -----------------------------------------------------
+ // NSS related code used by the compile server client
+ // -----------------------------------------------------
+-static void add_server_trust (systemtap_session &s, const string &cert_db_path, const vector<compile_server_info> &server_list);
++static void add_server_trust (systemtap_session &s, const string &cert_db_path, vector<compile_server_info> &server_list);
+ static void revoke_server_trust (systemtap_session &s, const string &cert_db_path, const vector<compile_server_info> &server_list);
+ static void get_server_info_from_db (systemtap_session &s, vector<compile_server_info> &servers, const string &cert_db_path);
+ 
+@@ -1132,10 +1145,10 @@ compile_server_client::find_and_connect_to_server ()
+        i != specified_servers.end ();
+        ++i)
+     {
+-      // If we have an ip address and port number, then just use the one we've
+-      // been given. Otherwise, check for matching online servers and try their
++      // If we have an ip address and were given a port number, then just use the one we've
++      // been given. Otherwise, check for matching compatible online servers and try their
+       // ip addresses and ports.
+-      if (i->hasAddress() && i->port() != 0)
++      if (i->hasAddress() && i->fully_specified)
+ 	add_server_info (*i, server_list);
+       else
+ 	{
+@@ -1145,8 +1158,8 @@ compile_server_client::find_and_connect_to_server ()
+ 
+ 	  // If no specific server (port) has been specified,
+ 	  // then we'll need the servers to be
+-	  // compatible and possible trusted as signers as well.
+-	  if (i->port() == 0)
++	  // compatible and possibly trusted as signers as well.
++	  if (! i->fully_specified)
+ 	    {
+ 	      get_or_keep_compatible_server_info (s, online_servers, true/*keep*/);
+ 	      if (! pr_contains (s.privilege, pr_stapdev))
+@@ -1227,7 +1240,7 @@ compile_server_client::find_and_connect_to_server ()
+ 
+ int 
+ compile_server_client::compile_using_server (
+-  const vector<compile_server_info> &servers
++  vector<compile_server_info> &servers
+ )
+ {
+   // Make sure NSPR is initialized. Must be done before NSS is initialized
+@@ -1275,14 +1288,16 @@ compile_server_client::compile_using_server (
+       server_zipfile = s.tmpdir + "/server.zip";
+ 
+       // Try each server in turn.
+-      for (vector<compile_server_info>::const_iterator j = servers.begin ();
++      for (vector<compile_server_info>::iterator j = servers.begin ();
+ 	   j != servers.end ();
+ 	   ++j)
+ 	{
+ 	  // At a minimum we need an ip_address along with a port
+ 	  // number in order to contact the server.
+-	  if (! j->hasAddress() || j->port() == 0)
++	  if (! j->hasAddress() || j->port == 0)
+ 	    continue;
++	  // Set the port within the address.
++	  j->setAddressPort (j->port);
+ 
+ 	  if (s.verbose >= 2)
+            clog << _F("Attempting SSL connection with %s\n"
+@@ -1673,7 +1688,7 @@ static void
+ add_server_trust (
+   systemtap_session &s,
+   const string &cert_db_path,
+-  const vector<compile_server_info> &server_list
++  vector<compile_server_info> &server_list
+ )
+ {
+   // Get a list of servers already trusted. This opens the database, so do it
+@@ -1716,7 +1731,7 @@ add_server_trust (
+   // Iterate over the servers to become trusted. Contact each one and
+   // add it to the list of trusted servers if it is not already trusted.
+   // client_connect will issue any error messages.
+-  for (vector<compile_server_info>::const_iterator server = server_list.begin();
++  for (vector<compile_server_info>::iterator server = server_list.begin();
+        server != server_list.end ();
+        ++server)
+     {
+@@ -1735,10 +1750,14 @@ add_server_trust (
+ 	    trust_already_in_place (*server, server_list, cert_db_path, false/*revoking*/);
+ 	  continue;
+ 	}
++
+       // At a minimum we need an ip_address along with a port
+       // number in order to contact the server.
+-      if (! server->hasAddress() || server->port() == 0)
++      if (! server->hasAddress() || server->port == 0)
+ 	continue;
++      // Set the port within the address.
++      server->setAddressPort (server->port);
++
+       int rc = client_connect (*server, NULL, NULL, "permanent");
+       if (rc != SUCCESS)
+ 	{
+@@ -2076,8 +2095,8 @@ ostream &operator<< (ostream &s, const compile_server_info &i)
+   else
+     s << "offline";
+   s << " port=";
+-  if (i.port() != 0)
+-    s << i.port();
++  if (i.port != 0)
++    s << i.port;
+   else
+     s << "unknown";
+   s << " sysinfo=\"";
+@@ -2586,7 +2605,8 @@ isPort (const char *pstr, compile_server_info &server_info)
+       clog << _F("Invalid port number specified: %s", pstr) << endl;
+       return false;
+     }
+-  server_info.setPort (p);
++  server_info.port = p;
++  server_info.fully_specified = true;
+   return true;
+ }
+ 
+@@ -2665,8 +2685,10 @@ isIPv6 (const string &server, compile_server_info &server_info)
+   if (! empty && components.size() != 8)
+     return false; // Not a valid IPv6 address
+ 
+-  // Calls to setPort and isPort need to know that this is an IPv6 address.
+-  server_info.address.raw.family = PR_AF_INET6;
++  // Try to convert the string to an address.
++  PRStatus prStatus = PR_StringToNetAddr (ip.c_str(), & server_info.address);
++  if (prStatus != PR_SUCCESS)
++    return false;
+ 
+   // Examine the optional port
+   if (portIx != string::npos)
+@@ -2683,10 +2705,8 @@ isIPv6 (const string &server, compile_server_info &server_info)
+ 	}
+     }
+   else
+-    server_info.setPort (0);
++    server_info.port = 0;
+ 
+-  // Treat the ip address string like a host name.
+-  server_info.host_name = ip;
+   return true; // valid IPv6 address.
+ }
+ 
+@@ -2703,20 +2723,20 @@ isIPv4 (const string &server, compile_server_info &server_info)
+   if (components.size() > 2)
+     return false; // Not a valid IPv4 address
+ 
+-  // Separate the host from the port (if any).
+-  string host;
++  // Separate the address from the port (if any).
++  string addr;
+   string port;
+   if (components.size() <= 1)
+-    host = server;
++    addr = server;
+   else {
+-    host = components[0];
++    addr = components[0];
+     port = components[1];
+   }
+ 
+-  // Separate the host components.
++  // Separate the address components.
+   // There must be exactly 4 components.
+   components.clear ();
+-  tokenize (server, components, ".");
++  tokenize (addr, components, ".");
+   if (components.size() != 4)
+     return false; // Not a valid IPv4 address
+   
+@@ -2732,8 +2752,10 @@ isIPv4 (const string &server, compile_server_info &server_info)
+ 	return false; // Not a valid IPv4 address
+     }
+ 
+-  // Calls to setPort and isPort need to know that this is an IPv4 address.
+-  server_info.address.raw.family = PR_AF_INET;
++  // Try to convert the string to an address.
++  PRStatus prStatus = PR_StringToNetAddr (addr.c_str(), & server_info.address);
++  if (prStatus != PR_SUCCESS)
++    return false;
+ 
+   // Examine the optional port
+   if (! port.empty ()) {
+@@ -2741,10 +2763,8 @@ isIPv4 (const string &server, compile_server_info &server_info)
+       return false; // not a valid port
+   }
+   else
+-    server_info.setPort (0);
++    server_info.port = 0;
+ 
+-  // Treat the ip address string like a host name.
+-  server_info.host_name = host;
+   return true; // valid IPv4 address.
+ }
+ 
+@@ -2754,8 +2774,6 @@ isCertSerialNumber (const string &server, compile_server_info &server_info)
+   // This function assumes that we have already ruled out the server spec being an IPv6 address.
+   // Certificate serial numbers are 5 fields separated by colons plus an optional 6th decimal
+   // field specifying a port.
+-  // Assume IPv4 (for now) when storing the port.
+-  server_info.address.raw.family = PR_AF_INET;
+   assert (! server.empty());
+   string host = server;
+   vector<string> components;
+@@ -2782,8 +2800,6 @@ isDomain (const string &server, compile_server_info &server_info)
+ {
+   // Accept one or two components separated by a colon. The first will be the domain name and
+   // the second must a port number.
+-  // Assume IPv4 (for now) when storing the port.
+-  server_info.address.raw.family = PR_AF_INET;
+   assert (! server.empty());
+   string host = server;
+   vector<string> components;
+@@ -2858,50 +2874,69 @@ get_specified_server_info (
+ 	      // Check for IPv6 addresses first. It reduces the amount of checking necessary for
+ 	      // certificate serial numbers.
+ 	      compile_server_info server_info;
+-	      vector<compile_server_info> known_servers;
++	      vector<compile_server_info> resolved_servers;
+ 	      if (isIPv6 (server, server_info) || isIPv4 (server, server_info) ||
+-		  isDomain (server, server_info))
++		  isCertSerialNumber (server, server_info))
+ 		{
+-		  // Resolve this host and add any information that is discovered.
+-		  // Try to augment the resolved servers with information about known servers.
+-		  // There may be no intersection.
+-		  get_all_server_info (s, known_servers);
+-
+-		  vector<compile_server_info> resolved_servers;
++		  // An address or cert serial number has been specified.
++		  // No resolution is needed.
++		  resolved_servers.push_back (server_info);
++		}		  
++	      else if (isDomain (server, server_info))
++		{
++		  // Try to resolve the given name.
+ 		  resolve_host (s, server_info, resolved_servers);
+-
+-		  vector<compile_server_info> common_servers = resolved_servers;
+-		  keep_common_server_info (known_servers, common_servers);
+-		  if (! common_servers.empty ())
+-		    add_server_info (common_servers, resolved_servers);
+-
+-		  if (s.verbose >= 3)
+-		    {
+-		      clog << _F("Servers matching %s: ", server.c_str()) << endl;
+-		      clog << resolved_servers;
+-		    }
+-		  add_server_info (resolved_servers, specified_servers);
+-		}
+-	      else if (isCertSerialNumber (server, server_info))
+-		{
+-		  // The host could not be resolved. Try resolving it as a certificate serial
+-		  // number. Look for all known servers with this serial number and (optional)
+-		  // port number.
+-		  get_all_server_info (s, known_servers);
+-		  keep_server_info_with_cert_and_port (s, server_info, known_servers);
+-		  if (s.verbose >= 3)
+-		    {
+-		      clog << _F("Servers matching %s: ", server.c_str()) << endl;
+-		      clog << known_servers;
+-		    }
+-
+-		  add_server_info (known_servers, specified_servers);
+ 		}
+ 	      else
+ 		{
+ 		  clog << _F("Invalid server specification for --use-server: %s", server.c_str())
+ 		       << endl;
++		  continue;
+ 		}
++
++	      // Now examine the server(s) identified and add them to the list of specified
++	      // servers.
++	      vector<compile_server_info> known_servers;
++	      vector<compile_server_info> new_servers;
++	      for (vector<compile_server_info>::iterator i = resolved_servers.begin();
++		   i != resolved_servers.end();
++		   ++i)
++		{
++		  // If this item was fully specified, then just add it.
++		  if (i->fully_specified)
++		    add_server_info (*i, new_servers);
++		  else {
++		    // It was not fully specified, so we need additional info. Try
++		    // to get it by matching what we have against other known servers.
++		    if (known_servers.empty ())
++		      get_all_server_info (s, known_servers);
++
++		    // See if this server spec matches that of a known server
++		    vector<compile_server_info> matched_servers = known_servers;
++		    keep_common_server_info (*i, matched_servers);
++
++		    // If this server spec matches one or more known servers, then add the
++		    // augmented info to the specified_servers. Otherwise, if this server
++		    // spec is complete, then add it directly. Otherwise this server spec
++		    // is incomplete.
++		    if (! matched_servers.empty())
++		      add_server_info (matched_servers, new_servers);
++		    else if (i->isComplete ())
++		      add_server_info (*i, new_servers);
++		    else if (s.verbose >= 3)
++		      clog << _("Incomplete server spec: ") << *i << endl;
++		  }
++		}
++
++	      if (s.verbose >= 3)
++		{
++		  clog << _F("Servers matching %s: ", server.c_str()) << endl;
++		  clog << new_servers;
++		}
++
++	      // Add the newly identified servers to the list.
++	      if (! new_servers.empty())
++		add_server_info (new_servers, specified_servers);
+ 	    } // Loop over --use-server options
+ 	} // -- use-server specified
+ 
+@@ -3087,13 +3122,16 @@ keep_server_info_with_cert_and_port (
+ 	  continue;
+ 	}
+       if (servers[i].certinfo == server.certinfo &&
+-	  (servers[i].port() == 0 || server.port() == 0 ||
+-	   servers[i].port() == server.port()))
++	  (servers[i].port == 0 || server.port == 0 ||
++	   servers[i].port == server.port))
+ 	{
+ 	  // If the server is not online, then use the specified
+ 	  // port, if any.
+-	  if (servers[i].port() == 0)
+-	    servers[i].setPort (server.port());
++	  if (servers[i].port == 0)
++	    {
++	      servers[i].port = server.port;
++	      servers[i].fully_specified = server.fully_specified;
++	    }
+ 	  ++i;
+ 	  continue;
+ 	}
+@@ -3110,8 +3148,8 @@ resolve_host (
+   vector<compile_server_info> &resolved_servers
+ )
+ {
+-  vector<compile_server_info>& cached_servers = cscache(s)->resolved_servers[server.host_name];
+-  if (cached_servers.empty ())
++  vector<resolved_host>& cached_hosts = cscache(s)->resolved_hosts[server.host_name];
++  if (cached_hosts.empty ())
+     {
+       // The server's host_name member is a string containing either a host name or an ip address.
+       // Either is acceptable for lookup.
+@@ -3128,10 +3166,8 @@ resolve_host (
+       // Failure to resolve will result in an appropriate message later, if other methods fail.
+       if (rc != 0)
+ 	{
+-	  // At a minimum, return the information we were given.
+ 	  if (s.verbose >= 6)
+ 	    clog << _F("%s not found: %s", lookup_name, gai_strerror (rc)) << endl;
+-	  add_server_info (server, cached_servers);
+ 	}
+       else
+ 	{
+@@ -3139,28 +3175,23 @@ resolve_host (
+ 	  assert (addr_info);
+ 	  for (const struct addrinfo *ai = addr_info; ai != NULL; ai = ai->ai_next)
+ 	    {
+-	      // Start with the info we were given.
+-	      compile_server_info new_server = server;
++	      PRNetAddr new_address;
+ 
+ 	      // We support IPv4 and IPv6, Ignore other protocols,
+ 	      if (ai->ai_family == AF_INET)
+ 		{
+ 		  // IPv4 Address
+ 		  struct sockaddr_in *ip = (struct sockaddr_in *)ai->ai_addr;
+-		  new_server.address.inet.family = PR_AF_INET;
+-		  if (ip->sin_port != 0)
+-		    new_server.address.inet.port = ip->sin_port;
+-		  new_server.address.inet.ip = ip->sin_addr.s_addr;
++		  new_address.inet.family = PR_AF_INET;
++		  new_address.inet.ip = ip->sin_addr.s_addr;
+ 		}
+ 	      else if (ai->ai_family == AF_INET6)
+ 		{
+ 		  // IPv6 Address
+ 		  struct sockaddr_in6 *ip = (struct sockaddr_in6 *)ai->ai_addr;
+-		  new_server.address.ipv6.family = PR_AF_INET6;
+-		  if (ip->sin6_port != 0)
+-		    new_server.address.ipv6.port = ip->sin6_port;
+-		  new_server.address.ipv6.scope_id = ip->sin6_scope_id;
+-		  copyAddress (new_server.address.ipv6.ip, ip->sin6_addr);
++		  new_address.ipv6.family = PR_AF_INET6;
++		  new_address.ipv6.scope_id = ip->sin6_scope_id;
++		  copyAddress (new_address.ipv6.ip, ip->sin6_addr);
+ 		}
+ 	      else
+ 		continue;
+@@ -3169,25 +3200,54 @@ resolve_host (
+ 	      char hbuf[NI_MAXHOST];
+ 	      int status = getnameinfo (ai->ai_addr, ai->ai_addrlen, hbuf, sizeof (hbuf), NULL, 0,
+ 					NI_NAMEREQD | NI_IDN);
+-	      if (status == 0)
+-		new_server.host_name = hbuf;
++	      if (status != 0)
++		hbuf[0] = '\0';
+ 
+-	      // Add the new resolved server to the list.
+-	      add_server_info (new_server, cached_servers);
++	      resolved_host *new_host = new resolved_host(hbuf, new_address);
++	      cached_hosts.push_back(*new_host);
+ 	    }
+ 	}
+       if (addr_info)
+ 	freeaddrinfo (addr_info); // free the linked list
+-
+-      if (s.verbose >= 6)
+-	{
+-	  clog << _F("%s resolves to:", lookup_name) << endl;
+-	  clog << cached_servers;
+-	}
+     }
+ 
+-  // Add the information, but not duplicates.
+-  add_server_info (cached_servers, resolved_servers);
++  // If no addresses were resolved, then return the info we were given.
++  if (cached_hosts.empty())
++    add_server_info (server, resolved_servers);
++  else {
++    // We will add a new server for each address resolved
++    vector<compile_server_info> new_servers;
++    for (vector<resolved_host>::const_iterator it = cached_hosts.begin();
++	 it != cached_hosts.end(); ++it)
++      {
++	// Start with the info we were given
++	compile_server_info new_server = server;
++
++	// NB: do not overwrite port info
++	if (it->address.raw.family == AF_INET)
++	  {
++	    new_server.address.inet.family = PR_AF_INET;
++	    new_server.address.inet.ip = it->address.inet.ip;
++	  }
++	else // AF_INET6
++	  {
++	    new_server.address.ipv6.family = PR_AF_INET6;
++	    new_server.address.ipv6.scope_id = it->address.ipv6.scope_id;
++	    new_server.address.ipv6.ip = it->address.ipv6.ip;
++	  }
++	if (!it->host_name.empty())
++	  new_server.host_name = it->host_name;
++	add_server_info (new_server, new_servers);
++      }
++
++    if (s.verbose >= 6)
++      {
++	clog << _F("%s resolves to:", server.host_name.c_str()) << endl;
++	clog << new_servers;
++      }
++
++    add_server_info (new_servers, resolved_servers);
++  }
+ }
+ 
+ #if HAVE_AVAHI
+@@ -3268,12 +3328,12 @@ void resolve_callback(
+ 	    // We support both IPv4 and IPv6. Ignore other protocols.
+ 	    if (protocol == AVAHI_PROTO_INET6) {
+ 	      info.address.ipv6.family = PR_AF_INET6;
+-	      info.address.ipv6.port = htons (port);
+ 	      info.address.ipv6.scope_id = interface;
++	      info.port = port;
+ 	    }
+ 	    else if (protocol == AVAHI_PROTO_INET) {
+ 	      info.address.inet.family = PR_AF_INET;
+-	      info.address.inet.port = htons (port);
++	      info.port = port;
+ 	    }
+ 	    else
+ 	      break;
+@@ -3388,7 +3448,6 @@ get_or_keep_online_server_info (
+       online_servers.push_back (compile_server_info ());
+ #if HAVE_AVAHI
+       // Must predeclare these due to jumping on error to fail:
+-      unsigned limit;
+       vector<compile_server_info> avahi_servers;
+ 
+       // Initialize.
+@@ -3449,25 +3508,6 @@ get_or_keep_online_server_info (
+ 	  clog << avahi_servers;
+ 	}
+ 
+-      // Resolve each server discovered, in case there are alternate ways to reach them
+-      // (e.g. localhost).
+-      limit = avahi_servers.size ();
+-      for (unsigned i = 0; i < limit; ++i)
+-	{
+-	  compile_server_info &avahi_server = avahi_servers[i];
+-
+-	  // Delete the domain, if it is '.local'
+-	  string &host_name = avahi_server.host_name;
+-	  string::size_type dot_index = host_name.find ('.');
+-	  assert (dot_index != 0);
+-	  string domain = host_name.substr (dot_index + 1);
+-	  if (domain == "local")
+-	    host_name = host_name.substr (0, dot_index);
+-
+-	  // Add it to the list of servers, unless it is duplicate.
+-	  resolve_host (s, avahi_server, online_servers);
+-	}
+-
+       // Merge with the list of servers, as obtained by avahi.
+       add_server_info (avahi_servers, online_servers);
+ 
+@@ -3619,15 +3659,19 @@ merge_server_info (
+   compile_server_info &target
+ )
+ {
+-  if (target.host_name.empty ())
++  // Copy the host name if the source has one.
++  if (! source.host_name.empty())
+     target.host_name = source.host_name;
+   // Copy the address unconditionally, if the source has an address, even if they are already
+   // equal. The source address may be an IPv6 address with a scope_id that the target is missing.
+   assert (! target.hasAddress () || ! source.hasAddress () || source.address == target.address);
+   if (source.hasAddress ())
+     copyNetAddr (target.address, source.address);
+-  if (target.port() == 0)
+-    target.setPort (source.port());
++  if (target.port == 0)
++    {
++      target.port = source.port;
++      target.fully_specified = source.fully_specified;
++    }
+   if (target.sysinfo.empty ())
+     target.sysinfo = source.sysinfo;
+   if (target.version.empty ())
+diff --git a/csclient.h b/csclient.h
+index b7eeda4..e4508ea 100644
+--- a/csclient.h
++++ b/csclient.h
+@@ -1,5 +1,5 @@
+ // -*- C++ -*-
+-// Copyright (C) 2010-2011 Red Hat Inc.
++// Copyright (C) 2010-2014 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
+@@ -35,7 +35,7 @@ private:
+   );
+   int add_package_args ();
+   int add_package_arg (const std::string &arg);
+-  int compile_using_server (const std::vector<compile_server_info> &servers);
++  int compile_using_server (std::vector<compile_server_info> &servers);
+   int add_localization_variables();
+ 
+   int read_from_file (const std::string &fname, int &data);
+diff --git a/nsscommon.cxx b/nsscommon.cxx
+index 70aac54..78e38b0 100644
+--- a/nsscommon.cxx
++++ b/nsscommon.cxx
+@@ -1,7 +1,7 @@
+ /*
+   Common functions used by the NSS-aware code in systemtap.
+ 
+-  Copyright (C) 2009-2013 Red Hat Inc.
++  Copyright (C) 2009-2014 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
+@@ -998,12 +998,19 @@ gen_cert_db (const string &db_path, const string &extraDnsNames, bool use_passwo
+       goto error;
+     }
+ 
+-  // Now, generate the cert. We need our host name and the supplied additional dns names (if any).
++  // For the cert, we need our host name.
+   struct utsname utsname;
+   uname (& utsname);
+   dnsNames = utsname.nodename;
++
++  // Because avahi identifies hosts using a ".local" domain, add one to the list of names.
++  dnsNames += string(",") + dnsNames + ".local";
++
++  // Add any extra names that were supplied.
+   if (! extraDnsNames.empty ())
+     dnsNames += "," + extraDnsNames;
++
++  // Now, generate the cert.
+   cert = create_cert (cr, dnsNames);
+   CERT_DestroyCertificateRequest (cr);
+   if (! cert)
+diff --git a/testsuite/lib/systemtap.exp b/testsuite/lib/systemtap.exp
+index d4e4d85..64bbed1 100644
+--- a/testsuite/lib/systemtap.exp
++++ b/testsuite/lib/systemtap.exp
+@@ -244,6 +244,7 @@ proc setup_server { args } {
+     }
+ 
+     # Make sure that stap can find the server.
++    exec sleep 1
+     set use_server --use-server
+     set res [catch { exec stap --list-servers=online,trusted,compatible >& stap-list-servers.out } looksee]
+     verbose -log "stap --list-servers returned: res==$res"
+diff --git a/testsuite/systemtap.server/client.exp b/testsuite/systemtap.server/client.exp
+index f0d0728..41a06cc 100644
+--- a/testsuite/systemtap.server/client.exp
++++ b/testsuite/systemtap.server/client.exp
+@@ -1,3 +1,6 @@
++# In this test, we are using arrays as sets. The key itself does not matter,
++# only the value
++
+ # many of these tests use as_root
+ if {! [installtest_p]} { return }
+ if {! [nss_p]} { return }
+@@ -5,37 +8,111 @@ if {! [nss_p]} { return }
+ # Let's start with a clean slate in terms of trust.
+ exec rm -fr $env(SYSTEMTAP_DIR)/ssl
+ 
+-# Compare two arrays. If equal, return 1, otherwise 0.
+-# (Borrowed from http://wiki.tcl.tk/1032.)
+-proc array_compare {array1 array2} {
+-    upvar 1 $array1 foo $array2 bar
++# arr given as list (e.g. [array_has [array get myarr] elem])
++proc array_has {arr elem} {
+ 
+-    if {![array exists foo]} {
+-        return -code error "$array1 is not an array"
+-    }
+-    if {![array exists bar]} {
+-        return -code error "$array2 is not an array"
+-    }
+-    if {[array size foo] != [array size bar]} {
+-        return 0
+-    }
++    array set foo $arr
+     if {[array size foo] == 0} {
++        return 0
++    }
++
++    foreach {key val} [array get foo] {
++        if {[string equal $val $elem]} {
++            return 1
++        }
++    }
++
++    return 0
++}
++
++# Check if array1 is a subset of array2. Returns 1 if yes, otherwise 0.
++# (Modified from http://wiki.tcl.tk/1032.)
++proc array_in {array1 array2} {
++    upvar 1 $array1 sub $array2 super
++
++    if {![array exists sub]} {
++        return -code error "$array1 is not an array"
++    }
++    if {![array exists super]} {
++        return -code error "$array2 is not an array"
++    }
++    if {[array size sub] > [array size super]} {
++        return 0
++    }
++    if {[array size sub] == 0} {
+         return 1
+     }
+ 
+-    set keys [lsort -unique [concat [array names foo] [array names bar]]]
+-    if {[llength $keys] != [array size foo]} {
+-       return 0
+-    }
+-
+-    foreach key $keys {
+-        if {$foo($key) ne $bar($key)} {
++    foreach key [array names sub] {
++        if {![array_has [array get super] $sub($key)]} {
+             return 0
+         }
+     }
+     return 1
+ }
+ 
++# Check if array1 and array2 have all the same elements
++proc array_equal {array1 array2} {
++    upvar 1 $array1 foo $array2 bar
++    return [array_in foo bar] \
++        && [array_in bar foo]
++}
++
++# Returns the union of the three arrays
++proc array_union {array1 array2 array3} {
++    upvar 1 $array1 foo $array2 bar $array3 baz
++    array unset ::union
++
++    if {![array exists foo]} {
++        return -code error "$array1 is not an array"
++    }
++    if {![array exists bar]} {
++        return -code error "$array2 is not an array"
++    }
++    if {![array exists baz]} {
++        return -code error "$array3 is not an array"
++    }
++
++    set n 0
++    foreach key [array names foo] {
++        set ::union($n) $foo($key)
++        incr n
++    }
++    foreach key [array names bar] {
++        if {![array_has [array get ::union] $bar($key)]} {
++            set ::union($n) $bar($key)
++            incr n
++        }
++    }
++    foreach key [array names baz] {
++        if {![array_has [array get ::union] $baz($key)]} {
++            set ::union($n) $baz($key)
++            incr n
++        }
++    }
++}
++
++# Returns all the elements in array_new not in array_old
++proc array_diff {array_new array_old} {
++    upvar 1 $array_new anew $array_old aold
++    array unset ::diff
++
++    if {![array exists anew]} {
++        return -code error "$array_new is not an array"
++    }
++    if {![array exists aold]} {
++        return -code error "$array_old is not an array"
++    }
++
++    set n 0
++    foreach key [array names anew] {
++        if {![array_has [array get aold] $anew($key)]} {
++            set ::diff($n) $anew($key)
++            incr n
++        }
++    }
++}
++
+ # Test the --list-servers option and return an array of the servers found.
+ proc list_servers { TEST_NAME SERVER_SPEC args } {
+     set failed 0
+@@ -82,7 +159,6 @@ proc list_servers { TEST_NAME SERVER_SPEC args } {
+ # Sometimes, we'll see a server running from the last test, if it
+ # hasn't quite died yet. So, make sure we get the same result twice.
+ list_servers "List existing online servers" online
+-array unset eos1
+ array set existing_online_servers [array get servers]
+ set i 0
+ while {1} {
+@@ -94,9 +170,9 @@ while {1} {
+ 	fail "List existing online servers: never got stable"
+ 	return
+     }
+-    
++
+     verbose -log "verify existing online servers - attempt $i: [array size existing_online_servers] [array size eos2]"
+-    if {[array_compare existing_online_servers eos2]} {
++    if {[array_equal existing_online_servers eos2]} {
+ 	# Arrays are equal, we're done
+ 	break
+     }
+@@ -120,37 +196,23 @@ list_servers "List all existing servers" all
+ array unset all_existing_servers
+ array set all_existing_servers [array get servers]
+ 
+-set test "Verify existing online server list"
+-if {[array_compare existing_online_servers all_existing_servers]} {
+-    pass "$test"
+-} else {
+-    fail "$test"
+-}
++# First we create a union
++array_union existing_online_servers \
++            existing_trusted_servers \
++            existing_signing_servers
++array set existing_unioned_servers [array get union]
+ 
+-set test "Verify existing trusted server list"
+-if {[array_compare existing_trusted_servers all_existing_servers]} {
+-    pass "$test"
+-} else {
+-    fail "$test"
+-}
+-
+-set test "Verify existing signing server list"
+-if {[array_compare existing_signing_servers all_existing_servers]} {
+-    pass "$test"
+-} else {
+-    fail "$test"
+-}
+-
+-set test "Verify all existing server list"
+-if {[array_compare existing_online_servers all_existing_servers]} {
++# Now we can compare
++set test "Verify existing server list"
++if {[array_equal existing_unioned_servers all_existing_servers]} {
+     pass "$test"
+ } else {
+     fail "$test"
+ }
+ 
+ list_servers "List existing online servers (before start)" online
+-array unset existing_online_servers1
+-array set existing_online_servers1 [array get servers]
++array unset existing_online_servers
++array set existing_online_servers [array get servers]
+ 
+ # Now start our own server and make sure we can work with it.
+ if {! [setup_server] || $avahi_ok_p != 1} {
+@@ -159,31 +221,22 @@ if {! [setup_server] || $avahi_ok_p != 1} {
+ }
+ 
+ # Our server should now appear online, separate from the previously discovered
+-# online servers. Note that our server could generate serveral listings
+-# because it could appear at more than one ip address,
++# online servers. Note that our server could generate serveral listings because
++# it could appear at more than one ip address,
+ list_servers "List current online servers" online
+ array unset current_online_servers
+ array set current_online_servers [array get servers]
+ 
++# array_diff will give us all the servers in current not in existing
++array_diff current_online_servers existing_online_servers
++array unset new_online_servers
++array set new_online_servers [array get diff]
++
+ set test "New online servers"
+-set n 0
+-foreach idx1 [array names current_online_servers] {
+-    set found 0
+-    foreach idx2 [array names existing_online_servers] {
+-	if {"$existing_online_servers($idx2)" == "$current_online_servers($idx1)"} {
+-	    set found 1
+-	    break
+-	}
+-    }
+-    if {$found == 0} {
+-	set new_online_servers($n) "$current_online_servers($idx1)"
+-	incr n
+-    }
+-}
+-if {$n == 0} {
+-    fail "$test"
+-} else {
++if {[array size new_online_servers] > 0} {
+     pass "$test"
++} else {
++    fail "$test"
+ }
+ 
+ # Our server should now be trusted, separate from the previously discovered
+@@ -192,48 +245,27 @@ list_servers "List current trusted servers" online,trusted
+ array unset current_trusted_servers
+ array set current_trusted_servers [array get servers]
+ 
++# array_diff will give us all the servers in current not in existing
++array_diff current_trusted_servers existing_trusted_servers
++array unset new_trusted_servers
++array set new_trusted_servers [array get diff]
++
+ set test "New trusted servers"
+-set n 0
+-foreach idx1 [array names current_trusted_servers] {
+-    set found 0
+-    foreach idx2 [array names existing_trusted_servers] {
+-	if {"$existing_trusted_servers($idx2)" == "$current_trusted_servers($idx1)"} {
+-	    set found 1
+-	    break
+-	}
+-    }
+-    if {$found == 0} {
+-	set new_trusted_servers($n) "$current_trusted_servers($idx1)"
+-	incr n
+-    }
+-}
+-if {$n == 0} {
+-    fail "$test"
+-} else {
++if {[array size new_trusted_servers] > 0} {
+     pass "$test"
++} else {
++    fail "$test"
+ }
+ 
+ # The new servers should automatically be trusted, so the new_trusted_servers
+-# array should be a subset of the new_online_servers
+-# array, but not necessarilty vice-versa, since new servers may have come
+-# online independently of our testing.
++# array should be a subset of the new_online_servers array, but not necessarily
++# vice-versa, since new servers may have come online independently of our
++# testing.
+ set test "Verify new trusted server list"
+-set failed 0
+-foreach idx1 [array names new_trusted_servers] {
+-    set found 0
+-    foreach idx2 [array names new_online_servers] {
+-	if {"$new_trusted_servers($idx1)" == "$new_online_servers($idx2)"} {
+-	    set found 1
+-	    break
+-	}
+-    }
+-    if {$found == 0} {
+-	set failed 1
+-	fail "$test $idx1"
+-    }
+-}
+-if {$failed == 0} {
++if {[array_in new_trusted_servers new_online_servers]} {
+     pass "$test"
++} else {
++    fail "$test"
+ }
+ 
+ # The newly trusted servers represent the server we just started.
+@@ -247,7 +279,7 @@ array unset current_signing_servers
+ array set current_signing_servers [array get servers]
+ 
+ set test "No new signing servers"
+-if {[array_compare current_signing_servers existing_signing_servers]} {
++if {[array_equal current_signing_servers existing_signing_servers]} {
+     pass "$test"
+ } else {
+     fail "$test"
+@@ -287,7 +319,7 @@ array unset current_trusted_servers
+ array set current_trusted_servers [array get servers]
+ 
+ set test "No longer trusted after revokation by host name"
+-if {[array_compare current_trusted_servers existing_trusted_servers]} {
++if {[array_equal current_trusted_servers existing_trusted_servers]} {
+     pass "$test"
+ } else {
+     fail "$test"
+@@ -320,54 +352,24 @@ list_servers "List current trusted servers after reinstatement by ip address" on
+ array unset current_trusted_servers
+ array set current_trusted_servers [array get servers]
+ 
++array_diff current_trusted_servers existing_trusted_servers
++array unset new_trusted_servers
++array set new_trusted_servers [array get diff]
++
+ set test "New trusted servers after reinstatement by ip address"
+-array unset new_trusted_servers
+-set n 0
+-foreach idx1 [array names current_trusted_servers] {
+-    set found 0
+-    foreach idx2 [array names existing_trusted_servers] {
+-	if {"$existing_trusted_servers($idx2)" == "$current_trusted_servers($idx1)"} {
+-	    set found 1
+-	    break
+-	}
+-    }
+-    if {$found == 0} {
+-	set new_trusted_servers($n) "$current_trusted_servers($idx1)"
+-	incr n
+-    }
+-}
+-if {$n == 0} {
+-    fail "$test"
+-} else {
++if {[array size new_trusted_servers] > 0} {
+     pass "$test"
++} else {
++    fail "$test"
+ }
+ 
+ # The new_trusted_servers array should now match the our_servers array, since
+ # the our_servers array is a copy of the original new_trusted_servers array.
+-set test "Number of new trusted servers matches after reinstatement by ip address"
+-if {[array size new_trusted_servers] == [array size our_servers]} {
+-    pass "$test"
+-} else {
+-    fail "$test"
+-}
+ set test "New trusted servers matches after reinstatement by ip address"
+-set n 0
+-foreach idx1 [array names new_trusted_servers] {
+-    set found 0
+-    foreach idx2 [array names our_servers] {
+-	if {"$our_servers($idx2)" == "$new_trusted_servers($idx1)"} {
+-	    set found 1
+-	    break
+-	}
+-    }
+-    if {$found == 1} {
+-	incr n
+-    }
+-}
+-if {$n != [array size new_trusted_servers]} {
+-    fail "$test"
+-} else {
++if {[array_equal new_trusted_servers our_servers]} {
+     pass "$test"
++} else {
++    fail "$test"
+ }
+ 
+ # Trust our server as a module signer. This must be done as root. Specify
+@@ -394,28 +396,18 @@ list_servers "List current online signing servers" online,signer
+ array unset current_signing_servers
+ array set current_signing_servers [array get servers]
+ 
++array_diff current_signing_servers existing_signing_servers
++array unset new_signing_servers
++array set new_signing_servers [array get diff]
++
+ set test "New signing servers"
+-set n 0
+-foreach idx1 [array names current_signing_servers] {
+-    set found 0
+-    foreach idx2 [array names existing_signing_servers] {
+-	if {"$existing_signing_servers($idx2)" == "$current_signing_servers($idx1)"} {
+-	    set found 1
+-	    break
+-	}
+-    }
+-    if {$found == 0} {
+-	set new_signing_servers($n) "$current_signing_servers($idx1)"
+-	incr n
+-    }
+-}
+ if {$effective_pid == 0} {
+     setup_xfail *-*-*
+ }
+-if {$n == 0} {
+-    fail "$test"
+-} else {
++if {[array size new_signing_servers] > 0} {
+     pass "$test"
++} else {
++    fail "$test"
+ }
+ 
+ # The new_signing_servers array should now match the our_servers array, since
+@@ -428,26 +420,13 @@ if {$effective_pid == 0} {
+ if {[array size new_signing_servers] == [array size our_servers]} {
+     pass "$test"
+     set test "New signing servers matches"
+-    set n 0
+-    foreach idx1 [array names new_signing_servers] {
+-	set found 0
+-	foreach idx2 [array names our_servers] {
+-	    if {"$our_servers($idx2)" == "$new_signing_servers($idx1)"} {
+-		set found 1
+-		break
+-	    }
+-	}
+-	if {$found == 1} {
+-	    incr n
+-	}
+-    }
+     if {$effective_pid == 0} {
+ 	setup_xfail *-*-*
+     }
+-    if {$n != [array size new_signing_servers]} {
+-	fail "$test"
+-    } else {
++    if {[array_equal new_signing_servers our_servers]} {
+ 	pass "$test"
++    } else {
++	fail "$test"
+     }
+ } else {
+     fail "$test"
+@@ -594,7 +573,7 @@ array unset current_signing_servers
+ array set current_signing_servers [array get servers]
+ 
+ set test "No longer trusted as a signer after revokation"
+-if {[array_compare current_signing_servers existing_signing_servers]} {
++if {[array_in current_signing_servers existing_signing_servers]} {
+     pass "$test"
+ } else {
+     fail "$test"
+diff --git a/testsuite/systemtap.server/server_args.exp b/testsuite/systemtap.server/server_args.exp
+index 2f5deed..91536a5 100644
+--- a/testsuite/systemtap.server/server_args.exp
++++ b/testsuite/systemtap.server/server_args.exp
+@@ -66,20 +66,23 @@ proc stap_direct_and_with_client {stap options} {
+     verbose -log $res_stap_client
+ 
+     # Now check the output
+-    set skip 0
++    set skip_hostname_mode 0
+     set n 0
+     set expected [split $res_stap "\n"]
+     set received [split $res_stap_client "\n"]
+     foreach line $received {
+-	# Instructed to skip a line?
+-	if {$skip} {
+-	    set skip [expr $skip - 1]
+-	    verbose -log "skipping: $line"
+-	    continue
++	# Instructed to skip hostnames?
++	if {$skip_hostname_mode} {
++	    if {[regexp {^  \S+$} $line]} {
++		verbose -log "skipping: $line"
++		continue
++	    } else {
++		set skip_hostname_mode 0
++	    }
+ 	}
+ 	# Ignore warnings about the domain name on the certificate not matching
+ 	if {[regexp {^WARNING: The domain name, [^,]*, does not match the DNS name\(s\) on the server certificate:} $line]} {
+-	    set skip 1
++	    set skip_hostname_mode 1
+ 	    verbose -log "skipping: $line"
+ 	    continue
+ 	}
+diff --git a/testsuite/systemtap.server/server_concurrency.exp b/testsuite/systemtap.server/server_concurrency.exp
+index dbacb51..a31415b 100644
+--- a/testsuite/systemtap.server/server_concurrency.exp
++++ b/testsuite/systemtap.server/server_concurrency.exp
+@@ -26,7 +26,7 @@ if {! [setup_server --max-threads 6]} {
+ set server_port 0
+ set f [open $logfile]
+ set matched 0
+-verbose -log "Server ouput: "
++verbose -log "Server output: "
+ while {1} {
+     set line [gets $f]
+     if {[eof $f]} {
+@@ -34,7 +34,7 @@ while {1} {
+         break
+     }
+     verbose -log "$line"
+-    if { [regexp {^.*Using network port (\d*)$} $line matched server_port ] } {
++    if { [regexp {^.*Using network address .+:(\d+)$} $line matched server_port ] } {
+       close $f
+       break
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.2.patch b/SOURCES/rhbz1051649.2.patch
new file mode 100644
index 0000000..35bed36
--- /dev/null
+++ b/SOURCES/rhbz1051649.2.patch
@@ -0,0 +1,63 @@
+commit b728b27964bbded79d0f8c07c0bdbf6acd8fe2db
+Author: Jonathan Lebon <jlebon@redhat.com>
+Date:   Wed Jan 8 16:38:57 2014 -0500
+
+    autoreconf
+
+diff --git a/Makefile.in b/Makefile.in
+index 2c543f1..e6d03fa 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -120,8 +120,10 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ 	$(top_srcdir)/initscript/config.systemtap.in \
+ 	$(top_srcdir)/initscript/config.stap-server.in \
+ 	$(top_srcdir)/initscript/systemtap.in \
+-	$(top_srcdir)/initscript/stap-server.in $(srcdir)/run-stap.in \
+-	$(srcdir)/dtrace.in $(top_srcdir)/staprun/guest/stapshd.in \
++	$(top_srcdir)/initscript/stap-server.in \
++	$(top_srcdir)/initscript/99stap/module-setup.sh.in \
++	$(srcdir)/run-stap.in $(srcdir)/dtrace.in \
++	$(top_srcdir)/staprun/guest/stapshd.in \
+ 	$(top_srcdir)/staprun/guest/stapsh-daemon.in \
+ 	$(top_srcdir)/staprun/guest/stapsh@.service.in depcomp \
+ 	$(am__noinst_HEADERS_DIST) $(oldinclude_HEADERS)
+@@ -139,7 +141,8 @@ mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = config.h
+ CONFIG_CLEAN_FILES = includes/sys/sdt-config.h \
+ 	initscript/config.systemtap initscript/config.stap-server \
+-	initscript/systemtap initscript/stap-server run-stap dtrace \
++	initscript/systemtap initscript/stap-server \
++	initscript/99stap/module-setup.sh run-stap dtrace \
+ 	staprun/guest/stapshd staprun/guest/stapsh-daemon \
+ 	staprun/guest/stapsh@.service
+ CONFIG_CLEAN_VPATH_FILES =
+@@ -724,6 +727,8 @@ initscript/systemtap: $(top_builddir)/config.status $(top_srcdir)/initscript/sys
+ 	cd $(top_builddir) && $(SHELL) ./config.status $@
+ initscript/stap-server: $(top_builddir)/config.status $(top_srcdir)/initscript/stap-server.in
+ 	cd $(top_builddir) && $(SHELL) ./config.status $@
++initscript/99stap/module-setup.sh: $(top_builddir)/config.status $(top_srcdir)/initscript/99stap/module-setup.sh.in
++	cd $(top_builddir) && $(SHELL) ./config.status $@
+ run-stap: $(top_builddir)/config.status $(srcdir)/run-stap.in
+ 	cd $(top_builddir) && $(SHELL) ./config.status $@
+ dtrace: $(top_builddir)/config.status $(srcdir)/dtrace.in
+diff --git a/configure b/configure
+index af7c03a..69231af 100755
+--- a/configure
++++ b/configure
+@@ -11420,7 +11420,7 @@ STAP_PREFIX="$stap_prefix"
+ 
+ ac_config_headers="$ac_config_headers config.h:config.in"
+ 
+-ac_config_files="$ac_config_files Makefile doc/Makefile man/Makefile doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile man/stappaths.7 initscript/config.systemtap initscript/config.stap-server initscript/systemtap initscript/stap-server"
++ac_config_files="$ac_config_files Makefile doc/Makefile man/Makefile doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile man/stappaths.7 initscript/config.systemtap initscript/config.stap-server initscript/systemtap initscript/stap-server initscript/99stap/module-setup.sh"
+ 
+ 
+ 
+@@ -12296,6 +12296,7 @@ do
+     "initscript/config.stap-server") CONFIG_FILES="$CONFIG_FILES initscript/config.stap-server" ;;
+     "initscript/systemtap") CONFIG_FILES="$CONFIG_FILES initscript/systemtap" ;;
+     "initscript/stap-server") CONFIG_FILES="$CONFIG_FILES initscript/stap-server" ;;
++    "initscript/99stap/module-setup.sh") CONFIG_FILES="$CONFIG_FILES initscript/99stap/module-setup.sh" ;;
+     "run-stap") CONFIG_FILES="$CONFIG_FILES run-stap" ;;
+     "dtrace") CONFIG_FILES="$CONFIG_FILES dtrace" ;;
+     "stapdyn/Makefile") CONFIG_FILES="$CONFIG_FILES stapdyn/Makefile" ;;
diff --git a/SOURCES/rhbz1051649.3.patch b/SOURCES/rhbz1051649.3.patch
new file mode 100644
index 0000000..47e4fce
--- /dev/null
+++ b/SOURCES/rhbz1051649.3.patch
@@ -0,0 +1,990 @@
+From f19a1ef476349c42861cfecf6dc5afdbedc9191f Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Mon, 10 Feb 2014 10:20:56 -0500
+Subject: [PATCH] man/systemtap.8.in: new man page to replace README
+
+This man page replaces the README.systemtap text file. The content is
+almost the same. A lot of rephrasing, some restructuring, and some
+clarifications that weren't present in the original document.
+
+- man/systemtap.8.in: new man page
+- initscript/README.systemtap: remove it
+- initscript/systemtap.in: add hint to man page
+
+- configure.ac: add man/systemtap.8.in in AC_CONFIG_FILES macro
+- man/Makefile.am: add systemtap.8 to man_MANS
+- systemtap.spec: replace README by man page in systemtap-initscript pkg
+  $files list
+---
+ configure.ac                |   2 +-
+ initscript/README.systemtap | 447 --------------------------------------------
+ initscript/systemtap.in     |   4 +-
+ man/Makefile.am             |   2 +-
+ man/systemtap.8.in          | 439 +++++++++++++++++++++++++++++++++++++++++++
+ systemtap.spec              |   2 +-
+ 6 files changed, 445 insertions(+), 451 deletions(-)
+ delete mode 100644 initscript/README.systemtap
+ create mode 100644 man/systemtap.8.in
+
+diff --git a/configure.ac b/configure.ac
+index 3f22549..9cc1e50 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -682,7 +682,7 @@ AC_SUBST(STAP_PREFIX, "$stap_prefix")
+ AC_CONFIG_HEADERS([config.h:config.in])
+ AC_CONFIG_FILES([Makefile doc/Makefile man/Makefile \
+ doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile \
+-man/stappaths.7 \
++man/stappaths.7 man/systemtap.8 \
+ initscript/config.systemtap initscript/config.stap-server \
+ initscript/systemtap initscript/stap-server \
+ initscript/99stap/module-setup.sh ])
+diff --git a/initscript/README.systemtap b/initscript/README.systemtap
+deleted file mode 100644
+index 9dd1ee6..0000000
+--- a/initscript/README.systemtap
++++ /dev/null
+@@ -1,447 +0,0 @@
+-Systemtap initscript
+-Version 0.2.1
+-Author: Masami Hiramatsu <mhiramat@redhat.com>
+-
+-INDEX
+-=====
+-1. Introduction
+-2. Usage
+-3. Files
+-4. Configuration Format
+-5. How to use
+-
+-1. Introduction
+-===============
+-Systemtap initscript aims to provide
+-- running systemtap script as a service with dependency.
+-- easy way to control(start/stop) those scripts individually.
+-The dependency means that which user-defined systemtap script is required by
+-other script (Here the scripts don't include tapsets). This dependency
+-will be useful for users who use -DRELAY_HOST and -DRELAY_GUEST.
+-
+-2. Usage
+-========
+-2.1 Synopsis
+-
+-/sbin/service systemtap {start|stop|restart|status|compile|onboot|cleanup} \
+-   [-r kernelrelease] [-o path.img] [-b] [-c config] [-R] [-y] [script(s)]
+-
+-2.2 Commands
+- You have to specify one of the below commands.
+-
+-2.2.1 start
+- Run script(s). If the script(s) is already started, the command will be
+- ignored. If it fails to start, return FAIL. If AUTOCOMPILE option is 'yes'
+- (see 4.1.9), this will try to compile or update the specified script when
+- one of the below condition is true.
+- - compiled cache file does not exist.
+- - mtime (modified time stamp) of original script file is newer than compiled
+-   script cache.
+- - script options which is used when compiling(see 4.2.1) has been changed.
+- - result of `uname -a` has been changed.
+- If no scripts specified from command line, it starts all scripts in the script
+- directory or the scripts specified by DEFAULT_START in config (see 4.1.10).
+-
+-2.2.2 stop
+- Stop script(s). If the script(s) is already stopped, this will be ignored.
+- If it fails to stop, return FAIL.
+- If no scripts specified from command line, it stops all running scripts.
+-
+-2.2.3 restart
+- Stop and start script(s) again.
+-
+-2.2.4 status
+- Show running script(s) status and dependency.
+-
+-2.2.5 compile
+- Compile script(s) on the specified kernel. This command takes '-r' option
+- which specifies the release of the kernel(see 2.3.4) on which you would
+- like to compile script(s). This command asks user whether it can overwrite
+- existing caches.
+-
+-2.2.6 onboot
+- Make script(s) part of the initramfs so that they are started earlier during
+- the boot process. Only works on dracut-based systems. This command also takes
+- the '-r' option. If '-r' is omitted, the initramfs is created for the running
+- kernel. If '-o path.img' is given, the initramfs is created at 'path.img' (must
+- be an absolute path).  Otherwise, defaults to '/boot/initramfs-KVER.img', where
+- KVER is `uname -r` if the '-r' option is omitted, or the given kernel version
+- otherwise.
+-
+- If the output file already exists, it is overwritten, unless the -b switch is
+- given, in which case the file is appended '.bak' rather than overwritten. Note
+- however that if a '.bak' version already exists, it will not be overwritten.
+-
+- If no scripts are specified on the command-line, the initramfs will be created
+- without including any scripts at all (i.e. no extra systemtap files added).
+-
+- Warning: do not use the stap -o option with onboot scripts because the
+- script is started before the root filesystem is even mounted. Increase the
+- buffer size if more space is needed.
+-
+-2.2.7 cleanup
+- Cleanup compiled script(s) from cache directory(see 3.4). This command also
+- takes '-r' option. If '-r' option is omitted, cleanup all caches for running
+- kernel. This command asks user whether it can remove caches.
+-
+-2.3 Options
+- Systemtap initscript can have some options. However, since user can't pass
+- these options on boot, these options are only for testing or managing scripts
+- after booting.
+-
+-2.3.1 -c config_path
+- You can specify configuration path of this initscript.
+-
+-2.3.2 script(s)
+- You can specify individual scripts to the commands. If you omit to specify
+- any script, systemtap initscript will execute the command with all scripts
+- in the script directory (except 'start', 'stop', and 'onboot' commands, see
+- 2.2.1, 2.2.2, and 2.2.6).
+-
+-2.3.3 -R
+- If this option is specified, systemtap initscript will try to solve
+- dependency of specified script(s). This option is always set if you don't
+- specify any script(s) from command line.
+-
+-2.3.4 -r kernelrelease
+- You can specify release version of the kernel(e.g. 2.6.26.1). This option
+- is valid only with compile, onboot, and cleanup commands.
+-
+-2.3.5 -y
+- Answer yes for all questions.
+-
+-2.3.6 -o path.img
+- Specify the path of the initramfs image. Otherwise, the default is
+- '/boot/initramfs-KVER.img', where KVER is `uname -r` if the '-r' option is
+- omitted, or the given kernel version otherwise. This option is only valid with
+- the onboot command.
+-
+-2.3.7 -b
+- If present, will backup an existing initramfs image by renaming it with a
+- '.bak' extension. Otherwise, the initramfs is overwritten without backing up.
+- This option is only valid with the onboot command.
+-
+-2.4 Misc
+-2.4.1 Service Priority
+- Each initscript has execution priority. Since user would like to trace
+- other services by using systemtap, systemtap initscript should have the
+- highest priority.
+-
+-3. Files
+-========
+-3.1 initscript
+- /etc/init.d/systemtap
+-
+- This file is an executable bash script.
+-
+-3.2 Configurations
+- Configuration files are written in bash script.
+-
+-3.2.1 Global config file
+- /etc/systemtap/config
+-
+- This config file is for global parameters(see 4.1).
+-
+-3.2.2 Script config files
+- /etc/systemtap/conf.d/*.conf
+-
+- The config files under this directory are for each scripts or script groups
+- (see 4.2).
+-
+-3.3 Script directory
+- /etc/systemtap/script.d/
+-
+- Systemtap initscript finds systemtap scripts from this directory.
+-
+-3.3.1 Scripts in the directory
+- /etc/systemtap/script.d/<script-name>.stp
+-
+- Systemtap scripts stored in the script directory must have ".stp" suffix.
+-
+-3.4 Cache directory
+- /var/cache/systemtap/<kernel-version>/
+-
+- Systemtap initscript stores compiled scripts in this directory.
+-
+-3.4.1 Compiled scripts (or script caches)
+- /var/cache/systemtap/<kernel-version>/<script-name>.ko
+- /var/cache/systemtap/<kernel-version>/<script-name>.opts
+-
+- *.ko file is the compiled script, and *.opts is the file which stores
+- stap options and uname -a.
+-
+-3.5 Message Log
+- /var/log/systemtap.log
+-
+- All messages including compilation errors and detailed messages are sent
+- to this file.
+- Some error and warning messages are also sent to console and syslogd (syslog
+- output is optional, because this service will start before syslog).
+-
+-3.6 Status files
+- /var/run/systemtap/<script-name>
+-
+-3.7 Dracut
+- Files related to dracut/initramfs creation
+-
+-3.7.1 Dracut stap module directory
+- /usr/lib/dracut/modules.d/99stap
+-
+- These files permit SystemTap modules to be included in the initramfs.
+-
+-4. Configuration Format
+-=======================
+-Configuration file allows us
+-- specifying options for each script
+-- supporting flight recorder mode (on file or memory)
+-
+-4.1 Global Parameters
+-
+-4.1.1 SCRIPT_PATH
+- Specify the absolute path of the script directory.
+- (default: /etc/systemtap/script.d)
+-
+-4.1.2 CONFIG_PATH
+- Specify the absolute path of the script config directory.
+- (default: /etc/systemtap/conf.d)
+-
+-4.1.3 CACHE_PATH
+- Specify the absolute path of the parent directory of the cache directory.
+- (default: /var/cache/systemtap)
+-
+-4.1.4 TEMP_PATH
+- Specify the absolute path of the temporary directory on which systemtap
+- initscript make temporary directories to compile scripts.
+- (default: /tmp)
+-
+-4.1.5 STAT_PATH
+- Specify the absolute path of the running status directory.
+- (default: /var/run/systemtap)
+-
+-4.1.6 LOG_FILE
+- Specify the absolute path of the log file
+- (default: /var/log/systemtap.log)
+-
+-4.1.7 PASSALL
+- If this is set 'yes', systemtap initscript will fail when it fails
+- to run one of the scripts. If not, systemtap initscript will not
+- fail(just warn).
+- (default: yes)
+-
+-4.1.8 RECURSIVE
+- If this is set 'yes', systemtap initscript will always follow script
+- dependencies. This means, you don't need to specify '-R' option. This flag is
+- effective only if you specify script(s) from command line.
+- (default: no)
+-
+-4.1.9 AUTOCOMPILE
+- If this is set 'yes', systemtap initscript automatically tries to compile
+- specified script if there is no valid cache. Otherwise, it just fails to
+- run script(s).
+- (default: yes)
+-
+-4.1.10 DEFAULT_START
+- Specify scripts which will be started by default. If omitted (or empty),
+- all scripts in the script directory will be started.
+- (default: "")
+-
+-4.1.11 ALLOW_CACHEONLY
+- If this is set 'yes', systemtap initscript list up cache-only scripts too.
+- *NOTE*: systemtap initscript will load unexpected obsolete caches with this
+- option. You should check cache directory before enabling this option.
+- (default: no)
+-
+-4.1.12 LOG_BOOT_ERR
+- Because boot-time scripts are run before the root filesystem is mounted,
+- staprun's stderr cannot be logged to the LOG_FILE as usual (see 4.1.6).
+- However, the log can instead be output to /var/run/systemtap/$script.log (which
+- is accessible at boot-time) by setting LOG_BOOT_ERR to 'yes'. If STAT_PATH is
+- different from the default, the log files will be moved there upon executing
+- any of the initscript commands.
+-
+-4.2 Script Parameters
+-
+-4.2.1 <script-name>_OPT
+- Specify options passed to stap command for each script. "script-name" is the
+- name of the script file without the suffix extension(.stp).
+- Some options are just ignored. And even if you don't specify -F option,
+- systemtap initscript always add it for flight recorder mode.
+- - Below options are ignored when compiling script.
+-   -p,-m,-r,-c,-x,-e,-s,-o,-h,-V,-k
+- - Below options are ignored when starting script.
+-   -h,-V,-v,-t,-p,-I,-e,-R,-r,-m,-k,-g,-P,-D,-b,-u,-q,-w,-l,-d,-L,-F, and
+-   other long options.
+-
+-4.2.2 <script-name>_REQ
+- Specify script dependency(which script this script requires).
+- For example, "foo.stp" script requires(or run after) "bar.stp" script, set
+-
+- foo_REQ="bar"
+-
+- If the script requires many scripts, set all scripts separated by spaces.
+-
+- foo_REQ="bar baz"
+-
+-4.3 Configuration Example
+-
+-4.3.1 Global Config Example
+----
+-SCRIPT_PATH=/var/systemtap/script.d/
+-PASSALL=yes
+-RECURSIVE=no
+----
+-
+-4.3.2 Script Config Example
+----
+-script1_OPT="-o /var/log/script1.out -DRELAYHOST=group1"
+-script2_OPT="-DRELAYGUEST=group1"
+-script2_REQ=script1
+----
+-
+-5. How to use
+-=============
+-
+-5.1 Package Installation
+- After installing systemtap package, install systemtap-initscript package.
+- # yum install systemtap-initscript
+- This package will include initscript and default configuration file and
+- other files.
+-
+-5.2 Script installation
+-5.2.1 Installing script files
+- Copy a systemtap script ("script1.stp") into script directory.
+- # cp script1.stp /etc/systemtap/script.d/
+-
+-5.2.2 Configuration script options
+- Add configuration file to specify options.
+- # vi /etc/systemtap/conf.d/group1
+- script1_OPT="-o /var/log/group1.log -DRELAYHOST=group1"
+-
+-5.2.3 Installing script file with dependency
+- For example, a script("script2.stp") which shares buffer with another
+- script("script1.stp"), there is a dependency. In this case, you just do
+- as following.
+-
+- # cp script2.stp /etc/systemtap/script.d/
+- # vi /etc/systemtap/conf.d/group1
+- script2_OPT="-DRELAYGUEST=group1"
+- script2_REQ=script1
+-
+- In this case, if stap fails to run script1.stp, systemtap initscript will
+- not run script2.stp.
+-
+-5.3 Testing
+- After installing all scripts, please make sure to run service successfully.
+- # service systemtap start
+- # service systemtap stop
+- If there is no error, we are ready to use it.
+-
+-5.4 Service Enabling
+- After all test passed, enable systemtap initscript.
+- # chkconfig systemtap on
+-
+-5.5 Adding script
+-5.5.1 Installing and configuring new scripts
+- Copy new systemtap script("script3.stp") into script directory.
+- # cp script3.stp /etc/systemtap/script.d/
+- and configure it.
+- # vi /etc/systemtap/conf.d/group1
+- script3_OPT="-DRELAYGUEST=group1"
+- script3_REQ="script1"
+-
+-5.5.2 Start new script
+- If you've already started systemtap initscript, just start new script.
+- # service systemtap start script3
+-
+-5.6 Deleting script
+-5.6.1 Deleting old script
+- Remove old script ("script2.stp") and remove configure lines
+- # rm /etc/systemtap/script.d/script2.stp
+- # vi /etc/systemtap/conf.d/group1
+- (delete script2_OPT and script2_REQ)
+-
+-5.6.2 Stopping old script and cleanup
+- Stop old script.
+- # service systemtap stop script2
+- And cleanup the script caches.
+- # service systemtap cleanup script2
+-
+-5.7 Updating kernel
+- Usually, you don't need to do anything. Systemtap initscript checks the
+- kernel version when starting the service, and compile scripts.
+- (If you would like to use compiled scripts due to lack of compiler or
+-  debuginfo on the system, see 5.8)
+- However, if you want to avoid compiling when booting system, you can prepare
+- script caches for new kernel.
+- # service systemtap compile -r <new kernel version>
+-
+-5.8 Using with compiled scripts
+- Sometimes, production systems don't have any compilation environment. Even
+- though, you can use systemtap initscript with compiled scripts as script
+- caches, which are compiled on other machine (but same software environment).
+-
+-5.8.1 Preparing compiled scripts
+- As described in 5.2, installing scripts and configure it on the compiling
+- machine (which has compilation environment).
+- After that, compile those scripts.
+- # service systemtap compile -r <kernel-version>
+- And package the compiled scripts and configuration file.
+- # tar czf stap-scripts-<kernel-version>.tar.gz \
+-   /var/cache/systemtap/<kernel-version> /etc/systemtap/conf.d/<config>
+- And copy this package to the target machine.
+-
+-5.8.2 Installing pre-compiled scripts
+- On the target machine, unpackage the compiled scripts into cache
+- directory.
+- # tar xzf stap-scripts-<kernel-version>.tar.gz -C /var/cache/systemtap/
+- # mv /var/cache/systemtap/<config> /etc/systemtap/conf.d/
+- At last, set AUTOCOMPILE=no and ALLOW_CACHEONLY=yes in config file.
+- # vi /etc/systemtap/config
+- AUTOCOMPILE=no
+- ALLOW_CACHEONLY=yes
+-
+-5.9 Starting scripts during early-boot
+- The initscript also allows you to start scripts earlier during the boot
+- process by creating an initramfs containing the script's module. Your system
+- must be dracut-based for this to work. Starting at this stage gives access to
+- information otherwise very hard to obtain.
+-
+-5.9.1 Preparing the script
+- As usual, place the script in /etc/systemtap/script.d and any configuration
+- settings in /etc/systemtap/conf.d. (Note however that -o and -c are not
+- supported).
+-
+-5.9.2 Adding to initramfs
+- Simply run the command:
+- # service systemtap onboot my_script
+- If the script is not already compiled and cached, it will be done at this
+- point.  A new initramfs will then be created at the default location. You can
+- specify the '-b' option to make sure that your current initramfs is backed up.
+- You can then restart your system. See 2.2.6 for more information regarding the
+- onboot command.
+-
+-5.9.3 Adding to a different initramfs
+- Rather than taking the spot of the default initramfs, you may want to create a
+- different initramfs for a one-time boot. You can do this using the -o option:
+- # service systemtap onboot -o /boot/special_initramfs.img
+- Once the initramfs is created, you can change the command-line options at
+- boot-time so that the new image is used rather than the usual one.
+-
+-5.9.4 Creating an initramfs for a different kernel
+- Just like the compile command, you can use the -r option to specify the kernel
+- for which you would like to create the initramfs. This is useful when you are
+- about to upgrade and would like to prepare in advance. For example:
+- # service systemtap onboot -r 3.12.6-200.fc19.x86_64 my_script
+-
+-5.9.5 Removing from initramfs
+- To remove all scripts from the initramfs, you can run:
+- # service systemtap onboot
+- (That is, without any scripts explicitly mentioned). This will simply create
+- a standard initramfs without any SystemTap modules inserted.
+-
+-5.9.6 Troubleshooting
+- There can be many reasons for which the module didn't insert or did not work as
+- expected. It may be useful to turn on dracut debugging by adding 'rdinitdebug' to
+- the kernel command-line and checking dmesg/journalctl -ae. Also, you can
+- capture the stderr output of staprun by setting LOG_BOOT_ERR to 'yes' (see
+- 4.1.12).
+diff --git a/initscript/systemtap.in b/initscript/systemtap.in
+index 5290f56..21f9018 100755
+--- a/initscript/systemtap.in
++++ b/initscript/systemtap.in
+@@ -83,7 +83,7 @@ INITRAMFS=
+ BACKUP_INITRAMFS=
+ 
+ echo_usage () {
+-  echo $"Usage: $prog {start|stop|status|restart|compile|onboot|cleanup|condrestart|try-restart|reload|force-reload} [option]"
++  echo $"Usage: $prog {start|stop|status|restart|compile|onboot|cleanup|condrestart|try-restart|reload|force-reload} [OPTIONS] [SCRIPTS]"
+   echo $"Options:"
+   echo $"	-b		: backup initramfs before overwriting"
+   echo $"	-c configfile	: specify config file"
+@@ -92,6 +92,8 @@ echo_usage () {
+   echo $"	-R 		: recursively dependency checking"
+   echo $"	-y 		: answer yes for all questions"
+   echo $"	script(s)	: specify systemtap scripts"
++  echo $""
++  echo $"See systemtap(8) for full documentation"
+ }
+ 
+ #-----------------------------------------------------------------
+diff --git a/man/Makefile.am b/man/Makefile.am
+index b626481..ef0892e 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -4,7 +4,7 @@
+ AUTOMAKE_OPTIONS = no-dist foreign
+ 
+ man_MANS = stapprobes.3stap stapfuncs.3stap stapvars.3stap stapex.3stap \
+-	dtrace.1 stap-merge.1 stappaths.7 stapsh.8
++	dtrace.1 stap-merge.1 stappaths.7 stapsh.8 systemtap.8
+ 
+ # NB: this doesn't work, apparently because make doesn't like
+ # file names with :: in them, misinterpreting them as some kind
+diff --git a/man/systemtap.8.in b/man/systemtap.8.in
+new file mode 100644
+index 0000000..cea3868
+--- /dev/null
++++ b/man/systemtap.8.in
+@@ -0,0 +1,439 @@
++.\" -*- nroff -*-
++.TH SYSTEMTAP 8
++.SH NAME
++systemtap \- SystemTap initscript service
++
++.\" macros
++.de SAMPLE
++
++.nr oldin \\n(.i
++.br
++.RS
++.nf
++.nh
++..
++.de ESAMPLE
++.hy
++.fi
++.RE
++.in \\n[oldin]u
++
++..
++
++.SH SYNOPSIS
++.B service systemtap
++.IR COMMAND " [" OPTIONS "] [" SCRIPT ...]
++
++.SH DESCRIPTION
++The SystemTap initscript aims to provide a way to run scripts as a service and
++easily control them individually. Scripts can be configured to start upon manual
++request, or during system startup. On dracut-based systems, it is also possible
++to integrate scripts in the initramfs and have them start during early-boot.
++
++There are various parameters and options available to modify global behaviour,
++as well as script behaviour. Dependencies between scripts can be established so
++that starting one starts others (especially convenient when using the
++-DRELAY_HOST and -DRELAY_GUEST options of \fIstap\fR(1)).
++
++The configuration file of the initscript is located at
++\fB@sysconfdir@/systemtap/config\fR. Acceptable parameters are detailed in the
++GLOBAL PARAMETERS section.
++
++Scripts must be placed in the \fB@sysconfdir@/systemtap/script.d\fR directory
++and must have a \fB.stp\fR extension. When referring to them on the command-line
++however, there in no need to include the \fB.stp\fR extension. The scripts
++directory may be changed by setting the SCRIPT_PATH parameter in the
++configuration file.
++
++.SH COMMANDS
++One of the commands below must be specified:
++
++.TP
++.B start
++Start \fISCRIPT\fRs. If no scripts are specified, start the scripts specified by
++the DEFAULT_START configuration. If DEFAULT_START is not set, start all scripts
++in the script directory. For scripts already started, the command is ignored.
++The command will fail if the scripts fail to start (see also the PASSALL
++configuration).
++
++If the AUTOCOMPILE configuration is on, the command will try to compile or
++update the specified scripts when one of the below conditions is true:
++.RS
++.IP - 2
++The compiled cache file does not exist.
++.IP -
++The mtime (modified timestamp) of the original script file is newer than the
++time of the compiled script cache.
++.IP -
++The specified stap options used to compile the script has been changed (see
++also the SCRIPT PARAMETERS section).
++.IP -
++The result of `uname -a` has been changed.
++.RE
++
++.TP
++.B stop
++Stop \fISCRIPT\fRs. If no scripts are specified, stop all running scripts. For
++scripts already stopped, the command is ignored. The command will fail if the
++scripts fail to stop (see also the PASSALL configuration).
++
++.TP
++.B restart
++Stop and start \fISCRIPT\fRs.
++
++.TP
++.B status
++Show the state of \fISCRIPT\fRs and their dependencies.
++
++.TP
++.B compile
++Compile \fISCRIPT\fRs but do not start them. If the scripts have already been
++compiled, prompt for confirmation before overwriting cache. Compile for the
++current kernel, or the kernel release specified by the \fB-r\fR option.
++
++.TP
++.B onboot
++Make \fISCRIPT\fRs part of the initramfs so that they are started earlier during
++the boot process. This command is only available on dracut-based systems. If no
++scripts are specified, create a normal initramfs devoid of any SystemTap files.
++
++The initramfs is created for the current kernel, or the kernel release specified
++by the \fB-r\fR option. The path of the created initramfs defaults
++to \fB/boot/initramfs-KVER.img\fR, where KVER is the output of `uname -r`. Use
++the \fB-o\fR option to specify a different path.
++
++If the output file already exists, it is overwritten, unless the \fB-b\fR switch
++is given, in which case the file is appended \fB.bak\fR rather than overwritten.
++However, if there is already a \fB.bak\fR version of the file, the backup will
++not be overwritten.
++
++WARNING: do not use the \fB-o\fR option of \fIstap\fR(1) with onboot scripts
++because the script is started before the root filesystem is even mounted.
++Increase the buffer size if more space is needed.
++
++.TP
++.B cleanup
++Delete the compiled \fISCRIPT\fRs from cache. If no scripts are specified, then
++all compiled scripts are deleted. Only the cache for the current kernel is
++deleted, or the kernel release specified by the \fB-r\fR option. Prompt for
++confirmation before deleting.
++
++.SH OPTIONS
++Many of the commands can also take options. However, since users can't pass
++these options on boot, they are only meant for managing scripts after boot and
++for testing. Available options are:
++
++.TP
++.BI "-c " CONFIG_FILE
++Specify a different configuration file in place of the default one.
++
++.TP
++.B -R
++When using the \fBstart\fR and \fBstop\fR commands, also include the scripts'
++dependencies (recursively).
++
++.TP
++.BI "-r " KERNEL_RELEASE
++When using the \fBcompile\fR, \fBonboot\fR, and \fBcleanup\fR commands, specify
++the target kernel version rather than using the current one. Must be in the same
++format as `uname -r`.
++
++.TP
++.B -y
++Answer yes for all prompts.
++
++.TP
++.BI "-o " PATH.IMG
++When using the \fBonboot\fR command, specify the output path of the created
++initramfs.
++
++.TP
++.B -b
++When using the \fBonboot\fR command, backup an existing initramfs image by
++adding a \fB.bak\fR extension rather than overwriting it. Without this option,
++the initramfs is overwritten.
++
++.SH GLOBAL PARAMETERS
++These parameters affect the general behaviour of the SystemTap initscript
++service. They can be specified in the configuration file.
++
++.TP
++.B SCRIPT_PATH
++Specify the absolute path of the script directory. These are the scripts on
++which the initscript can operate. Scripts must have the \fB.stp\fR extension.
++The default path is \fB@sysconfdir@/systemtap/script.d\fR.
++
++.TP
++.B CONFIG_PATH
++Specify the absolute path of the script configuration directory. These
++configuration files contain options for specific scripts. They must have the
++\fB.conf\fR extension. The default path is \fB@sysconfdir@/systemtap/conf.d\fR.
++
++.TP
++.B CACHE_PATH
++Specify the absolute path of the cache directory. The default path is
++\fB@localstatedir@/cache/systemtap\fR.
++
++.TP
++.B TEMP_PATH
++Specify the absolute path of the temporary directory in which SystemTap
++makes temporary directories to compile scripts. The default path is \fB/tmp\fR.
++
++.TP
++.B STAT_PATH
++Specify the absolute path of the directory containing PID files used to track
++the status of SystemTap scripts. The default path is
++\fB@localstatedir@/run/systemtap\fR.
++
++.TP
++.B LOG_FILE
++Specify the absolute path of the log file. All messages are sent to this file,
++including compilation and runtime errors. The default path is
++\fB@localstatedir@/log/systemtap.log\fR.
++
++.TP
++.B PASSALL
++If this is set \fByes\fR, initscript commands that operate on multiple scripts
++will report as failed when the action could not be performed on at least one
++script. If set to \fBno\fR, only a warning is emitted. The default is \fByes\fR.
++
++.TP
++.B RECURSIVE
++If this is set \fByes\fR, the initscript will always follow script dependencies
++recursively. This means that there is no need to specify the \fB-R\fR option.
++This flag is effective only if you specify script(s) from the command-line. The
++default is \fBno\fR.
++
++.TP
++.B AUTOCOMPILE
++If this is set \fByes\fR, the initscript automatically tries to compile
++specified scripts when needed if there is no valid cache. Otherwise, the related
++command simply fails. The default is \fByes\fR.
++
++.TP
++.B DEFAULT_START
++Specify scripts which will be started by default. If omitted (or empty), all
++scripts in the script directory will be started. The default is \fB""\fR.
++
++.TP
++.B ALLOW_CACHEONLY
++If this is set \fByes\fR, the initscript will also allow operating on scripts
++that are located in the cache directory, but not in the script directory. The
++default is \fBno\fR.
++
++WARNING: the initscript may load unexpected obsolete caches with this option.
++The cache directory should be checked before enabling this option.
++
++.TP
++.B LOG_BOOT_ERR
++Because boot-time scripts are run before the root filesystem is mounted,
++staprun's stderr cannot be logged to the LOG_FILE as usual. However, the log
++can instead be output to /var/run/systemtap/$script.log by setting LOG_BOOT_ERR
++to \fByes\fR. If STAT_PATH is different from the default, the log files will be
++moved there upon executing any of the initscript commands. The default is
++\fBno\fR.
++
++.PP
++Here is a global configuration file example:
++.SAMPLE
++SCRIPT_PATH=/var/systemtap/script.d/
++PASSALL=yes
++RECURSIVE=no
++.ESAMPLE
++
++.SH SCRIPT PARAMETERS
++These parameters affect the compilation or runtime behaviour of specific
++SystemTap scripts. They must be placed in config files located in the
++CONFIG_PATH directory.
++
++.TP
++.B <SCRIPT>_OPT
++Specify options passed to the \fIstap\fR(1) command for the SCRIPT. Here, SCRIPT
++is the name of the script file without the \fB.stp\fR extension. Note that the
++\fB-F\fR option is always added.
++
++The following options are ignored when compiling scripts: -p, -m, -r, -c, -x,
++-e, -s, -o, -h, -V, -k.
++
++The following options are ignored when running starting scripts: -h, -V, -v, -t,
++-p, -I, -e, -R, -r, -m, -k, -g, -P, -D, -b, -u, -q, -w, -l, -d, -L, -F, and all
++long options.
++
++.TP
++.B <SCRIPT>_REQ
++Specify script dependencies (i.e. which script this script requires). For
++example, if foo.stp requires (or needs to run after) bar.stp, set
++.SAMPLE
++foo_REQ="bar"
++.ESAMPLE
++Specify multiple scripts by separating their names by spaces.
++
++.PP
++Here is a script configuration file example:
++.SAMPLE
++script1_OPT="-o /var/log/script1.out -DRELAY_HOST=group1"
++script2_OPT="-DRELAY_GUEST=group1"
++script2_REQ="script1"
++.ESAMPLE
++
++.SH EXAMPLES
++
++.TP
++.B INSTALLING SCRIPTS
++We first copy a SystemTap script (e.g. "script1.stp") into the script directory:
++.SAMPLE
++\fB#\fR cp script1.stp /etc/systemtap/script.d/
++.ESAMPLE
++We can then set any script options, for example:
++.SAMPLE
++\fB#\fR vi /etc/systemtap/conf.d/group1
++script1_OPT="-o /var/log/group1.out -DRELAY_HOST=group1"
++.ESAMPLE
++If we then install a script (e.g. "script2.stp") which shares a buffer with
++script1, there is a dependency. In this case, we can do the following:
++.SAMPLE
++\fB#\fR cp script2.stp /etc/systemtap/script.d/
++\fB#\fR vi /etc/systemtap/conf.d/group1
++script2_OPT="-DRELAY_GUEST=group1"
++script2_REQ="script1"
++.ESAMPLE
++This way, if \fIstap\fR(1) fails to run script1, the initscript will not even
++try to run script2.
++
++.TP
++.B TESTING
++After installing scripts, we can test that they work by simply doing:
++.SAMPLE
++\fB#\fR service systemtap start
++\fB#\fR service systemtap stop
++.ESAMPLE
++We could be more specific as well, for example:
++.SAMPLE
++\fB#\fR service systemtap start script1
++\fB#\fR service systemtap stop script1
++.ESAMPLE
++If there were no errors, we are ready to use it.
++
++.TP
++.B ENABLING SERVICE
++After we're satisfied with the scripts and their tests, we can enable the
++SystemTap initscript service:
++.SAMPLE
++\fB#\fR chkconfig systemtap on
++.ESAMPLE
++
++.TP
++.B DELETING SCRIPTS
++Scripts are deleted by simply removing them from the script directory and
++removing any configuration lines specific to them:
++.SAMPLE
++\fB#\fR rm /etc/systemtap/script.d/script2.stp
++\fB#\fR vi /etc/systemtap/conf.d/group1
++.ESAMPLE
++If the script is still running, we also need to stop it:
++.SAMPLE
++\fB#\fR service systemtap stop script2
++.ESAMPLE
++We can then also remove the cache associated with the script:
++.SAMPLE
++\fB#\fR service systemtap cleanup script2
++.ESAMPLE
++
++.TP
++.B PREPARING FOR KERNEL UPDATES
++Usually, there is nothing to do when booting into a new kernel. The initscript
++will see that the kernel version is different and will compile the scripts. The
++compilation can be done beforehand as well to avoid having to compile during
++boot by using the \fB-r\fR option:
++.SAMPLE
++\fB#\fR service systemtap compile myscript -r <NEW_KERNEL_VERSION>
++.ESAMPLE
++
++.TP
++.B IMPORTING COMPILED SCRIPTS
++For environments which lack compilation infrastructure (e.g. no compilers or
++debuginfo), such as a production system, the scripts can be compiled on another
++(development) machine and then transferred over to the production system:
++.SAMPLE
++\fB#\fR service systemtap compile myscript -r \\
++.br
++>   <KERNEL_VERSION_OF_TARGET_MACHINE>
++\fB#\fR tar czf stap-scripts-<kernel-version>.tar.gz \\
++.br
++>   /var/cache/systemtap/<kernel-version> \\
++.br
++>   /etc/systemtap/conf.d/<configfile>
++.ESAMPLE
++And then copy this package to the target machine and extract it.
++
++.TP
++.B STARTING SCRIPTS DURING EARLY-BOOT
++The initscript also allows us to start scripts earlier during the boot process
++by creating an initramfs containing the script's module. The system must be
++dracut-based for this to work. Starting a script at this stage gives access to
++information otherwise very hard to obtain.
++
++We first install the script by copying it into the script directory as usual and
++setting whatever options we'd like:
++.SAMPLE
++\fB#\fR cp myscript.stp /etc/systemtap/script.d
++\fB#\fR vi /etc/systemtap/conf.d/myscript.conf
++.ESAMPLE
++To add the script to the initramfs, we use the \fBonboot\fR command:
++.SAMPLE
++\fB#\fR service systemtap onboot myscript
++.ESAMPLE
++If the script is not already compiled and cached, it will be done at this point.
++A new initramfs will then be created at the default location. We can use the
++\fB-b\fR option to ensure that the existing initramfs is backed up. We can then
++restart the system.
++
++.TP
++.B USING A DIFFERENT INITRAMFS
++If we would prefer to only start the script for one boot and not others, it
++might be easier to instead use the \fB-o\fR option to specify a different
++initramfs output file:
++.SAMPLE
++\fB#\fR service systemtap onboot myscript \\
++>   -o /boot/special_initramfs.img
++.ESAMPLE
++Once the initramfs is created, it's simply a matter of changing the command-line
++options at boot-time so that the new image is used rather than the usual one.
++
++.TP
++.B CREATING AN INITRAMFS FOR A DIFFERENT KERNEL
++Just like the compile command, we can use the \fB-r\fR option to specify the
++kernel for which we want to create the initramfs. This is useful when we are
++about to upgrade and would like to prepare in advance. For example:
++.SAMPLE
++\fB#\fR service systemtap onboot myscript \\
++>   -r 3.12.6-200.fc19.x86_64
++.ESAMPLE
++
++.TP
++.B REMOVING SCRIPTS FROM THE INITRAMFS
++Finally, to remove all script from the initramfs, we simple run the \fBonboot\fR
++command without specifying any scripts:
++.SAMPLE
++\fB#\fR service systemtap onboot
++.ESAMPLE
++This will simply create a standard initramfs without any SystemTap modules
++inserted.
++
++.TP
++.B TROUBLESHOOTING EARLY-BOOT ISSUES
++There can be many reasons for which the module didn't insert or did not work as
++expected. It may be useful to turn on dracut debugging by adding 'rdinitdebug'
++to the kernel command-line and checking dmesg/journalctl -ae. Also, the stderr
++output of staprun can be captured by setting the LOG_BOOT_ERR option to
++\fByes\fR.
++
++.SH SEE ALSO
++.IR stap (1)
++
++.SH BUGS
++Use the Bugzilla link of the project web page or our mailing list.
++.nh
++.BR http://sourceware.org/systemtap/ ", " <systemtap@sourceware.org> .
++.hy
++
+diff --git a/systemtap.spec b/systemtap.spec
+index 41945bd..41c746d 100644
+--- a/systemtap.spec
++++ b/systemtap.spec
+@@ -940,7 +940,7 @@ done
+ %config(noreplace) %{_sysconfdir}/systemtap/config
+ %dir %{_localstatedir}/cache/systemtap
+ %ghost %{_localstatedir}/run/systemtap
+-%doc initscript/README.systemtap
++%{_mandir}/man8/systemtap.8*
+ %if %{with_dracut}
+    %dir %{dracutstap}
+    %{dracutstap}/*
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.4.patch b/SOURCES/rhbz1051649.4.patch
new file mode 100644
index 0000000..4c3932b
--- /dev/null
+++ b/SOURCES/rhbz1051649.4.patch
@@ -0,0 +1,74 @@
+From b5c84307cd507c5fa8d7991e1b533d6983b07a73 Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Mon, 10 Feb 2014 10:21:26 -0500
+Subject: [PATCH] autoreconf
+
+---
+ configure       | 3 ++-
+ man/Makefile.in | 8 +++++---
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/configure b/configure
+index 69231af..2a964c1 100755
+--- a/configure
++++ b/configure
+@@ -11420,7 +11420,7 @@ STAP_PREFIX="$stap_prefix"
+ 
+ ac_config_headers="$ac_config_headers config.h:config.in"
+ 
+-ac_config_files="$ac_config_files Makefile doc/Makefile man/Makefile doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile man/stappaths.7 initscript/config.systemtap initscript/config.stap-server initscript/systemtap initscript/stap-server initscript/99stap/module-setup.sh"
++ac_config_files="$ac_config_files Makefile doc/Makefile man/Makefile doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile man/stappaths.7 man/systemtap.8 initscript/config.systemtap initscript/config.stap-server initscript/systemtap initscript/stap-server initscript/99stap/module-setup.sh"
+ 
+ 
+ 
+@@ -12292,6 +12292,7 @@ do
+     "doc/beginners/Makefile") CONFIG_FILES="$CONFIG_FILES doc/beginners/Makefile" ;;
+     "doc/SystemTap_Tapset_Reference/Makefile") CONFIG_FILES="$CONFIG_FILES doc/SystemTap_Tapset_Reference/Makefile" ;;
+     "man/stappaths.7") CONFIG_FILES="$CONFIG_FILES man/stappaths.7" ;;
++    "man/systemtap.8") CONFIG_FILES="$CONFIG_FILES man/systemtap.8" ;;
+     "initscript/config.systemtap") CONFIG_FILES="$CONFIG_FILES initscript/config.systemtap" ;;
+     "initscript/config.stap-server") CONFIG_FILES="$CONFIG_FILES initscript/config.stap-server" ;;
+     "initscript/systemtap") CONFIG_FILES="$CONFIG_FILES initscript/systemtap" ;;
+diff --git a/man/Makefile.in b/man/Makefile.in
+index 42c56be..ae68814 100644
+--- a/man/Makefile.in
++++ b/man/Makefile.in
+@@ -85,7 +85,7 @@ target_triplet = @target@
+ @HAVE_LIBVIRT_TRUE@@HAVE_LIBXML2_TRUE@am__append_3 = stapvirt.1
+ subdir = man
+ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+-	$(srcdir)/stappaths.7.in
++	$(srcdir)/stappaths.7.in $(srcdir)/systemtap.8.in
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
+ 	$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+@@ -96,7 +96,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ 	$(ACLOCAL_M4)
+ mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = $(top_builddir)/config.h
+-CONFIG_CLEAN_FILES = stappaths.7
++CONFIG_CLEAN_FILES = stappaths.7 systemtap.8
+ CONFIG_CLEAN_VPATH_FILES =
+ AM_V_P = $(am__v_P_@AM_V@)
+ am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+@@ -321,7 +321,7 @@ top_srcdir = @top_srcdir@
+ AUTOMAKE_OPTIONS = no-dist foreign
+ man_MANS = stapprobes.3stap stapfuncs.3stap stapvars.3stap \
+ 	stapex.3stap dtrace.1 stap-merge.1 stappaths.7 stapsh.8 \
+-	$(am__append_1) $(am__append_2) $(am__append_3)
++	systemtap.8 $(am__append_1) $(am__append_2) $(am__append_3)
+ all: all-am
+ 
+ .SUFFIXES:
+@@ -357,6 +357,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__aclocal_m4_deps):
+ stappaths.7: $(top_builddir)/config.status $(srcdir)/stappaths.7.in
+ 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
++systemtap.8: $(top_builddir)/config.status $(srcdir)/systemtap.8.in
++	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+ install-man1: $(man_MANS)
+ 	@$(NORMAL_INSTALL)
+ 	@list1=''; \
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.5.patch b/SOURCES/rhbz1051649.5.patch
new file mode 100644
index 0000000..db69d99
--- /dev/null
+++ b/SOURCES/rhbz1051649.5.patch
@@ -0,0 +1,147 @@
+From bb241c250cf74865382bfe099b550118d4badba0 Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Wed, 26 Mar 2014 11:39:11 -0400
+Subject: [PATCH] initscript: use new-kernel-pkg after dracut
+
+With this patch, we now also call new-kernel-pkg --update after creating
+the new image so that the bootloader is updated if need be (see also
+BZ1051649#c9).
+
+This patch also includes some polishing re. console log output.
+---
+ initscript/systemtap.in | 54 ++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 45 insertions(+), 9 deletions(-)
+
+diff --git a/initscript/systemtap.in b/initscript/systemtap.in
+index 21f9018..075226e 100755
+--- a/initscript/systemtap.in
++++ b/initscript/systemtap.in
+@@ -37,6 +37,7 @@ STAPRUN=@bindir@/staprun
+ UNAME=/bin/uname
+ LSMOD=/sbin/lsmod
+ DRACUT=/sbin/dracut
++NEWKERNELPKG=/usr/sbin/new-kernel-pkg
+ 
+ # Not actually used directly, but needed by
+ # stap dracut module for inclusion in initramfs
+@@ -81,6 +82,7 @@ OPTS=
+ OPT_ASSUMEYES=
+ INITRAMFS=
+ BACKUP_INITRAMFS=
++EXPLICIT_INITRAMFS=
+ 
+ echo_usage () {
+   echo $"Usage: $prog {start|stop|status|restart|compile|onboot|cleanup|condrestart|try-restart|reload|force-reload} [OPTIONS] [SCRIPTS]"
+@@ -202,6 +204,9 @@ parse_args $OPTS
+ # Set default output file if not given as an option
+ if [ ! "$INITRAMFS" ]; then
+   INITRAMFS=/boot/initramfs-$KRELEASE.img
++else
++  # User explicitly specified an img file to output to
++  EXPLICIT_INITRAMFS=1
+ fi
+ 
+ # Include configs
+@@ -738,9 +743,9 @@ compile () {
+   return 0
+ }
+ 
+-# Writes info to $DRACUT_SRC, which the stap dracut module will source
++# Writes info to $DRACUT_SRC, which the stap dracut module will source.
+ # Includes all needed info such as location of stap/staprun, which
+-# scripts to insert, and their options
++# scripts to insert, and their options.
+ update_dracut() { # scripts
+   local s opts
+ 
+@@ -773,20 +778,29 @@ update_dracut() { # scripts
+ backup_initramfs() {
+   # does target file exist?
+   if [ -f "$INITRAMFS" ]; then
++    clog
+     # don't overwrite an existing backup
+     if [ ! -f "$INITRAMFS.bak" ]; then
+       mv "$INITRAMFS" "$INITRAMFS.bak"
+-      clog "Renamed $INITRAMFS"
+-      clog "     to $INITRAMFS.bak"
++      clog "  Renamed $INITRAMFS"
++      clog "       to $INITRAMFS.bak ... " -n
+       RESTORE_INITRAMFS_ON_FAIL=1
+     else
+-      clog "Backup already exists: $INITRAMFS.bak"
++      clog "  Backup already exists: $INITRAMFS.bak ... " -n
+     fi
+   fi
+ }
+ 
+ onboot () {
+   local s ret ss
++  if [ ! -f "$NEWKERNELPKG" ]; then
++    clog "Could not find $NEWKERNELPKG" -n
++    do_failure "$NEWKERNELPKG not found"
++    clog
++    clog "This feature requires $NEWKERNELPKG."
++    clog "If it is located elsewhere, modify the \$NEWKERNELPKG parameter" -n
++    return 1
++  fi
+   if [ ! -f "$DRACUT" ]; then
+     clog "Could not find $DRACUT" -n
+     do_failure "$DRACUT not found"
+@@ -845,6 +859,9 @@ onboot () {
+     do_failure "Failed to make temporary file in $dir"
+     return 1
+   fi
++  # Create the initramfs image. We could have combined this with the
++  # new-kernel-pkg call below using --dracut, but then we would have
++  # lost error-checking and our backing up facilities.
+   out=$($DRACUT --force $TMPINITRAMFS $KRELEASE 2>&1)
+   # dracut will report success even if some modules (e.g. stap) failed
+   # to install some files, so we need to be a bit more involved in
+@@ -856,7 +873,7 @@ onboot () {
+     else
+       do_failure "See dracut log for more info"
+     fi
+-    echo # We need a new line
++    clog
+     if [ -f "$TMPINITRAMFS" ]; then
+       rm "$TMPINITRAMFS"
+     fi
+@@ -864,13 +881,32 @@ onboot () {
+     # whatever initramfs they used to boot in is still there)
+     if [ "$RESTORE_INITRAMFS_ON_FAIL" ]; then
+       mv "$INITRAMFS.bak" "$INITRAMFS"
+-      clog "Renamed $INITRAMFS.bak"
+-      clog "     to $INITRAMFS"
++      clog "  Renamed $INITRAMFS.bak"
++      clog "       to $INITRAMFS"
+     fi
+     return 1
+   fi
+   mv "$TMPINITRAMFS" "$INITRAMFS"
+-  might_success "initramfs created"
++  # The initramfs is in place. If the user explicitly specified an
++  # output file using -o, then we should skip updating the bootloader
++  # (the output file may not even be in /boot/).
++  if [ "$EXPLICIT_INITRAMFS" ]; then
++    might_success "initramfs created"
++    clog
++    clog "NB: bootloader was not updated" -n
++    return 0
++  fi
++  clog "done"
++  # We're installing the initramfs in the default location, so user
++  # expects the next boot to use it. Let's also update the bootloader.
++  clog " Updating bootloader ... " -n
++  logex $NEWKERNELPKG --initrdfile="$INITRAMFS" \
++                      --update $KRELEASE
++  if [ $? -ne 0 ]; then
++    do_failure "$NEWKERNELPKG exited with nonzero status"
++    return 1
++  fi
++  might_success "initramfs created and bootloader updated"
+   return 0
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.6.patch b/SOURCES/rhbz1051649.6.patch
new file mode 100644
index 0000000..30aaa33
--- /dev/null
+++ b/SOURCES/rhbz1051649.6.patch
@@ -0,0 +1,57 @@
+From 65dc00af707a48948d08dd4fec97ecb22459dd0c Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Wed, 26 Mar 2014 13:56:20 -0400
+Subject: [PATCH] initscript: skip dracut stap module by default
+
+We previously always enabled the dracut stap module as long as there
+were scripts to include. This can lead to issues since the params.conf
+file may be obsolete/not in sync e.g. during a kernel update. We now
+make the module an opt-in feature, and make the initscript explicit
+specify its inclusion.
+---
+ initscript/99stap/module-setup.sh.in | 10 +++++++---
+ initscript/systemtap.in              |  6 ++----
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/initscript/99stap/module-setup.sh.in b/initscript/99stap/module-setup.sh.in
+index 4f4583d..7b2b401 100644
+--- a/initscript/99stap/module-setup.sh.in
++++ b/initscript/99stap/module-setup.sh.in
+@@ -5,10 +5,14 @@
+ 
+ # Return 0 --> install stap module
+ # Return 1 --> skip stap module
++# Return 255 --> install stap module only if explicitly requested
+ check() {
+-   # Install it if we have early-boot scripts
+-   [ "$ONBOOT_SCRIPTS" ] && return 0
+-   return 1
++   # Do not include stap module if there are no scripts to include
++   [ "$ONBOOT_SCRIPTS" ] || return 1
++   # We're disabled by default: the initscript explicitly uses dracut's
++   # '--add stap' when creating the initramfs. Otherwise, we might be
++   # mistakenly included during e.g. kernel updates.
++   return 255
+ }
+ 
+ # We don't depend on anything
+diff --git a/initscript/systemtap.in b/initscript/systemtap.in
+index 075226e..ab882e9 100755
+--- a/initscript/systemtap.in
++++ b/initscript/systemtap.in
+@@ -859,10 +859,8 @@ onboot () {
+     do_failure "Failed to make temporary file in $dir"
+     return 1
+   fi
+-  # Create the initramfs image. We could have combined this with the
+-  # new-kernel-pkg call below using --dracut, but then we would have
+-  # lost error-checking and our backing up facilities.
+-  out=$($DRACUT --force $TMPINITRAMFS $KRELEASE 2>&1)
++  # Create the initramfs image with stap module enabled.
++  out=$($DRACUT --add stap --force $TMPINITRAMFS $KRELEASE 2>&1)
+   # dracut will report success even if some modules (e.g. stap) failed
+   # to install some files, so we need to be a bit more involved in
+   # checking for errors
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.7.patch b/SOURCES/rhbz1051649.7.patch
new file mode 100644
index 0000000..3f5bb16
--- /dev/null
+++ b/SOURCES/rhbz1051649.7.patch
@@ -0,0 +1,49 @@
+From bfb256e83ba00cbb44f7d115ebfcdd100821114d Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Wed, 26 Mar 2014 14:17:02 -0400
+Subject: [PATCH] systemtap.8: clarify docs regarding new-kernel-pkg
+
+---
+ man/systemtap.8.in | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/man/systemtap.8.in b/man/systemtap.8.in
+index cea3868..798a278 100644
+--- a/man/systemtap.8.in
++++ b/man/systemtap.8.in
+@@ -98,9 +98,11 @@ the boot process. This command is only available on dracut-based systems. If no
+ scripts are specified, create a normal initramfs devoid of any SystemTap files.
+ 
+ The initramfs is created for the current kernel, or the kernel release specified
+-by the \fB-r\fR option. The path of the created initramfs defaults
+-to \fB/boot/initramfs-KVER.img\fR, where KVER is the output of `uname -r`. Use
+-the \fB-o\fR option to specify a different path.
++by the \fB-r\fR option. The path of the created initramfs defaults to
++\fB/boot/initramfs-KVER.img\fR, where KVER is the output of `uname -r`. The
++bootloader is also updated (using \fInew-kernel-pkg\fR(8)) to make the kernel
++entry use the new initramfs file. Use the \fB-o\fR option to specify a different
++path (the bootloader will not be updated).
+ 
+ If the output file already exists, it is overwritten, unless the \fB-b\fR switch
+ is given, in which case the file is appended \fB.bak\fR rather than overwritten.
+@@ -145,7 +147,7 @@ Answer yes for all prompts.
+ .TP
+ .BI "-o " PATH.IMG
+ When using the \fBonboot\fR command, specify the output path of the created
+-initramfs.
++initramfs. When specified, the bootloader configuration is not updated.
+ 
+ .TP
+ .B -b
+@@ -430,6 +432,8 @@ output of staprun can be captured by setting the LOG_BOOT_ERR option to
+ 
+ .SH SEE ALSO
+ .IR stap (1)
++.IR dracut (8)
++.IR new-kernel-pkg (8)
+ 
+ .SH BUGS
+ Use the Bugzilla link of the project web page or our mailing list.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.8.patch b/SOURCES/rhbz1051649.8.patch
new file mode 100644
index 0000000..8036866
--- /dev/null
+++ b/SOURCES/rhbz1051649.8.patch
@@ -0,0 +1,79 @@
+From ae91e3d552aff4f0e74662d055dae06ea55eb6bc Mon Sep 17 00:00:00 2001
+From: "Frank Ch. Eigler" <fche@redhat.com>
+Date: Thu, 27 Mar 2014 21:29:04 -0400
+Subject: [PATCH] PR16766: kernel crash for failed-init module-notification
+
+Suppress the module_notifier callback for cases of failure of the
+main generated systemtap module-initialization code, which checks
+build-ids, privileges, etc. etc.; we don't want any module-notifier
+callbacks after an error.
+
+* runtime/transport/transport.c: Don't call module-notifier stuff
+  if initialization failed.
+* translate.cxx (emit_module_refresh): Emit code to suppress callback
+  payload if somehow the notifier got activated anyway.
+---
+ runtime/transport/transport.c | 20 ++++++++++++--------
+ translate.cxx                 | 11 +++++++++++
+ 2 files changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
+index 1800764..e4d4d8e 100644
+--- a/runtime/transport/transport.c
++++ b/runtime/transport/transport.c
+@@ -135,16 +135,20 @@ static void _stp_handle_start(struct _stp_msg_start *st)
+ 
+ 		_stp_target = st->target;
+ 		st->res = systemtap_module_init();
+-		if (st->res == 0)
++		if (st->res == 0) {
+ 			_stp_probes_started = 1;
+ 
+-                /* Register the module notifier. */
+-                if (!_stp_module_notifier_active) {
+-                        int rc = register_module_notifier(& _stp_module_notifier_nb);
+-                        if (rc == 0)
+-                                _stp_module_notifier_active = 1;
+-                        else
+-                                _stp_warn ("Cannot register module notifier (%d)\n", rc);
++                        /* Register the module notifier ... */
++                        /* NB: but not if the module_init stuff
++                           failed: something nasty has happened, and
++                           we want no further probing started.  PR16766 */
++                        if (!_stp_module_notifier_active) {
++                                int rc = register_module_notifier(& _stp_module_notifier_nb);
++                                if (rc == 0)
++                                        _stp_module_notifier_active = 1;
++                                else
++                                        _stp_warn ("Cannot register module notifier (%d)\n", rc);
++                        }
+                 }
+ 
+ 		/* Called from the user context in response to a proc
+diff --git a/translate.cxx b/translate.cxx
+index 9903751..17dedd4 100644
+--- a/translate.cxx
++++ b/translate.cxx
+@@ -1881,8 +1881,19 @@ c_unparser::emit_module_refresh ()
+ {
+   o->newline() << "static void systemtap_module_refresh (void) {";
+   o->newline(1) << "int i=0, j=0;"; // for derived_probe_group use
++
++  /* If we're not in STARTING/RUNNING state, don't try doing any work.
++     PR16766 */
++  o->newline() << "int state = atomic_read (session_state());";
++  o->newline() << "if (state != STAP_SESSION_RUNNING && state != STAP_SESSION_STARTING) {";
++  // cannot _stp_warn etc. since we're not in probe context
++  o->newline(1) << "printk (KERN_ERR \"stap module notifier triggered in unexpected state %d\", state);";
++  o->newline() << "return;";
++  o->newline(-1) << "}";
++
+   o->newline() << "(void) i;";
+   o->newline() << "(void) j;";
++
+   vector<derived_probe_group*> g = all_session_groups (*session);
+   for (unsigned i=0; i<g.size(); i++)
+     {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.9.patch b/SOURCES/rhbz1051649.9.patch
new file mode 100644
index 0000000..9d61928
--- /dev/null
+++ b/SOURCES/rhbz1051649.9.patch
@@ -0,0 +1,29 @@
+From 53d72bca75a2bfc75bceea0d094131c9d53bd942 Mon Sep 17 00:00:00 2001
+From: "Frank Ch. Eigler" <fche@redhat.com>
+Date: Fri, 28 Mar 2014 15:24:19 -0400
+Subject: [PATCH] PR16766 cont'd: unbreak --runtime=dyninst
+
+* translate.cxx: While emitting systemtap_module_refresh(), protect
+  the printk diagnostics with #if defined(__KERNEL__).
+---
+ translate.cxx | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/translate.cxx b/translate.cxx
+index 17dedd4..90b04d8 100644
+--- a/translate.cxx
++++ b/translate.cxx
+@@ -1887,7 +1887,9 @@ c_unparser::emit_module_refresh ()
+   o->newline() << "int state = atomic_read (session_state());";
+   o->newline() << "if (state != STAP_SESSION_RUNNING && state != STAP_SESSION_STARTING) {";
+   // cannot _stp_warn etc. since we're not in probe context
+-  o->newline(1) << "printk (KERN_ERR \"stap module notifier triggered in unexpected state %d\", state);";
++  o->newline(1) << "#if defined(__KERNEL__)";
++  o->newline() << "printk (KERN_ERR \"stap module notifier triggered in unexpected state %d\", state);";
++  o->newline() << "#endif";
+   o->newline() << "return;";
+   o->newline(-1) << "}";
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1051649.patch b/SOURCES/rhbz1051649.patch
new file mode 100644
index 0000000..326106a
--- /dev/null
+++ b/SOURCES/rhbz1051649.patch
@@ -0,0 +1,803 @@
+From 2512f77547e7a4b9bbfd46c01c5b2ded2c171cf3 Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Wed, 27 Nov 2013 11:21:02 -0500
+Subject: BZ1051649: backport boot-time probing feature
+
+---
+ configure.ac                         |   3 +-
+ initscript/99stap/module-setup.sh.in |  36 ++++++
+ initscript/99stap/start-staprun.sh   |  26 ++++
+ initscript/README.systemtap          | 108 ++++++++++++++--
+ initscript/config.systemtap.in       |   3 +
+ initscript/systemtap.in              | 230 +++++++++++++++++++++++++++++++++--
+ systemtap.spec                       |  39 ++++--
+ tapset-utrace.cxx                    |   9 --
+ 8 files changed, 413 insertions(+), 41 deletions(-)
+ create mode 100644 initscript/99stap/module-setup.sh.in
+ create mode 100644 initscript/99stap/start-staprun.sh
+ mode change 100644 => 100755 initscript/systemtap.in
+
+diff --git a/configure.ac b/configure.ac
+index 56c3b88..3d6b50b 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -681,7 +681,8 @@ AC_CONFIG_FILES([Makefile doc/Makefile man/Makefile \
+ doc/beginners/Makefile doc/SystemTap_Tapset_Reference/Makefile \
+ man/stappaths.7 \
+ initscript/config.systemtap initscript/config.stap-server \
+-initscript/systemtap initscript/stap-server ])
++initscript/systemtap initscript/stap-server \
++initscript/99stap/module-setup.sh ])
+ AC_CONFIG_SUBDIRS(testsuite)
+ if test $enable_translator == "yes"; then
+ 	AC_CONFIG_FILES([run-stap], [chmod +x run-stap])
+diff --git a/initscript/99stap/module-setup.sh.in b/initscript/99stap/module-setup.sh.in
+new file mode 100644
+index 0000000..4f4583d
+--- /dev/null
++++ b/initscript/99stap/module-setup.sh.in
+@@ -0,0 +1,36 @@
++#!/bin/bash
++
++# NB: $moddir only works in install()
++. @prefix@/lib/dracut/modules.d/99stap/params.conf
++
++# Return 0 --> install stap module
++# Return 1 --> skip stap module
++check() {
++   # Install it if we have early-boot scripts
++   [ "$ONBOOT_SCRIPTS" ] && return 0
++   return 1
++}
++
++# We don't depend on anything
++depends() {
++   echo ""
++}
++
++install() {
++
++   # These programs are very likely to already be included by other
++   # dracut modules so we're really not adding any weight
++   dracut_install bash mkdir
++
++   # The real payload...
++   inst "$STAPRUN"
++   inst "$STAPIO"
++   for script in $ONBOOT_SCRIPTS; do
++      inst "$CACHE_PATH/$script.ko"
++   done
++
++   # start-staprun.sh will need a copy of params.conf
++   inst_simple "$moddir/params.conf" "/etc/systemtap-params.conf"
++   inst_hook cmdline 01 "$moddir/start-staprun.sh"
++}
++
+diff --git a/initscript/99stap/start-staprun.sh b/initscript/99stap/start-staprun.sh
+new file mode 100644
+index 0000000..efb4d2f
+--- /dev/null
++++ b/initscript/99stap/start-staprun.sh
+@@ -0,0 +1,26 @@
++#!/bin/bash
++
++# Inserts the SystemTap modules using staprun.
++
++. /etc/systemtap-params.conf
++
++# From here, we can access /var/run (or rather what it will link to),
++# but because $STAT_PATH is user-configurable, we're not guaranteed that
++# it will be /var/run.  Regardless, we can't have access to the final
++# root so we make do and write to /var/run/systemtap anyway. The init
++# script will take care of moving the PID files to the real directory if
++# necessary.
++PIDDIR=/run/systemtap
++mkdir -p $PIDDIR
++
++for script in $ONBOOT_SCRIPTS; do
++   pid=$PIDDIR/$script
++   eval opts=\$${script}_OPT
++   if [ $LOG_BOOT_ERR -eq 1 ]; then
++      $STAPRUN $opts $CACHE_PATH/$script.ko 2> $PIDDIR/$script.log
++   else
++      $STAPRUN $opts $CACHE_PATH/$script.ko
++   fi
++   echo 0 > $pid
++done
++
+diff --git a/initscript/README.systemtap b/initscript/README.systemtap
+index d583d72..9dd1ee6 100644
+--- a/initscript/README.systemtap
++++ b/initscript/README.systemtap
+@@ -23,8 +23,8 @@ will be useful for users who use -DRELAY_HOST and -DRELAY_GUEST.
+ ========
+ 2.1 Synopsis
+ 
+-/sbin/service systemtap {start|stop|restart|status|compile|cleanup} \
+-	[-r kernelrelease] [-c config] [-R] [-y] [script(s)]
++/sbin/service systemtap {start|stop|restart|status|compile|onboot|cleanup} \
++   [-r kernelrelease] [-o path.img] [-b] [-c config] [-R] [-y] [script(s)]
+ 
+ 2.2 Commands
+  You have to specify one of the below commands.
+@@ -57,9 +57,29 @@ will be useful for users who use -DRELAY_HOST and -DRELAY_GUEST.
+  Compile script(s) on the specified kernel. This command takes '-r' option
+  which specifies the release of the kernel(see 2.3.4) on which you would
+  like to compile script(s). This command asks user whether it can overwrite
+-existing caches.
++ existing caches.
+ 
+-2.2.6 cleanup
++2.2.6 onboot
++ Make script(s) part of the initramfs so that they are started earlier during
++ the boot process. Only works on dracut-based systems. This command also takes
++ the '-r' option. If '-r' is omitted, the initramfs is created for the running
++ kernel. If '-o path.img' is given, the initramfs is created at 'path.img' (must
++ be an absolute path).  Otherwise, defaults to '/boot/initramfs-KVER.img', where
++ KVER is `uname -r` if the '-r' option is omitted, or the given kernel version
++ otherwise.
++
++ If the output file already exists, it is overwritten, unless the -b switch is
++ given, in which case the file is appended '.bak' rather than overwritten. Note
++ however that if a '.bak' version already exists, it will not be overwritten.
++
++ If no scripts are specified on the command-line, the initramfs will be created
++ without including any scripts at all (i.e. no extra systemtap files added).
++
++ Warning: do not use the stap -o option with onboot scripts because the
++ script is started before the root filesystem is even mounted. Increase the
++ buffer size if more space is needed.
++
++2.2.7 cleanup
+  Cleanup compiled script(s) from cache directory(see 3.4). This command also
+  takes '-r' option. If '-r' option is omitted, cleanup all caches for running
+  kernel. This command asks user whether it can remove caches.
+@@ -75,8 +95,8 @@ existing caches.
+ 2.3.2 script(s)
+  You can specify individual scripts to the commands. If you omit to specify
+  any script, systemtap initscript will execute the command with all scripts
+- in the script directory(except 'start' and 'stop' command, see 2.2.1 and
+- 2.2.2).
++ in the script directory (except 'start', 'stop', and 'onboot' commands, see
++ 2.2.1, 2.2.2, and 2.2.6).
+ 
+ 2.3.3 -R
+  If this option is specified, systemtap initscript will try to solve
+@@ -85,11 +105,22 @@ existing caches.
+ 
+ 2.3.4 -r kernelrelease
+  You can specify release version of the kernel(e.g. 2.6.26.1). This option
+- is valid only with compile and cleanup commands.
++ is valid only with compile, onboot, and cleanup commands.
+ 
+ 2.3.5 -y
+  Answer yes for all questions.
+ 
++2.3.6 -o path.img
++ Specify the path of the initramfs image. Otherwise, the default is
++ '/boot/initramfs-KVER.img', where KVER is `uname -r` if the '-r' option is
++ omitted, or the given kernel version otherwise. This option is only valid with
++ the onboot command.
++
++2.3.7 -b
++ If present, will backup an existing initramfs image by renaming it with a
++ '.bak' extension. Otherwise, the initramfs is overwritten without backing up.
++ This option is only valid with the onboot command.
++
+ 2.4 Misc
+ 2.4.1 Service Priority
+  Each initscript has execution priority. Since user would like to trace
+@@ -147,9 +178,16 @@ existing caches.
+  Some error and warning messages are also sent to console and syslogd (syslog
+  output is optional, because this service will start before syslog).
+ 
+-3.7 Status files
++3.6 Status files
+  /var/run/systemtap/<script-name>
+ 
++3.7 Dracut
++ Files related to dracut/initramfs creation
++
++3.7.1 Dracut stap module directory
++ /usr/lib/dracut/modules.d/99stap
++
++ These files permit SystemTap modules to be included in the initramfs.
+ 
+ 4. Configuration Format
+ =======================
+@@ -213,6 +251,14 @@ Configuration file allows us
+  option. You should check cache directory before enabling this option.
+  (default: no)
+ 
++4.1.12 LOG_BOOT_ERR
++ Because boot-time scripts are run before the root filesystem is mounted,
++ staprun's stderr cannot be logged to the LOG_FILE as usual (see 4.1.6).
++ However, the log can instead be output to /var/run/systemtap/$script.log (which
++ is accessible at boot-time) by setting LOG_BOOT_ERR to 'yes'. If STAT_PATH is
++ different from the default, the log files will be moved there upon executing
++ any of the initscript commands.
++
+ 4.2 Script Parameters
+ 
+ 4.2.1 <script-name>_OPT
+@@ -353,3 +399,49 @@ script2_REQ=script1
+  # vi /etc/systemtap/config
+  AUTOCOMPILE=no
+  ALLOW_CACHEONLY=yes
++
++5.9 Starting scripts during early-boot
++ The initscript also allows you to start scripts earlier during the boot
++ process by creating an initramfs containing the script's module. Your system
++ must be dracut-based for this to work. Starting at this stage gives access to
++ information otherwise very hard to obtain.
++
++5.9.1 Preparing the script
++ As usual, place the script in /etc/systemtap/script.d and any configuration
++ settings in /etc/systemtap/conf.d. (Note however that -o and -c are not
++ supported).
++
++5.9.2 Adding to initramfs
++ Simply run the command:
++ # service systemtap onboot my_script
++ If the script is not already compiled and cached, it will be done at this
++ point.  A new initramfs will then be created at the default location. You can
++ specify the '-b' option to make sure that your current initramfs is backed up.
++ You can then restart your system. See 2.2.6 for more information regarding the
++ onboot command.
++
++5.9.3 Adding to a different initramfs
++ Rather than taking the spot of the default initramfs, you may want to create a
++ different initramfs for a one-time boot. You can do this using the -o option:
++ # service systemtap onboot -o /boot/special_initramfs.img
++ Once the initramfs is created, you can change the command-line options at
++ boot-time so that the new image is used rather than the usual one.
++
++5.9.4 Creating an initramfs for a different kernel
++ Just like the compile command, you can use the -r option to specify the kernel
++ for which you would like to create the initramfs. This is useful when you are
++ about to upgrade and would like to prepare in advance. For example:
++ # service systemtap onboot -r 3.12.6-200.fc19.x86_64 my_script
++
++5.9.5 Removing from initramfs
++ To remove all scripts from the initramfs, you can run:
++ # service systemtap onboot
++ (That is, without any scripts explicitly mentioned). This will simply create
++ a standard initramfs without any SystemTap modules inserted.
++
++5.9.6 Troubleshooting
++ There can be many reasons for which the module didn't insert or did not work as
++ expected. It may be useful to turn on dracut debugging by adding 'rdinitdebug' to
++ the kernel command-line and checking dmesg/journalctl -ae. Also, you can
++ capture the stderr output of staprun by setting LOG_BOOT_ERR to 'yes' (see
++ 4.1.12).
+diff --git a/initscript/config.systemtap.in b/initscript/config.systemtap.in
+index 23068e1..9237b3b 100644
+--- a/initscript/config.systemtap.in
++++ b/initscript/config.systemtap.in
+@@ -18,3 +18,6 @@
+ # Start these scripts by default. If omitted, all scripts are started.
+ # DEFAULT_START=
+ 
++# Log boot-time staprun stderr to /var/run/systemtap/$script.log
++# LOG_BOOT_ERR=no
++
+diff --git a/initscript/systemtap.in b/initscript/systemtap.in
+old mode 100644
+new mode 100755
+index c1c8854..5290f56
+--- a/initscript/systemtap.in
++++ b/initscript/systemtap.in
+@@ -36,6 +36,11 @@ STAP=@bindir@/stap
+ STAPRUN=@bindir@/staprun
+ UNAME=/bin/uname
+ LSMOD=/sbin/lsmod
++DRACUT=/sbin/dracut
++
++# Not actually used directly, but needed by
++# stap dracut module for inclusion in initramfs
++STAPIO=@libexecdir@/systemtap/stapio
+ 
+ # Path setup
+ SCRIPT_PATH=@sysconfdir@/systemtap/script.d
+@@ -45,6 +50,9 @@ STAT_PATH=@localstatedir@/run/systemtap
+ TEMP_PATH=/tmp
+ LOG_FILE=@localstatedir@/log/systemtap.log
+ 
++# NB: this path is also used in 99stap/module-setup.sh
++DRACUT_SRC=@prefix@/lib/dracut/modules.d/99stap/params.conf
++
+ # FAIL unless all scripts succeeded to run
+ PASSALL=yes
+ 
+@@ -60,6 +68,9 @@ DEFAULT_START=
+ # Allow cache only scripts
+ ALLOW_CACHEONLY=no
+ 
++# Log boot-time staprun stderr to /var/run/systemtap/$script.log
++LOG_BOOT_ERR=no
++
+ # Optional settings
+ CONFIG=@sysconfdir@/systemtap/config
+ SCRIPTS=
+@@ -68,14 +79,18 @@ OPT_RECURSIVE=
+ OPT_SCRIPTS=
+ OPTS=
+ OPT_ASSUMEYES=
++INITRAMFS=
++BACKUP_INITRAMFS=
+ 
+ echo_usage () {
+-  echo $"Usage: $prog {start|stop|status|restart|compile|cleanup|condrestart|try-restart|reload|force-reload} [option]"
++  echo $"Usage: $prog {start|stop|status|restart|compile|onboot|cleanup|condrestart|try-restart|reload|force-reload} [option]"
+   echo $"Options:"
++  echo $"	-b		: backup initramfs before overwriting"
+   echo $"	-c configfile	: specify config file"
++  echo $"	-o path.img	: specify initramfs output file"
+   echo $"	-r kernelrelease: specify kernel release version"
+   echo $"	-R 		: recursively dependency checking"
+-  echo $"	-y 		: answer yes for all questions."
++  echo $"	-y 		: answer yes for all questions"
+   echo $"	script(s)	: specify systemtap scripts"
+ }
+ 
+@@ -154,6 +169,13 @@ parse_args () { # arguments
+       -y)
+         OPT_ASSUMEYES=1
+         ;;
++      -o)
++        INITRAMFS=$2
++        shift 1
++        ;;
++      -b)
++        BACKUP_INITRAMFS=1
++        ;;
+       --)
+         ;;
+       *)
+@@ -166,7 +188,7 @@ parse_args () { # arguments
+ 
+ CMD=$1
+ shift 1
+-OPTS=`getopt -s bash -u -o 'r:c:Ry' -- $@`
++OPTS=`getopt -s bash -u -o 'r:c:Ryo:b' -- $@`
+ if [ $? -ne 0 ]; then
+   slog "Error: Argument parse error: $@"
+   failure $"parse error"
+@@ -175,6 +197,11 @@ if [ $? -ne 0 ]; then
+ fi
+ parse_args $OPTS
+ 
++# Set default output file if not given as an option
++if [ ! "$INITRAMFS" ]; then
++  INITRAMFS=/boot/initramfs-$KRELEASE.img
++fi
++
+ # Include configs
+ . "$CONFIG"
+ 
+@@ -188,7 +215,7 @@ check_bool $PASSALL
+ PASSALL=$?
+ check_bool $RECURSIVE
+ RECURSIVE=$?
+-if [ "$OPT_RECURSIVE" ]; then # -r option overrides RECURSIVE.
++if [ "$OPT_RECURSIVE" ]; then # -R option overrides RECURSIVE.
+   RECURSIVE=1
+ fi
+ check_bool $AUTOCOMPILE
+@@ -198,6 +225,9 @@ CACHE_PATH="$CACHE_PATH/$KRELEASE"
+ check_bool $ALLOW_CACHEONLY
+ ALLOW_CACHEONLY=$?
+ 
++check_bool $LOG_BOOT_ERR
++LOG_BOOT_ERR=$?
++
+ __get_all_scripts () {
+   local s
+   if [ $ALLOW_CACHEONLY -eq 1 ]; then
+@@ -225,6 +255,29 @@ else
+   SCRIPTS="$OPT_SCRIPTS"
+ fi
+ 
++# Move over any pid files in /var/run/systemtap (from boot-time scripts)
++# to the user-defined $STAT_PATH if it's different.
++if [ "$STAT_PATH" != /var/run/systemtap ] && # XXX: use inodes instead?
++   [ -d /var/run/systemtap ]; then
++
++   # Check if there's stuff to copy
++  if [ "$(ls -A /var/run/systemtap)" ]; then
++
++    # Create target dir if it does not exist
++    if [ ! -d "$STAT_PATH" ]; then
++      logex mkdir -p "$STAT_PATH"
++      if [ $? -ne 0 ]; then
++        do_failure $"Failed to make stat directory ($STAT_PATH)"
++        exit 1
++      fi
++    fi
++
++    cp /var/run/systemtap/* "$STAT_PATH"
++  fi
++
++  rm -rf /var/run/systemtap
++fi
++
+ #------------------------------------------------------------------
+ # Main routine
+ #------------------------------------------------------------------
+@@ -328,10 +381,13 @@ get_compile_opts () { # opts
+   done
+ }
+ 
++# Returns 0 if something went wrong
++# Returns 1 if in -L mode
++# Returns 2 if in -D (daemon) mode
+ get_run_opts () { # normalized_opts
+   local opts o show mode
+   opts=`stap_getopt $*`
+-  [ $? -ne 0 ] && return 1
++  [ $? -ne 0 ] && return 0
+   mode='-L'
+   show=0
+   for o in $opts; do
+@@ -351,6 +407,9 @@ get_run_opts () { # normalized_opts
+     esac
+   done
+   echo -n $mode
++  [ "$mode" == "-L" ] && return 1
++  [ "$mode" == "-D" ] && return 2
++  return 0
+ }
+ 
+ prepare_cache_dir () {
+@@ -457,7 +516,7 @@ sort_dependency () { # scripts
+ }
+ 
+ start_script () { # script
+-  local tmpdir s=$1 ret count=0
++  local tmpdir s=$1 ret count=0 mode
+   check_running $s
+   ret=$?
+   [ $ret -eq 0 ] && return 0 # already running
+@@ -472,7 +531,8 @@ start_script () { # script
+ 
+   eval opts=\$${s}_OPT
+   opts=`get_run_opts $opts`
+-  [ $? -ne 0 ] && return 2
++  mode=$?
++  [ $mode -eq 0 ] && return 2
+ 
+   clog " Starting $1 ... " -n
+   tmpdir=`mktemp -d -p "$TEMP_PATH" cache.XXXXXXXX`  # bz7097
+@@ -489,12 +549,14 @@ start_script () { # script
+   # used, staprun detaches from the terminal and *then* prints the new
+   # pid.  So, it is possible to check the ./pid file before it has
+   # been written.  To avoid this, wait a bit (if necessary).
+-  while [ $count -lt 10 ]; do
+-    # when the file exists and has a size > 0, quit
+-    [ -s ./pid ] && break
+-    sleep 1
+-    count=`expr $count + 1`
+-  done
++  if [ $mode -eq 2 ]; then
++    while [ $count -lt 10 ]; do
++      # when the file exists and has a size > 0, quit
++      [ -s ./pid ] && break
++      sleep 1
++      count=`expr $count + 1`
++    done
++  fi
+ 
+   [ x`cat ./pid` = x ] && echo 0 > ./pid
+   if [ $ret -eq 0 ]; then
+@@ -674,6 +736,142 @@ compile () {
+   return 0
+ }
+ 
++# Writes info to $DRACUT_SRC, which the stap dracut module will source
++# Includes all needed info such as location of stap/staprun, which
++# scripts to insert, and their options
++update_dracut() { # scripts
++  local s opts
++
++  if [ -f "$DRACUT_SRC" ]; then
++    rm -f "$DRACUT_SRC"
++  fi
++
++  echo      "STAPRUN=\"$STAPRUN\""      >> "$DRACUT_SRC"
++  echo       "STAPIO=\"$STAPIO\""       >> "$DRACUT_SRC"
++  echo   "CACHE_PATH=\"$CACHE_PATH\""   >> "$DRACUT_SRC"
++  echo    "STAT_PATH=\"$STAT_PATH\""    >> "$DRACUT_SRC"
++  echo     "KRELEASE=\"$KRELEASE\""     >> "$DRACUT_SRC"
++  echo "LOG_BOOT_ERR=\"$LOG_BOOT_ERR\"" >> "$DRACUT_SRC"
++
++  echo -n "ONBOOT_SCRIPTS=\"" >> "$DRACUT_SRC"
++  for s in $*; do
++    echo -n "$s " >> "$DRACUT_SRC"
++  done
++  echo "\"" >> "$DRACUT_SRC"
++
++  for s in $*; do
++    eval opts=\$${s}_OPT
++    opts=`get_run_opts $opts`
++    [ $? -eq 0 ] && return 1
++    echo -n "$s" >> "$DRACUT_SRC"
++    echo "_OPT=\"$opts\"" >> "$DRACUT_SRC"
++  done
++}
++
++backup_initramfs() {
++  # does target file exist?
++  if [ -f "$INITRAMFS" ]; then
++    # don't overwrite an existing backup
++    if [ ! -f "$INITRAMFS.bak" ]; then
++      mv "$INITRAMFS" "$INITRAMFS.bak"
++      clog "Renamed $INITRAMFS"
++      clog "     to $INITRAMFS.bak"
++      RESTORE_INITRAMFS_ON_FAIL=1
++    else
++      clog "Backup already exists: $INITRAMFS.bak"
++    fi
++  fi
++}
++
++onboot () {
++  local s ret ss
++  if [ ! -f "$DRACUT" ]; then
++    clog "Could not find $DRACUT" -n
++    do_failure "$DRACUT not found"
++    clog
++    clog "The system must be dracut-based to use this feature"
++    clog "If it is located elsewhere, modify the \$DRACUT parameter" -n
++    return 1
++  fi
++  if [ ! -d "$(dirname $DRACUT_SRC)" ]; then
++    clog "Could not find dracut module" -n
++    do_failure "SystemTap dracut module $(dirname $DRACUT_SRC) not found"
++    return 1
++  fi
++  prepare_cache_dir
++  if [ $? -ne 0 ]; then
++    do_failure "Failed to make cache directory ($CACHE_PATH)"
++    return 1
++  fi
++  # NB: we use OPT_SCRIPTS, not SCRIPTS because we want
++  # no scripts passed to mean building a virgin initramfs
++  for s in $OPT_SCRIPTS; do
++    compile_script $s check
++    ret=$?
++    [ $ret -ne 0 ] && might_fail "Could not compile $s ($ret)"
++    eval opts=\$${s}_OPT
++    opts=`get_run_opts $opts`
++    mode=$?
++    clog " Checking options $s ... " -n
++    [ $mode -eq 0 ] && might_fail "Bad runtime options for script $s"
++    [ $mode -eq 2 ] && might_fail "Unsupported option -o in script $s"
++    if [ $ret -eq 0 ] && [ $mode -eq 1 ]; then
++      ss="$ss$s "
++      clog "done"
++    fi
++  done
++  # User specified script(s) but they were all skipped
++  if [ -n "$OPT_SCRIPTS" ] && [ -z "$ss" ]; then
++    do_failure "No scripts left to operate on"
++    return 1
++  fi
++  if [ ! "$ss" ]; then
++    clog " Creating initramfs without scripts ... " -n
++  else
++    clog " Creating initramfs with $ss... " -n
++  fi
++  update_dracut $ss
++  if [ $? -ne 0 ]; then
++    do_failure "Call to update_dracut failed. Bad opts?"
++    return 1
++  fi
++  if [ "$BACKUP_INITRAMFS" ]; then
++    backup_initramfs
++  fi
++  dir=`dirname $INITRAMFS` && TMPINITRAMFS=`mktemp --tmpdir=$dir`
++  if [ $? -ne 0 ]; then
++    do_failure "Failed to make temporary file in $dir"
++    return 1
++  fi
++  out=$($DRACUT --force $TMPINITRAMFS $KRELEASE 2>&1)
++  # dracut will report success even if some modules (e.g. stap) failed
++  # to install some files, so we need to be a bit more involved in
++  # checking for errors
++  if [ $? -ne 0 ] || [[ "$out" == *ERROR* ]]; then
++    do_failure "The initramfs creation is unsuccessful"
++    if [ -f /var/log/dracut.log ]; then
++      do_failure "See /var/log/dracut.log for more info"
++    else
++      do_failure "See dracut log for more info"
++    fi
++    echo # We need a new line
++    if [ -f "$TMPINITRAMFS" ]; then
++      rm "$TMPINITRAMFS"
++    fi
++    # Put back the initramfs if we moved it (if we didn't move it, then
++    # whatever initramfs they used to boot in is still there)
++    if [ "$RESTORE_INITRAMFS_ON_FAIL" ]; then
++      mv "$INITRAMFS.bak" "$INITRAMFS"
++      clog "Renamed $INITRAMFS.bak"
++      clog "     to $INITRAMFS"
++    fi
++    return 1
++  fi
++  mv "$TMPINITRAMFS" "$INITRAMFS"
++  might_success "initramfs created"
++  return 0
++}
++
+ # Cleanup caches
+ cleanup () {
+   local s ss ret
+@@ -731,6 +929,10 @@ case $CMD in
+   compile
+   RETVAL=$?
+   ;;
++  onboot)
++  onboot
++  RETVAL=$?
++  ;;
+   cleanup)
+   cleanup
+   RETVAL=$?
+@@ -748,3 +950,5 @@ esac
+ 
+ echo
+ exit $RETVAL
++
++# vim: sw=2 ts=8
+diff --git a/systemtap.spec b/systemtap.spec
+index 39d22ca..6cd5853 100644
+--- a/systemtap.spec
++++ b/systemtap.spec
+@@ -32,6 +32,7 @@
+ # don't want to build runtime-virthost for f18 or RHEL5/6
+ %{!?with_virthost: %global with_virthost 0%{?fedora} >= 19 || 0%{?rhel} >= 7}
+ %{!?with_virtguest: %global with_virtguest 1}
++%{!?with_dracut: %global with_dracut 0%{?fedora} >= 19 || 0%{?rhel} >= 7}
+ 
+ %if 0%{?fedora} >= 18 || 0%{?rhel} >= 6
+    %define initdir %{_initddir}
+@@ -47,6 +48,9 @@
+    %endif
+ %endif
+ 
++%define dracutlibdir %{_prefix}/lib/dracut
++%define dracutstap %{dracutlibdir}/modules.d/99stap
++
+ Name: systemtap
+ Version: 2.4
+ Release: 1%{?dist}
+@@ -60,7 +64,7 @@ Release: 1%{?dist}
+ # systemtap-devel        /usr/bin/stap, runtime, tapset, req:kernel-devel
+ # systemtap-runtime      /usr/bin/staprun, /usr/bin/stapsh, /usr/bin/stapdyn
+ # systemtap-client       /usr/bin/stap, samples, docs, tapset(bonus), req:-runtime
+-# systemtap-initscript   /etc/init.d/systemtap, req:systemtap
++# systemtap-initscript   /etc/init.d/systemtap, dracut module, req:systemtap
+ # systemtap-sdt-devel    /usr/include/sys/sdt.h /usr/bin/dtrace
+ # systemtap-testsuite    /usr/share/systemtap/testsuite*, req:systemtap, req:sdt-devel
+ # systemtap-runtime-java libHelperSDT.so, HelperSDT.jar, stapbm, req:-runtime
+@@ -245,7 +249,9 @@ Requires(preun): initscripts
+ Requires(postun): initscripts
+ 
+ %description initscript
+-Sysvinit scripts to launch selected systemtap scripts at system startup.
++This package includes a SysVinit script to launch selected systemtap
++scripts at system startup, along with a dracut module for early
++boot-time probing if supported.
+ 
+ 
+ %package sdt-devel
+@@ -545,6 +551,13 @@ done
+    %endif
+ %endif
+ 
++%if %{with_dracut}
++   mkdir -p $RPM_BUILD_ROOT%{dracutstap}
++   install -p -m 755 initscript/99stap/module-setup.sh $RPM_BUILD_ROOT%{dracutstap}
++   install -p -m 755 initscript/99stap/start-staprun.sh $RPM_BUILD_ROOT%{dracutstap}
++   touch $RPM_BUILD_ROOT%{dracutstap}/params.conf
++%endif
++
+ %clean
+ rm -rf ${RPM_BUILD_ROOT}
+ 
+@@ -615,7 +628,7 @@ if [ $1 = 0 ] ; then
+        /bin/systemctl stop stap-server.service >/dev/null 2>&1 || :
+     %else
+         /sbin/service stap-server stop >/dev/null 2>&1
+-    	/sbin/chkconfig --del stap-server
++        /sbin/chkconfig --del stap-server
+     %endif
+ fi
+ exit 0
+@@ -625,7 +638,7 @@ exit 0
+ # If so, restart the service if it's running
+ if [ "$1" -ge "1" ] ; then
+     %if %{with_systemd}
+-    	/bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
++        /bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
+     %else
+         /sbin/service stap-server condrestart >/dev/null 2>&1 || :
+     %endif
+@@ -634,8 +647,7 @@ exit 0
+ 
+ %post initscript
+ %if %{with_systemd}
+-    /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
+-     /bin/systemd-tmpfiles --create >/dev/null 2>&1 || :
++    /bin/systemctl enable systemtap.service >/dev/null 2>&1 || :
+ %else
+     /sbin/chkconfig --add systemtap
+ %endif
+@@ -646,11 +658,11 @@ exit 0
+ # just removing the old package on upgrade.
+ if [ $1 = 0 ] ; then
+     %if %{with_systemd}
+-    	/bin/systemctl --no-reload disable stap-server.service >/dev/null 2>&1 || :
+-	/bin/systemctl stop stap-server.service >/dev/null 2>&1 || :
++        /bin/systemctl --no-reload disable systemtap.service >/dev/null 2>&1 || :
++        /bin/systemctl stop systemtap.service >/dev/null 2>&1 || :
+     %else
+         /sbin/service systemtap stop >/dev/null 2>&1
+-    	/sbin/chkconfig --del systemtap
++        /sbin/chkconfig --del systemtap
+     %endif
+ fi
+ exit 0
+@@ -660,7 +672,7 @@ exit 0
+ # If so, restart the service if it's running
+ if [ "$1" -ge "1" ] ; then
+     %if %{with_systemd}
+-        /bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
++        /bin/systemctl condrestart systemtap.service >/dev/null 2>&1 || :
+     %else
+         /sbin/service systemtap condrestart >/dev/null 2>&1 || :
+     %endif
+@@ -917,6 +929,10 @@ done
+ %dir %{_localstatedir}/cache/systemtap
+ %ghost %{_localstatedir}/run/systemtap
+ %doc initscript/README.systemtap
++%if %{with_dracut}
++   %dir %{dracutstap}
++   %{dracutstap}/*
++%endif
+ 
+ 
+ %files sdt-devel
+@@ -970,6 +986,9 @@ done
+ #   http://sourceware.org/systemtap/wiki/SystemTapReleases
+ 
+ %changelog
++* Mon Jan 06 2014 Jonathan Lebon <jlebon@redhat.com>
++- Added dracut module to initscript package
++
+ * Wed Nov 06 2013 Frank Ch. Eigler <fche@redhat.com> - 2.4-1
+ - Upstream release.
+ 
+diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
+index 05491f3..d0f90ea 100644
+--- a/tapset-utrace.cxx
++++ b/tapset-utrace.cxx
+@@ -700,15 +700,6 @@ struct utrace_builder: public derived_probe_builder
+         sess.unwindsym_modules.insert (path);
+         path_tgt = path_remove_sysroot(sess, path);
+       }
+-    else if (has_pid)
+-      {
+-	// We can't probe 'init' (pid 1).  XXX: where does this limitation come from?
+-	if (pid < 2)
+-	  throw SEMANTIC_ERROR (_("process pid must be greater than 1"),
+-				location->components.front()->tok);
+-
+-        // XXX: could we use /proc/$pid/exe in unwindsym_modules and elsewhere?
+-      }
+ 
+     finished_results.push_back(new utrace_derived_probe(sess, base, location,
+ 							has_path, path_tgt, pid,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1054954.patch b/SOURCES/rhbz1054954.patch
new file mode 100644
index 0000000..e3df1cf
--- /dev/null
+++ b/SOURCES/rhbz1054954.patch
@@ -0,0 +1,24 @@
+From f551ef1599fa4ff5d244285eef731928a5d9820e Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Tue, 10 Dec 2013 11:38:39 -0500
+Subject: BZ1054954: PR16309: spawn stap-serverd with / cwd
+
+---
+ stap-start-server | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/stap-start-server b/stap-start-server
+index b6ec943..4221631 100755
+--- a/stap-start-server
++++ b/stap-start-server
+@@ -18,6 +18,7 @@
+ startup_timeout=10
+ 
+ # start the server
++cd / # change to a dir we're 100% sure we have RD_ONLY access to
+ ${stap_pkglibexecdir}stap-serverd "$@" </dev/null >/dev/null 2>/dev/null &
+ server_pid=$!
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1054956.patch b/SOURCES/rhbz1054956.patch
new file mode 100644
index 0000000..6f65b6e
--- /dev/null
+++ b/SOURCES/rhbz1054956.patch
@@ -0,0 +1,84 @@
+From b48894ebfc1e123ec9030bb7a31a269d13995ce0 Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Sat, 30 Nov 2013 11:14:25 -0500
+Subject: BZ1054956: stapsh.c: fix handling of POLLIN to indicate EOF
+
+We previously relied on POLLHUP to indicate EOF. However, it is also
+possible to receive POLLIN when EOF is reached. With this patch, upon
+receiving POLLIN and reading from the associated fd, if EOF is found, we
+modify the polling array to indicate we're no longer interested.
+---
+ staprun/stapsh.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/staprun/stapsh.c b/staprun/stapsh.c
+index 3d88537..5c3229b 100644
+--- a/staprun/stapsh.c
++++ b/staprun/stapsh.c
+@@ -638,7 +638,11 @@ process_command(void)
+   // stap commands are short and always end in \n. Even if we do block it's not
+   // so bad a thing.
+   if (fgets(command, sizeof(command), stapsh_in) == NULL)
+-    return;
++    {
++      if (feof(stapsh_in)) // no more stap commands coming
++        pfds[PFD_STAP_OUT].events = 0;
++      return;
++    }
+ 
+   dbug(1, "command: %s", command);
+   const char* arg = strtok(command, STAPSH_TOK_DELIM) ?: "(null)";
+@@ -665,10 +669,10 @@ process_command(void)
+ }
+ 
+ static void
+-prefix_staprun(int fdin, FILE *out, const char *stream)
++prefix_staprun(int i, FILE *out, const char *stream)
+ {
+   char buf[4096];
+-  ssize_t n = read(fdin, buf, sizeof buf);
++  ssize_t n = read(pfds[i].fd, buf, sizeof buf);
+   if (n > 0)
+     {
+       // actually check if we need to prefix data (we could also be piping for
+@@ -679,6 +683,8 @@ prefix_staprun(int fdin, FILE *out, const char *stream)
+         dbug(2, "failed fwrite\n"); // appease older gccs (don't ignore fwrite rc)
+       fflush(out);
+     }
++  else if (n == 0) // eof
++    pfds[i].events = 0;
+ }
+ 
+ int
+@@ -751,17 +757,24 @@ main(int argc, char* const argv[])
+       sleep(2); // Once we support only platforms with guaranteed SIGIO support,
+                 // we could replace this with a pause().
+ 
+-  for (;;)
++  // keep polling as long as we're listening for stap commands
++  while (pfds[PFD_STAP_OUT].events)
+     {
+-      poll(pfds, staprun_pid > 0 ? 3 : 1, -1);
++      if (poll(pfds, 3, -1) < 0)
++        {
++          if (errno == EINTR)
++            continue; // go back to poll()
++          else
++            die ("poll() failed with critical error");
++        }
+       if (pfds[PFD_STAP_OUT].revents & POLLHUP)
+         break;
+       if (pfds[PFD_STAP_OUT].revents & POLLIN)
+         process_command();
+       if (pfds[PFD_STAPRUN_OUT].revents & POLLIN)
+-        prefix_staprun(pfds[PFD_STAPRUN_OUT].fd, stapsh_out, "stdout");
++        prefix_staprun(PFD_STAPRUN_OUT, stapsh_out, "stdout");
+       if (pfds[PFD_STAPRUN_ERR].revents & POLLIN)
+-        prefix_staprun(pfds[PFD_STAPRUN_ERR].fd, stapsh_err, "stderr");
++        prefix_staprun(PFD_STAPRUN_ERR, stapsh_err, "stderr");
+     }
+ 
+   cleanup(0);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1054962.patch b/SOURCES/rhbz1054962.patch
new file mode 100644
index 0000000..3a89259
--- /dev/null
+++ b/SOURCES/rhbz1054962.patch
@@ -0,0 +1,93 @@
+From a94b495c5b48324cecff42afce15a4d843577741 Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Wed, 13 Nov 2013 12:29:49 -0500
+Subject: BZ1054962
+
+BZ1054962: PR16166: assign token to new block
+
+BZ1054962: stap translator: tolerate NULLs coming from some elfutils string lookups
+
+It was reported on the mailing list, and privately experienced, that
+stap pass-2 crashes could occur due to NULL dwarf_diename or
+dwarf_decl_file's being propagated rather far within stap.  This
+commit adds protections (of the form ?: "foo") to eliminate the
+problem in a few spots.  There may be others; we should not store
+so many raw char*'s.
+---
+ dwflpp.cxx  |  4 ++--
+ tapsets.cxx | 16 +++++++++++-----
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/dwflpp.cxx b/dwflpp.cxx
+index f8b1517..93713d0 100644
+--- a/dwflpp.cxx
++++ b/dwflpp.cxx
+@@ -1742,7 +1742,7 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
+                 {
+                   // Get the file/line number for this label
+                   int dline;
+-                  const char *file = dwarf_decl_file (&die);
++                  const char *file = dwarf_decl_file (&die) ?: "<unknown source>";
+                   dwarf_decl_line (&die, &dline);
+ 
+                   vector<Dwarf_Die> scopes = getscopes_die(&die);
+@@ -2045,7 +2045,7 @@ dwflpp::function_file (char const ** c)
+ {
+   assert (function);
+   assert (c);
+-  *c = dwarf_decl_file (function);
++  *c = dwarf_decl_file (function) ?: "<unknown source>";
+ }
+ 
+ 
+diff --git a/tapsets.cxx b/tapsets.cxx
+index 6dea4d2..205de34 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -1683,8 +1683,14 @@ inline_instance_info::operator<(const inline_instance_info& other) const
+     return decl_line < other.decl_line;
+ 
+   int cmp = name.compare(other.name);
+-  if (!cmp)
+-    cmp = strcmp(decl_file, other.decl_file);
++
++  if (!cmp) 
++    {
++      assert (decl_file);
++      assert (other.decl_file);
++      cmp = strcmp(decl_file, other.decl_file);
++    }
++
+   return cmp < 0;
+ }
+ 
+@@ -3874,6 +3880,7 @@ dwarf_var_expanding_visitor::visit_perf_op (perf_op *e)
+   t->content = e_lit_val;
+ 
+   add_block = new block;
++  add_block->tok = e->tok;
+ 
+   systemtap_session &s = this->q.sess;
+   map<string, pair<string,derived_probe*> >::iterator it;
+@@ -4187,8 +4194,7 @@ dwarf_atvar_query::atvar_query_cu (Dwarf_Die * cudie, void * data)
+ 
+   if (! q->e.cu_name.empty())
+     {
+-      const char *die_name = dwarf_diename(cudie);
+-
++      const char *die_name = dwarf_diename(cudie) ?: "";
+       if (strcmp(die_name, q->e.cu_name.c_str()) != 0 // Perfect match
+           && fnmatch(q->cu_name_pattern.c_str(), die_name, 0) != 0)
+         {
+@@ -9714,7 +9720,7 @@ tracepoint_derived_probe::build_args(dwflpp&, Dwarf_Die& func_die)
+         {
+           // build a tracepoint_arg for this parameter
+           tracepoint_arg tparg;
+-          tparg.name = dwarf_diename(&arg);
++          tparg.name = dwarf_diename(&arg) ?: "";
+ 
+           // read the type of this parameter
+           if (!dwarf_attr_die (&arg, DW_AT_type, &tparg.type_die)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1055778.patch b/SOURCES/rhbz1055778.patch
new file mode 100644
index 0000000..169f8a6
--- /dev/null
+++ b/SOURCES/rhbz1055778.patch
@@ -0,0 +1,91 @@
+diff --git a/buildrun.cxx b/buildrun.cxx
+index 3c26d50..cfb3ae0 100644
+--- a/buildrun.cxx
++++ b/buildrun.cxx
+@@ -1,5 +1,5 @@
+ // build/run probes
+-// Copyright (C) 2005-2013 Red Hat Inc.
++// Copyright (C) 2005-2014 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
+@@ -378,6 +378,7 @@ compile_pass (systemtap_session& s)
+   output_autoconf(s, o, "autoconf-relay-umode_t.c", "STAPCONF_RELAY_UMODE_T", NULL);
+   output_autoconf(s, o, "autoconf-fs_supers-hlist.c", "STAPCONF_FS_SUPERS_HLIST", NULL);
+   output_autoconf(s, o, "autoconf-compat_sigaction.c", "STAPCONF_COMPAT_SIGACTION", NULL);
++  output_autoconf(s, o, "autoconf-netfilter.c", "STAPCONF_NETFILTER_V313", NULL);
+ 
+   // used by tapset/timestamp_monotonic.stp
+   output_exportconf(s, o, "cpu_clock", "STAPCONF_CPU_CLOCK");
+diff --git a/man/stapprobes.3stap b/man/stapprobes.3stap
+index 4bc99fc..2229c9c 100644
+--- a/man/stapprobes.3stap
++++ b/man/stapprobes.3stap
+@@ -1043,6 +1043,9 @@ the C code generated by systemtap.
+ 
+ The netfilter probe points define the following context variables:
+ .TP
++.IR $hooknum
++The hook number.
++.TP
+ .IR $skb
+ The address of the sk_buff struct representing the packet. See
+ <linux/skbuff.h> for details on how to use this struct, or
+diff --git a/runtime/linux/autoconf-netfilter.c b/runtime/linux/autoconf-netfilter.c
+new file mode 100644
+index 0000000..f122664
+--- /dev/null
++++ b/runtime/linux/autoconf-netfilter.c
+@@ -0,0 +1,16 @@
++#include <linux/netfilter.h>
++
++unsigned int
++new_style_hook(const struct nf_hook_ops *ops,  /* not: unsigned int hook; */
++               struct sk_buff *skb,
++               const struct net_device *in, const struct net_device *out,
++               int (*okfn)(struct sk_buff *))
++{
++  (void) ops; (void) skb;  (void) in; (void) out; (void) okfn;
++  return 0;
++}
++
++struct nf_hook_ops netfilter_ops = {
++  .hook = new_style_hook
++};
++
+diff --git a/tapset-netfilter.cxx b/tapset-netfilter.cxx
+index f20b569..eec7e31 100644
+--- a/tapset-netfilter.cxx
++++ b/tapset-netfilter.cxx
+@@ -1,5 +1,5 @@
+ // tapset for netfilter hooks
+-// Copyright (C) 2012 Red Hat Inc.
++// Copyright (C) 2012-2014 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
+@@ -267,7 +267,13 @@ netfilter_derived_probe_group::emit_module_decls (systemtap_session& s)
+       // Previous to kernel 2.6.22, the hookfunction definition takes a struct sk_buff **skb,
+       // whereas currently it uses a *skb. We need emit the right version so this will
+       // compile on RHEL5, for example.
+-      s.op->newline() << "#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)";
++      s.op->newline() << "#ifdef STAPCONF_NETFILTER_V313";
++
++      s.op->newline() << "(const struct nf_hook_ops *nf_ops, struct sk_buff *nf_skb, const struct net_device *nf_in, const struct net_device *nf_out, int (*nf_okfn)(struct sk_buff *))";
++      s.op->newline() << "{";
++
++      s.op->newline() << "#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)";
++
+       s.op->newline() << "(unsigned int nf_hooknum, struct sk_buff *nf_skb, const struct net_device *nf_in, const struct net_device *nf_out, int (*nf_okfn)(struct sk_buff *))";
+       s.op->newline() << "{";
+ 
+@@ -280,6 +286,9 @@ netfilter_derived_probe_group::emit_module_decls (systemtap_session& s)
+       s.op->newline(-1) << "#endif";
+       s.op->newline(1) << "const struct stap_probe * const stp = & stap_probes[" << np->session_index << "];";
+       s.op->newline() << "int nf_verdict = NF_ACCEPT;"; // default NF_ACCEPT, to be used by $verdict context var
++      s.op->newline() << "#ifdef STAPCONF_NETFILTER_V313";
++      s.op->newline() << "unsigned int nf_hooknum = nf_ops->hooknum;";
++      s.op->newline() << "#endif";
+       common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "stp",
+                                      "stp_probe_type_netfilter",
+                                      false);
diff --git a/SOURCES/rhbz1056687.patch b/SOURCES/rhbz1056687.patch
new file mode 100644
index 0000000..f936c9e
--- /dev/null
+++ b/SOURCES/rhbz1056687.patch
@@ -0,0 +1,35 @@
+commit fb3db0ca1cf6bed4bb4beabbf9bf91d09759cae6
+Author: Martin Cermak <mcermak@redhat.com>
+Date:   Wed Jan 22 17:01:36 2014 +0100
+
+    PR16448: adapt stap-prep for el7
+    
+    * stap-prep: use yum to install needed kernel information RPMs
+      should work across all yum-based rhel releases
+
+diff --git a/stap-prep b/stap-prep
+index 541316a..dc997ab 100755
+--- a/stap-prep
++++ b/stap-prep
+@@ -30,18 +30,10 @@ NEEDED=`rpm --qf "%{name}-%{version}-%{release}.%{arch}\n" \
+     -q $CANDIDATES | grep "is not installed" | awk '{print $2}'`
+ if [ "$NEEDED" != "" ]; then
+     echo -e "Need to install the following packages:\n$NEEDED"
+-    if [ `id -u` = "0" ]; then #attempt download and install
+-        DIR=`mktemp -d` || exit 1
+-        if [ ! -x /usr/bin/yumdownloader ]; then
+-            echo "Need to first install yum-utils for yumdownloader"
+-            yum install -y yum-utils
+-        fi
+-        yumdownloader --enablerepo="*debuginfo*" $NEEDED --destdir=$DIR \
+-                      --resolve
+-        check_error $? "problem downloading rpm(s) $NEEDED"
+-        rpm --force -ivh $DIR/*.rpm
++    if [ `id -u` = "0" ]; then #attempt to install
++        yum install -y --enablerepo=\* $NEEDED
++        rpm -q $NEEDED
+         check_error $? "problem installing rpm(s) $NEEDED"
+-        rm -r $DIR #cleanup
+     fi
+ fi
+ }
diff --git a/SOURCES/rhbz1057773.patch b/SOURCES/rhbz1057773.patch
new file mode 100644
index 0000000..72502b2
--- /dev/null
+++ b/SOURCES/rhbz1057773.patch
@@ -0,0 +1,40 @@
+From 95ac9a456e725b2f508c03322b5f13245e6027de Mon Sep 17 00:00:00 2001
+From: Josh Stone <jistone@redhat.com>
+Date: Fri, 24 Jan 2014 09:53:53 -0800
+Subject: [PATCH] Resolves: rhbz1057773
+
+---
+ systemtap.spec | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/systemtap.spec b/systemtap.spec
+index c8daaeb..09baff1 100644
+--- a/systemtap.spec
++++ b/systemtap.spec
+@@ -599,10 +599,11 @@ test -e %{_localstatedir}/log/stap-server/log || {
+ if test ! -e ~stap-server/.systemtap/ssl/server/stap.cert; then
+    runuser -s /bin/sh - stap-server -c %{_libexecdir}/systemtap/stap-gen-cert >/dev/null
+ fi
+-# Activate the service
++# Prepare the service
+ %if %{with_systemd}
+-     /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
+-     /bin/systemd-tmpfiles --create >/dev/null 2>&1 || :
++     # Note, Fedora policy doesn't allow network services enabled by default
++     # /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
++     /bin/systemd-tmpfiles --create %{_tmpfilesdir}/stap-server.conf >/dev/null 2>&1 || :
+ %else
+     /sbin/chkconfig --add stap-server
+ %endif
+@@ -636,7 +637,7 @@ exit 0
+ # If so, restart the service if it's running
+ if [ "$1" -ge "1" ] ; then
+     %if %{with_systemd}
+-        /bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
++        /bin/systemctl condrestart stap-server.service >/dev/null 2>&1 || :
+     %else
+         /sbin/service stap-server condrestart >/dev/null 2>&1 || :
+     %endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1062076.patch b/SOURCES/rhbz1062076.patch
new file mode 100644
index 0000000..9d5919e
--- /dev/null
+++ b/SOURCES/rhbz1062076.patch
@@ -0,0 +1,391 @@
+From ba7071cd1ca2ed84d351e6cfbe1db5c0bf1a5a09 Mon Sep 17 00:00:00 2001
+From: David Smith <dsmith@redhat.com>
+Date: Mon, 10 Feb 2014 09:59:21 -0600
+Subject: [PATCH] rhbz1062076
+
+---
+ tapset/linux/nfsd.stp | 130 +++++++++++++++++++++++++++++++++-----------------
+ tapset/linux/rpc.stp  |  15 ++++--
+ tapset/linux/scsi.stp |  16 ++++---
+ 3 files changed, 106 insertions(+), 55 deletions(-)
+
+diff --git a/tapset/linux/nfsd.stp b/tapset/linux/nfsd.stp
+index 092f55d..83765a3 100644
+--- a/tapset/linux/nfsd.stp
++++ b/tapset/linux/nfsd.stp
+@@ -146,6 +146,34 @@ function ftype:string(type:long) %{ /* pure */
+ 	}
+ %}
+ 
++function __rqstp_uid:long(rqstp:long)
++{
++%( CONFIG_USER_NS == "y" %?
++	# Notice we're using the 'init_user_ns' here, not
++	# 'current_user_ns()'. This matches up with the use in
++	# net/sunrpc/auth_generic.c.
++	return %{ /* pure */
++		  from_kuid_munged(&init_user_ns,
++				   ((struct svc_rqst *)STAP_ARG_rqstp)->rq_cred.cr_uid) %}
++%:
++	return @cast(rqstp, "svc_rqst", "kernel:nfsd")->rq_cred->cr_uid
++%)
++}
++
++function __rqstp_gid:long(rqstp:long)
++{
++%( CONFIG_USER_NS == "y" %?
++	# Notice we're using the 'init_user_ns' here, not
++	# 'current_user_ns()'. This matches up with the use in
++	# net/sunrpc/auth_generic.c.
++	return %{ /* pure */
++		  from_kgid_munged(&init_user_ns,
++				   ((struct svc_rqst *)STAP_ARG_rqstp)->rq_cred.cr_gid) %}
++%:
++	return @cast(rqstp, "svc_rqst", "kernel:nfsd")->rq_cred->cr_gid
++%)
++}
++
+ /**
+  * probe nfsd.dispatch - NFS server receives an operation from client 
+  *
+@@ -230,8 +258,8 @@ probe nfsd.proc2.lookup = kernel.function("nfsd_proc_lookup") !,
+ 	filelen = $argp->len
+ 	filename = kernel_string_n($argp->name, $argp->len)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc2.lookup"
+ 	argstr = sprintf("%s", kernel_string_n($argp->name, $argp->len))
+@@ -259,8 +287,8 @@ probe nfsd.proc3.lookup = kernel.function("nfsd3_proc_lookup") !,
+ 	filelen = $argp->len
+ 	filename  = kernel_string_n($argp->name, $argp->len)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.lookup"
+ 	argstr = sprintf("%s", kernel_string_n($argp->name, $argp->len))
+@@ -306,8 +334,8 @@ probe nfsd.proc4.lookup = kernel.function("nfsd4_lookup").call !,
+ 	filelen = $lookup->lo_len
+ 	filename  = kernel_string_n($lookup->lo_name, $lookup->lo_len)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.lookup"
+ 	argstr = sprintf("%s", kernel_string_n($lookup->lo_name, $lookup->lo_len))
+@@ -364,8 +392,8 @@ probe nfsd.proc2.read = kernel.function("nfsd_proc_read") !,
+ 	vec = @choose_defined($rqstp->rq_vec, $argp->vec)
+ 	vlen = $argp->vlen
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc2.read"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -398,8 +426,8 @@ probe nfsd.proc3.read = kernel.function("nfsd3_proc_read") !,
+ 	vec = @choose_defined($rqstp->rq_vec, $argp->vec)
+ 	vlen = $argp->vlen
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.read"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -432,8 +460,8 @@ probe nfsd.proc4.read = kernel.function("nfsd4_read").call !,
+ 	vec = $rqstp->rq_vec
+ 	vlen = $read->rd_vlen
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.read"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -494,8 +522,8 @@ probe nfsd.proc2.write = kernel.function("nfsd_proc_write") !,
+ 	vlen = $argp->vlen
+ 	stable = 1			# hardcoded in nfsd_proc_write()
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc2.write"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -531,8 +559,8 @@ probe nfsd.proc3.write = kernel.function("nfsd3_proc_write") !,
+ 	vlen = $argp->vlen
+ 	stable = $argp->stable
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.write"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -567,8 +595,8 @@ probe nfsd.proc4.write = kernel.function("nfsd4_write").call !,
+ 	vlen = @choose_defined($write->wr_vlen, 0)
+ 	stable = $write->wr_stable_how
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.write"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -625,8 +653,8 @@ probe nfsd.proc3.commit = kernel.function("nfsd3_proc_commit") !,
+ 	count = $argp->count 
+ 	offset = $argp->offset 
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.commit"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -656,8 +684,8 @@ probe nfsd.proc4.commit = kernel.function("nfsd4_commit").call !,
+ 	count = $commit->co_count 
+ 	offset = $commit->co_offset 
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.commit"
+ 	argstr = sprintf("%d,%d",count,offset)
+@@ -712,8 +740,8 @@ probe nfsd.proc2.create = kernel.function("nfsd_proc_create") !,
+ 	filename  = kernel_string_n($argp->name, $argp->len)
+ 	createmode = 0			# gets computed by nfsd_proc_create
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc2.create"
+ 	argstr = sprintf("%s", kernel_string_n($argp->name, $argp->len))
+@@ -742,8 +770,8 @@ probe nfsd.proc3.create = kernel.function("nfsd3_proc_create") !,
+ 	filename  = kernel_string_n($argp->name, $argp->len)
+ 	createmode = $argp->createmode
+ 	
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.create"
+ 	argstr = sprintf("%s (mode=%s)",
+@@ -775,8 +803,8 @@ probe nfsd.proc4.create = kernel.function("nfsd4_create").call !,
+ 	filename  = kernel_string_n($create->cr_name, $create->cr_namelen)
+ 	createmode = $create->cr_type
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.create"
+ 	argstr = sprintf("%s (type=%s)", 
+@@ -830,8 +858,8 @@ probe nfsd.proc2.remove = kernel.function("nfsd_proc_remove") !,
+ 	filelen = $argp->len
+ 	filename  = kernel_string_n($argp->name, $argp->len)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc2.remove"
+ 	argstr = sprintf("%s", kernel_string_n($argp->name, $argp->len))
+@@ -859,8 +887,8 @@ probe nfsd.proc3.remove = kernel.function("nfsd3_proc_remove") !,
+ 	filelen = $argp->len
+ 	filename  = kernel_string_n($argp->name, $argp->len)
+ 	
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.remove"
+ 	argstr = sprintf("%s", kernel_string_n($argp->name, $argp->len))
+@@ -887,8 +915,8 @@ probe nfsd.proc4.remove = kernel.function("nfsd4_remove").call !,
+ 	filelen = $remove->rm_namelen
+ 	filename  = kernel_string_n($remove->rm_name, $remove->rm_namelen)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.remove"
+ 	argstr = sprintf("%s", 
+@@ -946,8 +974,8 @@ probe nfsd.proc2.rename = kernel.function("nfsd_proc_rename") !,
+ 	tlen = $argp->tlen
+ 	tname = kernel_string_n($argp->tname, $argp->tlen)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc2.rename"
+ 	argstr = sprintf("%s to %s", 
+@@ -980,8 +1008,8 @@ probe nfsd.proc3.rename = kernel.function("nfsd3_proc_rename") !,
+ 	tlen = $argp->tlen
+ 	tname = kernel_string_n($argp->tname, $argp->tlen)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc3.rename"
+ 	argstr = sprintf("%s to %s", 
+@@ -1014,8 +1042,8 @@ probe nfsd.proc4.rename = kernel.function("nfsd4_rename").call !,
+ 	tlen = $rename->rn_tnamelen
+ 	tname = kernel_string_n($rename->rn_tname, $rename->rn_tnamelen)
+ 
+-	uid = $rqstp->rq_cred->cr_uid
+-	gid = $rqstp->rq_cred->cr_gid
++	uid = __rqstp_uid($rqstp)
++	gid = __rqstp_gid($rqstp)
+ 
+ 	name = "nfsd.proc4.rename"
+ 	argstr = sprintf("%s to %s", 
+@@ -1093,15 +1121,29 @@ probe nfsd.open.return = kernel.function("nfsd_open").return !,
+  *
+  * @filename: file name
+  */
+-probe nfsd.close = kernel.function("nfsd_close") !,
+-                   module("nfsd").function("nfsd_close") ?
++probe nfsd.close = __nfsd.call_close ?, __nfsd.inlined_close ?
+ {
+ 	client_ip ="N/A"
+-	filename = __file_filename($filp)
+-
+ 	name = "nfsd.close"
+ 	argstr = sprintf("%s",filename)
+ }
++/*
++ * Why split nfsd.close up into '__nfsd.call_close' and
++ * '__nfds.inlined_close'? We need the '@choose_defined()' since
++ * SystemTap has trouble accessing the arguments of inlined functions
++ * (PR 1155). But, if we only used '@choose_defined()', we wouldn't
++ * automatically notice a change in the argument name.
++ */
++probe __nfsd.call_close = kernel.function("nfsd_close").call !,
++			  module("nfsd").function("nfsd_close").call ?
++{
++	filename = __file_filename($filp)
++}
++probe __nfsd.inlined_close = kernel.function("nfsd_close").inline !,
++			     module("nfsd").function("nfsd_close").inline ?
++{
++	filename = __file_filename(@choose_defined($filp, 0))
++}
+ 
+ probe nfsd.close.return = kernel.function("nfsd_close").return !,
+                           module("nfsd").function("nfsd_close").return ?
+diff --git a/tapset/linux/rpc.stp b/tapset/linux/rpc.stp
+index 0b8d957..10c9d74 100644
+--- a/tapset/linux/rpc.stp
++++ b/tapset/linux/rpc.stp
+@@ -289,7 +289,8 @@ probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") !,
+ 	servername = kernel_string(@choose_defined($clnt->cl_server,
+ 				   @cast(rcu_dereference($clnt->cl_xprt),
+ 					 "struct rpc_xprt")->servername))
+-	progname = kernel_string($clnt->cl_protname)
++	progname = kernel_string(@choose_defined($clnt->cl_program->name,
++						 $clnt->cl_protname))
+ 	prog = prog_from_clnt($clnt)
+ 	vers = vers_from_clnt($clnt)
+ 	prot = prot_from_clnt($clnt)
+@@ -337,7 +338,8 @@ probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") !,
+ 	servername = kernel_string(@choose_defined($clnt->cl_server,
+ 				   @cast(rcu_dereference($clnt->cl_xprt),
+ 					 "struct rpc_xprt")->servername))
+-	progname = kernel_string($clnt->cl_protname)
++	progname = kernel_string(@choose_defined($clnt->cl_program->name,
++						 $clnt->cl_protname))
+ 	prog = prog_from_clnt($clnt)
+ 	vers = vers_from_clnt($clnt)
+ 	prot = prot_from_clnt($clnt)
+@@ -409,7 +411,8 @@ probe sunrpc.clnt.bind_new_program =
+ 	servername = kernel_string(@choose_defined($old->cl_server,
+ 				   @cast(rcu_dereference($old->cl_xprt),
+ 					 "struct rpc_xprt")->servername))
+-	old_progname = kernel_string($old->cl_protname)
++	old_progname = kernel_string(@choose_defined($old->cl_program->name,
++						     $old->cl_protname))
+ 	old_prog = prog_from_clnt($old)
+ 	old_vers = vers_from_clnt($old)
+ 	progname = kernel_string($program->name)
+@@ -450,7 +453,8 @@ probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") !,
+ 	servername = kernel_string(@choose_defined($clnt->cl_server,
+ 				   @cast(rcu_dereference($clnt->cl_xprt),
+ 					 "struct rpc_xprt")->servername))
+-	progname = kernel_string($clnt->cl_protname)
++	progname = kernel_string(@choose_defined($clnt->cl_program->name,
++						 $clnt->cl_protname))
+ 	prog = prog_from_clnt($clnt)
+ 	vers = vers_from_clnt($clnt)
+ 	prot = prot_from_clnt($clnt)
+@@ -497,7 +501,8 @@ probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") !,
+ 	servername = kernel_string(@choose_defined($clnt->cl_server,
+ 				   @cast(rcu_dereference($clnt->cl_xprt),
+ 					 "struct rpc_xprt")->servername))
+-	progname = kernel_string($clnt->cl_protname)
++	progname = kernel_string(@choose_defined($clnt->cl_program->name,
++						 $clnt->cl_protname))
+ 	prog = prog_from_clnt($clnt)
+ 	vers = vers_from_clnt($clnt)
+ 	prot = prot_from_clnt($clnt)
+diff --git a/tapset/linux/scsi.stp b/tapset/linux/scsi.stp
+index b8f0c2c..d54e83e 100644
+--- a/tapset/linux/scsi.stp
++++ b/tapset/linux/scsi.stp
+@@ -126,15 +126,19 @@ probe scsi.iodispatching
+  * @scsi_timer_pending: 1 if a timer is pending on this request
+  */
+ probe scsi.iodone
+-	= module("scsi_mod").function("scsi_done@drivers/scsi/scsi.c")!,
++	= kernel.trace("scsi_dispatch_cmd_done")!,
++	  module("scsi_mod").function("scsi_done@drivers/scsi/scsi.c")!,
+ 	  kernel.function("scsi_done@drivers/scsi/scsi.c")?
+ 
+ {
+-	host_no = $cmd->device->host->host_no
+-	channel = $cmd->device->channel
+-	lun = $cmd->device->lun
+-	dev_id = $cmd->device->id
+-	device_state = $cmd->device->sdev_state
++	# Why is the @cast() needed here? When the probe alias uses
++	# the "scsi_dispatch_cmd_done" tracepoint, the type info isn't
++	# in scope. 
++	host_no = @cast($cmd->device, "scsi_device", "kernel:scsi_mod")->host->host_no
++	channel = @cast($cmd->device, "scsi_device", "kernel:scsi_mod")->channel
++	lun = @cast($cmd->device, "scsi_device", "kernel:scsi_mod")->lun
++	dev_id = @cast($cmd->device, "scsi_device", "kernel:scsi_mod")->id
++	device_state = @cast($cmd->device, "scsi_device", "kernel:scsi_mod")->sdev_state
+ 	device_state_str = describe_device_state(device_state)
+ 	data_direction = $cmd->sc_data_direction
+ 	data_direction_str = describe_data_direction(data_direction)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.1.patch b/SOURCES/rhbz1073640.1.patch
new file mode 100644
index 0000000..42c9439
--- /dev/null
+++ b/SOURCES/rhbz1073640.1.patch
@@ -0,0 +1,354 @@
+From f4faaf86acd0fe9d410c16c8ec44664ef92559ef Mon Sep 17 00:00:00 2001
+From: Josh Stone <jistone@redhat.com>
+Date: Wed, 13 Nov 2013 17:04:19 -0800
+Subject: [PATCH] PR16162: Support .plt probes on prelinked libraries
+
+There were a few bias issues in how plt addresses were handled, which
+broke in the face of prelink offsets.  This patch tries to standardize
+how these addresses are handled.
+
+* tapsets.cxx (query_plt_statement): New function to fix plt addresses,
+  both adding dwfl's elf bias and subtracting the dw bias, so it will
+  work with dwflpp::relocate_address like everything else.
+  (base_query::base_query): Leave session::consult_symtab alone!
+  (dwarf_query::query_module_symtab): PLT doesn't fake a path through
+  the symbol table anymore.
+  (dwarf_query::handle_query_module): Direct PLT to query_plt_statement.
+  (dwarf_query::add_probe_point): Remove the relocate exemption for plt.
+* testsuite/systemtap.base/plt.exp: Update with a prelink test, and
+  refactor a lot of the test on the way.
+---
+ tapsets.cxx                      |  52 ++++++++-----
+ testsuite/systemtap.base/plt.exp | 163 ++++++++++++++++-----------------------
+ testsuite/systemtap.base/plt.stp |   9 +++
+ 3 files changed, 109 insertions(+), 115 deletions(-)
+ create mode 100644 testsuite/systemtap.base/plt.stp
+
+diff --git a/tapsets.cxx b/tapsets.cxx
+index 49740b0..f7947ca 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -405,6 +405,7 @@ static const string TOK_CLASS("class");;
+ 
+ static int query_cu (Dwarf_Die * cudie, void * arg);
+ static void query_addr(Dwarf_Addr addr, dwarf_query *q);
++static void query_plt_statement(dwarf_query *q);
+ 
+ // Can we handle this query with just symbol-table info?
+ enum dbinfo_reqt
+@@ -665,8 +666,6 @@ base_query::base_query(dwflpp & dw, literal_map_t const & params):
+       if ((has_plt = has_null_param (params, TOK_PLT)))
+         plt_val = "*";
+       else has_plt = get_string_param (params, TOK_PLT, plt_val);
+-      if (has_plt)
+-	sess.consult_symtab = true;
+       has_statement = get_number_param(params, TOK_STATEMENT, statement_num_val);
+ 
+       if (has_process)
+@@ -1049,14 +1048,7 @@ dwarf_query::query_module_symtab()
+       // Find the "function" in which the indicated address resides.
+       Dwarf_Addr addr =
+       		(has_function_num ? function_num_val : statement_num_val);
+-      if (has_plt)
+-        {
+-          // Use the raw address from the .plt
+-          fi = sym_table->get_first_func();
+-          fi->addr = addr;
+-        }
+-      else
+-        fi = sym_table->get_func_containing_address(addr);
++      fi = sym_table->get_func_containing_address(addr);
+ 
+       if (!fi)
+         {
+@@ -1081,6 +1073,12 @@ dwarf_query::query_module_symtab()
+ void
+ dwarf_query::handle_query_module()
+ {
++  if (has_plt && has_statement_num)
++    {
++      query_plt_statement (this);
++      return;
++    }
++
+   bool report = dbinfo_reqt == dbr_need_dwarf || !sess.consult_symtab;
+   dw.get_module_dwarf(false, report);
+ 
+@@ -1250,14 +1248,7 @@ dwarf_query::add_probe_point(const string& dw_funcname,
+ 
+   assert (! has_absolute); // already handled in dwarf_builder::build()
+ 
+-  if (!has_plt)
+-    reloc_addr = dw.relocate_address(addr, reloc_section);
+-  else
+-    {
+-      // Set the reloc_section but use the plt entry for reloc_addr
+-      dw.relocate_address(addr, reloc_section);
+-      reloc_addr = addr;
+-    }
++  reloc_addr = dw.relocate_address(addr, reloc_section);
+ 
+   // If we originally used the linkage name, then let's call it that way
+   const char* linkage_name;
+@@ -1515,6 +1506,29 @@ query_addr(Dwarf_Addr addr, dwarf_query *q)
+ }
+ 
+ static void
++query_plt_statement(dwarf_query *q)
++{
++  assert (q->has_plt && q->has_statement_num);
++
++  Dwarf_Addr addr = q->statement_num_val;
++  if (q->sess.verbose > 2)
++    clog << "query_plt_statement 0x" << hex << addr << dec << endl;
++
++  // First adjust the raw address to dwfl's elf bias.
++  Dwarf_Addr elf_bias;
++  Elf *elf = dwfl_module_getelf (q->dw.module, &elf_bias);
++  assert(elf);
++  addr += elf_bias;
++
++  // Now compensate for the dw bias
++  q->dw.get_module_dwarf(false, false);
++  addr -= q->dw.module_bias;
++
++  // Build a probe at this point
++  query_statement(q->plt_val, NULL, -1, NULL, addr, q);
++}
++
++static void
+ query_label (string const & func,
+              char const * label,
+              char const * file,
+@@ -2233,8 +2247,6 @@ query_one_plt (const char *entry, long addr, dwflpp & dw,
+       if (dw.sess.verbose > 2)
+         clog << _F("plt entry=%s\n", entry);
+ 
+-      // query_module_symtab requires .plt to recognize that it can set the probe at
+-      // a plt entry so we convert process.plt to process.plt.statement
+       vector<probe_point::component*>::iterator it;
+       for (it = specific_loc->components.begin();
+           it != specific_loc->components.end(); ++it)
+diff --git a/testsuite/systemtap.base/plt.exp b/testsuite/systemtap.base/plt.exp
+index 71b7987..a6d2a86 100644
+--- a/testsuite/systemtap.base/plt.exp
++++ b/testsuite/systemtap.base/plt.exp
+@@ -1,4 +1,5 @@
+ set test "plt"
++set script "$srcdir/$subdir/$test.stp"
+ 
+ proc cleanup_handler { verbose } {
+     if { $verbose == 0 } {
+@@ -20,127 +21,99 @@ proc error_handler { res test message } {
+     }
+ }
+ 
++set ::result_string \
++{__cxa_finalize 2
++__libc_start_main 1
++__xpg_basename 1
++asctime 1
++asprintf 3
++basename2 1
++bsearch 3
++critters 1
++datetime 1
++find_critter 3
++fprintf 3
++fputs 3
++free 4
++localtime 1
++malloc 3
++memcpy 1
++open 2
++open2 1
++open3 1
++print_critter 32
++printf 38
++qsort 1
++register_printf_function 1
++savestring 1
++stpcpy 4
++strcmp 51
++strftime 2
++strlen 4
++time 1
++widgets 1
++xmalloc 2
++zenme 1}
++
+ if {![installtest_p]} { untested $test; return }
+ if {![plt_probes_p]} { untested $test; return }
+ 
+-set stap_path $env(SYSTEMTAP_PATH)/stap
+-
+ set exepath "./plt.x"
+ 
++
+ set F additional_flags
+-set flags "$F=-I. $F=-shared $F=-fPIC $F=-DLIBPLT1 $F=-g $F=-Wno-deprecated-declarations $F=-Wno-format"
++set common_flags "$F=-g $F=-Wno-deprecated-declarations $F=-Wno-format $F=-fno-builtin"
++set flags "$F=-I. $F=-shared $F=-fPIC $F=-DLIBPLT1 $common_flags"
+ set res [target_compile $srcdir/$subdir/plt.c ./libplt1.so executable $flags ]
+ if { [error_handler [expr {$res == ""}] "target_compile libplt1.so" ""] } { return }
+ 
+-set flags "$F=-I. $F=-shared $F=-fPIC $F=-DLIBPLT2 $F=-g $F=-Wno-deprecated-declarations $F=-Wno-format"
++set flags "$F=-I. $F=-shared $F=-fPIC $F=-DLIBPLT2 $common_flags"
+ set res [target_compile $srcdir/$subdir/plt.c ./libplt2.so executable $flags ]
+ if { [error_handler [expr {$res == ""}] "target_compile libplt2.so" ""] } { return }
+ 
+-set flags "$F=-Wl,-rpath,[pwd] $F=-L[pwd] $F=-lplt1 $F=-lplt2 $F=-DONLY_MAIN $F=-g $F=-Wno-deprecated-declarations $F=-Wno-format"
++set flags "$F=-Wl,-rpath,[pwd] $F=-L[pwd] $F=-lplt1 $F=-lplt2 $F=-DONLY_MAIN $common_flags"
+ set res [target_compile $srcdir/$subdir/plt.c $exepath executable $flags ]
+ if { [error_handler [expr {$res == ""}] "target_compile plt.x" ""] } { return }
+ 
+ # test process.plt
+ 
+-set ok 0
+-spawn $stap_path -c $exepath -e "global calls probe process(\"./plt.x\").plt {calls\[\$\$name\] += 1} probe process(\"./libplt1.so\").plt {calls\[\$\$name\] += 1} probe process(\"./libplt2.so\").plt {calls\[\$\$name\] += 1} probe end {foreach (x in calls) printf (\"%s %d\\n\", x, calls\[x\])}"
+-
+-expect {
+-    -timeout 180
+-    -re {__libc_start_main 1\r\n} { incr ok; exp_continue }
+-    -re {xmalloc 2\r\n} { incr ok; exp_continue }
+-    -re {savestring 1\r\n} { incr ok; exp_continue }
+-    -re {memcpy 1\r\n} { incr ok; exp_continue }
+-    -re {open2 1\r\n} { incr ok; exp_continue }
+-    -re {stpcpy 4\r\n} { incr ok; exp_continue }
+-    -re {open 2\r\n} { incr ok; exp_continue }
+-    -re {open3 1\r\n} { incr ok; exp_continue }
+-    -re {basename2 1\r\n} { incr ok; exp_continue }
+-    -re {__xpg_basename 1\r\n} { incr ok; exp_continue }
+-    -re {critters 1\r\n} { incr ok; exp_continue }
+-    -re {print_critter 32\r\n} { incr ok; exp_continue }
+-    -re {printf 36\r\n} { incr ok; exp_continue }
+-    -re {putchar 2\r\n} { incr ok; exp_continue }
+-    -re {qsort 1\r\n} { incr ok; exp_continue }
+-    -re {strcmp 51\r\n} { incr ok; exp_continue }
+-    -re {find_critter 3\r\n} { incr ok; exp_continue }
+-    -re {bsearch 3\r\n} { incr ok; exp_continue }
+-    -re {widgets 1\r\n} { incr ok; exp_continue }
+-    -re {register_printf_function 1\r\n} { incr ok; exp_continue }
+-    -re {asprintf 3\r\n} { incr ok; exp_continue }
+-    -re {fprintf 3\r\n} { incr ok; exp_continue }
+-    -re {datetime 1\r\n} { incr ok; exp_continue }
+-    -re {time 1\r\n} { incr ok; exp_continue }
+-    -re {localtime 1\r\n} { incr ok; exp_continue }
+-    -re {asctime 1\r\n} { incr ok; exp_continue }
+-    -re {fputs 3\r\n} { incr ok; exp_continue }
+-    -re {strftime 2\r\n} { incr ok; exp_continue }
+-    timeout { fail "$test (timeout)" }
+-    eof {  }
+-}
+-
+-catch { close}; catch { wait}
+-
+-error_handler [expr {$ok == 28}] "plt" "($ok != 28)"
++set pp {process("./plt.x").plt, process("./libplt1.so").plt, process("./libplt2.so").plt}
++stap_run3 "plt" "$script" "$pp" -c "$exepath >/dev/null"
+ 
+ # test process.library.plt
+ 
+-set ok 0
+-spawn $stap_path -c $exepath -e "global calls probe process(\"./plt.x\").plt {calls\[\$\$name\] += 1} probe process(\"./plt.x\").library(\"*\").plt {calls\[\$\$name\] += 1} probe end {foreach (x in calls) printf (\"%s %d\\n\", x, calls\[x\])}"
++set pp {process("./plt.x").plt, process("./plt.x").library("libplt*").plt}
++stap_run3 "plt library" "$script" "$pp" -c "$exepath >/dev/null"
+ 
+-expect {
+-    -timeout 180
+-    -re {__libc_start_main 1\r\n} { incr ok; exp_continue }
+-    -re {xmalloc 2\r\n} { incr ok; exp_continue }
+-    -re {savestring 1\r\n} { incr ok; exp_continue }
+-    -re {memcpy 1\r\n} { incr ok; exp_continue }
+-    -re {open2 1\r\n} { incr ok; exp_continue }
+-    -re {stpcpy 4\r\n} { incr ok; exp_continue }
+-    -re {open 2\r\n} { incr ok; exp_continue }
+-    -re {open3 1\r\n} { incr ok; exp_continue }
+-    -re {basename2 1\r\n} { incr ok; exp_continue }
+-    -re {__xpg_basename 1\r\n} { incr ok; exp_continue }
+-    -re {critters 1\r\n} { incr ok; exp_continue }
+-    -re {print_critter 32\r\n} { incr ok; exp_continue }
+-    -re {printf 36\r\n} { incr ok; exp_continue }
+-    -re {putchar 2\r\n} { incr ok; exp_continue }
+-    -re {qsort 1\r\n} { incr ok; exp_continue }
+-    -re {strcmp 51\r\n} { incr ok; exp_continue }
+-    -re {find_critter 3\r\n} { incr ok; exp_continue }
+-    -re {bsearch 3\r\n} { incr ok; exp_continue }
+-    -re {widgets 1\r\n} { incr ok; exp_continue }
+-    -re {register_printf_function 1\r\n} { incr ok; exp_continue }
+-    -re {asprintf 3\r\n} { incr ok; exp_continue }
+-    -re {fprintf 3\r\n} { incr ok; exp_continue }
+-    -re {datetime 1\r\n} { incr ok; exp_continue }
+-    -re {time 1\r\n} { incr ok; exp_continue }
+-    -re {localtime 1\r\n} { incr ok; exp_continue }
+-    -re {asctime 1\r\n} { incr ok; exp_continue }
+-    -re {fputs 3\r\n} { incr ok; exp_continue }
+-    -re {strftime 2\r\n} { incr ok; exp_continue }
+-    timeout { fail "$test (timeout)" }
+-    eof {  }
++# test process.library.plt prelinked
++
++set prelink_bin "/usr/sbin/prelink"
++if {[file exists $prelink_bin]} {
++    set addr "-r 0x6400000"
++    set prelink_cmd [concat $prelink_bin -vfNR $addr libplt1.so]
++    send_log "Executing: $prelink_cmd\n"
++    catch {eval exec $prelink_cmd} result
++    if { $result != "" } {
++        verbose -log "prelink failed: $result"
++        fail "plt prelink libplt1.so"
++        untested "plt prelinked library"
++    } else {
++        pass "plt prelink libplt1.so"
++
++        set pp {process("./plt.x").plt, process("./plt.x").library("libplt*").plt}
++        stap_run3 "plt prelinked library" "$script" "$pp" -c "$exepath >/dev/null"
++    }
++} else {
++    untested "plt prelink libplt1.so"
++    untested "plt prelinked library"
+ }
+ 
+-catch { close}; catch { wait}
+-
+-error_handler [expr {$ok == 28}] "plt library" "($ok != 28)"
+-
+ # test process.plt("glob")
+ 
+ set ok 0
+-spawn $stap_path -c $exepath -e "global calls probe process(\"./libplt2.so\").plt(\"strcmp\") {calls\[\$\$name\] += 1} probe end {foreach (x in calls) printf (\"%s %d\\n\", x, calls\[x\])}"
++set ::result_string {strcmp 51}
++set pp {process("./libplt2.so").plt("strcmp")}
++stap_run3 "plt glob" "$script" "$pp" -c "$exepath >/dev/null"
+ 
+-expect {
+-    -timeout 180
+-    -re {strcmp 51\r\n} { incr ok; exp_continue }
+-    -re {printf 36\r\n} { incr ok; exp_continue }
+-    timeout { fail "$test (timeout)" }
+-    eof {  }
+-}
+-
+-catch { close}; catch { wait}
+-
+-error_handler [expr {$ok == 1}] "plt glob" "($ok != 1)"
+ 
+ cleanup_handler $verbose
+diff --git a/testsuite/systemtap.base/plt.stp b/testsuite/systemtap.base/plt.stp
+new file mode 100644
+index 0000000..286c4e9
+--- /dev/null
++++ b/testsuite/systemtap.base/plt.stp
+@@ -0,0 +1,9 @@
++global calls
++probe $1 {
++  calls[$$name] += 1
++}
++probe end {
++  foreach (x+ in calls)
++    printf ("%s %d\n", x, calls[x])
++}
++
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.2.patch b/SOURCES/rhbz1073640.2.patch
new file mode 100644
index 0000000..31d870e
--- /dev/null
+++ b/SOURCES/rhbz1073640.2.patch
@@ -0,0 +1,247 @@
+From 91bb9081f0f2342d2e7df985d448ea9c9ebd34b5 Mon Sep 17 00:00:00 2001
+From: Lukas Berk <lberk@redhat.com>
+Date: Fri, 29 Nov 2013 16:34:11 -0500
+Subject: [PATCH] PR10208 Support probing weak symbols
+
+*tapsets.cxx - Now always query the symtab (unless there is a pending interrupt
+	       or dwarf callback error) on a function probe.  We need to be careful
+	       to check probe point's we've already resolved which will already
+	       have full debug information and to not place another probe there.
+	       We've removed the case of probing the symbol table on a statement probe,
+	       as that code was written specifically for the kernel without userspace
+	       in mind and was resolving the function the statement resided in (causing
+	       errors in some cases).
+
+*list.exp    - Added testcase for weak symbols
+*last_100_frees.stp   - we use @defined($mem) here because on 64 bit systems, the
+		        wildcard search takes us through both 64 bit and 32 bit libc
+		        (which doesn't have debuginfo), this means the probe point
+		        resolved from the 32 bit library has no context info
+*mutex-contention.stp - ditto but for @defined($mutex) and @defined($rwlock)
+---
+ tapsets.cxx                                        | 94 ++++++++++++----------
+ testsuite/systemtap.base/list.exp                  |  4 +
+ .../systemtap.examples/memory/last_100_frees.stp   | 12 ++-
+ .../process/mutex-contention.stp                   | 14 +++-
+ 4 files changed, 74 insertions(+), 50 deletions(-)
+
+diff --git a/tapsets.cxx b/tapsets.cxx
+index 7927106..4e05d4a 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -989,6 +989,40 @@ dwarf_query::query_module_dwarf()
+ static void query_func_info (Dwarf_Addr entrypc, func_info & fi,
+ 							dwarf_query * q);
+ 
++static void
++query_symtab_func_info (func_info & fi, dwarf_query * q)
++{
++  assert(null_die(&fi.die));
++
++  Dwarf_Addr addr = fi.addr;
++
++  // Now compensate for the dw bias because the addresses come
++  // from dwfl_module_symtab, so fi->addr is NOT a normal dw address.
++  q->dw.get_module_dwarf(false, false);
++  addr -= q->dw.module_bias;
++
++  // If there are already probes in this module, lets not duplicate.
++  // This can come from other weak symbols/aliases or existing
++  // matches from Dwarf DIE functions.
++  if (q->alias_dupes.size() > 0)
++    {
++      for (set<Dwarf_Addr>::iterator it=q->alias_dupes.begin(); it!=q->alias_dupes.end(); ++it)
++	{
++	  // If we've already got a probe at that pc, skip it
++	  if (*it == addr)
++	    return;
++	  if (*it != addr && ++it==q->alias_dupes.end())
++	    {
++	      // Build a probe at this point
++	      query_func_info(addr, fi, q);
++	      return;
++	    }
++	}
++    }
++  else
++    query_func_info(addr,fi,q);
++}
++
+ void
+ dwarf_query::query_module_symtab()
+ {
+@@ -1014,15 +1048,6 @@ dwarf_query::query_module_symtab()
+       assert(spec_type == function_alone);
+       if (dw.name_has_wildcard(function_str_val))
+         {
+-          // Until we augment the blacklist sufficently...
+-	  if ((function_str_val.find_first_not_of("*?") == string::npos) && !dw.has_gnu_debugdata())
+-            {
+-              // e.g., kernel.function("*")
+-              cerr << _F("Error: Pattern '%s' matches every single "
+-                         "instruction address in the symbol table,\n"
+-                         "some of which aren't even functions.\n", function_str_val.c_str()) << endl;
+-              return;
+-            }
+           symbol_table::iterator_t iter;
+           for (iter = sym_table->map_by_addr.begin();
+                iter != sym_table->map_by_addr.end();
+@@ -1032,42 +1057,16 @@ dwarf_query::query_module_symtab()
+               if (!null_die(&fi->die))
+                 continue;       // already handled in query_module_dwarf()
+               if (dw.function_name_matches_pattern(fi->name, function_str_val))
+-                query_func_info(fi->addr, *fi, this);
++                query_symtab_func_info(*fi, this);
+             }
+         }
+       else
+         {
+           fi = sym_table->lookup_symbol(function_str_val);
+           if (fi && !fi->descriptor && null_die(&fi->die))
+-            query_func_info(fi->addr, *fi, this);
++	     query_symtab_func_info(*fi, this);
+         }
+     }
+-  else
+-    {
+-      assert(has_function_num || has_statement_num);
+-      // Find the "function" in which the indicated address resides.
+-      Dwarf_Addr addr =
+-      		(has_function_num ? function_num_val : statement_num_val);
+-      fi = sym_table->get_func_containing_address(addr);
+-
+-      if (!fi)
+-        {
+-          sess.print_warning(_F("address %#" PRIx64 " out of range for module %s",
+-                  addr, dw.module_name.c_str()));
+-          return;
+-        }
+-      if (!null_die(&fi->die))
+-        {
+-          // addr looks like it's in the compilation unit containing
+-          // the indicated function, but query_module_dwarf() didn't
+-          // match addr to any compilation unit, so addr must be
+-          // above that cu's address range.
+-          sess.print_warning(_F("address %#" PRIx64 " maps to no known compilation unit in module %s",
+-                       addr, dw.module_name.c_str()));
+-          return;
+-        }
+-      query_func_info(fi->addr, *fi, this);
+-    }
+ }
+ 
+ void
+@@ -1092,10 +1091,11 @@ dwarf_query::handle_query_module()
+   if (dw.mod_info->dwarf_status == info_present)
+     query_module_dwarf();
+ 
+-  // Consult the symbol table if we haven't found all we're looking for.
+-  // asm functions can show up in the symbol table but not in dwarf,
+-  // or if we want to check the .gnu_debugdata section
+-  if ((sess.consult_symtab || dw.has_gnu_debugdata()) && !query_done)
++  // Consult the symbol table, asm and weak functions can show up
++  // in the symbol table but not in dwarf and minidebuginfo is
++  // located in the gnu_debugdata section, alias_dupes checking
++  // is done before adding any probe points
++  if (!query_done && !pending_interrupts)
+     query_module_symtab();
+ }
+ 
+@@ -1252,7 +1252,7 @@ dwarf_query::add_probe_point(const string& dw_funcname,
+ 
+   // If we originally used the linkage name, then let's call it that way
+   const char* linkage_name;
+-  if (scope_die && startswith (this->function, "_Z")
++  if (!null_die(scope_die) && startswith (this->function, "_Z")
+       && (linkage_name = dwarf_linkage_name (scope_die)))
+     funcname = linkage_name;
+ 
+@@ -1954,8 +1954,14 @@ dwarf_query::query_module_functions ()
+       inline_dupes.clear();
+ 
+       // Run the query again on the individual CUs
+-      for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i)
+-        query_cu(&*i, this);
++      for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i){
++        rc = query_cu(&*i, this);
++	if (rc != DWARF_CB_OK)
++	  {
++	    query_done = true;
++	    return;
++	  }
++      }
+     }
+   catch (const semantic_error& e)
+     {
+diff --git a/testsuite/systemtap.base/list.exp b/testsuite/systemtap.base/list.exp
+index 1aa97f8..bae7e0e 100644
+--- a/testsuite/systemtap.base/list.exp
++++ b/testsuite/systemtap.base/list.exp
+@@ -81,3 +81,7 @@ test_list copy_flags-inline {kernel.function("copy_flags@kernel/fork.c").inline}
+ # PR15587: make sure we have line numbers on statements of an inline function
+ test_list copy_flags-statement {kernel.statement("copy_flags@kernel/fork.c:*")} \
+     {kernel.statement."copy_flags@kernel/fork.c:\d+".\r\n}
++
++# PR10208: ensure we can probe weak symbols
++test_uprobes_list function-weak {process("/lib*/libc.so.*").function("chmod")} \
++    {process.*.function."chmod".\r\n}
+diff --git a/testsuite/systemtap.examples/memory/last_100_frees.stp b/testsuite/systemtap.examples/memory/last_100_frees.stp
+index 06d7acf..4ca43b5 100755
+--- a/testsuite/systemtap.examples/memory/last_100_frees.stp
++++ b/testsuite/systemtap.examples/memory/last_100_frees.stp
+@@ -1,10 +1,16 @@
+-#! /usr/bin/env stap 
++#! /usr/bin/env stap
+ 
+ global bt%[100]
+ 
+ probe process("/lib*/libc.so.*").function("free") {
+-  bt[execname(),tid(),$mem,sprint_ubacktrace()]
+-    <<< local_clock_ns()
++  // we use @defined($mem) here because on 64 bit systems, the
++  // wildcard search takes us through both 64 bit and 32 bit
++  // libc (which doesn't have debuginfo), this means the probe
++  // point resolved from the 32 bit library has no context info
++  if (@defined($mem)) {
++    bt[execname(),tid(),$mem,sprint_ubacktrace()]
++      <<< local_clock_ns()
++  }
+   // Any monotonically increasing expression would do.
+   // With some arbitrary expression or constant instead,
+   // at worst we get the last 100ish results out of order.
+diff --git a/testsuite/systemtap.examples/process/mutex-contention.stp b/testsuite/systemtap.examples/process/mutex-contention.stp
+index 669618e..f418754 100755
+--- a/testsuite/systemtap.examples/process/mutex-contention.stp
++++ b/testsuite/systemtap.examples/process/mutex-contention.stp
+@@ -71,17 +71,25 @@ function show_contention(mutex, stack, type)
+   }
+ }
+ 
++// we use @defined($muex) and @defined($rwlock) here because
++// on 64 bit systems, the wildcard search takes us through
++// both 64 bit and 32 bit libc (which doesn't have debuginfo),
++// this means the probe point resolved from the 32 bit library
++// has no context info
+ probe process("/lib*/libc.so*").function("pthread_mutex_init")
+ {
+-  process_mutex_init($mutex, probefunc())
++  if(@defined($mutex))
++    process_mutex_init($mutex, probefunc())
+ }
+ probe process("/lib*/libpthread.so*").function("__pthread_mutex_init")
+ {
+-  process_mutex_init($mutex, probefunc())
++  if(@defined($mutex))
++    process_mutex_init($mutex, probefunc())
+ }
+ probe process("/lib*/libpthread.so*").function("__pthread_rwlock_init")
+ {
+-  process_mutex_init($rwlock, probefunc())
++  if(@defined($rwlock))
++    process_mutex_init($rwlock, probefunc())
+ }
+ 
+ probe syscall.futex.return
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.3.patch b/SOURCES/rhbz1073640.3.patch
new file mode 100644
index 0000000..1ed495d
--- /dev/null
+++ b/SOURCES/rhbz1073640.3.patch
@@ -0,0 +1,52 @@
+From a41f2ad77a642e70f46caa8261746c651f5dc2ad Mon Sep 17 00:00:00 2001
+From: Josh Stone <jistone@redhat.com>
+Date: Mon, 2 Dec 2013 14:34:07 -0800
+Subject: [PATCH] Use proper set operations for symtab dupe checks
+
+In query_symtab_func_info, rather than full set iteration to check an
+address in alias_dupes, just use set::insert().second as a test.  This
+is what sets are designed to be algorithmically good at.
+
+This also has the benefit of adding to alias_dupes, so duplicates within
+the symbol table itself will still only be probed once.  (If we didn't
+want that effect, we would just use set::count() to test membership.)
+---
+ tapsets.cxx | 22 ++++------------------
+ 1 file changed, 4 insertions(+), 18 deletions(-)
+
+diff --git a/tapsets.cxx b/tapsets.cxx
+index f1a5843..b3cfa0e 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -1003,24 +1003,10 @@ query_symtab_func_info (func_info & fi, dwarf_query * q)
+ 
+   // If there are already probes in this module, lets not duplicate.
+   // This can come from other weak symbols/aliases or existing
+-  // matches from Dwarf DIE functions.
+-  if (q->alias_dupes.size() > 0)
+-    {
+-      for (set<Dwarf_Addr>::iterator it=q->alias_dupes.begin(); it!=q->alias_dupes.end(); ++it)
+-	{
+-	  // If we've already got a probe at that pc, skip it
+-	  if (*it == addr)
+-	    return;
+-	  if (*it != addr && ++it==q->alias_dupes.end())
+-	    {
+-	      // Build a probe at this point
+-	      query_func_info(addr, fi, q);
+-	      return;
+-	    }
+-	}
+-    }
+-  else
+-    query_func_info(addr,fi,q);
++  // matches from Dwarf DIE functions.  Try to add this addr to the
++  // collection, and only continue if it was new.
++  if (q->alias_dupes.insert(addr).second)
++    query_func_info(addr, fi, q);
+ }
+ 
+ void
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.4.patch b/SOURCES/rhbz1073640.4.patch
new file mode 100644
index 0000000..3c58c59
--- /dev/null
+++ b/SOURCES/rhbz1073640.4.patch
@@ -0,0 +1,27 @@
+From 3449dd58cbbb28d6d0b89740b68ae158b08d0b1c Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Tue, 21 Jan 2014 16:14:21 -0500
+Subject: [PATCH] PR16478: always use dwarf for labels
+
+Now that the symtab is queried more often for function probes, we need
+to explicitly make .label queries use dwarf or they won't work properly.
+---
+ tapsets.cxx | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tapsets.cxx b/tapsets.cxx
+index d8e8cf7..5bae070 100644
+--- a/tapsets.cxx
++++ b/tapsets.cxx
+@@ -1296,7 +1296,7 @@ dwarf_query::assess_dbinfo_reqt()
+       // kernel.statement(NUM).absolute
+       return dbr_none;
+     }
+-  if (has_inline)
++  if (has_inline || has_label)
+     {
+       // kernel.function("f").inline or module("m").function("f").inline
+       return dbr_need_dwarf;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.5.patch b/SOURCES/rhbz1073640.5.patch
new file mode 100644
index 0000000..53565e1
--- /dev/null
+++ b/SOURCES/rhbz1073640.5.patch
@@ -0,0 +1,115 @@
+From b2c99fdcc379ae65a83e25a6b6a8bc2b77a5b03c Mon Sep 17 00:00:00 2001
+From: Jonathan Lebon <jlebon@redhat.com>
+Date: Tue, 21 Jan 2014 16:21:31 -0500
+Subject: [PATCH] testsuite: adjust tests for new probing powers
+
+Since we can now probe more functions (such as _start,
+register_tm_clones), a few tests need to be adjusted.
+
+* rep_ret.exp
+
+  Get rid of 'bad' var and handle the case where main is not the first
+  line printed out (which is now _start).
+
+* process_by_cmd.exp
+
+  Change wildcard probe (which now picks up too many functions) for
+  multiple probe points targetting only the functions we want.
+
+* exelib.exp
+
+  Same as process_by_cmd.exp
+---
+ testsuite/systemtap.base/process_by_cmd.stp      | 5 ++++-
+ testsuite/systemtap.base/rep_ret.exp             | 9 ++++++---
+ testsuite/systemtap.exelib/libmarkunamestack.stp | 6 ++++--
+ testsuite/systemtap.exelib/uname.stp             | 6 ++++--
+ 4 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/testsuite/systemtap.base/process_by_cmd.stp b/testsuite/systemtap.base/process_by_cmd.stp
+index 8f744e0..5fe1dec 100644
+--- a/testsuite/systemtap.base/process_by_cmd.stp
++++ b/testsuite/systemtap.base/process_by_cmd.stp
+@@ -1,3 +1,6 @@
+ probe process.function("main") { printf("func end\n") }
+-probe process.function("*").return { printf("func return end\n") }
++probe process.function("main").return,
++      process.function("first").return,
++      process.function("second").return,
++      process.function("third") { printf("func return end\n") }
+ probe process.mark("*") { printf("mark end\n") }
+diff --git a/testsuite/systemtap.base/rep_ret.exp b/testsuite/systemtap.base/rep_ret.exp
+index 959050e..75b64df 100644
+--- a/testsuite/systemtap.base/rep_ret.exp
++++ b/testsuite/systemtap.base/rep_ret.exp
+@@ -32,11 +32,14 @@ foreach arch $arches {
+ 
+   if {[installtest_p] && [uprobes_p]} {
+     set ok 0
+-    set bad 0
+     set warn 0
+ 
+     spawn stap -e {probe process(@1).function("*") { println(probefunc()) }} ./$exe -c ./$exe
++    # We have two cases for main below to handle the possibility of main not being the first
++    # line being printed out (but only one of the two will ever fire, so the count is still 3)
++    # The test however does still ensure that main is followed by rep_ret then by repnz_ret.
+     expect {
++      -re {\r\nmain\r\n} { incr ok; exp_continue }
+       -re {^main\r\n} { incr ok; exp_continue }
+       -re {^rep_ret\r\n} { incr ok; exp_continue }
+       -re {^repnz_ret\r\n} { incr ok; exp_continue }
+@@ -46,10 +49,10 @@ foreach arch $arches {
+     }
+     wait
+ 
+-    if {$ok == 3 && $bad == 0 && $warn == 0} {
++    if {$ok == 3 && $warn == 0} {
+       pass "$exe"
+     } else {
+-      fail "$exe ($ok, $bad, $warn)"
++      fail "$exe ($ok, $warn)"
+     }
+   } else {
+     untested "$exe"
+diff --git a/testsuite/systemtap.exelib/libmarkunamestack.stp b/testsuite/systemtap.exelib/libmarkunamestack.stp
+index 3ad1aa5..7894ef4 100644
+--- a/testsuite/systemtap.exelib/libmarkunamestack.stp
++++ b/testsuite/systemtap.exelib/libmarkunamestack.stp
+@@ -28,11 +28,13 @@ probe process(@2).mark("func_count") {
+ }
+ 
+ #uname
+-probe process(@1).function("*") {
++probe process(@1).function("main"),
++      process(@1).function("main_func") {
+   printf("exe: %s=%s\n",probefunc(), usymname(uaddr()));
+ }
+ 
+-probe process(@2).function("*") {
++probe process(@2).function("lib_main"),
++      process(@2).function("lib_func") {
+   printf("lib: %s=%s\n",probefunc(), usymname(uaddr()));
+ }
+ 
+diff --git a/testsuite/systemtap.exelib/uname.stp b/testsuite/systemtap.exelib/uname.stp
+index aaf7ef1..25e6f8d 100644
+--- a/testsuite/systemtap.exelib/uname.stp
++++ b/testsuite/systemtap.exelib/uname.stp
+@@ -1,10 +1,12 @@
+ // Prints probefunc() and usymname(uaddr()) to check they are similar.
+ // Arguments: @1 uprobes_exe, @2 libuprobes_lib.so
+ 
+-probe process(@1).function("*") {
++probe process(@1).function("main"),
++      process(@1).function("main_func") {
+   printf("exe: %s=%s\n",probefunc(), usymname(uaddr()));
+ }
+ 
+-probe process(@2).function("*") {
++probe process(@2).function("lib_main"),
++      process(@2).function("lib_func") {
+   printf("lib: %s=%s\n",probefunc(), usymname(uaddr()));
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.6.patch b/SOURCES/rhbz1073640.6.patch
new file mode 100644
index 0000000..cb7352b
--- /dev/null
+++ b/SOURCES/rhbz1073640.6.patch
@@ -0,0 +1,32 @@
+From e695d462f82f64f567aadbdbe9d4c2389a406321 Mon Sep 17 00:00:00 2001
+From: Torsten Polle <Torsten.Polle@gmx.de>
+Date: Fri, 7 Mar 2014 14:37:11 -0600
+Subject: [PATCH 6/8] Fix: Crash when canceling task work.
+
+As the elements of the list __stp_tf_task_work_list are removed from
+the list, a safe iteration has to be used in __stp_tf_cancel_task_work().
+---
+ runtime/linux/task_finder2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
+index 16fda87..e8f33a3 100644
+--- a/runtime/linux/task_finder2.c
++++ b/runtime/linux/task_finder2.c
+@@ -169,11 +169,12 @@ static void __stp_tf_free_task_work(struct task_work *work)
+ static void __stp_tf_cancel_task_work(void)
+ {
+ 	struct __stp_tf_task_work *node;
++	struct __stp_tf_task_work *tmp;
+ 	unsigned long flags;
+ 
+ 	// Cancel all remaining requests.
+ 	spin_lock_irqsave(&__stp_tf_task_work_list_lock, flags);
+-	list_for_each_entry(node, &__stp_tf_task_work_list, list) {
++	list_for_each_entry_safe(node, tmp, &__stp_tf_task_work_list, list) {
+ 	    // Remove the item from the list, cancel it, then free it.
+ 	    list_del(&node->list);
+ 	    stp_task_work_cancel(node->task, node->work.func);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.7.patch b/SOURCES/rhbz1073640.7.patch
new file mode 100644
index 0000000..b0afc73
--- /dev/null
+++ b/SOURCES/rhbz1073640.7.patch
@@ -0,0 +1,33 @@
+From 9ee1bfe9ac1c92a0640e64a463efd43c9c5a57ac Mon Sep 17 00:00:00 2001
+From: Torsten Polle <Torsten.Polle@gmx.de>
+Date: Fri, 7 Mar 2014 14:39:31 -0600
+Subject: [PATCH 7/8] Fix: stap/staprun deadlocks when probing ends.
+
+stap_stop_task_finder() exits utrace through utrace_exit(). At that
+time, there might be outstanding task workers. Hence, waiting for
+exiting the task work waits forever. Therefore exiting the task work
+is done after canceling all task workers.
+---
+ runtime/linux/task_finder2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
+index e8f33a3..a3abc16 100644
+--- a/runtime/linux/task_finder2.c
++++ b/runtime/linux/task_finder2.c
+@@ -1875,10 +1875,10 @@ stap_stop_task_finder(void)
+ 	debug_task_finder_report();
+ #endif
+ 
+-	utrace_exit();
+-
+ 	/* Make sure all outstanding task work requests are canceled. */
+ 	__stp_tf_cancel_task_work();
++
++	utrace_exit();
+ }
+ 
+ #endif /* TASK_FINDER2_C */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz1073640.8.patch b/SOURCES/rhbz1073640.8.patch
new file mode 100644
index 0000000..2eb26fc
--- /dev/null
+++ b/SOURCES/rhbz1073640.8.patch
@@ -0,0 +1,119 @@
+From 66283521fac33ac5716b71a6d2662093aec409c1 Mon Sep 17 00:00:00 2001
+From: David Smith <dsmith@redhat.com>
+Date: Wed, 12 Mar 2014 09:07:58 -0500
+Subject: [PATCH] Improve task_finder/utrace shutdown.
+
+* runtime/stp_utrace.c (utrace_exit): Move the call to
+  stp_task_work_exit() up above the calls to free the kmem caches. This
+  make sure any running task work items don't have the memory freed out
+  from under them.
+* runtime/linux/task_finder2.c (__stp_task_finder_cleanup): Move
+  utrace_shutdown() call into stap_stop_task_finder().
+  (stap_stop_task_finder): Call utrace_shutdown() directly. Wait to make
+  sure all tracepoint probes are finished.
+---
+ runtime/linux/task_finder2.c | 24 +++++++-----------------
+ runtime/stp_utrace.c         | 27 +++++++++++++++++++--------
+ 2 files changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
+index a3abc16..ef074c5 100644
+--- a/runtime/linux/task_finder2.c
++++ b/runtime/linux/task_finder2.c
+@@ -418,15 +418,6 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops)
+ 	debug_task_finder_report();
+ }
+ 
+-static void
+-__stp_task_finder_cleanup(void)
+-{
+-	// The utrace_shutdown() function detaches and deletes
+-	// everything for us - we don't have to go through each
+-	// engine.
+-	utrace_shutdown();
+-}
+-
+ static char *
+ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
+ {
+@@ -1849,16 +1840,16 @@ stap_stop_task_finder(void)
+ 	atomic_set(&__stp_task_finder_state, __STP_TF_STOPPING);
+ 
+ 	debug_task_finder_report();
+-#if 0
+-	/* We don't need this since __stp_task_finder_cleanup()
+-	 * removes everything by calling utrace_shutdown(). */
+-	stap_utrace_detach_ops(&__stp_utrace_task_finder_ops);
+-#endif
+-	__stp_task_finder_cleanup();
++
++	// The utrace_shutdown() function detaches and cleans up
++	// everything for us - we don't have to go through each
++	// engine. This also means that the attach_count could end up
++	// > 0 (since we don't got through each engine individually).
++	utrace_shutdown();
++
+ 	debug_task_finder_report();
+ 	atomic_set(&__stp_task_finder_state, __STP_TF_STOPPED);
+ 
+-#if 0
+ 	/* Now that all the engines are detached, make sure
+ 	 * all the callbacks are finished.  If they aren't, we'll
+ 	 * crash the kernel when the module is removed. */
+@@ -1873,7 +1864,6 @@ stap_stop_task_finder(void)
+ 		printk(KERN_ERR "it took %d polling loops to quit.\n", i);
+ #endif
+ 	debug_task_finder_report();
+-#endif
+ 
+ 	/* Make sure all outstanding task work requests are canceled. */
+ 	__stp_tf_cancel_task_work();
+diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c
+index 89ea0e4..a6f363d 100644
+--- a/runtime/stp_utrace.c
++++ b/runtime/stp_utrace.c
+@@ -286,12 +286,18 @@ static int utrace_exit(void)
+ {
+ 	utrace_shutdown();
+ 
+-	if (utrace_cachep)
+-		kmem_cache_destroy(utrace_cachep);
+-	if (utrace_engine_cachep)
+-		kmem_cache_destroy(utrace_engine_cachep);
+-
+ 	stp_task_work_exit();
++
++	/* After utrace_shutdown() and stp_task_work_exit() (and the
++	 * code in stap_stop_task_finder()), we're *sure* there are no
++	 * tracepoint probes or task work items running or scheduled
++	 * to be run. So, now would be a great time to actually free
++	 * everything. */
++
++	if (utrace_cachep)
++		kmem_cache_destroy(utrace_cachep);
++	if (utrace_engine_cachep)
++		kmem_cache_destroy(utrace_engine_cachep);
+ 	return 0;
+ }
+ 
+@@ -373,9 +379,14 @@ static void utrace_shutdown(void)
+ 	unregister_trace_sys_exit(utrace_report_syscall_exit, NULL);
+ 	tracepoint_synchronize_unregister();
+ 
+-	/* After calling tracepoint_synchronize_unregister(), we're
+-	 * sure there are no outstanding tracepoint probes being
+-	 * called.  So, now would be a great time to free everything. */
++	/* After tracepoint_synchronize_unregister(), we're *sure*
++	 * there will be no new tracepoint probes running. There could
++	 * be currently running tracepoint probes or task work
++	 * items. So, now would be a great time to cleanup.
++	 *
++	 * Currently running items should be OK, since
++	 * utrace_cleanup() just puts the memory back into the utrace
++	 * kmem caches. */
+ 	
+ #ifdef STP_TF_DEBUG
+ 	printk(KERN_ERR "%s:%d - freeing task-specific\n", __FUNCTION__, __LINE__);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/rhbz847285.patch b/SOURCES/rhbz847285.patch
new file mode 100644
index 0000000..f6418d8
--- /dev/null
+++ b/SOURCES/rhbz847285.patch
@@ -0,0 +1,32 @@
+From 1436fd6092bf724e8bc80c53c7bc3c71ff9835cc Mon Sep 17 00:00:00 2001
+From: Dave Brolley <brolley@redhat.com>
+Date: Wed, 12 Feb 2014 16:03:51 -0500
+Subject: [PATCH] RHBZ 847285: Don't allow 'systemctl reload'.
+
+'reload' is not supported by the stap-server script. The
+ExecReload line in stap-server.service was calling
+'stap-server restart' which stops the server and starts a
+new one. This behavior is not expected or tolerated by systemd
+which promptly sends SIGKILL to the new server.
+
+We cannot supported 'reload' in systemctl. Note that 'restart'
+is supported and works properly.
+---
+ stap-server.service | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/stap-server.service b/stap-server.service
+index 000ee74..76e2196 100644
+--- a/stap-server.service
++++ b/stap-server.service
+@@ -8,7 +8,6 @@ After=network.target avahi-daemon.service
+ Type=oneshot
+ User=stap-server
+ ExecStart=/usr/bin/stap-server start
+-ExecReload=/usr/bin/stap-server restart
+ ExecStop=/usr/bin/stap-server stop
+ RemainAfterExit=yes 
+  
+-- 
+1.8.3.1
+
diff --git a/SPECS/systemtap.spec b/SPECS/systemtap.spec
index c639ea2..c63d1d0 100644
--- a/SPECS/systemtap.spec
+++ b/SPECS/systemtap.spec
@@ -32,6 +32,7 @@
 # don't want to build runtime-virthost for f18 or RHEL5/6
 %{!?with_virthost: %global with_virthost 0%{?fedora} >= 19 || 0%{?rhel} >= 7}
 %{!?with_virtguest: %global with_virtguest 1}
+%{!?with_dracut: %global with_dracut 0%{?fedora} >= 19 || 0%{?rhel} >= 7}
 
 %if 0%{?fedora} >= 18 || 0%{?rhel} >= 6
    %define initdir %{_initddir}
@@ -47,11 +48,44 @@
    %endif
 %endif
 
+%define dracutlibdir %{_prefix}/lib/dracut
+%define dracutstap %{dracutlibdir}/modules.d/99stap
+
 Name: systemtap
 Version: 2.4
-Release: 1%{?dist}
+Release: 14%{?dist}
 # for version, see also configure.ac
 
+#Patch1: reserved for elfutils (see below)
+Patch2: rhbz1054962.patch
+Patch3: rhbz1054956.patch
+Patch4: rhbz1054954.patch
+Patch5: rhbz1051649.patch
+Patch6: rhbz1044429.patch
+Patch7: rhbz1055778.patch
+Patch8: rhbz1035752.patch
+Patch9: rhbz1035850.patch
+Patch10: rhbz1056687.patch
+Patch11: rhbz1057773.patch
+Patch12: rhbz1020207.patch
+Patch13: rhbz1062076.patch
+Patch14: rhbz1051649.2.patch
+Patch15: rhbz847285.patch
+Patch16: rhbz1073640.1.patch
+Patch17: rhbz1073640.2.patch
+Patch18: rhbz1073640.3.patch
+Patch19: rhbz1073640.4.patch
+Patch20: rhbz1073640.5.patch
+Patch21: rhbz1073640.6.patch
+Patch22: rhbz1073640.7.patch
+Patch23: rhbz1073640.8.patch
+Patch24: rhbz1051649.3.patch
+Patch25: rhbz1051649.4.patch
+Patch26: rhbz1051649.5.patch
+Patch27: rhbz1051649.6.patch
+Patch28: rhbz1051649.7.patch
+Patch29: rhbz1051649.8.patch
+Patch30: rhbz1051649.9.patch
 
 # Packaging abstract:
 #
@@ -60,7 +94,7 @@ Release: 1%{?dist}
 # systemtap-devel        /usr/bin/stap, runtime, tapset, req:kernel-devel
 # systemtap-runtime      /usr/bin/staprun, /usr/bin/stapsh, /usr/bin/stapdyn
 # systemtap-client       /usr/bin/stap, samples, docs, tapset(bonus), req:-runtime
-# systemtap-initscript   /etc/init.d/systemtap, req:systemtap
+# systemtap-initscript   /etc/init.d/systemtap, dracut module, req:systemtap
 # systemtap-sdt-devel    /usr/include/sys/sdt.h /usr/bin/dtrace
 # systemtap-testsuite    /usr/share/systemtap/testsuite*, req:systemtap, req:sdt-devel
 # systemtap-runtime-java libHelperSDT.so, HelperSDT.jar, stapbm, req:-runtime
@@ -245,7 +279,9 @@ Requires(preun): initscripts
 Requires(postun): initscripts
 
 %description initscript
-Sysvinit scripts to launch selected systemtap scripts at system startup.
+This package includes a SysVinit script to launch selected systemtap
+scripts at system startup, along with a dracut module for early
+boot-time probing if supported.
 
 
 %package sdt-devel
@@ -368,6 +404,36 @@ find . \( -name configure -o -name config.h.in \) -print | xargs touch
 cd ..
 %endif
 
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+
 %build
 
 %if %{with_bundled_elfutils}
@@ -545,6 +611,13 @@ done
    %endif
 %endif
 
+%if %{with_dracut}
+   mkdir -p $RPM_BUILD_ROOT%{dracutstap}
+   install -p -m 755 initscript/99stap/module-setup.sh $RPM_BUILD_ROOT%{dracutstap}
+   install -p -m 755 initscript/99stap/start-staprun.sh $RPM_BUILD_ROOT%{dracutstap}
+   touch $RPM_BUILD_ROOT%{dracutstap}/params.conf
+%endif
+
 %clean
 rm -rf ${RPM_BUILD_ROOT}
 
@@ -588,10 +661,11 @@ test -e %{_localstatedir}/log/stap-server/log || {
 if test ! -e ~stap-server/.systemtap/ssl/server/stap.cert; then
    runuser -s /bin/sh - stap-server -c %{_libexecdir}/systemtap/stap-gen-cert >/dev/null
 fi
-# Activate the service
+# Prepare the service
 %if %{with_systemd}
-     /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
-     /bin/systemd-tmpfiles --create >/dev/null 2>&1 || :
+     # Note, Fedora policy doesn't allow network services enabled by default
+     # /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
+     /bin/systemd-tmpfiles --create %{_tmpfilesdir}/stap-server.conf >/dev/null 2>&1 || :
 %else
     /sbin/chkconfig --add stap-server
 %endif
@@ -615,7 +689,7 @@ if [ $1 = 0 ] ; then
        /bin/systemctl stop stap-server.service >/dev/null 2>&1 || :
     %else
         /sbin/service stap-server stop >/dev/null 2>&1
-    	/sbin/chkconfig --del stap-server
+        /sbin/chkconfig --del stap-server
     %endif
 fi
 exit 0
@@ -625,7 +699,7 @@ exit 0
 # If so, restart the service if it's running
 if [ "$1" -ge "1" ] ; then
     %if %{with_systemd}
-    	/bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
+        /bin/systemctl condrestart stap-server.service >/dev/null 2>&1 || :
     %else
         /sbin/service stap-server condrestart >/dev/null 2>&1 || :
     %endif
@@ -634,8 +708,7 @@ exit 0
 
 %post initscript
 %if %{with_systemd}
-    /bin/systemctl enable stap-server.service >/dev/null 2>&1 || :
-     /bin/systemd-tmpfiles --create >/dev/null 2>&1 || :
+    /bin/systemctl enable systemtap.service >/dev/null 2>&1 || :
 %else
     /sbin/chkconfig --add systemtap
 %endif
@@ -646,11 +719,11 @@ exit 0
 # just removing the old package on upgrade.
 if [ $1 = 0 ] ; then
     %if %{with_systemd}
-    	/bin/systemctl --no-reload disable stap-server.service >/dev/null 2>&1 || :
-	/bin/systemctl stop stap-server.service >/dev/null 2>&1 || :
+        /bin/systemctl --no-reload disable systemtap.service >/dev/null 2>&1 || :
+        /bin/systemctl stop systemtap.service >/dev/null 2>&1 || :
     %else
         /sbin/service systemtap stop >/dev/null 2>&1
-    	/sbin/chkconfig --del systemtap
+        /sbin/chkconfig --del systemtap
     %endif
 fi
 exit 0
@@ -660,7 +733,7 @@ exit 0
 # If so, restart the service if it's running
 if [ "$1" -ge "1" ] ; then
     %if %{with_systemd}
-        /bin/systemctl restart stap-server.service >/dev/null 2>&1 || :
+        /bin/systemctl condrestart systemtap.service >/dev/null 2>&1 || :
     %else
         /sbin/service systemtap condrestart >/dev/null 2>&1 || :
     %endif
@@ -916,7 +989,11 @@ done
 %config(noreplace) %{_sysconfdir}/systemtap/config
 %dir %{_localstatedir}/cache/systemtap
 %ghost %{_localstatedir}/run/systemtap
-%doc initscript/README.systemtap
+%{_mandir}/man8/systemtap.8*
+%if %{with_dracut}
+   %dir %{dracutstap}
+   %{dracutstap}/*
+%endif
 
 
 %files sdt-devel
@@ -970,6 +1047,47 @@ done
 #   http://sourceware.org/systemtap/wiki/SystemTapReleases
 
 %changelog
+* Fri Mar 28 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-14
+- Small fix on latest backport fix for dyninst runtime
+
+* Fri Mar 28 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-13
+- Backport fixes for 1051649 (see comments 4 and 5)
+
+* Thu Mar 06 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-12
+- Backport fix for 1073640
+
+* Wed Feb 12 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-11
+- Backport fix for 847285
+
+* Wed Feb 12 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-10
+- Apply spec file patches to this one, not the tarred one
+- Add missing autoreconf patch for backport feature (1051649)
+
+* Tue Feb 11 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-9
+- Backport fixes for: 1062076, 1020207
+
+* Tue Jan 28 2014 Daniel Mach <dmach@redhat.com> - 2.4-8
+- Mass rebuild 2014-01-24
+
+* Fri Jan 24 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-7
+- Backport fix for 1057773
+
+* Wed Jan 22 2014 Frank Ch. Subbackportmeister Eigler <fche@redhat.com> - 2.4-6
+- Backport fixes for: 1056687
+
+* Wed Jan 22 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-5
+- Backport fixes for: 1035752, 1035850
+
+* Tue Jan 21 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-4
+- Backport fix for 1055778
+
+* Fri Jan 17 2014 Jonathan Lebon <jlebon@redhat.com> - 2.4-3
+- Backport fixes for: 1054962, 1054956, 1054954, 1044429
+- Backport boot-time probing feature (1051649)
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 2.4-2
+- Mass rebuild 2013-12-27
+
 * Wed Nov 06 2013 Frank Ch. Eigler <fche@redhat.com> - 2.4-1
 - Upstream release.