xref: /linux/tools/verification/rv/src/in_kernel.c (revision 33ec2269a4155cad7e9e42c92327dcaa9aee59a7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * in kernel monitor support: allows rv to control in-kernel monitors.
4  *
5  * Copyright (C) 2022 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
6  */
7 #include <getopt.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <dirent.h>
14 
15 #include <trace.h>
16 #include <utils.h>
17 #include <rv.h>
18 
19 static int config_has_id;
20 static int config_is_container;
21 static int config_my_pid;
22 static int config_trace;
23 
24 static char *config_initial_reactor;
25 static char *config_reactor;
26 
27 /*
28  * __ikm_read_enable - reads monitor's enable status
29  *
30  * __does not log errors.
31  *
32  * Returns the current status, or -1 if the monitor does not exist,
33  * __hence not logging errors.
34  */
35 static int __ikm_read_enable(char *monitor_name)
36 {
37 	char path[MAX_PATH];
38 	long long enabled;
39 	int retval;
40 
41 	snprintf(path, MAX_PATH, "rv/monitors/%s/enable", monitor_name);
42 
43 	retval = tracefs_instance_file_read_number(NULL, path, &enabled);
44 	if (retval < 0)
45 		return -1;
46 
47 	return enabled;
48 }
49 
50 /*
51  * __ikm_find_monitor - find the full name of a possibly nested module
52  *
53  * __does not log errors.
54  *
55  * Returns 1 if we found the monitor, -1 on error and 0 if it does not exist.
56  * The string out_name is populated with the full name, which can be
57  * equal to monitor_name or container/monitor_name if nested
58  */
59 static int __ikm_find_monitor_name(char *monitor_name, char *out_name)
60 {
61 	char *available_monitors, *cursor, *line;
62 	int len = strlen(monitor_name);
63 	int found = 0;
64 
65 	available_monitors = tracefs_instance_file_read(NULL, "rv/available_monitors", NULL);
66 	if (!available_monitors)
67 		return -1;
68 
69 	config_is_container = 0;
70 	cursor = available_monitors;
71 	while ((line = strsep(&cursor, "\n"))) {
72 		char *colon = strchr(line, ':');
73 
74 		if (strcmp(line, monitor_name) && (!colon || strcmp(colon + 1, monitor_name)))
75 			continue;
76 
77 		strncpy(out_name, line, 2 * MAX_DA_NAME_LEN);
78 		out_name[2 * MAX_DA_NAME_LEN - 1] = '\0';
79 
80 		if (colon) {
81 			out_name[colon - line] = '/';
82 		} else {
83 			/* If there are children, they are on the next line. */
84 			line = strsep(&cursor, "\n");
85 			if (line && !strncmp(line, monitor_name, len) && line[len] == ':')
86 				config_is_container = 1;
87 		}
88 
89 		found = 1;
90 		break;
91 	}
92 
93 	free(available_monitors);
94 	return found;
95 }
96 
97 /*
98  * ikm_read_enable - reads monitor's enable status
99  *
100  * Returns the current status, or -1 on error.
101  */
102 static int ikm_read_enable(char *monitor_name)
103 {
104 	int enabled;
105 
106 	enabled = __ikm_read_enable(monitor_name);
107 	if (enabled < 0) {
108 		err_msg("ikm: fail read enabled: %d\n", enabled);
109 		return -1;
110 	}
111 
112 	debug_msg("ikm: read enabled: %d\n", enabled);
113 
114 	return enabled;
115 }
116 
117 /*
118  * ikm_write_enable - write to the monitor's enable file
119  *
120  * Return the number of bytes written, -1 on error.
121  */
122 static int ikm_write_enable(char *monitor_name, char *enable_disable)
123 {
124 	char path[MAX_PATH];
125 	int retval;
126 
127 	debug_msg("ikm: writing enabled: %s\n", enable_disable);
128 
129 	snprintf(path, MAX_PATH, "rv/monitors/%s/enable", monitor_name);
130 	retval = tracefs_instance_file_write(NULL, path, enable_disable);
131 	if (retval < strlen(enable_disable)) {
132 		err_msg("ikm: writing enabled: %s\n", enable_disable);
133 		return -1;
134 	}
135 
136 	return retval;
137 }
138 
139 /*
140  * ikm_enable - enable a monitor
141  *
142  * Returns -1 on failure. Success otherwise.
143  */
144 static int ikm_enable(char *monitor_name)
145 {
146 	return ikm_write_enable(monitor_name, "1");
147 }
148 
149 /*
150  * ikm_disable - disable a monitor
151  *
152  * Returns -1 on failure. Success otherwise.
153  */
154 static int ikm_disable(char *monitor_name)
155 {
156 	return ikm_write_enable(monitor_name, "0");
157 }
158 
159 /*
160  * ikm_read_desc - read monitors' description
161  *
162  * Return a dynamically allocated string with the monitor's
163  * description, NULL otherwise.
164  */
165 static char *ikm_read_desc(char *monitor_name)
166 {
167 	char path[MAX_PATH];
168 	char *desc;
169 
170 	snprintf(path, MAX_PATH, "rv/monitors/%s/desc", monitor_name);
171 	desc = tracefs_instance_file_read(NULL, path, NULL);
172 	if (!desc) {
173 		err_msg("ikm: error reading monitor %s desc\n", monitor_name);
174 		return NULL;
175 	}
176 
177 	*strstr(desc, "\n") = '\0';
178 
179 	return desc;
180 }
181 
182 /*
183  * ikm_fill_monitor_definition - fill monitor's definition
184  *
185  * Returns -1 on error, 1 if the monitor does not belong in the container, 0 otherwise.
186  * container can be NULL
187  */
188 static int ikm_fill_monitor_definition(char *name, struct monitor *ikm, char *container)
189 {
190 	int enabled;
191 	char *desc, *nested_name;
192 
193 	nested_name = strstr(name, ":");
194 	if (nested_name) {
195 		/* it belongs in container if it starts with "container:" */
196 		if (container) {
197 			int len = strlen(container);
198 
199 			if (strncmp(name, container, len) || name[len] != ':')
200 				return 1;
201 		}
202 		*nested_name = '/';
203 		++nested_name;
204 		ikm->nested = 1;
205 	} else {
206 		if (container)
207 			return 1;
208 		nested_name = name;
209 		ikm->nested = 0;
210 	}
211 
212 	enabled = ikm_read_enable(name);
213 	if (enabled < 0) {
214 		err_msg("ikm: monitor %s fail to read enable file, bug?\n", name);
215 		return -1;
216 	}
217 
218 	desc = ikm_read_desc(name);
219 	if (!desc) {
220 		err_msg("ikm: monitor %s does not have desc file, bug?\n", name);
221 		return -1;
222 	}
223 
224 	strncpy(ikm->name, nested_name, sizeof(ikm->name) - 1);
225 	ikm->name[sizeof(ikm->name) - 1] = '\0';
226 	ikm->enabled = enabled;
227 	strncpy(ikm->desc, desc, sizeof(ikm->desc) - 1);
228 	ikm->desc[sizeof(ikm->desc) - 1] = '\0';
229 	free(desc);
230 
231 	return 0;
232 }
233 
234 /*
235  * ikm_write_reactor - switch the reactor to *reactor
236  *
237  * Return the number or characters written, -1 on error.
238  */
239 static int ikm_write_reactor(char *monitor_name, char *reactor)
240 {
241 	char path[MAX_PATH];
242 	int retval;
243 
244 	snprintf(path, MAX_PATH, "rv/monitors/%s/reactors", monitor_name);
245 	retval = tracefs_instance_file_write(NULL, path, reactor);
246 	debug_msg("ikm: write \"%s\" reactors: %d\n", reactor, retval);
247 
248 	return retval;
249 }
250 
251 /*
252  * ikm_read_reactor - read the reactors file
253  *
254  * Returns a dynamically allocated string with monitor's
255  * available reactors, or NULL on error.
256  */
257 static char *ikm_read_reactor(char *monitor_name)
258 {
259 	char path[MAX_PATH];
260 	char *reactors;
261 
262 	snprintf(path, MAX_PATH, "rv/monitors/%s/reactors", monitor_name);
263 	reactors = tracefs_instance_file_read(NULL, path, NULL);
264 	if (!reactors) {
265 		err_msg("ikm: fail reading monitor's %s reactors file\n", monitor_name);
266 		return NULL;
267 	}
268 
269 	return reactors;
270 }
271 
272 /*
273  * ikm_get_current_reactor - get the current enabled reactor
274  *
275  * Reads the reactors file and find the currently enabled
276  * [reactor].
277  *
278  * Returns a dynamically allocated memory with the current
279  * reactor. NULL otherwise.
280  */
281 static char *ikm_get_current_reactor(char *monitor_name)
282 {
283 	char *reactors = ikm_read_reactor(monitor_name);
284 	char *curr_reactor = NULL;
285 	char *start;
286 	char *end;
287 
288 	if (!reactors)
289 		return NULL;
290 
291 	start = strstr(reactors, "[");
292 	if (!start)
293 		goto out_free;
294 
295 	start++;
296 
297 	end = strstr(start, "]");
298 	if (!end)
299 		goto out_free;
300 
301 	*end = '\0';
302 
303 	curr_reactor = calloc(strlen(start) + 1, sizeof(char));
304 	if (!curr_reactor)
305 		goto out_free;
306 
307 	strncpy(curr_reactor, start, strlen(start));
308 	debug_msg("ikm: read current reactor %s\n", curr_reactor);
309 
310 out_free:
311 	free(reactors);
312 
313 	return curr_reactor;
314 }
315 
316 static int ikm_has_id(char *monitor_name)
317 {
318 	char path[MAX_PATH];
319 	char *format;
320 	int has_id;
321 
322 	snprintf(path, MAX_PATH, "events/rv/event_%s/format", monitor_name);
323 	format = tracefs_instance_file_read(NULL, path, NULL);
324 	if (!format) {
325 		err_msg("ikm: fail reading monitor's %s format event file\n", monitor_name);
326 		return -1;
327 	}
328 
329 	/* print fmt: "%d: %s x %s -> %s %s", REC->id, ... */
330 	has_id = !!strstr(format, "REC->id");
331 
332 	debug_msg("ikm: monitor %s has id: %s\n", monitor_name, has_id ? "yes" : "no");
333 
334 	free(format);
335 
336 	return has_id;
337 }
338 
339 /**
340  * ikm_list_monitors - list all available monitors
341  *
342  * Returns 0 on success, -1 otherwise.
343  */
344 int ikm_list_monitors(char *container)
345 {
346 	char *available_monitors;
347 	struct monitor ikm = {0};
348 	char *curr, *next;
349 	int retval, list_monitor = 0;
350 
351 	available_monitors = tracefs_instance_file_read(NULL, "rv/available_monitors", NULL);
352 
353 	if (!available_monitors) {
354 		err_msg("ikm: available monitors is not available, is CONFIG_RV enabled?\n");
355 		return -1;
356 	}
357 
358 	curr = available_monitors;
359 	do {
360 		next = strstr(curr, "\n");
361 		*next = '\0';
362 
363 		retval = ikm_fill_monitor_definition(curr, &ikm, container);
364 		if (retval < 0)
365 			err_msg("ikm: error reading %d in kernel monitor, skipping\n", curr);
366 
367 		if (!retval) {
368 			int indent = ikm.nested && !container;
369 
370 			list_monitor = 1;
371 			printf("%s%-*s %s %s\n", indent ? " - " : "",
372 			       indent ? MAX_DA_NAME_LEN - 3 : MAX_DA_NAME_LEN,
373 			       ikm.name, ikm.desc, ikm.enabled ? "[ON]" : "[OFF]");
374 		}
375 		curr = ++next;
376 
377 	} while (strlen(curr));
378 
379 	if (!list_monitor) {
380 		if (container)
381 			printf("-- No monitor found in container %s --\n", container);
382 		else
383 			printf("-- No monitor found --\n");
384 	}
385 
386 	free(available_monitors);
387 
388 	return 0;
389 }
390 
391 static void ikm_print_header(struct trace_seq *s)
392 {
393 	trace_seq_printf(s, "%16s-%-8s %5s %5s ", "<TASK>", "PID", "[CPU]", "TYPE");
394 	if (config_has_id)
395 		trace_seq_printf(s, "%8s ", "ID");
396 
397 	trace_seq_printf(s, "%24s x %-24s -> %-24s %s\n",
398 			 "STATE",
399 			 "EVENT",
400 			 "NEXT_STATE",
401 			 "FINAL");
402 
403 	trace_seq_printf(s, "%16s %-8s %5s %5s ", " | ", " | ", " | ", " | ");
404 
405 	if (config_has_id)
406 		trace_seq_printf(s, "%8s ", " | ");
407 
408 	trace_seq_printf(s, "%24s   %-24s    %-24s %s\n",
409 			 " | ",
410 			 " | ",
411 			 " | ",
412 			 "|");
413 
414 }
415 
416 /*
417  * ikm_event_handler - callback to handle event events
418  *
419  * Called any time a rv:"monitor"_event events is generated.
420  * It parses and prints event.
421  */
422 static int
423 ikm_event_handler(struct trace_seq *s, struct tep_record *record,
424 		  struct tep_event *trace_event, void *context)
425 {
426 	/* if needed: struct trace_instance *inst = context; */
427 	char *state, *event, *next_state;
428 	unsigned long long final_state;
429 	unsigned long long pid;
430 	unsigned long long id;
431 	int val;
432 	bool missing_id;
433 
434 	if (config_has_id)
435 		missing_id = tep_get_field_val(s, trace_event, "id", record, &id, 1);
436 
437 	tep_get_common_field_val(s, trace_event, "common_pid", record, &pid, 1);
438 
439 	if (config_has_id && (config_my_pid == id))
440 		return 0;
441 	else if (config_my_pid == pid)
442 		return 0;
443 
444 	tep_print_event(trace_event->tep, s, record, "%16s-%-8d [%.3d] ",
445 			TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU);
446 
447 	if (config_is_container)
448 		tep_print_event(trace_event->tep, s, record, "%s ", TEP_PRINT_NAME);
449 	else
450 		trace_seq_printf(s, "event ");
451 
452 	if (config_has_id) {
453 		if (missing_id)
454 			/* placeholder if we are dealing with a mixed-type container*/
455 			trace_seq_printf(s, "        ");
456 		else
457 			trace_seq_printf(s, "%8llu ", id);
458 	}
459 
460 	state = tep_get_field_raw(s, trace_event, "state", record, &val, 0);
461 	event = tep_get_field_raw(s, trace_event, "event", record, &val, 0);
462 	next_state = tep_get_field_raw(s, trace_event, "next_state", record, &val, 0);
463 	tep_get_field_val(s, trace_event, "final_state", record, &final_state, 1);
464 
465 	trace_seq_printf(s, "%24s x %-24s -> %-24s %s\n",
466 			 state,
467 			 event,
468 			 next_state,
469 			 final_state ? "Y" : "N");
470 
471 	trace_seq_do_printf(s);
472 	trace_seq_reset(s);
473 
474 	return 0;
475 }
476 
477 /*
478  * ikm_error_handler - callback to handle error events
479  *
480  * Called any time a rv:"monitor"_errors events is generated.
481  * It parses and prints event.
482  */
483 static int
484 ikm_error_handler(struct trace_seq *s, struct tep_record *record,
485 		  struct tep_event *trace_event, void *context)
486 {
487 	unsigned long long pid, id;
488 	int cpu = record->cpu;
489 	char *state, *event;
490 	int val;
491 	bool missing_id;
492 
493 	if (config_has_id)
494 		missing_id = tep_get_field_val(s, trace_event, "id", record, &id, 1);
495 
496 	tep_get_common_field_val(s, trace_event, "common_pid", record, &pid, 1);
497 
498 	if (config_has_id && config_my_pid == id)
499 		return 0;
500 	else if (config_my_pid == pid)
501 		return 0;
502 
503 	trace_seq_printf(s, "%8lld [%03d] ", pid, cpu);
504 
505 	if (config_is_container)
506 		tep_print_event(trace_event->tep, s, record, "%s ", TEP_PRINT_NAME);
507 	else
508 		trace_seq_printf(s, "error ");
509 
510 	if (config_has_id) {
511 		if (missing_id)
512 			/* placeholder if we are dealing with a mixed-type container*/
513 			trace_seq_printf(s, "        ");
514 		else
515 			trace_seq_printf(s, "%8llu ", id);
516 	}
517 
518 	state = tep_get_field_raw(s, trace_event, "state", record, &val, 0);
519 	event = tep_get_field_raw(s, trace_event, "event", record, &val, 0);
520 
521 	trace_seq_printf(s, "%24s x %s\n", state, event);
522 
523 	trace_seq_do_printf(s);
524 	trace_seq_reset(s);
525 
526 	return 0;
527 }
528 
529 static int ikm_enable_trace_events(char *monitor_name, struct trace_instance *inst)
530 {
531 	char event[MAX_DA_NAME_LEN + 7]; /* max(error_,event_) + '0' = 7 */
532 	int retval;
533 
534 	snprintf(event, sizeof(event), "event_%s", monitor_name);
535 	retval = tracefs_event_enable(inst->inst, "rv",  event);
536 	if (retval)
537 		return -1;
538 
539 	tep_register_event_handler(inst->tep, -1, "rv", event,
540 				   ikm_event_handler, NULL);
541 
542 	snprintf(event, sizeof(event), "error_%s", monitor_name);
543 	retval = tracefs_event_enable(inst->inst, "rv", event);
544 	if (retval)
545 		return -1;
546 
547 	tep_register_event_handler(inst->tep, -1, "rv", event,
548 				   ikm_error_handler, NULL);
549 
550 	/* set if at least 1 monitor has id in case of a container */
551 	config_has_id = ikm_has_id(monitor_name);
552 	if (config_has_id < 0)
553 		return -1;
554 
555 
556 	return 0;
557 }
558 
559 static int ikm_enable_trace_container(char *monitor_name,
560 				      struct trace_instance *inst)
561 {
562 	DIR *dp;
563 	char *abs_path, rv_path[MAX_PATH];
564 	struct dirent *ep;
565 	int retval = 0;
566 
567 	snprintf(rv_path, MAX_PATH, "rv/monitors/%s", monitor_name);
568 	abs_path = tracefs_instance_get_file(NULL, rv_path);
569 	if (!abs_path)
570 		return -1;
571 	dp = opendir(abs_path);
572 	if (!dp)
573 		goto out_free;
574 
575 	while (!retval && (ep = readdir(dp))) {
576 		if (ep->d_type != DT_DIR || ep->d_name[0] == '.')
577 			continue;
578 		retval = ikm_enable_trace_events(ep->d_name, inst);
579 	}
580 
581 	closedir(dp);
582 out_free:
583 	free(abs_path);
584 	return retval;
585 }
586 
587 /*
588  * ikm_setup_trace_instance - set up a tracing instance to collect data
589  *
590  * Create a trace instance, enable rv: events and enable the trace.
591  *
592  * Returns the trace_instance * with all set, NULL otherwise.
593  */
594 static struct trace_instance *ikm_setup_trace_instance(char *monitor_name)
595 {
596 	struct trace_instance *inst;
597 	int retval;
598 
599 	if (!config_trace)
600 		return NULL;
601 
602 	/* alloc data */
603 	inst = calloc(1, sizeof(*inst));
604 	if (!inst) {
605 		err_msg("ikm: failed to allocate trace instance");
606 		goto out_err;
607 	}
608 
609 	retval = trace_instance_init(inst, monitor_name);
610 	if (retval)
611 		goto out_free;
612 
613 	if (config_is_container)
614 		retval = ikm_enable_trace_container(monitor_name, inst);
615 	else
616 		retval = ikm_enable_trace_events(monitor_name, inst);
617 	if (retval)
618 		goto out_inst;
619 
620 	/* ready to enable */
621 	tracefs_trace_on(inst->inst);
622 
623 	return inst;
624 
625 out_inst:
626 	trace_instance_destroy(inst);
627 out_free:
628 	free(inst);
629 out_err:
630 	return NULL;
631 }
632 
633 /**
634  * ikm_destroy_trace_instance - destroy a previously created instance
635  */
636 static void ikm_destroy_trace_instance(struct trace_instance *inst)
637 {
638 	if (!inst)
639 		return;
640 
641 	trace_instance_destroy(inst);
642 	free(inst);
643 }
644 
645 /*
646  * ikm_usage_print_reactors - print all available reactors, one per line.
647  */
648 static void ikm_usage_print_reactors(void)
649 {
650 	char *reactors = tracefs_instance_file_read(NULL, "rv/available_reactors", NULL);
651 	char *start, *end;
652 
653 	if (!reactors)
654 		return;
655 
656 	fprintf(stderr, "  available reactors:");
657 
658 	start = reactors;
659 	end = strstr(start, "\n");
660 
661 	while (end) {
662 		*end = '\0';
663 
664 		fprintf(stderr, " %s", start);
665 
666 		start = ++end;
667 		end = strstr(start, "\n");
668 	}
669 
670 	fprintf(stderr, "\n");
671 }
672 /*
673  * ikm_usage - print usage
674  */
675 static void ikm_usage(int exit_val, char *monitor_name, const char *fmt, ...)
676 {
677 
678 	char message[1024];
679 	va_list ap;
680 	int i;
681 
682 	static const char *const usage[] = {
683 		"",
684 		"	-h/--help: print this menu and the reactor list",
685 		"	-r/--reactor 'reactor': enables the 'reactor'",
686 		"	-s/--self: when tracing (-t), also trace rv command",
687 		"	-t/--trace: trace monitor's event",
688 		"	-v/--verbose: print debug messages",
689 		"",
690 		NULL,
691 	};
692 
693 	va_start(ap, fmt);
694 	vsnprintf(message, sizeof(message), fmt, ap);
695 	va_end(ap);
696 
697 	fprintf(stderr, "  %s\n", message);
698 
699 	fprintf(stderr, "\n  usage: rv mon %s [-h] [-q] [-r reactor] [-s] [-v]", monitor_name);
700 
701 	for (i = 0; usage[i]; i++)
702 		fprintf(stderr, "%s\n", usage[i]);
703 
704 	ikm_usage_print_reactors();
705 	exit(exit_val);
706 }
707 
708 /*
709  * parse_arguments - parse arguments and set config
710  */
711 static int parse_arguments(char *monitor_name, int argc, char **argv)
712 {
713 	int c, retval;
714 
715 	config_my_pid = getpid();
716 
717 	while (1) {
718 		static struct option long_options[] = {
719 			{"help",		no_argument,		0, 'h'},
720 			{"reactor",		required_argument,	0, 'r'},
721 			{"self",		no_argument,		0, 's'},
722 			{"trace",		no_argument,		0, 't'},
723 			{"verbose",		no_argument,		0, 'v'},
724 			{0, 0, 0, 0}
725 		};
726 
727 		/* getopt_long stores the option index here. */
728 		int option_index = 0;
729 
730 		c = getopt_long(argc, argv, "hr:stv", long_options, &option_index);
731 
732 		/* detect the end of the options. */
733 		if (c == -1)
734 			break;
735 
736 		switch (c) {
737 		case 'h':
738 			ikm_usage(0, monitor_name, "help:");
739 			break;
740 		case 'r':
741 			config_reactor = optarg;
742 			break;
743 		case 's':
744 			config_my_pid = -1;
745 			break;
746 		case 't':
747 			config_trace = 1;
748 			break;
749 		case 'v':
750 			config_debug = 1;
751 			break;
752 		}
753 	}
754 
755 	if (config_reactor) {
756 		config_initial_reactor = ikm_get_current_reactor(monitor_name);
757 		if (!config_initial_reactor)
758 			ikm_usage(1, monitor_name,
759 				  "ikm: failed to read current reactor, are reactors enabled?");
760 
761 		retval = ikm_write_reactor(monitor_name, config_reactor);
762 		if (retval <= 0)
763 			ikm_usage(1, monitor_name,
764 				  "ikm: failed to set %s reactor, is it available?",
765 				  config_reactor);
766 	}
767 
768 	debug_msg("ikm: my pid is %d\n", config_my_pid);
769 
770 	return 0;
771 }
772 
773 /**
774  * ikm_run_monitor - apply configs and run the monitor
775  *
776  * Returns 1 if a monitor was found an executed, 0 if no
777  * monitors were found, or -1 on error.
778  */
779 int ikm_run_monitor(char *monitor_name, int argc, char **argv)
780 {
781 	struct trace_instance *inst = NULL;
782 	char *nested_name, full_name[2*MAX_DA_NAME_LEN];
783 	int retval;
784 
785 	nested_name = strstr(monitor_name, ":");
786 	if (nested_name)
787 		++nested_name;
788 	else
789 		nested_name = monitor_name;
790 
791 	retval = __ikm_find_monitor_name(monitor_name, full_name);
792 	if (!retval)
793 		return 0;
794 	if (retval < 0) {
795 		err_msg("ikm: error finding monitor %s\n", nested_name);
796 		return -1;
797 	}
798 
799 	retval = __ikm_read_enable(full_name);
800 	if (retval) {
801 		err_msg("ikm: monitor %s (in-kernel) is already enabled\n", nested_name);
802 		return -1;
803 	}
804 
805 	/* we should be good to go */
806 	retval = parse_arguments(full_name, argc, argv);
807 	if (retval)
808 		ikm_usage(1, nested_name, "ikm: failed parsing arguments");
809 
810 	if (config_trace) {
811 		inst = ikm_setup_trace_instance(nested_name);
812 		if (!inst)
813 			goto out_free_instance;
814 	}
815 
816 	retval = ikm_enable(full_name);
817 	if (retval < 0)
818 		goto out_free_instance;
819 
820 	if (config_trace)
821 		ikm_print_header(inst->seq);
822 
823 	while (!should_stop()) {
824 		if (config_trace) {
825 			retval = tracefs_iterate_raw_events(inst->tep,
826 							    inst->inst,
827 							    NULL,
828 							    0,
829 							    collect_registered_events,
830 							    inst);
831 			if (retval) {
832 				err_msg("ikm: error reading trace buffer\n");
833 				break;
834 			}
835 		}
836 
837 		sleep(1);
838 	}
839 
840 	ikm_disable(full_name);
841 	ikm_destroy_trace_instance(inst);
842 
843 	if (config_reactor && config_initial_reactor)
844 		ikm_write_reactor(full_name, config_initial_reactor);
845 
846 	return 1;
847 
848 out_free_instance:
849 	ikm_destroy_trace_instance(inst);
850 	if (config_reactor && config_initial_reactor)
851 		ikm_write_reactor(full_name, config_initial_reactor);
852 	return -1;
853 }
854