Loading init/README.md +7 −1 Original line number Diff line number Diff line Loading @@ -298,7 +298,8 @@ Commands > Fork and execute command with the given arguments. The command starts after "--" so that an optional security context, user, and supplementary groups can be provided. No other commands will be run until this one finishes. _seclabel_ can be a - to denote default. finishes. _seclabel_ can be a - to denote default. Properties are expanded within _argument_. `export <name> <value>` > Set the environment variable _name_ equal to _value_ in the Loading Loading @@ -412,6 +413,11 @@ Commands or the timeout has been reached. If timeout is not specified it currently defaults to five seconds. `wait_for_prop <name> <value>` > Wait for system property _name_ to be _value_. Properties are expanded within _value_. If property _name_ is already set to _value_, continue immediately. `write <path> <content>` > Open the file at _path_ and write a string to it with write(2). If the file does not exist, it will be created. If it does exist, Loading init/builtins.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -1003,6 +1003,29 @@ static int do_wait(const std::vector<std::string>& args) { return -1; } static int do_wait_for_prop(const std::vector<std::string>& args) { const char* name = args[1].c_str(); const char* value = args[2].c_str(); size_t value_len = strlen(value); if (!is_legal_property_name(name)) { LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value << "\") failed: bad name"; return -1; } if (value_len >= PROP_VALUE_MAX) { LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value << "\") failed: value too long"; return -1; } if (!wait_property(name, value)) { LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value << "\") failed: init already in waiting"; return -1; } return 0; } /* * Callback to make a directory from the ext4 code */ Loading Loading @@ -1074,6 +1097,7 @@ BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"verity_load_state", {0, 0, do_verity_load_state}}, {"verity_update_state", {0, 0, do_verity_update_state}}, {"wait", {1, 2, do_wait}}, {"wait_for_prop", {2, 2, do_wait_for_prop}}, {"write", {2, 2, do_write}}, }; return builtin_functions; Loading init/init.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -87,6 +87,10 @@ bool waiting_for_exec = false; static int epoll_fd = -1; static std::unique_ptr<Timer> waiting_for_prop(nullptr); static std::string wait_prop_name; static std::string wait_prop_value; void register_epoll_handler(int fd, void (*fn)()) { epoll_event ev; ev.events = EPOLLIN; Loading Loading @@ -128,10 +132,34 @@ int add_environment(const char *key, const char *val) return -1; } bool wait_property(const char *name, const char *value) { if (waiting_for_prop) { return false; } if (property_get(name) != value) { // Current property value is not equal to expected value wait_prop_name = name; wait_prop_value = value; waiting_for_prop.reset(new Timer()); } else { LOG(INFO) << "wait_property(\"" << name << "\", \"" << value << "\"): already set"; } return true; } void property_changed(const char *name, const char *value) { if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyTrigger(name, value); if (waiting_for_prop) { if (wait_prop_name == name && wait_prop_value == value) { wait_prop_name.clear(); wait_prop_value.clear(); LOG(INFO) << "Wait for property took " << *waiting_for_prop; waiting_for_prop.reset(); } } } static void restart_processes() Loading Loading @@ -876,7 +904,7 @@ int main(int argc, char** argv) { am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers"); while (true) { if (!waiting_for_exec) { if (!(waiting_for_exec || waiting_for_prop)) { am.ExecuteOneCommand(); restart_processes(); } Loading init/init.h +2 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,6 @@ void register_epoll_handler(int fd, void (*fn)()); int add_environment(const char* key, const char* val); bool wait_property(const char *name, const char *value); #endif /* _INIT_INIT_H */ Loading
init/README.md +7 −1 Original line number Diff line number Diff line Loading @@ -298,7 +298,8 @@ Commands > Fork and execute command with the given arguments. The command starts after "--" so that an optional security context, user, and supplementary groups can be provided. No other commands will be run until this one finishes. _seclabel_ can be a - to denote default. finishes. _seclabel_ can be a - to denote default. Properties are expanded within _argument_. `export <name> <value>` > Set the environment variable _name_ equal to _value_ in the Loading Loading @@ -412,6 +413,11 @@ Commands or the timeout has been reached. If timeout is not specified it currently defaults to five seconds. `wait_for_prop <name> <value>` > Wait for system property _name_ to be _value_. Properties are expanded within _value_. If property _name_ is already set to _value_, continue immediately. `write <path> <content>` > Open the file at _path_ and write a string to it with write(2). If the file does not exist, it will be created. If it does exist, Loading
init/builtins.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -1003,6 +1003,29 @@ static int do_wait(const std::vector<std::string>& args) { return -1; } static int do_wait_for_prop(const std::vector<std::string>& args) { const char* name = args[1].c_str(); const char* value = args[2].c_str(); size_t value_len = strlen(value); if (!is_legal_property_name(name)) { LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value << "\") failed: bad name"; return -1; } if (value_len >= PROP_VALUE_MAX) { LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value << "\") failed: value too long"; return -1; } if (!wait_property(name, value)) { LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value << "\") failed: init already in waiting"; return -1; } return 0; } /* * Callback to make a directory from the ext4 code */ Loading Loading @@ -1074,6 +1097,7 @@ BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"verity_load_state", {0, 0, do_verity_load_state}}, {"verity_update_state", {0, 0, do_verity_update_state}}, {"wait", {1, 2, do_wait}}, {"wait_for_prop", {2, 2, do_wait_for_prop}}, {"write", {2, 2, do_write}}, }; return builtin_functions; Loading
init/init.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -87,6 +87,10 @@ bool waiting_for_exec = false; static int epoll_fd = -1; static std::unique_ptr<Timer> waiting_for_prop(nullptr); static std::string wait_prop_name; static std::string wait_prop_value; void register_epoll_handler(int fd, void (*fn)()) { epoll_event ev; ev.events = EPOLLIN; Loading Loading @@ -128,10 +132,34 @@ int add_environment(const char *key, const char *val) return -1; } bool wait_property(const char *name, const char *value) { if (waiting_for_prop) { return false; } if (property_get(name) != value) { // Current property value is not equal to expected value wait_prop_name = name; wait_prop_value = value; waiting_for_prop.reset(new Timer()); } else { LOG(INFO) << "wait_property(\"" << name << "\", \"" << value << "\"): already set"; } return true; } void property_changed(const char *name, const char *value) { if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyTrigger(name, value); if (waiting_for_prop) { if (wait_prop_name == name && wait_prop_value == value) { wait_prop_name.clear(); wait_prop_value.clear(); LOG(INFO) << "Wait for property took " << *waiting_for_prop; waiting_for_prop.reset(); } } } static void restart_processes() Loading Loading @@ -876,7 +904,7 @@ int main(int argc, char** argv) { am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers"); while (true) { if (!waiting_for_exec) { if (!(waiting_for_exec || waiting_for_prop)) { am.ExecuteOneCommand(); restart_processes(); } Loading
init/init.h +2 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,6 @@ void register_epoll_handler(int fd, void (*fn)()); int add_environment(const char* key, const char* val); bool wait_property(const char *name, const char *value); #endif /* _INIT_INIT_H */