init parses *.rc files from APEXes
Init now parses *.rc files from the APEXs when the apexd notifies the mount event via apexd.status sysprop. Bug: 117403679 Test: m apex.test; adb root; adb push <builtfile> /data/apex; adb reboot adb root; adb shell setprop ctl.start apex.test; dmesg shows that init tries to start the service which doesn't exist. [ 47.979657] init: Could not ctl.start for 'apex.test': Cannot find '/apex/com.android.example.apex/bin/test': No such file or directory Change-Id: I3f12355346eeb212eca4de85b6b73257283fa054
This commit is contained in:
parent
9e04f62895
commit
c240440eec
6 changed files with 51 additions and 1 deletions
|
@ -275,6 +275,10 @@ runs the service.
|
|||
since it has some peculiarities for backwards compatibility reasons. The 'imports' section of
|
||||
this file has more details on the order.
|
||||
|
||||
`parse_apex_configs`
|
||||
Parses config file(s) from the mounted APEXes. Intented to be used only once
|
||||
when apexd notifies the mount event by setting apexd.status to ready.
|
||||
|
||||
`priority <priority>`
|
||||
> Scheduling priority of the service process. This value has to be in range
|
||||
-20 to 19. Default priority is 0. Priority is set via setpriority().
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fts.h>
|
||||
#include <glob.h>
|
||||
#include <linux/loop.h>
|
||||
#include <linux/module.h>
|
||||
#include <mntent.h>
|
||||
|
@ -1053,6 +1054,38 @@ static Result<Success> do_init_user0(const BuiltinArguments& args) {
|
|||
{{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
|
||||
}
|
||||
|
||||
static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) {
|
||||
glob_t glob_result;
|
||||
// @ is added to filter out the later paths, which are bind mounts of the places
|
||||
// where the APEXes are really mounted at. Otherwise, we will parse the
|
||||
// same file twice.
|
||||
static constexpr char glob_pattern[] = "/apex/*@*/etc/*.rc";
|
||||
if (glob(glob_pattern, GLOB_MARK, nullptr, &glob_result) != 0) {
|
||||
globfree(&glob_result);
|
||||
return Error() << "glob pattern '" << glob_pattern << "' failed";
|
||||
}
|
||||
std::vector<std::string> configs;
|
||||
Parser parser = CreateServiceOnlyParser(ServiceList::GetInstance());
|
||||
for (size_t i = 0; i < glob_result.gl_pathc; i++) {
|
||||
configs.emplace_back(glob_result.gl_pathv[i]);
|
||||
}
|
||||
globfree(&glob_result);
|
||||
|
||||
bool success = true;
|
||||
for (const auto& c : configs) {
|
||||
if (c.back() == '/') {
|
||||
// skip if directory
|
||||
continue;
|
||||
}
|
||||
success &= parser.ParseConfigFile(c);
|
||||
}
|
||||
if (success) {
|
||||
return Success();
|
||||
} else {
|
||||
return Error() << "Could not parse apex configs";
|
||||
}
|
||||
}
|
||||
|
||||
// Builtin-function-map start
|
||||
const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
||||
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
|
||||
|
@ -1090,6 +1123,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
|||
// mount and umount are run in the same context as mount_all for symmetry.
|
||||
{"mount_all", {1, kMax, {false, do_mount_all}}},
|
||||
{"mount", {3, kMax, {false, do_mount}}},
|
||||
{"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}},
|
||||
{"umount", {1, 1, {false, do_umount}}},
|
||||
{"readahead", {1, 2, {true, do_readahead}}},
|
||||
{"restart", {1, 1, {false, do_restart}}},
|
||||
|
|
|
@ -132,6 +132,14 @@ Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
|
|||
return parser;
|
||||
}
|
||||
|
||||
// parser that only accepts new services
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list) {
|
||||
Parser parser;
|
||||
|
||||
parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, subcontexts));
|
||||
return parser;
|
||||
}
|
||||
|
||||
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
|
||||
Parser parser = CreateParser(action_manager, service_list);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ extern std::string default_console;
|
|||
extern std::vector<std::string> late_import_paths;
|
||||
|
||||
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list);
|
||||
|
||||
void HandleControlMessage(const std::string& msg, const std::string& arg, pid_t pid);
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ class Parser {
|
|||
Parser();
|
||||
|
||||
bool ParseConfig(const std::string& path);
|
||||
bool ParseConfigFile(const std::string& path);
|
||||
void AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser);
|
||||
void AddSingleLineParser(const std::string& prefix, LineCallback callback);
|
||||
|
||||
|
@ -82,7 +83,6 @@ class Parser {
|
|||
|
||||
private:
|
||||
void ParseData(const std::string& filename, std::string* data);
|
||||
bool ParseConfigFile(const std::string& path);
|
||||
bool ParseConfigDir(const std::string& path);
|
||||
|
||||
std::map<std::string, std::unique_ptr<SectionParser>> section_parsers_;
|
||||
|
|
|
@ -801,3 +801,6 @@ on property:ro.debuggable=1
|
|||
service flash_recovery /system/bin/install-recovery.sh
|
||||
class main
|
||||
oneshot
|
||||
|
||||
on property:apexd.status=ready
|
||||
parse_apex_configs
|
||||
|
|
Loading…
Reference in a new issue