Checks the interface inheritance hierarchy in init_rc files.
Bug: 118016875
Test: Added 'interface' lines to an init_rc file and observed errors
when misspelled or missing entire inheritance hierarchy.
Change-Id: I681420f15539742d8415808b2a0dcbf0bf6faaf1
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index ba35104..88ce364 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -18,6 +18,9 @@
#include <linux/input.h>
+#include <algorithm>
+#include <sstream>
+
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
@@ -152,12 +155,6 @@
return Error() << "Interface name must not be a value name '" << interface_name << "'";
}
- if (known_interfaces_ && known_interfaces_->count(interface_name) == 0) {
- return Error() << "Interface is not in the known set of hidl_interfaces: '"
- << interface_name << "'. Please ensure the interface is built "
- << "by a hidl_interface target.";
- }
-
const std::string fullname = interface_name + "/" + instance_name;
for (const auto& svc : *service_list_) {
@@ -540,6 +537,37 @@
return {};
}
+ if (interface_inheritance_hierarchy_) {
+ std::set<std::string> interface_names;
+ for (const std::string& intf : service_->interfaces()) {
+ interface_names.insert(Split(intf, "/")[0]);
+ }
+ std::ostringstream error_stream;
+ for (const std::string& intf : interface_names) {
+ if (interface_inheritance_hierarchy_->count(intf) == 0) {
+ error_stream << "\nInterface is not in the known set of hidl_interfaces: '" << intf
+ << "'. Please ensure the interface is spelled correctly and built "
+ << "by a hidl_interface target.";
+ continue;
+ }
+ const std::set<std::string>& required_interfaces =
+ (*interface_inheritance_hierarchy_)[intf];
+ std::set<std::string> diff;
+ std::set_difference(required_interfaces.begin(), required_interfaces.end(),
+ interface_names.begin(), interface_names.end(),
+ std::inserter(diff, diff.begin()));
+ if (!diff.empty()) {
+ error_stream << "\nInterface '" << intf << "' requires its full inheritance "
+ << "hierarchy to be listed in this init_rc file. Missing "
+ << "interfaces: [" << base::Join(diff, " ") << "]";
+ }
+ }
+ const std::string& errors = error_stream.str();
+ if (!errors.empty()) {
+ return Error() << errors;
+ }
+ }
+
Service* old_service = service_list_->FindService(service_->name());
if (old_service) {
if (!service_->is_override()) {