*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Parts of this file were imported from Jens Axboe's blktrace sources (also GPL)
*/
#include "blkparse.h"
#include "list.h"
+static int line_len = 1024;
+static char line[1024];
+
static pid_t blktrace_pid = 0;
+static pid_t mpstat_pid = 0;
-char *blktrace_args[] = {
- "-d", NULL,
- "-b", "16384",
- "-o", "trace",
- "-D", ".",
+char *blktrace_args[17 + MAX_DEVICES_PER_TRACE * 2] = {
+ "blktrace",
+ "-b", "8192",
"-a", "queue",
"-a", "complete",
"-a", "issue",
+ "-a", "notify",
+ "-D", ".",
+ NULL,
+};
+
+char *mpstat_args[] = {
+ "mpstat",
+ "-P", "ALL", "1",
NULL,
};
-#define DEVICE_INDEX 1
-#define DEST_DIR_INDEX 7
-#define TRACE_NAME_INDEX 5
+#define DEST_DIR_INDEX 12
+#define LAST_ARG 13
-int stop_blktrace(void)
+int stop_tracer(pid_t *tracer_pid)
{
int ret;
- pid_t pid;
+ pid_t pid = *tracer_pid;
pid_t pid_ret;
int status = 0;
- if (blktrace_pid == 0)
+ if (pid == 0)
return 0;
- pid = blktrace_pid;
- blktrace_pid = 0;
+ *tracer_pid = 0;
ret = kill(pid, SIGTERM);
if (ret) {
- fprintf(stderr, "failed to stop blktrace pid %lu error %s\n",
- (unsigned long)blktrace_pid, strerror(errno));
+ fprintf(stderr, "failed to stop tracer pid %lu error %s\n",
+ (unsigned long)pid, strerror(errno));
return -errno;
}
pid_ret = waitpid(pid, &status, WUNTRACED);
void stop_all_tracers(void)
{
- stop_blktrace();
+ stop_tracer(&blktrace_pid);
+ stop_tracer(&mpstat_pid);
}
void sig_handler_for_quit(int val)
}
-int start_blktrace(char *device, char *trace_name, char *dest)
+int start_blktrace(char **devices, int num_devices, char *trace_name, char *dest)
{
pid_t pid;
int ret;
char **arg = blktrace_args;
- blktrace_args[DEVICE_INDEX] = device;
+ int i;
+ int arg_index;
fprintf(stderr, "running blktrace");
- if (dest)
- blktrace_args[DEST_DIR_INDEX] = dest;
- if (trace_name)
- blktrace_args[TRACE_NAME_INDEX] = trace_name;
+ if (!trace_name)
+ trace_name = "trace";
+
+ arg_index = LAST_ARG;
+ for (i = 0; i < num_devices; i++) {
+ blktrace_args[arg_index++] = "-d";
+ blktrace_args[arg_index++] = devices[i];
+ }
+
+ /*
+ * single device traces use -o and are put into
+ * the dest dir if provided
+ */
+ if (num_devices == 1) {
+ blktrace_args[arg_index++] = "-o";
+ blktrace_args[arg_index++] = trace_name;
+ if (dest)
+ blktrace_args[DEST_DIR_INDEX] = dest;
+ } else {
+ /*
+ * multi device traces are put into a dest
+ * dir based on the trace name
+ */
+ blktrace_args[DEST_DIR_INDEX] = trace_name;
+ }
+
+ blktrace_args[arg_index] = NULL;
while(*arg) {
fprintf(stderr, " %s", *arg);
stop_all_tracers();
return -errno;
}
- stop_blktrace();
+ stop_all_tracers();
return 0;
}
int wait_for_tracers(void)
{
int status = 0;
- if (blktrace_pid == 0)
- return 0;
-
- waitpid(blktrace_pid, &status, WUNTRACED);
- blktrace_pid = 0;
+ if (blktrace_pid != 0) {
+ waitpid(blktrace_pid, &status, WUNTRACED);
+ blktrace_pid = 0;
+ }
+ if (mpstat_pid != 0) {
+ waitpid(mpstat_pid, &status, WUNTRACED);
+ mpstat_pid = 0;
+ }
return 0;
}
int blktrace_to_dump(char *trace_name)
{
- char line[1024];
- snprintf(line, 1024, "blkparse -O -i %s -d '%s.%s'",
+ snprintf(line, line_len, "blkparse -O -i %s -d '%s.%s'",
trace_name, trace_name, "dump");
system(line);
return 0;
}
+
+int start_mpstat(char *trace_name)
+{
+ int fd;
+ pid_t pid;
+
+ snprintf(line, line_len, "%s.mpstat", trace_name);
+
+ fd = open(line, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s for writing err %s\n",
+ line, strerror(errno));
+ exit(1);
+ }
+ pid = fork();
+ if (pid == 0) {
+ int ret;
+
+ close(1);
+ ret = dup2(fd, 1);
+ if (ret < 0) {
+ fprintf(stderr, "failed to setup output file for mpstat\n");
+ exit(1);
+ }
+ ret = execvp("mpstat", mpstat_args);
+ if (ret < 0) {
+ fprintf(stderr, "failed to exec mpstat err %s\n",
+ strerror(ret));
+ exit(1);
+ }
+ }
+ mpstat_pid = pid;
+ return 0;
+}