]> Git Repo - linux.git/blob - tools/verification/rv/src/rv.c
scsi: zfcp: Trace when request remove fails after qdio send fails
[linux.git] / tools / verification / rv / src / rv.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 <[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]",
45                 "",
46                 "       list all available monitors",
47                 "",
48                 "       -h/--help: print this menu",
49                 NULL,
50         };
51         int i;
52
53         if (argc > 1) {
54                 fprintf(stderr, "rv version %s\n", VERSION);
55
56                 /* more than 1 is always usage */
57                 for (i = 0; usage[i]; i++)
58                         fprintf(stderr, "%s\n", usage[i]);
59
60                 /* but only -h is valid */
61                 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
62                         exit(0);
63                 else
64                         exit(1);
65         }
66
67         ikm_list_monitors();
68         exit(0);
69 }
70
71 /*
72  * rv_mon - try to run a monitor passed as argument
73  */
74 static void rv_mon(int argc, char **argv)
75 {
76         char *monitor_name;
77         int i, run;
78
79         static const char *const usage[] = {
80                 "",
81                 "  usage: rv mon [-h] monitor [monitor options]",
82                 "",
83                 "       run a monitor",
84                 "",
85                 "       -h/--help: print this menu",
86                 "",
87                 "       monitor [monitor options]: the monitor, passing",
88                 "       the arguments to the [monitor options]",
89                 NULL,
90         };
91
92         /* requires at least one argument */
93         if (argc == 1) {
94
95                 fprintf(stderr, "rv version %s\n", VERSION);
96
97                 for (i = 0; usage[i]; i++)
98                         fprintf(stderr, "%s\n", usage[i]);
99                 exit(1);
100         } else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
101
102                 fprintf(stderr, "rv version %s\n", VERSION);
103
104                 for (i = 0; usage[i]; i++)
105                         fprintf(stderr, "%s\n", usage[i]);
106                 exit(0);
107         }
108
109         monitor_name = argv[1];
110         /*
111          * Call all possible monitor implementations, looking
112          * for the [monitor].
113          */
114         run += ikm_run_monitor(monitor_name, argc-1, &argv[1]);
115
116         if (!run)
117                 err_msg("rv: monitor %s does not exist\n", monitor_name);
118         exit(!run);
119 }
120
121 static void usage(int exit_val, const char *fmt, ...)
122 {
123         char message[1024];
124         va_list ap;
125         int i;
126
127         static const char *const usage[] = {
128                 "",
129                 "  usage: rv command [-h] [command_options]",
130                 "",
131                 "       -h/--help: print this menu",
132                 "",
133                 "       command: run one of the following command:",
134                 "         list: list all available monitors",
135                 "         mon:  run a monitor",
136                 "",
137                 "       [command options]: each command has its own set of options",
138                 "                          run rv command -h for further information",
139                 NULL,
140         };
141
142         va_start(ap, fmt);
143         vsnprintf(message, sizeof(message), fmt, ap);
144         va_end(ap);
145
146         fprintf(stderr, "rv version %s: %s\n", VERSION, message);
147
148         for (i = 0; usage[i]; i++)
149                 fprintf(stderr, "%s\n", usage[i]);
150
151         exit(exit_val);
152 }
153
154 /*
155  * main - select which main sending the command
156  *
157  * main itself redirects the arguments to the sub-commands
158  * to handle the options.
159  *
160  * subcommands should exit.
161  */
162 int main(int argc, char **argv)
163 {
164         if (geteuid())
165                 usage(1, "%s needs root permission", argv[0]);
166
167         if (argc <= 1)
168                 usage(1, "%s requires a command", argv[0]);
169
170         if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
171                 usage(0, "help");
172
173         if (!strcmp(argv[1], "list"))
174                 rv_list(--argc, &argv[1]);
175
176         if (!strcmp(argv[1], "mon")) {
177                 /*
178                  * monitor's main should monitor should_stop() function.
179                  * and exit.
180                  */
181                 signal(SIGINT, stop_rv);
182
183                 rv_mon(argc - 1, &argv[1]);
184         }
185
186         /* invalid sub-command */
187         usage(1, "%s does not know the %s command, old version?", argv[0], argv[1]);
188 }
This page took 0.042884 seconds and 4 git commands to generate.