Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/verification/rv/src/rv.c
26288 views
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 <[email protected]>
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
17
static int stop_session;
18
19
/*
20
* stop_rv - tell monitors to stop
21
*/
22
static 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
*/
32
int should_stop(void)
33
{
34
return stop_session;
35
}
36
37
/*
38
* rv_list - list all available monitors
39
*/
40
static 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
*/
86
static 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
133
static 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
*/
174
int 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
}
202
203