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