brintos

brintos / linux-shallow public Read only

0
0
Text · 3.7 KiB · 1ddb855 Raw
189 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * rv tool, the interface for the Linux kernel RV subsystem and home of4 * 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 stop21 */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 monitors39 */40static 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		else64			exit(1);65	}66 67	ikm_list_monitors();68	exit(0);69}70 71/*72 * rv_mon - try to run a monitor passed as argument73 */74static void rv_mon(int argc, char **argv)75{76	char *monitor_name;77	int i, run = 0;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, looking112	 * 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 121static 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 command156 *157 * main itself redirects the arguments to the sub-commands158 * to handle the options.159 *160 * subcommands should exit.161 */162int 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}189