main.c (30b6496ac81b878ac8ccfe03f495386e24ff1a19) main.c (d65368be2872800621eb2528d6ff9494ab2362c3)
1// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2021 IBM Corp.
3
1// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2021 IBM Corp.
3
4/*
5 * debug-trigger listens for an external signal that the BMC is in some way unresponsive. When the
6 * signal is received it triggers a crash to collect debug data and reboots the system in the hope
7 * that it will recover.
8 *
9 * Usage: debug-trigger [SOURCE] [SINK]
10 *
11 * Examples:
12 * debug-trigger
13 * Set the source as stdin and the sink as stdout. Useful for testing.
14 *
15 * debug-trigger /dev/serio_raw0 /proc/sysrq-trigger
16 * Open /dev/serio_raw0 as the source and /proc/sysrq-trigger as the sink.
17 */
18
4#include <err.h>
5#include <fcntl.h>
6#include <getopt.h>
7#include <libgen.h>
8#include <limits.h>
9#include <linux/reboot.h>
10#include <stdlib.h>
11#include <string.h>

--- 64 unchanged lines hidden (view full) ---

76
77int main(int argc, char * const argv[])
78{
79 char devnode[PATH_MAX];
80 char *devid;
81 int source;
82 int sink;
83
19#include <err.h>
20#include <fcntl.h>
21#include <getopt.h>
22#include <libgen.h>
23#include <limits.h>
24#include <linux/reboot.h>
25#include <stdlib.h>
26#include <string.h>

--- 64 unchanged lines hidden (view full) ---

91
92int main(int argc, char * const argv[])
93{
94 char devnode[PATH_MAX];
95 char *devid;
96 int source;
97 int sink;
98
99 /* Option processing. Currently nothing implemented, but allows us to use optind */
84 while (1) {
85 static struct option long_options[] = {
86 {0, 0, 0, 0},
87 };
88 int c;
89
90 c = getopt_long(argc, argv, "", long_options, NULL);
91 if (c == -1)
92 break;
93 }
94
100 while (1) {
101 static struct option long_options[] = {
102 {0, 0, 0, 0},
103 };
104 int c;
105
106 c = getopt_long(argc, argv, "", long_options, NULL);
107 if (c == -1)
108 break;
109 }
110
111 /*
112 * The default behaviour sets the source as stdin and the sink as stdout. This allows
113 * trivial testing on the command-line with just a keyboard and without crashing the system.
114 */
95 source = 0;
96 sink = 1;
97
115 source = 0;
116 sink = 1;
117
118 /* Handle the source argument, if any */
98 if (optind < argc) {
99 char devpath[PATH_MAX];
100
119 if (optind < argc) {
120 char devpath[PATH_MAX];
121
122 /*
123 * To make our lives easy with udev we take the basename of the source argument and
124 * look for it in /dev. This allows us to use %p (the devpath specifier) in the udev
125 * rule to pass the device of interest to the systemd unit.
126 */
101 strncpy(devpath, argv[optind], sizeof(devpath));
102 devpath[PATH_MAX - 1] = '\0';
103 devid = basename(devpath);
104
105 strncpy(devnode, "/dev/", sizeof(devnode));
106 strncat(devnode, devid, sizeof(devnode));
107 devnode[PATH_MAX - 1] = '\0';
108
109 if ((source = open(devnode, O_RDONLY)) == -1)
110 err(EXIT_FAILURE, "Failed to open %s", devnode);
111
112 optind++;
113 }
114
127 strncpy(devpath, argv[optind], sizeof(devpath));
128 devpath[PATH_MAX - 1] = '\0';
129 devid = basename(devpath);
130
131 strncpy(devnode, "/dev/", sizeof(devnode));
132 strncat(devnode, devid, sizeof(devnode));
133 devnode[PATH_MAX - 1] = '\0';
134
135 if ((source = open(devnode, O_RDONLY)) == -1)
136 err(EXIT_FAILURE, "Failed to open %s", devnode);
137
138 optind++;
139 }
140
141 /* Handle the sink argument, if any */
115 if (optind < argc) {
142 if (optind < argc) {
143 /*
144 * Just open the sink path directly. If we ever need different behaviour then we
145 * patch this bit when we know what we need.
146 */
116 if ((sink = open(argv[optind], O_WRONLY)) == -1)
117 err(EXIT_FAILURE, "Failed to open %s", argv[optind]);
118
119 optind++;
120 }
121
147 if ((sink = open(argv[optind], O_WRONLY)) == -1)
148 err(EXIT_FAILURE, "Failed to open %s", argv[optind]);
149
150 optind++;
151 }
152
153 /* Check we're done with the command-line */
122 if (optind < argc)
123 err(EXIT_FAILURE, "Found %d unexpected arguments", argc - optind);
124
154 if (optind < argc)
155 err(EXIT_FAILURE, "Found %d unexpected arguments", argc - optind);
156
157 /* Trigger the actions on the sink when we receive an event from the source */
125 if (process(source, sink) < 0)
126 errx(EXIT_FAILURE, "Failure while processing command stream");
127
128 return 0;
129}
158 if (process(source, sink) < 0)
159 errx(EXIT_FAILURE, "Failure while processing command stream");
160
161 return 0;
162}