2020
2121#include "trace_synth.h"
2222
23+ #undef ERRORS
24+ #define ERRORS \
25+ C(BAD_NAME, "Illegal name"), \
26+ C(CMD_INCOMPLETE, "Incomplete command"), \
27+ C(EVENT_EXISTS, "Event already exists"), \
28+ C(TOO_MANY_FIELDS, "Too many fields"), \
29+ C(INCOMPLETE_TYPE, "Incomplete type"), \
30+ C(INVALID_TYPE, "Invalid type"), \
31+ C(INVALID_FIELD, "Invalid field"), \
32+ C(CMD_TOO_LONG, "Command too long"),
33+
34+ #undef C
35+ #define C (a , b ) SYNTH_ERR_##a
36+
37+ enum { ERRORS };
38+
39+ #undef C
40+ #define C (a , b ) b
41+
42+ static const char * err_text [] = { ERRORS };
43+
44+ static char last_cmd [MAX_FILTER_STR_VAL ];
45+
46+ static int errpos (const char * str )
47+ {
48+ return err_pos (last_cmd , str );
49+ }
50+
51+ static void last_cmd_set (char * str )
52+ {
53+ if (!str )
54+ return ;
55+
56+ strncpy (last_cmd , str , MAX_FILTER_STR_VAL - 1 );
57+ }
58+
59+ static void synth_err (u8 err_type , u8 err_pos )
60+ {
61+ tracing_log_err (NULL , "synthetic_events" , last_cmd , err_text ,
62+ err_type , err_pos );
63+ }
64+
2365static int create_synth_event (int argc , const char * * argv );
2466static int synth_event_show (struct seq_file * m , struct dyn_event * ev );
2567static int synth_event_release (struct dyn_event * ev );
@@ -545,8 +587,10 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
545587 field_type ++ ;
546588
547589 if (!strcmp (field_type , "unsigned" )) {
548- if (argc < 3 )
590+ if (argc < 3 ) {
591+ synth_err (SYNTH_ERR_INCOMPLETE_TYPE , errpos (field_type ));
549592 return ERR_PTR (- EINVAL );
593+ }
550594 prefix = "unsigned " ;
551595 field_type = argv [1 ];
552596 field_name = argv [2 ];
@@ -573,6 +617,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
573617 goto free ;
574618 }
575619 if (!is_good_name (field -> name )) {
620+ synth_err (SYNTH_ERR_BAD_NAME , errpos (field_name ));
576621 ret = - EINVAL ;
577622 goto free ;
578623 }
@@ -601,6 +646,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
601646
602647 size = synth_field_size (field -> type );
603648 if (size < 0 ) {
649+ synth_err (SYNTH_ERR_INVALID_TYPE , errpos (field_type ));
604650 ret = - EINVAL ;
605651 goto free ;
606652 } else if (size == 0 ) {
@@ -621,6 +667,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
621667 field -> is_dynamic = true;
622668 size = sizeof (u64 );
623669 } else {
670+ synth_err (SYNTH_ERR_INVALID_TYPE , errpos (field_type ));
624671 ret = - EINVAL ;
625672 goto free ;
626673 }
@@ -1098,31 +1145,70 @@ int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, const char *name,
10981145}
10991146EXPORT_SYMBOL_GPL (synth_event_gen_cmd_array_start );
11001147
1148+ static int save_cmdstr (int argc , const char * name , const char * * argv )
1149+ {
1150+ struct seq_buf s ;
1151+ char * buf ;
1152+ int i ;
1153+
1154+ buf = kzalloc (MAX_DYNEVENT_CMD_LEN , GFP_KERNEL );
1155+ if (!buf )
1156+ return - ENOMEM ;
1157+
1158+ seq_buf_init (& s , buf , MAX_DYNEVENT_CMD_LEN );
1159+
1160+ seq_buf_puts (& s , name );
1161+
1162+ for (i = 0 ; i < argc ; i ++ ) {
1163+ seq_buf_putc (& s , ' ' );
1164+ seq_buf_puts (& s , argv [i ]);
1165+ }
1166+
1167+ if (!seq_buf_buffer_left (& s )) {
1168+ synth_err (SYNTH_ERR_CMD_TOO_LONG , 0 );
1169+ kfree (buf );
1170+ return - EINVAL ;
1171+ }
1172+ buf [s .len ] = 0 ;
1173+ last_cmd_set (buf );
1174+
1175+ kfree (buf );
1176+ return 0 ;
1177+ }
1178+
11011179static int __create_synth_event (int argc , const char * name , const char * * argv )
11021180{
11031181 struct synth_field * field , * fields [SYNTH_FIELDS_MAX ];
11041182 struct synth_event * event = NULL ;
11051183 int i , consumed = 0 , n_fields = 0 , ret = 0 ;
11061184
1185+ ret = save_cmdstr (argc , name , argv );
1186+ if (ret )
1187+ return ret ;
1188+
11071189 /*
11081190 * Argument syntax:
11091191 * - Add synthetic event: <event_name> field[;field] ...
11101192 * - Remove synthetic event: !<event_name> field[;field] ...
11111193 * where 'field' = type field_name
11121194 */
11131195
1114- if (name [0 ] == '\0' || argc < 1 )
1196+ if (name [0 ] == '\0' || argc < 1 ) {
1197+ synth_err (SYNTH_ERR_CMD_INCOMPLETE , 0 );
11151198 return - EINVAL ;
1199+ }
11161200
11171201 mutex_lock (& event_mutex );
11181202
11191203 if (!is_good_name (name )) {
1204+ synth_err (SYNTH_ERR_BAD_NAME , errpos (name ));
11201205 ret = - EINVAL ;
11211206 goto out ;
11221207 }
11231208
11241209 event = find_synth_event (name );
11251210 if (event ) {
1211+ synth_err (SYNTH_ERR_EVENT_EXISTS , errpos (name ));
11261212 ret = - EEXIST ;
11271213 goto out ;
11281214 }
@@ -1131,6 +1217,7 @@ static int __create_synth_event(int argc, const char *name, const char **argv)
11311217 if (strcmp (argv [i ], ";" ) == 0 )
11321218 continue ;
11331219 if (n_fields == SYNTH_FIELDS_MAX ) {
1220+ synth_err (SYNTH_ERR_TOO_MANY_FIELDS , 0 );
11341221 ret = - EINVAL ;
11351222 goto err ;
11361223 }
@@ -1145,6 +1232,7 @@ static int __create_synth_event(int argc, const char *name, const char **argv)
11451232 }
11461233
11471234 if (i < argc && strcmp (argv [i ], ";" ) != 0 ) {
1235+ synth_err (SYNTH_ERR_INVALID_FIELD , errpos (argv [i ]));
11481236 ret = - EINVAL ;
11491237 goto err ;
11501238 }
0 commit comments