aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-01-17 19:51:43 -0500
committerSteven Rostedt <rostedt@goodmis.org>2011-02-01 21:00:59 -0500
commit111fc9a48383619c3cf4f4cda6992716d661ba3a (patch)
tree5e86ac22701202f6470662ec0d42ed136d2259e6
parent749f8c9a993d1feb059cabf35a35b64153bd68ea (diff)
trace-cmd: Add events to handle sched switch/wakeup filters
The sched_switch and sched_wakeup filters are special for tracing pids. If we are tracing a pid, we want sched_switch and sched_wakeup to be traced if it is waking up or switching to the given pid. Since events are now expanded into a list holding the filter files to be updated. Either reuse or create if necessary the sched_* events to add the extra filters. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-cmd.c95
1 files changed, 60 insertions, 35 deletions
diff --git a/trace-cmd.c b/trace-cmd.c
index ad3ac91..5322e61 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -104,6 +104,11 @@ struct event_list {
104 int neg; 104 int neg;
105}; 105};
106 106
107static struct event_list *sched_switch_event;
108static struct event_list *sched_wakeup_event;
109static struct event_list *sched_wakeup_new_event;
110static struct event_list *sched_event;
111
107static struct event_list *event_selection; 112static struct event_list *event_selection;
108struct tracecmd_event_list *listed_events; 113struct tracecmd_event_list *listed_events;
109 114
@@ -783,55 +788,53 @@ static void disable_all(void)
783 clear_trace(); 788 clear_trace();
784} 789}
785 790
786static void update_filter(const char *event_name, const char *field, 791static void
787 const char *pid) 792update_sched_event(struct event_list **event, const char *file,
793 const char *field, const char *pid)
788{ 794{
789 char buf[BUFSIZ];
790 char *filter_name;
791 char *path;
792 char *filter; 795 char *filter;
793 int fd; 796 char *path;
794 int ret; 797 char *buf;
795 798 char *p;
796 filter_name = malloc_or_die(strlen(event_name) +
797 strlen("events//filter") + 1);
798 sprintf(filter_name, "events/%s/filter", event_name);
799
800 path = tracecmd_get_tracing_file(filter_name);
801 free(filter_name);
802
803 /* Ignore if file does not exist */
804 fd = open(path, O_RDONLY);
805 if (fd < 0)
806 goto out;
807 799
808 ret = read(fd, buf, BUFSIZ); 800 if (!*event) {
809 if (ret < 0) 801 /* No sched events are being processed, ignore */
810 die("Can't read %s", path); 802 if (!sched_event)
811 close(fd); 803 return;
804 *event = malloc_or_die(sizeof(**event));
805 memset(*event, 0, sizeof(**event));
806 (*event)->event = file;
807 p = malloc_or_die(strlen(file) + strlen("events//filter") + 1);
808 sprintf(p, "events/%s/filter", file);
809 path = tracecmd_get_tracing_file(p);
810 free(p);
811 (*event)->filter_file = strdup(path);
812 if (sched_event->filter)
813 (*event)->filter = strdup(sched_event->filter);
814 tracecmd_put_tracing_file(path);
815 }
812 816
813 if (ret >= BUFSIZ) 817 path = (*event)->filter_file;
814 ret = BUFSIZ - 1; 818 if (!path)
819 return;
815 820
816 buf[ret] = 0; 821 filter = (*event)->filter;
817 822
818 /* append unless there is currently no filter */ 823 if (!filter) {
819 if (strncmp(buf, "none", 4) == 0) {
820 filter = malloc_or_die(strlen(pid) + strlen(field) + 824 filter = malloc_or_die(strlen(pid) + strlen(field) +
821 strlen("(==)") + 1); 825 strlen("(==)") + 1);
822 sprintf(filter, "(%s==%s)", field, pid); 826 sprintf(filter, "(%s==%s)", field, pid);
823 } else { 827 } else {
828 buf = filter;
824 filter = malloc_or_die(strlen(pid) + strlen(field) + 829 filter = malloc_or_die(strlen(pid) + strlen(field) +
825 strlen(buf) + strlen("()||(==)") + 1); 830 strlen(buf) + strlen("()||(==)") + 1);
826 sprintf(filter, "(%s)||(%s==%s)", buf, field, pid); 831 sprintf(filter, "(%s)||(%s==%s)", buf, field, pid);
832 free(buf);
827 } 833 }
828 834
829 write_filter(path, filter); 835 (*event)->filter = filter;
830
831 free(filter);
832 836
833 out: 837 write_filter(path, filter);
834 tracecmd_put_tracing_file(path);
835} 838}
836 839
837static void update_pid_event_filters(const char *pid) 840static void update_pid_event_filters(const char *pid)
@@ -863,9 +866,11 @@ static void update_pid_event_filters(const char *pid)
863 /* 866 /*
864 * Also make sure that the sched_switch to this pid 867 * Also make sure that the sched_switch to this pid
865 * and wakeups of this pid are also traced. 868 * and wakeups of this pid are also traced.
869 * Only need to do this if the events are active.
866 */ 870 */
867 update_filter("sched/sched_switch", "next_pid", pid); 871 update_sched_event(&sched_switch_event, "sched/sched_switch", "next_pid", pid);
868 update_filter("sched/sched_wakeup", "pid", pid); 872 update_sched_event(&sched_wakeup_event, "sched/sched_wakeup", "pid", pid);
873 update_sched_event(&sched_wakeup_new_event, "sched/sched_wakeup_new", "pid", pid);
869} 874}
870 875
871static void enable_events(void) 876static void enable_events(void)
@@ -884,6 +889,17 @@ static void enable_events(void)
884 } 889 }
885} 890}
886 891
892static void test_event(struct event_list *event, const char *path,
893 const char *name, struct event_list **save, int len)
894{
895 path += len - strlen(name);
896
897 if (strcmp(path, name) != 0)
898 return;
899
900 *save = event;
901}
902
887static int expand_event_files(const char *file, struct event_list *old_event) 903static int expand_event_files(const char *file, struct event_list *old_event)
888{ 904{
889 struct event_list *save_events = event_selection; 905 struct event_list *save_events = event_selection;
@@ -910,6 +926,8 @@ static int expand_event_files(const char *file, struct event_list *old_event)
910 die("No filters found"); 926 die("No filters found");
911 927
912 for (i = 0; i < globbuf.gl_pathc; i++) { 928 for (i = 0; i < globbuf.gl_pathc; i++) {
929 int len;
930
913 path = globbuf.gl_pathv[i]; 931 path = globbuf.gl_pathv[i];
914 932
915 event = malloc_or_die(sizeof(*event)); 933 event = malloc_or_die(sizeof(*event));
@@ -932,6 +950,13 @@ static int expand_event_files(const char *file, struct event_list *old_event)
932 event->enable_file = p; 950 event->enable_file = p;
933 else 951 else
934 free(p); 952 free(p);
953
954 len = strlen(path);
955
956 test_event(event, path, "sched/sched_switch", &sched_switch_event, len);
957 test_event(event, path, "sched/sched_wakeup_new", &sched_wakeup_new_event, len);
958 test_event(event, path, "sched/sched_wakeup", &sched_wakeup_event, len);
959 test_event(event, path, "sched", &sched_event, len);
935 } 960 }
936 globfree(&globbuf); 961 globfree(&globbuf);
937 962