Skip to content

Commit 63368be

Browse files
author
Mark Salyzyn
committed
modprobe: add -s/--syslog flag
There is a desire to ensure that modprobe as a service can log to kmesg to help triage issues, so add support for the -s or --syslog flag to do so. SideEffects: - help goes to stdout instead of stderr. - verbose flag once, sets DEBUG, twice, sets VERBOSE minimum. - quiet flag sets WARNING minimum. Bug: 159424228 Bug: 151950334 Test: use modprobe as a service to load modules, check logs Change-Id: I884995f364b0fc604861797eb90d7225a372f864
1 parent 3d246cc commit 63368be

File tree

1 file changed

+70
-58
lines changed

1 file changed

+70
-58
lines changed

toolbox/modprobe.cpp

Lines changed: 70 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
*/
1616

1717
#include <ctype.h>
18-
#include <errno.h>
1918
#include <getopt.h>
2019
#include <stdlib.h>
21-
#include <string.h>
2220

23-
#include <iostream>
2421
#include <string>
2522

2623
#include <android-base/file.h>
24+
#include <android-base/logging.h>
2725
#include <android-base/strings.h>
2826
#include <modprobe/modprobe.h>
2927

@@ -37,32 +35,31 @@ enum modprobe_mode {
3735
};
3836

3937
void print_usage(void) {
40-
std::cerr << "Usage:" << std::endl;
41-
std::cerr << std::endl;
38+
LOG(INFO) << "Usage:";
39+
LOG(INFO);
4240
// -d option is required on Android
43-
std::cerr << " modprobe [options] -d DIR [--all=FILE|MODULE]..." << std::endl;
44-
std::cerr << " modprobe [options] -d DIR MODULE [symbol=value]..." << std::endl;
45-
std::cerr << std::endl;
46-
std::cerr << "Options:" << std::endl;
47-
std::cerr << " --all=FILE: FILE to acquire module names from" << std::endl;
48-
std::cerr << " -b, --use-blocklist: Apply blocklist to module names too" << std::endl;
49-
std::cerr << " -d, --dirname=DIR: Load modules from DIR, option may be used multiple times"
50-
<< std::endl;
51-
std::cerr << " -D, --show-depends: Print dependencies for modules only, do not load"
52-
<< std::endl;
53-
std::cerr << " -h, --help: Print this help" << std::endl;
54-
std::cerr << " -l, --list: List modules matching pattern" << std::endl;
55-
std::cerr << " -r, --remove: Remove MODULE (multiple modules may be specified)" << std::endl;
56-
std::cerr << " -q, --quiet: disable messages" << std::endl;
57-
std::cerr << " -v, --verbose: enable more messages" << std::endl;
58-
std::cerr << std::endl;
41+
LOG(INFO) << " modprobe [options] -d DIR [--all=FILE|MODULE]...";
42+
LOG(INFO) << " modprobe [options] -d DIR MODULE [symbol=value]...";
43+
LOG(INFO);
44+
LOG(INFO) << "Options:";
45+
LOG(INFO) << " --all=FILE: FILE to acquire module names from";
46+
LOG(INFO) << " -b, --use-blocklist: Apply blocklist to module names too";
47+
LOG(INFO) << " -d, --dirname=DIR: Load modules from DIR, option may be used multiple times";
48+
LOG(INFO) << " -D, --show-depends: Print dependencies for modules only, do not load";
49+
LOG(INFO) << " -h, --help: Print this help";
50+
LOG(INFO) << " -l, --list: List modules matching pattern";
51+
LOG(INFO) << " -r, --remove: Remove MODULE (multiple modules may be specified)";
52+
LOG(INFO) << " -s, --syslog: print to syslog also";
53+
LOG(INFO) << " -q, --quiet: disable messages";
54+
LOG(INFO) << " -v, --verbose: enable more messages, even more with a second -v";
55+
LOG(INFO);
5956
}
6057

61-
#define check_mode() \
62-
if (mode != AddModulesMode) { \
63-
std::cerr << "Error, multiple mode flags specified" << std::endl; \
64-
print_usage(); \
65-
return EXIT_FAILURE; \
58+
#define check_mode() \
59+
if (mode != AddModulesMode) { \
60+
LOG(ERROR) << "multiple mode flags specified"; \
61+
print_usage(); \
62+
return EXIT_FAILURE; \
6663
}
6764

6865
std::string stripComments(const std::string& str) {
@@ -76,16 +73,28 @@ std::string stripComments(const std::string& str) {
7673
/* NOTREACHED */
7774
}
7875

76+
auto syslog = false;
77+
78+
void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
79+
const char* file, unsigned int line, const char* message) {
80+
android::base::StdioLogger(id, severity, tag, file, line, message);
81+
if (syslog && message[0]) {
82+
android::base::KernelLogger(id, severity, tag, file, line, message);
83+
}
84+
}
85+
7986
} // anonymous namespace
8087

8188
extern "C" int modprobe_main(int argc, char** argv) {
89+
android::base::InitLogging(argv, MyLogger);
90+
android::base::SetMinimumLogSeverity(android::base::INFO);
91+
8292
std::vector<std::string> modules;
8393
std::string module_parameters;
8494
std::string mods;
8595
std::vector<std::string> mod_dirs;
8696
modprobe_mode mode = AddModulesMode;
8797
bool blocklist = false;
88-
bool verbose = false;
8998
int rv = EXIT_SUCCESS;
9099

91100
int opt;
@@ -102,19 +111,19 @@ extern "C" int modprobe_main(int argc, char** argv) {
102111
{ "list", no_argument, 0, 'l' },
103112
{ "quiet", no_argument, 0, 'q' },
104113
{ "remove", no_argument, 0, 'r' },
114+
{ "syslog", no_argument, 0, 's' },
105115
{ "verbose", no_argument, 0, 'v' },
106116
};
107117
// clang-format on
108-
while ((opt = getopt_long(argc, argv, "a::bd:Dhlqrv", long_options, &option_index)) != -1) {
118+
while ((opt = getopt_long(argc, argv, "a::bd:Dhlqrsv", long_options, &option_index)) != -1) {
109119
switch (opt) {
110120
case 'a':
111121
// toybox modprobe supported -a to load multiple modules, this
112122
// is supported here by default, ignore flag if no argument.
113123
check_mode();
114124
if (optarg == NULL) break;
115125
if (!android::base::ReadFileToString(optarg, &mods)) {
116-
std::cerr << "Failed to open " << optarg << ": " << strerror(errno)
117-
<< std::endl;
126+
PLOG(ERROR) << "Failed to open " << optarg;
118127
rv = EXIT_FAILURE;
119128
}
120129
for (auto mod : android::base::Split(stripComments(mods), "\n")) {
@@ -135,24 +144,33 @@ extern "C" int modprobe_main(int argc, char** argv) {
135144
mode = ShowDependenciesMode;
136145
break;
137146
case 'h':
147+
android::base::SetMinimumLogSeverity(android::base::INFO);
138148
print_usage();
139-
return EXIT_SUCCESS;
149+
return rv;
140150
case 'l':
141151
check_mode();
142152
mode = ListModulesMode;
143153
break;
144154
case 'q':
145-
verbose = false;
155+
android::base::SetMinimumLogSeverity(android::base::WARNING);
146156
break;
147157
case 'r':
148158
check_mode();
149159
mode = RemoveModulesMode;
150160
break;
161+
case 's':
162+
syslog = true;
163+
break;
151164
case 'v':
152-
verbose = true;
165+
if (android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
166+
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
167+
} else {
168+
android::base::SetMinimumLogSeverity(android::base::DEBUG);
169+
}
153170
break;
154171
default:
155-
std::cerr << "Unrecognized option: " << opt << std::endl;
172+
LOG(ERROR) << "Unrecognized option: " << opt;
173+
print_usage();
156174
return EXIT_FAILURE;
157175
}
158176
}
@@ -171,39 +189,33 @@ extern "C" int modprobe_main(int argc, char** argv) {
171189
}
172190
}
173191

174-
if (verbose) {
175-
std::cout << "mode is " << mode << std::endl;
176-
std::cout << "verbose is " << verbose << std::endl;
177-
std::cout << "mod_dirs is: " << android::base::Join(mod_dirs, " ") << std::endl;
178-
std::cout << "modules is: " << android::base::Join(modules, " ") << std::endl;
179-
std::cout << "module parameters is: " << android::base::Join(module_parameters, " ")
180-
<< std::endl;
181-
}
192+
LOG(DEBUG) << "mode is " << mode;
193+
LOG(DEBUG) << "mod_dirs is: " << android::base::Join(mod_dirs, " ");
194+
LOG(DEBUG) << "modules is: " << android::base::Join(modules, " ");
195+
LOG(DEBUG) << "module parameters is: " << android::base::Join(module_parameters, " ");
182196

183197
if (modules.empty()) {
184198
if (mode == ListModulesMode) {
185199
// emulate toybox modprobe list with no pattern (list all)
186200
modules.emplace_back("*");
187201
} else {
188-
std::cerr << "No modules given." << std::endl;
202+
LOG(ERROR) << "No modules given.";
189203
print_usage();
190204
return EXIT_FAILURE;
191205
}
192206
}
193207
if (mod_dirs.empty()) {
194-
std::cerr << "No module configuration directories given." << std::endl;
208+
LOG(ERROR) << "No module configuration directories given.";
195209
print_usage();
196210
return EXIT_FAILURE;
197211
}
198212
if (parameter_count && modules.size() > 1) {
199-
std::cerr << "Only one module may be loaded when specifying module parameters."
200-
<< std::endl;
213+
LOG(ERROR) << "Only one module may be loaded when specifying module parameters.";
201214
print_usage();
202215
return EXIT_FAILURE;
203216
}
204217

205218
Modprobe m(mod_dirs);
206-
m.EnableVerbose(verbose);
207219
if (blocklist) {
208220
m.EnableBlocklist(true);
209221
}
@@ -212,19 +224,19 @@ extern "C" int modprobe_main(int argc, char** argv) {
212224
switch (mode) {
213225
case AddModulesMode:
214226
if (!m.LoadWithAliases(module, true, module_parameters)) {
215-
std::cerr << "Failed to load module " << module << std::endl;
227+
PLOG(ERROR) << "Failed to load module " << module;
216228
rv = EXIT_FAILURE;
217229
}
218230
break;
219231
case RemoveModulesMode:
220232
if (!m.Remove(module)) {
221-
std::cerr << "Failed to remove module " << module << std::endl;
233+
PLOG(ERROR) << "Failed to remove module " << module;
222234
rv = EXIT_FAILURE;
223235
}
224236
break;
225237
case ListModulesMode: {
226238
std::vector<std::string> list = m.ListModules(module);
227-
std::cout << android::base::Join(list, "\n") << std::endl;
239+
LOG(INFO) << android::base::Join(list, "\n");
228240
break;
229241
}
230242
case ShowDependenciesMode: {
@@ -235,17 +247,17 @@ extern "C" int modprobe_main(int argc, char** argv) {
235247
rv = EXIT_FAILURE;
236248
break;
237249
}
238-
std::cout << "Dependencies for " << module << ":" << std::endl;
239-
std::cout << "Soft pre-dependencies:" << std::endl;
240-
std::cout << android::base::Join(pre_deps, "\n") << std::endl;
241-
std::cout << "Hard dependencies:" << std::endl;
242-
std::cout << android::base::Join(deps, "\n") << std::endl;
243-
std::cout << "Soft post-dependencies:" << std::endl;
244-
std::cout << android::base::Join(post_deps, "\n") << std::endl;
250+
LOG(INFO) << "Dependencies for " << module << ":";
251+
LOG(INFO) << "Soft pre-dependencies:";
252+
LOG(INFO) << android::base::Join(pre_deps, "\n");
253+
LOG(INFO) << "Hard dependencies:";
254+
LOG(INFO) << android::base::Join(deps, "\n");
255+
LOG(INFO) << "Soft post-dependencies:";
256+
LOG(INFO) << android::base::Join(post_deps, "\n");
245257
break;
246258
}
247259
default:
248-
std::cerr << "Bad mode" << std::endl;
260+
LOG(ERROR) << "Bad mode";
249261
rv = EXIT_FAILURE;
250262
}
251263
}

0 commit comments

Comments
 (0)