···115115 return CMD_RET_FAILURE;
116116 }
117117118118- /* <3> < 6 > <2+1 + 7 > < 16 > < unbounded... */
119119- printf("num policy level categories files\n");
120118 list_for_each_entry(filt, &ldev->filter_head, sibling_node) {
121121- printf("%3d %6.6s %s %-7.7s ", filt->filter_num,
122122- filt->flags & LOGFF_DENY ? "deny" : "allow",
119119+ printf("%-3d: %s %s %s\n", filt->filter_num,
120120+ filt->flags & LOGFF_DENY ? "DENY" : "ALLOW",
123121 filt->flags & LOGFF_LEVEL_MIN ? ">=" : "<=",
124122 log_get_level_name(filt->level));
125123126124 if (filt->flags & LOGFF_HAS_CAT) {
127127- int i;
128128-129129- if (filt->cat_list[0] != LOGC_END)
130130- printf("%16.16s %s\n",
131131- log_get_cat_name(filt->cat_list[0]),
132132- filt->file_list ? filt->file_list : "");
133133-134134- for (i = 1; i < LOGF_MAX_CATEGORIES &&
135135- filt->cat_list[i] != LOGC_END; i++)
136136- printf("%21c %16.16s\n", ' ',
125125+ printf(" Categories:");
126126+ for (int i = 0;
127127+ i < LOGF_MAX_CATEGORIES &&
128128+ filt->cat_list[i] != LOGC_END;
129129+ ++i) {
130130+ printf(" %s",
137131 log_get_cat_name(filt->cat_list[i]));
138138- } else {
139139- printf("%16c %s\n", ' ',
140140- filt->file_list ? filt->file_list : "");
132132+ }
133133+ printf("\n");
141134 }
135135+ if (filt->file_list)
136136+ printf(" Files: %s\n", filt->file_list);
137137+ if (filt->func_list)
138138+ printf(" Functions: %s\n", filt->func_list);
142139 }
143140144141 return CMD_RET_SUCCESS;
···151148 bool print_num = false;
152149 bool type_set = false;
153150 char *file_list = NULL;
151151+ char *func_list = NULL;
154152 const char *drv_name = "console";
155153 int opt, err;
156154 int cat_count = 0;
···160158 struct getopt_state gs;
161159162160 getopt_init_state(&gs);
163163- while ((opt = getopt(&gs, argc, argv, "Ac:d:Df:l:L:p")) > 0) {
161161+ while ((opt = getopt(&gs, argc, argv, "Ac:d:Df:F:l:L:p")) > 0) {
164162 switch (opt) {
165163 case 'A':
166164#define do_type() do { \
···199197 case 'f':
200198 file_list = gs.arg;
201199 break;
200200+ case 'F':
201201+ func_list = gs.arg;
202202+ break;
202203 case 'l':
203204#define do_level() do { \
204205 if (level_set) { \
···229230230231 cat_list[cat_count] = LOGC_END;
231232 err = log_add_filter_flags(drv_name, cat_count ? cat_list : NULL, level,
232232- file_list, flags);
233233+ file_list, func_list, flags);
233234 if (err < 0) {
234235 printf("Could not add filter (err = %d)\n", err);
235236 return CMD_RET_FAILURE;
···388389 "\t-d <driver> - Specify the log driver to add the filter to; defaults\n"
389390 "\t to console\n"
390391 "\t-D - Deny messages matching this filter; mutually exclusive with -A\n"
391391- "\t-f <files_list> - A comma-separated list of files to match\n"
392392+ "\t-f <file_list> - A comma-separated list of files to match\n"
393393+ "\t-F <func_list> - A comma-separated list of functions to match\n"
392394 "\t-l <level> - Match log levels less than or equal to <level>;\n"
393395 "\t mutually-exclusive with -L\n"
394396 "\t-L <level> - Match log levels greather than or equal to <level>;\n"
+12-1
common/log.c
···192192 !log_has_member(filt->file_list, rec->file))
193193 continue;
194194195195+ if (filt->func_list &&
196196+ !log_has_member(filt->func_list, rec->func))
197197+ continue;
198198+195199 if (filt->flags & LOGFF_DENY)
196200 return false;
197201 else
···329333330334int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[],
331335 enum log_level_t level, const char *file_list,
332332- int flags)
336336+ const char *func_list, int flags)
333337{
334338 struct log_filter *filt;
335339 struct log_device *ldev;
···360364 if (file_list) {
361365 filt->file_list = strdup(file_list);
362366 if (!filt->file_list) {
367367+ ret = -ENOMEM;
368368+ goto err;
369369+ }
370370+ }
371371+ if (func_list) {
372372+ filt->func_list = strdup(func_list);
373373+ if (!filt->func_list) {
363374 ret = -ENOMEM;
364375 goto err;
365376 }
+5-2
include/log.h
···500500 * @level: Maximum (or minimum, if %LOGFF_MIN_LEVEL) log level to allow
501501 * @file_list: List of files to allow, separated by comma. If NULL then all
502502 * files are permitted
503503+ * @func_list: Comma separated list of functions or NULL.
503504 * @sibling_node: Next filter in the list of filters for this log device
504505 */
505506struct log_filter {
···508509 enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
509510 enum log_level_t level;
510511 const char *file_list;
512512+ const char *func_list;
511513 struct list_head sibling_node;
512514};
513515···599601 * @level: Maximum (or minimum, if %LOGFF_LEVEL_MIN) log level to allow
600602 * @file_list: List of files to allow, separated by comma. If NULL then all
601603 * files are permitted
604604+ * @func_list: Comma separated list of functions or NULL.
602605 * Return:
603606 * the sequence number of the new filter (>=0) if the filter was added, or a
604607 * -ve value on error
605608 */
606609int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[],
607610 enum log_level_t level, const char *file_list,
608608- int flags);
611611+ const char *func_list, int flags);
609612610613/**
611614 * log_add_filter() - Add a new filter to a log device
···628631 const char *file_list)
629632{
630633 return log_add_filter_flags(drv_name, cat_list, max_level, file_list,
631631- 0);
634634+ NULL, 0);
632635}
633636634637/**