host_init_verifier: use libhidlmetadata

Since it's available in C++, it's easier to build host_init_verifier
with this than create a new way to export the json file.

Bug: 141567104
Test: manually change hidl interface in a manifest
host_init_verifier: system/core/rootdir/init.rc: 69:
host_init_verifier: Interface is not in the known set of hidl_interfaces: 'android.hardwar.edne@1.0::IFoo'. Please ensure the interface is spelled correctly and built by a hidl_interface target.
Change-Id: Ic73dcb51855cb751734bc497d8e69f379966c511
This commit is contained in:
Steven Moreland 2019-10-15 14:53:19 -07:00
parent f5bad500f3
commit 422a758568
4 changed files with 27 additions and 50 deletions

View file

@ -82,7 +82,6 @@ cc_defaults {
"libfscrypt",
"libgsi",
"libhidl-gen-utils",
"libjsoncpp",
"libkeyutils",
"liblog",
"liblogwrap",
@ -286,13 +285,11 @@ cc_binary {
shared_libs: [
"libcutils",
"libhidl-gen-utils",
"libhidlmetadata",
"liblog",
"libprocessgroup",
"libprotobuf-cpp-lite",
],
header_libs: [
"libjsoncpp_headers",
],
srcs: [
"action.cpp",
"action_manager.cpp",

View file

@ -30,6 +30,7 @@
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <hidl/metadata.h>
#include "action.h"
#include "action_manager.h"
@ -142,28 +143,46 @@ static Result<void> check_stub(const BuiltinArguments& args) {
#include "generated_stub_builtin_function_map.h"
void PrintUsage() {
std::cout << "usage: host_init_verifier [-p FILE] -i FILE <init rc file>\n"
std::cout << "usage: host_init_verifier [-p FILE] <init rc file>\n"
"\n"
"Tests an init script for correctness\n"
"\n"
"-p FILE\tSearch this passwd file for users and groups\n"
"-i FILE\tParse this JSON file for the HIDL interface inheritance hierarchy\n"
<< std::endl;
}
Result<InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy() {
InterfaceInheritanceHierarchyMap result;
for (const HidlInterfaceMetadata& iface : HidlInterfaceMetadata::all()) {
std::set<FQName> inherited_interfaces;
for (const std::string& intf : iface.inherited) {
FQName fqname;
if (!fqname.setTo(intf)) {
return Error() << "Unable to parse interface '" << intf << "'";
}
inherited_interfaces.insert(fqname);
}
FQName fqname;
if (!fqname.setTo(iface.name)) {
return Error() << "Unable to parse interface '" << iface.name << "'";
}
result[fqname] = inherited_interfaces;
}
return result;
}
int main(int argc, char** argv) {
android::base::InitLogging(argv, &android::base::StdioLogger);
android::base::SetMinimumLogSeverity(android::base::ERROR);
std::string interface_inheritance_hierarchy_file;
while (true) {
static const struct option long_options[] = {
{"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0},
};
int arg = getopt_long(argc, argv, "p:i:", long_options, nullptr);
int arg = getopt_long(argc, argv, "p:", long_options, nullptr);
if (arg == -1) {
break;
@ -176,9 +195,6 @@ int main(int argc, char** argv) {
case 'p':
passwd_files.emplace_back(optarg);
break;
case 'i':
interface_inheritance_hierarchy_file = optarg;
break;
default:
std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl;
return EXIT_FAILURE;
@ -188,13 +204,12 @@ int main(int argc, char** argv) {
argc -= optind;
argv += optind;
if (argc != 1 || interface_inheritance_hierarchy_file.empty()) {
if (argc != 1) {
PrintUsage();
return EXIT_FAILURE;
}
auto interface_inheritance_hierarchy_map =
ReadInterfaceInheritanceHierarchy(interface_inheritance_hierarchy_file);
auto interface_inheritance_hierarchy_map = ReadInterfaceInheritanceHierarchy();
if (!interface_inheritance_hierarchy_map) {
LOG(ERROR) << interface_inheritance_hierarchy_map.error();
return EXIT_FAILURE;

View file

@ -21,7 +21,6 @@
#include <android-base/strings.h>
#include <hidl-util/FqInstance.h>
#include <json/json.h>
using android::FqInstance;
using android::FQName;
@ -42,37 +41,6 @@ std::string FQNamesToString(const std::set<FQName>& fqnames) {
} // namespace
Result<InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy(
const std::string& path) {
Json::Value root;
Json::Reader reader;
std::ifstream stream(path);
if (!reader.parse(stream, root)) {
return Error() << "Failed to read interface inheritance hierarchy file: " << path << "\n"
<< reader.getFormattedErrorMessages();
}
InterfaceInheritanceHierarchyMap result;
for (const Json::Value& entry : root) {
std::set<FQName> inherited_interfaces;
for (const Json::Value& intf : entry["inheritedInterfaces"]) {
FQName fqname;
if (!fqname.setTo(intf.asString())) {
return Error() << "Unable to parse interface '" << intf.asString() << "'";
}
inherited_interfaces.insert(fqname);
}
std::string intf_string = entry["interface"].asString();
FQName fqname;
if (!fqname.setTo(intf_string)) {
return Error() << "Unable to parse interface '" << intf_string << "'";
}
result[fqname] = inherited_interfaces;
}
return result;
}
Result<void> CheckInterfaceInheritanceHierarchy(const std::set<std::string>& instances,
const InterfaceInheritanceHierarchyMap& hierarchy) {
std::set<FQName> interface_fqnames;

View file

@ -29,9 +29,6 @@ namespace init {
using InterfaceInheritanceHierarchyMap = std::map<android::FQName, std::set<android::FQName>>;
// Reads the HIDL interface inheritance hierarchy JSON file at the given path.
Result<InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy(const std::string& path);
// For the given set of interfaces / interface instances, checks that each
// interface's hierarchy of inherited interfaces is also included in the given
// interface set. Uses the provided hierarchy data.