Upstream-Status: Pending

The patch gives a low overhead way of starting/stopping oprofile which
doesn't involve script exection.

(written by RP in OpenedHand days)

diff --git a/utils/Makefile.am b/utils/Makefile.am
index d34b060..dff15f9 100644
--- oprofile.orig/utils/Makefile.am
+++ oprofile/utils/Makefile.am
@@ -7,7 +7,7 @@ AM_LDFLAGS = @OP_LDFLAGS@
 
 LIBS=@POPT_LIBS@ @LIBERTY_LIBS@
 
-bin_PROGRAMS = ophelp op-check-perfevents
+bin_PROGRAMS = ophelp op-check-perfevents opstart
 dist_bin_SCRIPTS = opcontrol
 
 op_check_perfevents_SOURCES = op_perf_events_checker.c
@@ -15,3 +15,10 @@ op_check_perfevents_CPPFLAGS = ${AM_CFLAGS} @PERF_EVENT_FLAGS@
 
 ophelp_SOURCES = ophelp.c
 ophelp_LDADD = ../libop/libop.a ../libutil/libutil.a
+
+opstart_SOURCES = opstart.c
+
+install-exec-local:
+	cd $(DESTDIR)/$(bindir) && \
+	rm -f opstop && \
+	$(LN_S) opstart opstop
Index: oprofile/utils/opstart.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ oprofile/utils/opstart.c	2008-07-02 15:14:07.000000000 +0100
@@ -0,0 +1,110 @@
+/**
+ * @file opstart.c
+ * Start/Stop oprofile
+ *
+ * @remark Copyright 2007 Openedhand Ltd.
+ * @remark Read the file COPYING
+ *
+ * @author Richard Purdie
+ */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+int main(const int argc, const char* argv[])
+{
+	const char *enable = "/dev/oprofile/enable";
+	const char *lockfile;
+	unsigned long dpid;
+	struct stat sbuf;
+	FILE *lfile, *efile;
+	int sig, enb, err;
+
+	if (argc >= 2) {
+		printf("Error: Invalid options.\n");
+		return 1;
+	}
+
+	lockfile = getenv("LOCK_FILE");
+	if (!lockfile)
+		lockfile = "/var/lib/oprofile/lock";
+
+	/* Add SESSION_DIR support? */
+
+	if (geteuid()) {
+		printf("Error: This program must be run as root.\n");
+		return 1;
+	}
+
+	if (stat(enable, &sbuf)) {
+		printf("Error: Could not find /dev/oprofile/enable, the"
+		       " kernel module probably isn't loaded.\n");
+		printf("This binary only works with 2.6 kernels and oprofile"
+		       " must have been initialised with 'opcontrol --start-daemon'.\n");
+		return 1;
+	}
+
+	if (stat(lockfile, &sbuf)) {
+		printf("Error: Could not find lockfile %s.\n", lockfile);
+		printf("The oprofile daemon must be running (oprofile must"
+		       " have been initialised with 'opcontrol --start-daemon').\n");
+		return 1;
+	}
+
+	lfile = fopen(lockfile, "r");
+	if (!lfile) {
+		printf("Error opening lockfile %s.\n", lockfile);
+		return 1;
+	}
+
+	err = fscanf(lfile, "%lud", (unsigned long *) &dpid);
+	if (err != 1) {
+		printf("Error reading pid from lockfile %s.\n", lockfile);
+		return 1;
+	}
+	fclose(lfile);
+
+	efile = fopen(enable, "r");
+	if (!efile) {
+		printf("Error opening %s.\n", enable);
+		return 1;
+	}
+
+	if (strstr(argv[0], "opstart")) {
+		printf("Starting Profiler\n");
+		sig = SIGUSR1;
+		enb = 1;
+	} else if (strstr(argv[0], "opstop")) {
+		printf("Stopping Oprofile.\n");
+		printf("You need to run 'opcontrol --dump' when the session"
+		       " is finished.\n");
+		sig = SIGUSR2;
+		enb = 0;
+	} else {
+		printf("Error: Please call as 'opstart' or 'opstop'\n");
+		return 1;
+	}
+
+	err = kill(dpid, 0);
+	if (err) {
+		printf("Error sending signal to oprofiled. Stale lockfile"
+		       " (%s) ?\n", lockfile);
+		return 1;
+	}
+
+	fprintf(efile, "%d\n", enb);
+	err = kill(dpid, sig);
+	if (err) {
+		printf("Error sending signal to oprofiled. Stale lockfile"
+		       " (%s) ?\n", lockfile);
+		return 1;
+	}
+
+	return 0;
+}
+
Index: oprofile/configure.ac
===================================================================
--- oprofile.orig/configure.ac	2008-07-02 15:13:58.000000000 +0100
+++ oprofile/configure.ac	2008-07-02 15:17:37.000000000 +0100
@@ -16,6 +16,7 @@
 AM_CONFIG_HEADER(config.h)
 
 AC_PROG_RANLIB
+AC_PROG_LN_S
 AC_PROG_LIBTOOL
 
 dnl for the man page
@@ -241,6 +242,8 @@
 	doc/xsl/catalog-1.xml \
 	doc/oprofile.1 \
 	doc/opcontrol.1 \
+	doc/opstart.1 \
+	doc/opstop.1 \
 	doc/ophelp.1 \
 	doc/opreport.1 \
 	doc/opannotate.1 \
Index: oprofile/doc/Makefile.am
===================================================================
--- oprofile.orig/doc/Makefile.am	2008-07-02 15:13:59.000000000 +0100
+++ oprofile/doc/Makefile.am	2008-07-02 15:14:07.000000000 +0100
@@ -11,6 +11,8 @@
 man_MANS = \
 	oprofile.1 \
 	opcontrol.1 \
+	opstart.1 \
+	opstop.1 \
 	opreport.1 \
 	opannotate.1 \
 	opgprof.1 \
Index: oprofile/doc/opstart.1.in
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ oprofile/doc/opstart.1.in	2008-07-02 15:14:07.000000000 +0100
@@ -0,0 +1,27 @@
+.TH OPSTART 1 "@DATE@" "oprofile @VERSION@"
+.UC 4
+.SH NAME
+opstart \- start OProfile profiling
+.SH SYNOPSIS
+.br
+.B opstart
+.SH DESCRIPTION
+.B opstart
+is a simple optimised command to start profiling with 2.6 Linux kernels.
+OProfile should have already been initialised by calling "opcontrol --start-daemon".
+
+.SH ENVIRONMENT
+No special environment variables are recognised by opstart.
+
+.SH FILES
+.TP
+.I /var/lib/oprofile/samples/
+The location of the generated sample files.
+
+.SH VERSION
+.TP
+This man page is current for @PACKAGE@-@VERSION@.
+
+.SH SEE ALSO
+.BR @OP_DOCDIR@,
+.BR oprofile(1)
Index: oprofile/doc/opstop.1.in
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ oprofile/doc/opstop.1.in	2008-07-02 15:14:07.000000000 +0100
@@ -0,0 +1,28 @@
+.TH OPSTOP 1 "@DATE@" "oprofile @VERSION@"
+.UC 4
+.SH NAME
+opstop \- stop OProfile profiling
+.SH SYNOPSIS
+.br
+.B opstop
+.SH DESCRIPTION
+.B opstop
+is a simple optimsed command to stop profiling with 2.6 Linux kernels.
+You need to run "opcontrol --dump" before being able to view a profile
+with opreport.
+
+.SH ENVIRONMENT
+No special environment variables are recognised by opstop.
+
+.SH FILES
+.TP
+.I /var/lib/oprofile/samples/
+The location of the generated sample files.
+
+.SH VERSION
+.TP
+This man page is current for @PACKAGE@-@VERSION@.
+
+.SH SEE ALSO
+.BR @OP_DOCDIR@,
+.BR oprofile(1)
