1*00c7fec1SAndroid Build Coastguard Worker /*
2*00c7fec1SAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*00c7fec1SAndroid Build Coastguard Worker *
4*00c7fec1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*00c7fec1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*00c7fec1SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*00c7fec1SAndroid Build Coastguard Worker *
8*00c7fec1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*00c7fec1SAndroid Build Coastguard Worker *
10*00c7fec1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*00c7fec1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*00c7fec1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*00c7fec1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*00c7fec1SAndroid Build Coastguard Worker * limitations under the License.
15*00c7fec1SAndroid Build Coastguard Worker */
16*00c7fec1SAndroid Build Coastguard Worker
17*00c7fec1SAndroid Build Coastguard Worker #include <ctype.h>
18*00c7fec1SAndroid Build Coastguard Worker #include <getopt.h>
19*00c7fec1SAndroid Build Coastguard Worker #include <stdlib.h>
20*00c7fec1SAndroid Build Coastguard Worker #include <unistd.h>
21*00c7fec1SAndroid Build Coastguard Worker
22*00c7fec1SAndroid Build Coastguard Worker #include <string>
23*00c7fec1SAndroid Build Coastguard Worker
24*00c7fec1SAndroid Build Coastguard Worker #include <android-base/file.h>
25*00c7fec1SAndroid Build Coastguard Worker #include <android-base/logging.h>
26*00c7fec1SAndroid Build Coastguard Worker #include <android-base/strings.h>
27*00c7fec1SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
28*00c7fec1SAndroid Build Coastguard Worker #include <modprobe/modprobe.h>
29*00c7fec1SAndroid Build Coastguard Worker
30*00c7fec1SAndroid Build Coastguard Worker #include <sys/utsname.h>
31*00c7fec1SAndroid Build Coastguard Worker
32*00c7fec1SAndroid Build Coastguard Worker namespace {
33*00c7fec1SAndroid Build Coastguard Worker
34*00c7fec1SAndroid Build Coastguard Worker enum modprobe_mode {
35*00c7fec1SAndroid Build Coastguard Worker AddModulesMode,
36*00c7fec1SAndroid Build Coastguard Worker RemoveModulesMode,
37*00c7fec1SAndroid Build Coastguard Worker ListModulesMode,
38*00c7fec1SAndroid Build Coastguard Worker ShowDependenciesMode,
39*00c7fec1SAndroid Build Coastguard Worker };
40*00c7fec1SAndroid Build Coastguard Worker
print_usage(void)41*00c7fec1SAndroid Build Coastguard Worker void print_usage(void) {
42*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << "Usage:";
43*00c7fec1SAndroid Build Coastguard Worker LOG(INFO);
44*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " modprobe [options] [-d DIR] [--all=FILE|MODULE]...";
45*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " modprobe [options] [-d DIR] MODULE [symbol=value]...";
46*00c7fec1SAndroid Build Coastguard Worker LOG(INFO);
47*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << "Options:";
48*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " --all=FILE: FILE to acquire module names from";
49*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -b, --use-blocklist: Apply blocklist to module names too";
50*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -d, --dirname=DIR: Load modules from DIR, option may be used multiple times";
51*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -D, --show-depends: Print dependencies for modules only, do not load";
52*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -h, --help: Print this help";
53*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -l, --list: List modules matching pattern";
54*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -r, --remove: Remove MODULE (multiple modules may be specified)";
55*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -s, --syslog: print to syslog also";
56*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -q, --quiet: disable messages";
57*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << " -v, --verbose: enable more messages, even more with a second -v";
58*00c7fec1SAndroid Build Coastguard Worker LOG(INFO);
59*00c7fec1SAndroid Build Coastguard Worker }
60*00c7fec1SAndroid Build Coastguard Worker
61*00c7fec1SAndroid Build Coastguard Worker #define check_mode() \
62*00c7fec1SAndroid Build Coastguard Worker if (mode != AddModulesMode) { \
63*00c7fec1SAndroid Build Coastguard Worker LOG(ERROR) << "multiple mode flags specified"; \
64*00c7fec1SAndroid Build Coastguard Worker print_usage(); \
65*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE; \
66*00c7fec1SAndroid Build Coastguard Worker }
67*00c7fec1SAndroid Build Coastguard Worker
stripComments(const std::string & str)68*00c7fec1SAndroid Build Coastguard Worker std::string stripComments(const std::string& str) {
69*00c7fec1SAndroid Build Coastguard Worker for (std::string rv = str;;) {
70*00c7fec1SAndroid Build Coastguard Worker auto comment = rv.find('#');
71*00c7fec1SAndroid Build Coastguard Worker if (comment == std::string::npos) return rv;
72*00c7fec1SAndroid Build Coastguard Worker auto end = rv.find('\n', comment);
73*00c7fec1SAndroid Build Coastguard Worker if (end != std::string::npos) end = end - comment;
74*00c7fec1SAndroid Build Coastguard Worker rv.erase(comment, end);
75*00c7fec1SAndroid Build Coastguard Worker }
76*00c7fec1SAndroid Build Coastguard Worker /* NOTREACHED */
77*00c7fec1SAndroid Build Coastguard Worker }
78*00c7fec1SAndroid Build Coastguard Worker
79*00c7fec1SAndroid Build Coastguard Worker auto syslog = false;
80*00c7fec1SAndroid Build Coastguard Worker
MyLogger(android::base::LogId id,android::base::LogSeverity severity,const char * tag,const char * file,unsigned int line,const char * message)81*00c7fec1SAndroid Build Coastguard Worker void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
82*00c7fec1SAndroid Build Coastguard Worker const char* file, unsigned int line, const char* message) {
83*00c7fec1SAndroid Build Coastguard Worker android::base::StdioLogger(id, severity, tag, file, line, message);
84*00c7fec1SAndroid Build Coastguard Worker if (syslog && message[0]) {
85*00c7fec1SAndroid Build Coastguard Worker android::base::KernelLogger(id, severity, tag, file, line, message);
86*00c7fec1SAndroid Build Coastguard Worker }
87*00c7fec1SAndroid Build Coastguard Worker }
88*00c7fec1SAndroid Build Coastguard Worker
ModDirMatchesKernelPageSize(const char * mod_dir)89*00c7fec1SAndroid Build Coastguard Worker static bool ModDirMatchesKernelPageSize(const char* mod_dir) {
90*00c7fec1SAndroid Build Coastguard Worker static const unsigned int kernel_pgsize_kb = getpagesize() / 1024;
91*00c7fec1SAndroid Build Coastguard Worker const char* mod_sfx = strrchr(mod_dir, '_');
92*00c7fec1SAndroid Build Coastguard Worker unsigned int mod_pgsize_kb;
93*00c7fec1SAndroid Build Coastguard Worker int mod_sfx_len;
94*00c7fec1SAndroid Build Coastguard Worker
95*00c7fec1SAndroid Build Coastguard Worker if (mod_sfx == NULL || sscanf(mod_sfx, "_%uk%n", &mod_pgsize_kb, &mod_sfx_len) != 1 ||
96*00c7fec1SAndroid Build Coastguard Worker strlen(mod_sfx) != mod_sfx_len) {
97*00c7fec1SAndroid Build Coastguard Worker mod_pgsize_kb = 4;
98*00c7fec1SAndroid Build Coastguard Worker }
99*00c7fec1SAndroid Build Coastguard Worker
100*00c7fec1SAndroid Build Coastguard Worker return kernel_pgsize_kb == mod_pgsize_kb;
101*00c7fec1SAndroid Build Coastguard Worker }
102*00c7fec1SAndroid Build Coastguard Worker
103*00c7fec1SAndroid Build Coastguard Worker // Find directories in format of "/lib/modules/x.y.z-*".
KernelVersionNameFilter(const dirent * de)104*00c7fec1SAndroid Build Coastguard Worker static int KernelVersionNameFilter(const dirent* de) {
105*00c7fec1SAndroid Build Coastguard Worker unsigned int major, minor;
106*00c7fec1SAndroid Build Coastguard Worker static std::string kernel_version;
107*00c7fec1SAndroid Build Coastguard Worker utsname uts;
108*00c7fec1SAndroid Build Coastguard Worker
109*00c7fec1SAndroid Build Coastguard Worker if (kernel_version.empty()) {
110*00c7fec1SAndroid Build Coastguard Worker if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) {
111*00c7fec1SAndroid Build Coastguard Worker LOG(ERROR) << "Could not parse the kernel version from uname";
112*00c7fec1SAndroid Build Coastguard Worker return 0;
113*00c7fec1SAndroid Build Coastguard Worker }
114*00c7fec1SAndroid Build Coastguard Worker kernel_version = android::base::StringPrintf("%u.%u", major, minor);
115*00c7fec1SAndroid Build Coastguard Worker }
116*00c7fec1SAndroid Build Coastguard Worker
117*00c7fec1SAndroid Build Coastguard Worker if (android::base::StartsWith(de->d_name, kernel_version)) {
118*00c7fec1SAndroid Build Coastguard Worker return ModDirMatchesKernelPageSize(de->d_name);
119*00c7fec1SAndroid Build Coastguard Worker }
120*00c7fec1SAndroid Build Coastguard Worker return 0;
121*00c7fec1SAndroid Build Coastguard Worker }
122*00c7fec1SAndroid Build Coastguard Worker
123*00c7fec1SAndroid Build Coastguard Worker } // anonymous namespace
124*00c7fec1SAndroid Build Coastguard Worker
modprobe_main(int argc,char ** argv)125*00c7fec1SAndroid Build Coastguard Worker extern "C" int modprobe_main(int argc, char** argv) {
126*00c7fec1SAndroid Build Coastguard Worker android::base::InitLogging(argv, MyLogger);
127*00c7fec1SAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::INFO);
128*00c7fec1SAndroid Build Coastguard Worker
129*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> modules;
130*00c7fec1SAndroid Build Coastguard Worker std::string modules_load_file;
131*00c7fec1SAndroid Build Coastguard Worker std::string module_parameters;
132*00c7fec1SAndroid Build Coastguard Worker std::string mods;
133*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> mod_dirs;
134*00c7fec1SAndroid Build Coastguard Worker modprobe_mode mode = AddModulesMode;
135*00c7fec1SAndroid Build Coastguard Worker bool blocklist = false;
136*00c7fec1SAndroid Build Coastguard Worker int rv = EXIT_SUCCESS;
137*00c7fec1SAndroid Build Coastguard Worker
138*00c7fec1SAndroid Build Coastguard Worker int opt, fd;
139*00c7fec1SAndroid Build Coastguard Worker int option_index = 0;
140*00c7fec1SAndroid Build Coastguard Worker // NB: We have non-standard short options -l and -D to make it easier for
141*00c7fec1SAndroid Build Coastguard Worker // OEMs to transition from toybox.
142*00c7fec1SAndroid Build Coastguard Worker // clang-format off
143*00c7fec1SAndroid Build Coastguard Worker static struct option long_options[] = {
144*00c7fec1SAndroid Build Coastguard Worker { "all", optional_argument, 0, 'a' },
145*00c7fec1SAndroid Build Coastguard Worker { "use-blocklist", no_argument, 0, 'b' },
146*00c7fec1SAndroid Build Coastguard Worker { "dirname", required_argument, 0, 'd' },
147*00c7fec1SAndroid Build Coastguard Worker { "show-depends", no_argument, 0, 'D' },
148*00c7fec1SAndroid Build Coastguard Worker { "help", no_argument, 0, 'h' },
149*00c7fec1SAndroid Build Coastguard Worker { "list", no_argument, 0, 'l' },
150*00c7fec1SAndroid Build Coastguard Worker { "quiet", no_argument, 0, 'q' },
151*00c7fec1SAndroid Build Coastguard Worker { "remove", no_argument, 0, 'r' },
152*00c7fec1SAndroid Build Coastguard Worker { "syslog", no_argument, 0, 's' },
153*00c7fec1SAndroid Build Coastguard Worker { "verbose", no_argument, 0, 'v' },
154*00c7fec1SAndroid Build Coastguard Worker };
155*00c7fec1SAndroid Build Coastguard Worker // clang-format on
156*00c7fec1SAndroid Build Coastguard Worker while ((opt = getopt_long(argc, argv, "a::bd:Dhlqrsv", long_options, &option_index)) != -1) {
157*00c7fec1SAndroid Build Coastguard Worker switch (opt) {
158*00c7fec1SAndroid Build Coastguard Worker case 'a':
159*00c7fec1SAndroid Build Coastguard Worker // toybox modprobe supported -a to load multiple modules, this
160*00c7fec1SAndroid Build Coastguard Worker // is supported here by default, ignore flag if no argument.
161*00c7fec1SAndroid Build Coastguard Worker check_mode();
162*00c7fec1SAndroid Build Coastguard Worker if (optarg == NULL) break;
163*00c7fec1SAndroid Build Coastguard Worker
164*00c7fec1SAndroid Build Coastguard Worker // Since libmodprobe doesn't fail when the modules load file
165*00c7fec1SAndroid Build Coastguard Worker // doesn't exist, let's check that here so that we don't
166*00c7fec1SAndroid Build Coastguard Worker // silently fail.
167*00c7fec1SAndroid Build Coastguard Worker fd = open(optarg, O_RDONLY | O_CLOEXEC | O_BINARY);
168*00c7fec1SAndroid Build Coastguard Worker if (fd == -1) {
169*00c7fec1SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to open " << optarg;
170*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE;
171*00c7fec1SAndroid Build Coastguard Worker }
172*00c7fec1SAndroid Build Coastguard Worker close(fd);
173*00c7fec1SAndroid Build Coastguard Worker
174*00c7fec1SAndroid Build Coastguard Worker mod_dirs.emplace_back(android::base::Dirname(optarg));
175*00c7fec1SAndroid Build Coastguard Worker modules_load_file = android::base::Basename(optarg);
176*00c7fec1SAndroid Build Coastguard Worker break;
177*00c7fec1SAndroid Build Coastguard Worker case 'b':
178*00c7fec1SAndroid Build Coastguard Worker blocklist = true;
179*00c7fec1SAndroid Build Coastguard Worker break;
180*00c7fec1SAndroid Build Coastguard Worker case 'd':
181*00c7fec1SAndroid Build Coastguard Worker mod_dirs.emplace_back(optarg);
182*00c7fec1SAndroid Build Coastguard Worker break;
183*00c7fec1SAndroid Build Coastguard Worker case 'D':
184*00c7fec1SAndroid Build Coastguard Worker check_mode();
185*00c7fec1SAndroid Build Coastguard Worker mode = ShowDependenciesMode;
186*00c7fec1SAndroid Build Coastguard Worker break;
187*00c7fec1SAndroid Build Coastguard Worker case 'h':
188*00c7fec1SAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::INFO);
189*00c7fec1SAndroid Build Coastguard Worker print_usage();
190*00c7fec1SAndroid Build Coastguard Worker return rv;
191*00c7fec1SAndroid Build Coastguard Worker case 'l':
192*00c7fec1SAndroid Build Coastguard Worker check_mode();
193*00c7fec1SAndroid Build Coastguard Worker mode = ListModulesMode;
194*00c7fec1SAndroid Build Coastguard Worker break;
195*00c7fec1SAndroid Build Coastguard Worker case 'q':
196*00c7fec1SAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::WARNING);
197*00c7fec1SAndroid Build Coastguard Worker break;
198*00c7fec1SAndroid Build Coastguard Worker case 'r':
199*00c7fec1SAndroid Build Coastguard Worker check_mode();
200*00c7fec1SAndroid Build Coastguard Worker mode = RemoveModulesMode;
201*00c7fec1SAndroid Build Coastguard Worker break;
202*00c7fec1SAndroid Build Coastguard Worker case 's':
203*00c7fec1SAndroid Build Coastguard Worker syslog = true;
204*00c7fec1SAndroid Build Coastguard Worker break;
205*00c7fec1SAndroid Build Coastguard Worker case 'v':
206*00c7fec1SAndroid Build Coastguard Worker if (android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
207*00c7fec1SAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::VERBOSE);
208*00c7fec1SAndroid Build Coastguard Worker } else {
209*00c7fec1SAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::DEBUG);
210*00c7fec1SAndroid Build Coastguard Worker }
211*00c7fec1SAndroid Build Coastguard Worker break;
212*00c7fec1SAndroid Build Coastguard Worker default:
213*00c7fec1SAndroid Build Coastguard Worker LOG(ERROR) << "Unrecognized option: " << opt;
214*00c7fec1SAndroid Build Coastguard Worker print_usage();
215*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE;
216*00c7fec1SAndroid Build Coastguard Worker }
217*00c7fec1SAndroid Build Coastguard Worker }
218*00c7fec1SAndroid Build Coastguard Worker
219*00c7fec1SAndroid Build Coastguard Worker int parameter_count = 0;
220*00c7fec1SAndroid Build Coastguard Worker for (opt = optind; opt < argc; opt++) {
221*00c7fec1SAndroid Build Coastguard Worker if (!strchr(argv[opt], '=')) {
222*00c7fec1SAndroid Build Coastguard Worker modules.emplace_back(argv[opt]);
223*00c7fec1SAndroid Build Coastguard Worker } else {
224*00c7fec1SAndroid Build Coastguard Worker parameter_count++;
225*00c7fec1SAndroid Build Coastguard Worker if (module_parameters.empty()) {
226*00c7fec1SAndroid Build Coastguard Worker module_parameters = argv[opt];
227*00c7fec1SAndroid Build Coastguard Worker } else {
228*00c7fec1SAndroid Build Coastguard Worker module_parameters = module_parameters + " " + argv[opt];
229*00c7fec1SAndroid Build Coastguard Worker }
230*00c7fec1SAndroid Build Coastguard Worker }
231*00c7fec1SAndroid Build Coastguard Worker }
232*00c7fec1SAndroid Build Coastguard Worker
233*00c7fec1SAndroid Build Coastguard Worker if (mod_dirs.empty()) {
234*00c7fec1SAndroid Build Coastguard Worker static constexpr auto LIB_MODULES_PREFIX = "/lib/modules/";
235*00c7fec1SAndroid Build Coastguard Worker dirent** kernel_dirs = NULL;
236*00c7fec1SAndroid Build Coastguard Worker
237*00c7fec1SAndroid Build Coastguard Worker int n = scandir(LIB_MODULES_PREFIX, &kernel_dirs, KernelVersionNameFilter, NULL);
238*00c7fec1SAndroid Build Coastguard Worker if (n == -1) {
239*00c7fec1SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to scan dir " << LIB_MODULES_PREFIX;
240*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE;
241*00c7fec1SAndroid Build Coastguard Worker } else if (n > 0) {
242*00c7fec1SAndroid Build Coastguard Worker while (n--) {
243*00c7fec1SAndroid Build Coastguard Worker mod_dirs.emplace_back(LIB_MODULES_PREFIX + std::string(kernel_dirs[n]->d_name));
244*00c7fec1SAndroid Build Coastguard Worker }
245*00c7fec1SAndroid Build Coastguard Worker }
246*00c7fec1SAndroid Build Coastguard Worker free(kernel_dirs);
247*00c7fec1SAndroid Build Coastguard Worker
248*00c7fec1SAndroid Build Coastguard Worker if (mod_dirs.empty() || getpagesize() == 4096) {
249*00c7fec1SAndroid Build Coastguard Worker // Allow modules to be directly inside /lib/modules
250*00c7fec1SAndroid Build Coastguard Worker mod_dirs.emplace_back(LIB_MODULES_PREFIX);
251*00c7fec1SAndroid Build Coastguard Worker }
252*00c7fec1SAndroid Build Coastguard Worker }
253*00c7fec1SAndroid Build Coastguard Worker
254*00c7fec1SAndroid Build Coastguard Worker LOG(DEBUG) << "mode is " << mode;
255*00c7fec1SAndroid Build Coastguard Worker LOG(DEBUG) << "mod_dirs is: " << android::base::Join(mod_dirs, " ");
256*00c7fec1SAndroid Build Coastguard Worker LOG(DEBUG) << "modules is: " << android::base::Join(modules, " ");
257*00c7fec1SAndroid Build Coastguard Worker LOG(DEBUG) << "modules load file is: " << modules_load_file;
258*00c7fec1SAndroid Build Coastguard Worker LOG(DEBUG) << "module parameters is: " << android::base::Join(module_parameters, " ");
259*00c7fec1SAndroid Build Coastguard Worker
260*00c7fec1SAndroid Build Coastguard Worker if (modules.empty()) {
261*00c7fec1SAndroid Build Coastguard Worker if (mode == ListModulesMode) {
262*00c7fec1SAndroid Build Coastguard Worker // emulate toybox modprobe list with no pattern (list all)
263*00c7fec1SAndroid Build Coastguard Worker modules.emplace_back("*");
264*00c7fec1SAndroid Build Coastguard Worker } else if (modules_load_file.empty()) {
265*00c7fec1SAndroid Build Coastguard Worker LOG(ERROR) << "No modules given.";
266*00c7fec1SAndroid Build Coastguard Worker print_usage();
267*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE;
268*00c7fec1SAndroid Build Coastguard Worker }
269*00c7fec1SAndroid Build Coastguard Worker }
270*00c7fec1SAndroid Build Coastguard Worker if (parameter_count && (modules.size() > 1 || !modules_load_file.empty())) {
271*00c7fec1SAndroid Build Coastguard Worker LOG(ERROR) << "Only one module may be loaded when specifying module parameters.";
272*00c7fec1SAndroid Build Coastguard Worker print_usage();
273*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE;
274*00c7fec1SAndroid Build Coastguard Worker }
275*00c7fec1SAndroid Build Coastguard Worker
276*00c7fec1SAndroid Build Coastguard Worker Modprobe m(mod_dirs, modules_load_file.empty() ? "modules.load" : modules_load_file, blocklist);
277*00c7fec1SAndroid Build Coastguard Worker if (mode == AddModulesMode && !modules_load_file.empty()) {
278*00c7fec1SAndroid Build Coastguard Worker if (!m.LoadListedModules(false)) {
279*00c7fec1SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to load all the modules from " << modules_load_file;
280*00c7fec1SAndroid Build Coastguard Worker return EXIT_FAILURE;
281*00c7fec1SAndroid Build Coastguard Worker }
282*00c7fec1SAndroid Build Coastguard Worker /* Fall-through to load modules provided on the command line (if any)*/
283*00c7fec1SAndroid Build Coastguard Worker }
284*00c7fec1SAndroid Build Coastguard Worker
285*00c7fec1SAndroid Build Coastguard Worker for (const auto& module : modules) {
286*00c7fec1SAndroid Build Coastguard Worker switch (mode) {
287*00c7fec1SAndroid Build Coastguard Worker case AddModulesMode:
288*00c7fec1SAndroid Build Coastguard Worker if (!m.LoadWithAliases(module, true, module_parameters)) {
289*00c7fec1SAndroid Build Coastguard Worker if (m.IsBlocklisted(module)) continue;
290*00c7fec1SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to load module " << module;
291*00c7fec1SAndroid Build Coastguard Worker rv = EXIT_FAILURE;
292*00c7fec1SAndroid Build Coastguard Worker }
293*00c7fec1SAndroid Build Coastguard Worker break;
294*00c7fec1SAndroid Build Coastguard Worker case RemoveModulesMode:
295*00c7fec1SAndroid Build Coastguard Worker if (!m.Remove(module)) {
296*00c7fec1SAndroid Build Coastguard Worker PLOG(ERROR) << "Failed to remove module " << module;
297*00c7fec1SAndroid Build Coastguard Worker rv = EXIT_FAILURE;
298*00c7fec1SAndroid Build Coastguard Worker }
299*00c7fec1SAndroid Build Coastguard Worker break;
300*00c7fec1SAndroid Build Coastguard Worker case ListModulesMode: {
301*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> list = m.ListModules(module);
302*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << android::base::Join(list, "\n");
303*00c7fec1SAndroid Build Coastguard Worker break;
304*00c7fec1SAndroid Build Coastguard Worker }
305*00c7fec1SAndroid Build Coastguard Worker case ShowDependenciesMode: {
306*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> pre_deps;
307*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> deps;
308*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> post_deps;
309*00c7fec1SAndroid Build Coastguard Worker if (!m.GetAllDependencies(module, &pre_deps, &deps, &post_deps)) {
310*00c7fec1SAndroid Build Coastguard Worker rv = EXIT_FAILURE;
311*00c7fec1SAndroid Build Coastguard Worker break;
312*00c7fec1SAndroid Build Coastguard Worker }
313*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << "Dependencies for " << module << ":";
314*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << "Soft pre-dependencies:";
315*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << android::base::Join(pre_deps, "\n");
316*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << "Hard dependencies:";
317*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << android::base::Join(deps, "\n");
318*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << "Soft post-dependencies:";
319*00c7fec1SAndroid Build Coastguard Worker LOG(INFO) << android::base::Join(post_deps, "\n");
320*00c7fec1SAndroid Build Coastguard Worker break;
321*00c7fec1SAndroid Build Coastguard Worker }
322*00c7fec1SAndroid Build Coastguard Worker default:
323*00c7fec1SAndroid Build Coastguard Worker LOG(ERROR) << "Bad mode";
324*00c7fec1SAndroid Build Coastguard Worker rv = EXIT_FAILURE;
325*00c7fec1SAndroid Build Coastguard Worker }
326*00c7fec1SAndroid Build Coastguard Worker }
327*00c7fec1SAndroid Build Coastguard Worker
328*00c7fec1SAndroid Build Coastguard Worker return rv;
329*00c7fec1SAndroid Build Coastguard Worker }
330