main: Add --sink-actions=... command-line option
Allow explicit configuration of the actions to take when a valid command
is received from the source. This patch gives the current set of actions
the name 'sysrq'.
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: Ie8e7446599edb5927468865bcea36b596aef12f6
diff --git a/main.c b/main.c
index c3408c0..6a81933 100644
--- a/main.c
+++ b/main.c
@@ -2,18 +2,30 @@
// Copyright (C) 2021 IBM Corp.
/*
- * debug-trigger listens for an external signal that the BMC is in some way unresponsive. When the
+ * debug-trigger listens for an external signal that the BMC is in some way unresponsive. When a
* signal is received it triggers a crash to collect debug data and reboots the system in the hope
* that it will recover.
*
* Usage: debug-trigger [SOURCE] [SINK]
*
+ * Options:
+ * --sink-actions=ACTION
+ * Set the class of sink action(s) to be used. Defaults to 'sysrq'
+ *
* Examples:
* debug-trigger
- * Set the source as stdin and the sink as stdout. Useful for testing.
+ * Set the source as stdin, the sink as stdout, and use the default 'sysrq' set of sink
+ * actions. Useful for testing.
+ *
+ * debug-trigger --sink-actions=sysrq
+ * Explicitly use the 'sysrq' set of sink actions with stdin as the source and stdout as the
+ * sink.
*
* debug-trigger /dev/serio_raw0 /proc/sysrq-trigger
- * Open /dev/serio_raw0 as the source and /proc/sysrq-trigger as the sink.
+ * Open /dev/serio_raw0 as the source and /proc/sysrq-trigger as the sink, with the default
+ * 'sysrq' set of sink actions. When 'D' is read from /dev/serio_raw0 'c' will be written to
+ * /proc/sysrq-trigger, causing a kernel panic. When 'R' is read from /dev/serio_raw0 'b' will
+ * be written to /proc/sysrq-trigger, causing an immediate reboot of the system.
*/
#include <err.h>
@@ -112,6 +124,7 @@
int main(int argc, char * const argv[])
{
+ const char *sink_actions = NULL;
struct debug_sink_sysrq sysrq;
struct debug_sink sink;
char devnode[PATH_MAX];
@@ -119,9 +132,10 @@
int sourcefd;
int sinkfd;
- /* Option processing. Currently nothing implemented, but allows us to use optind */
+ /* Option processing */
while (1) {
static struct option long_options[] = {
+ {"sink-actions", required_argument, 0, 's'},
{0, 0, 0, 0},
};
int c;
@@ -129,16 +143,25 @@
c = getopt_long(argc, argv, "", long_options, NULL);
if (c == -1)
break;
+
+ switch (c) {
+ case 's':
+ sink_actions = optarg;
+ break;
+ default:
+ break;
+ }
}
/*
- * The default behaviour sets the source as stdin and the sink as stdout. This allows
- * trivial testing on the command-line with just a keyboard and without crashing the system.
+ * The default behaviour sets the source file descriptor as stdin and the sink file
+ * descriptor as stdout. This allows trivial testing on the command-line with just a
+ * keyboard and without crashing the system.
*/
sourcefd = 0;
sinkfd = 1;
- /* Handle the source argument, if any */
+ /* Handle the source path argument, if any */
if (optind < argc) {
char devpath[PATH_MAX];
@@ -161,26 +184,32 @@
optind++;
}
- /* Handle the sink argument, if any */
- if (optind < argc) {
- /*
- * Just open the sink path directly. If we ever need different behaviour then we
- * patch this bit when we know what we need.
- */
- if ((sinkfd = open(argv[optind], O_WRONLY)) == -1)
- err(EXIT_FAILURE, "Failed to open %s", argv[optind]);
+ /*
+ * Handle the sink path argument, if any. If sink_actions hasn't been set via the
+ * --sink-actions option, then default to 'sysrq'. Otherwise, if --sink-actions=sysrq has
+ * been passed, do as we're told and use the 'sysrq' sink actions.
+ */
+ if (!sink_actions || !strcmp("sysrq", sink_actions)) {
+ if (optind < argc) {
+ /*
+ * Just open the sink path directly. If we ever need different behaviour
+ * then we patch this bit when we know what we need.
+ */
+ if ((sinkfd = open(argv[optind], O_WRONLY)) == -1)
+ err(EXIT_FAILURE, "Failed to open %s", argv[optind]);
- optind++;
+ optind++;
+ }
+
+ sysrq.sink = sinkfd;
+ sink.ops = &sysrq_sink_ops;
+ sink.ctx = &sysrq;
}
/* Check we're done with the command-line */
if (optind < argc)
err(EXIT_FAILURE, "Found %d unexpected arguments", argc - optind);
- sysrq.sink = sinkfd;
- sink.ops = &sysrq_sink_ops;
- sink.ctx = &sysrq;
-
/* Trigger the actions on the sink when we receive an event from the source */
if (process(sourcefd, &sink) < 0)
errx(EXIT_FAILURE, "Failure while processing command stream");