diff options
| author | Treehugger Robot <treehugger-gerrit@google.com> | 2019-06-19 00:30:27 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-06-19 00:30:27 +0000 |
| commit | 90eb2ed62d2ccaf25b325019c11050d53a390bb2 (patch) | |
| tree | 2796627390f272bf2025faffd63fe93da4c959d7 /libmodprobe/libmodprobe_ext.cpp | |
| parent | ad0f27fe729ccdeb077e266a65ce3f8c3da5e27e (diff) | |
| parent | 18b981ea7c5f0964941931a71fa55d880bec0c16 (diff) | |
Merge "create libmodprobe, integrate into first_stage_init"
Diffstat (limited to 'libmodprobe/libmodprobe_ext.cpp')
| -rw-r--r-- | libmodprobe/libmodprobe_ext.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/libmodprobe/libmodprobe_ext.cpp b/libmodprobe/libmodprobe_ext.cpp new file mode 100644 index 0000000000..5f3a04da8b --- /dev/null +++ b/libmodprobe/libmodprobe_ext.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/stat.h> +#include <sys/syscall.h> + +#include <android-base/logging.h> +#include <android-base/unique_fd.h> + +#include <modprobe/modprobe.h> + +bool Modprobe::Insmod(const std::string& path_name) { + android::base::unique_fd fd( + TEMP_FAILURE_RETRY(open(path_name.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC))); + if (fd == -1) { + LOG(ERROR) << "Could not open module '" << path_name << "'"; + return false; + } + + std::string options = ""; + auto options_iter = module_options_.find(MakeCanonical(path_name)); + if (options_iter != module_options_.end()) { + options = options_iter->second; + } + + LOG(INFO) << "Loading module " << path_name << " with args \"" << options << "\""; + int ret = syscall(__NR_finit_module, fd.get(), options.c_str(), 0); + if (ret != 0) { + if (errno == EEXIST) { + // Module already loaded + return true; + } + LOG(ERROR) << "Failed to insmod '" << path_name << "' with args '" << options << "'"; + return false; + } + + LOG(INFO) << "Loaded kernel module " << path_name; + return true; +} + +bool Modprobe::ModuleExists(const std::string& module_name) { + struct stat fileStat; + auto deps = GetDependencies(module_name); + if (deps.empty()) { + // missing deps can happen in the case of an alias + return false; + } + if (stat(deps.front().c_str(), &fileStat)) { + return false; + } + if (!S_ISREG(fileStat.st_mode)) { + return false; + } + return true; +} |
