File Index
Files and directories
Sign in
FILE

rv.c

File preview with syntax highlighting.

linux-6.19.14/tools/verification/rv/src/rv.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * rv tool, the interface for the Linux kernel RV subsystem and home of
  4 * user-space controlled monitors.
  5 *
  6 * Copyright (C) 2022 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
  7 */
  8
  9#include <stdlib.h>
 10#include <signal.h>
 11#include <unistd.h>
 12
 13#include <trace.h>
 14#include <utils.h>
 15#include <in_kernel.h>
 16
 17static int stop_session;
 18
 19/*
 20 * stop_rv - tell monitors to stop
 21 */
 22static void stop_rv(int sig)
 23{
 24	stop_session = 1;
 25}
 26
 27/**
 28 * should_stop - check if the monitor should stop.
 29 *
 30 * Returns 1 if the monitor should stop, 0 otherwise.
 31 */
 32int should_stop(void)
 33{
 34	return stop_session;
 35}
 36
 37/*
 38 * rv_list - list all available monitors
 39 */
 40static void rv_list(int argc, char **argv)
 41{
 42	static const char *const usage[] = {
 43		"",
 44		"  usage: rv list [-h] [container]",
 45		"",
 46		"	list all available monitors",
 47		"",
 48		"	-h/--help: print this menu",
 49		"",
 50		"	[container]: list only monitors in this container",
 51		NULL,
 52	};
 53	int i, print_help = 0, retval = 0;
 54	char *container = NULL;
 55
 56	if (argc == 2) {
 57		if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
 58			print_help = 1;
 59			retval = 0;
 60		} else if (argv[1][0] == '-') {
 61			/* assume invalid option */
 62			print_help = 1;
 63			retval = 1;
 64		} else
 65			container = argv[1];
 66	} else if (argc > 2) {
 67		/* more than 2 is always usage */
 68		print_help = 1;
 69		retval = 1;
 70	}
 71	if (print_help) {
 72		fprintf(stderr, "rv version %s\n", VERSION);
 73		for (i = 0; usage[i]; i++)
 74			fprintf(stderr, "%s\n", usage[i]);
 75		exit(retval);
 76	}
 77
 78	ikm_list_monitors(container);
 79
 80	exit(0);
 81}
 82
 83/*
 84 * rv_mon - try to run a monitor passed as argument
 85 */
 86static void rv_mon(int argc, char **argv)
 87{
 88	char *monitor_name;
 89	int i, run = 0;
 90
 91	static const char *const usage[] = {
 92		"",
 93		"  usage: rv mon [-h] monitor [monitor options]",
 94		"",
 95		"	run a monitor",
 96		"",
 97		"	-h/--help: print this menu",
 98		"",
 99		"	monitor [monitor options]: the monitor, passing",
100		"	the arguments to the [monitor options]",
101		NULL,
102	};
103
104	/* requires at least one argument */
105	if (argc == 1) {
106
107		fprintf(stderr, "rv version %s\n", VERSION);
108
109		for (i = 0; usage[i]; i++)
110			fprintf(stderr, "%s\n", usage[i]);
111		exit(1);
112	} else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
113
114		fprintf(stderr, "rv version %s\n", VERSION);
115
116		for (i = 0; usage[i]; i++)
117			fprintf(stderr, "%s\n", usage[i]);
118		exit(0);
119	}
120
121	monitor_name = argv[1];
122	/*
123	 * Call all possible monitor implementations, looking
124	 * for the [monitor].
125	 */
126	run += ikm_run_monitor(monitor_name, argc-1, &argv[1]);
127
128	if (!run)
129		err_msg("rv: monitor %s does not exist\n", monitor_name);
130	exit(!run);
131}
132
133static void usage(int exit_val, const char *fmt, ...)
134{
135	char message[1024];
136	va_list ap;
137	int i;
138
139	static const char *const usage[] = {
140		"",
141		"  usage: rv command [-h] [command_options]",
142		"",
143		"	-h/--help: print this menu",
144		"",
145		"	command: run one of the following command:",
146		"	  list: list all available monitors",
147		"	  mon:  run a monitor",
148		"",
149		"	[command options]: each command has its own set of options",
150		"		           run rv command -h for further information",
151		NULL,
152	};
153
154	va_start(ap, fmt);
155	vsnprintf(message, sizeof(message), fmt, ap);
156	va_end(ap);
157
158	fprintf(stderr, "rv version %s: %s\n", VERSION, message);
159
160	for (i = 0; usage[i]; i++)
161		fprintf(stderr, "%s\n", usage[i]);
162
163	exit(exit_val);
164}
165
166/*
167 * main - select which main sending the command
168 *
169 * main itself redirects the arguments to the sub-commands
170 * to handle the options.
171 *
172 * subcommands should exit.
173 */
174int main(int argc, char **argv)
175{
176	if (geteuid())
177		usage(1, "%s needs root permission", argv[0]);
178
179	if (argc <= 1)
180		usage(1, "%s requires a command", argv[0]);
181
182	if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
183		usage(0, "help");
184
185	if (!strcmp(argv[1], "list"))
186		rv_list(--argc, &argv[1]);
187
188	if (!strcmp(argv[1], "mon")) {
189		/*
190		 * monitor's main should monitor should_stop() function.
191		 * and exit.
192		 */
193		signal(SIGINT, stop_rv);
194		signal(SIGTERM, stop_rv);
195
196		rv_mon(argc - 1, &argv[1]);
197	}
198
199	/* invalid sub-command */
200	usage(1, "%s does not know the %s command, old version?", argv[0], argv[1]);
201}
~/ Read-only file preview.