We currently throw out the return values from builtin functions and
occasionally log errors with no supporting context. This change uses
the newly introduced Result<T> class to communicate a successful result
or an error back to callers in order to print an error with clear
context when a builtin fails.
Example:
init: Command 'write /sys/class/leds/vibrator/trigger transient' action=init (/init.rc:245) took 0ms and failed: Unable to write to file '/sys/class/leds/vibrator/trigger': open() failed: No such file or directory
Test: boot bullhead
Change-Id: Idc18f331d2d646629c6093c1e0f2996cf9b42aec
init tries to propagate error information up to build context before
logging errors. This is a good thing, however too often init has the
overly verbose paradigm for error handling, below:
bool CalculateResult(const T& input, U* output, std::string* err)
bool CalculateAndUseResult(const T& input, std::string* err) {
U output;
std::string calculate_result_err;
if (!CalculateResult(input, &output, &calculate_result_err)) {
*err = "CalculateResult " + input + " failed: " +
calculate_result_err;
return false;
}
UseResult(output);
return true;
}
Even more common are functions that return only true/false but also
require passing a std::string* err in order to see the error message.
This change introduces a Result<T> that is use to either hold a
successful return value of type T or to hold an error message as a
std::string. If the functional only returns success or a failure with
an error message, Result<Success> may be used. The classes Error and
ErrnoError are used to indicate a failed Result<T>.
A successful Result<T> is constructed implicitly from any type that
can be implicitly converted to T or from the constructor arguments for
T. This allows you to return a type T directly from a function that
returns Result<T>.
Error and ErrnoError are used to construct a Result<T> has
failed. Each of these classes take an ostream as an input and are
implicitly cast to a Result<T> containing that failure. ErrnoError()
additionally appends ": " + strerror(errno) to the end of the failure
string to aid in interacting with C APIs.
The end result is that the above code snippet is turned into the much
clearer example below:
Result<U> CalculateResult(const T& input);
Result<Success> CalculateAndUseResult(const T& input) {
auto output = CalculateResult(input);
if (!output) {
return Error() << "CalculateResult " << input << " failed: "
<< output.error();
}
UseResult(*output);
return Success();
}
This change also makes this conversion for some of the util.cpp
functions that used the old paradigm.
Test: boot bullhead, init unit tests
Change-Id: I1e7d3a8820a79362245041251057fbeed2f7979b
This change splits out the selinux initialization and supporting
functionality into selinux.cpp and splits the security related
initialization of the rng, etc to security.cpp. It also provides
additional documentation for SEPolicy loading as this has been
requested by some teams.
It additionally cleans up sehandle and sehandle_prop. The former is
static within selinux.cpp and new wrapper functions are created around
selabel_lookup*() to better serve the users. The latter is moved to
property_service.cpp as it is isolated to that file for its usage.
Test: boot bullhead
Merged-In: Idc95d493cebc681fbe686b5160502f36af149f60
Change-Id: Idc95d493cebc681fbe686b5160502f36af149f60
(cherry picked from commit 9afb86b25d8675927cb37c86119a7ecf19f74819)
Inspired by ag/2659809/, this CL add readahead built-in command in init
to let files be prefetched into pagecache for faster reading.
Readahead happens in background but due to filesystem limitation it
might take small amount of time in it reading the filesystem metadata
needed to locate the requested blocks. So the command is executed in a
forked process to not block init execution.
Bug: 62413151
Test: boottime, dumpcache
Change-Id: I56c86e2ebc20efda4aa509e6efb736bd1d92baa5
ServiceManager is essentially just a list now that the rest of its
functionality has been moved elsewhere, so the class is renamed
appropriately.
The ServiceList::Find* functions have been cleaned up into a single
smaller interface.
The ServiceList::ForEach functions have been removed in favor of
ServiceList itself being directly iterable.
Test: boot bullhead
Change-Id: Ibd57c103338f03b83d81e8b48ea0e46cd48fd8f0
These can be implemented without ServiceManager, so we remove them and
make ServiceManager slightly less of a God class.
Test: boot bullhead
Test: init unit tests
Change-Id: Ia6e546fe5292255412245256f7d230af4ece135f
* Remove the Parser singleton (Hooray!)
* Rename parser.* to tokenizer.* as this is actually a tokenizer
* Rename init_parser.* to parser.* as this is a generic parser
* Move contents of init_parser_test.cpp to service_test.cpp as this
actually is a test of the parsing in MakeExecOneshotService() and
nothing related to (init_)parser.cpp
Test: boot bullhead
Test: bool sailfish
Test: init unit tests
Change-Id: I4fe39e6483f58ebd3ce5ee715a45dbba0acf5d91
We have been seeing panics and errors during shutdown sequence in
some vendor's platform, and it is required to disable error handling
during shutdown.
This CL separates the shutdown request to execute another "shutdown"
trigger at the beginning of shutdown stage. And vendor can use this
trigger to add custom commands needed for shutting down gracefully.
Bug: 38203024
Bug: 62084631
Test: device reboot/shutdown
Change-Id: I3fac4ed59f06667d86e477ee55ed391cf113717f
1) property_set() takes const std::string& for both of its arguments,
so stop using .c_str() with its parameters
2) Simplify a few places where StringPrintf() is used to concatenate strings
3) Use std::to_string() instead of StringPrintf() where it's better suited
Test: Boot bullhead
Test: init unit tests
Change-Id: I68ebda0e469f6230c8f9ad3c8d5f9444e0c4fdfd
restorecon() has become nothing more than a small wrapper around
selinux_android_restore(). This itself isn't super problematic, but
it is an obstacle for compiling util.cpp on the host as that function
is not available on the host.
Bug: 36970783
Test: Boot bullhead
Merged-In: I7e209ece6898f9a0d5eb9e5d5d8155c2f1ba9faf
Change-Id: I7e209ece6898f9a0d5eb9e5d5d8155c2f1ba9faf
restorecon() has become nothing more than a small wrapper around
selinux_android_restore(). This itself isn't super problematic, but
it is an obstacle for compiling util.cpp on the host as that function
is not available on the host.
Bug: 36970783
Test: Boot bullhead
Change-Id: I7e209ece6898f9a0d5eb9e5d5d8155c2f1ba9faf
Their callers may be able to add more context, so use an error string
to record the error.
Bug: 38038887
Test: boot bullhead
Test: Init unit tests
Change-Id: I46690d1c66e00a4b15cadc6fd0d6b50e990388c3
Check the result of DecodeUid() and return failure when uids/gids are
unable to be decoded.
Also, use an error string instead of logging directly such that more
context can be added when decoding fails.
Bug: 38038887
Test: Boot bullhead
Test: Init unit tests
Change-Id: I84c11aa5a8041bf5d2f754ee9af748344b789b37
Similar to what installkey used to do, init_user0 forks and
synchronously waits for vdc to return. This is dangerous to do in
init however as init also processes properties from a single thread.
I'm not aware of any specific issues that this is currently causing,
but it's a good preventative measure to match what installkey does and
use do_exec().
Test: Boot bullhead, see that init_user0 still happens
Change-Id: I853c61594fe3d97e91bbb2319ebddf2bbe80d457
Init exposes a global 'sehandle' that ueventd references as part of
devices.cpp and util.cpp. This is particularly dangerous in
device_init() in which both uevent and init write to this global.
This change creates a separate local copy for devices.cpp and puts
restrictions on where init.h can be included to make sure the global
used by init is not reference by non-init code. Future changes to
init should remove this global.
Test: Boot bullhead
Change-Id: Ifefa9e1932e9d647d06cca2618f5c8e5a7a85460
Start a init_tests.cpp file for end-to-end tests that parse small init script
segments and verify that they act as expected.
The first tests ensure that the execution order of event triggers
happens appropriately.
Test: Boot bullhead, run unit tests
Change-Id: Ic446c02605ab796fd41e0596ce1fd381aee80ce0
Remove the dependency on Action and Service from what should be a
generic Parser class.
Make ActionParser, ImportParser, and ServiceParser take a pointer to
their associated classes instead of accessing them through a
singleton.
Misc fixes to SectionParser Interface:
1) Make SectionParser::ParseLineSection() non-const as it always should
have been.
2) Use Rvalue references where appropriate
3) Remove extra std::string& filename in SectionParser::EndFile()
4) Only have SectionParser::ParseSection() as pure virtual
Document SectionParser.
Make ImportParser report the filename and line number of failed imports.
Make ServiceParser report the filename and line number of duplicated services.
Test: Boot bullhead
Change-Id: I86568a5b375fb4f27f4cb235ed1e37635f01d630
Currently if a process sets the sys.powerctl property, init adds this
property change into the event queue, just like any other property.
The actual logic to shutdown the device is not executed until init
gets to the action associated with the property change.
This is bad for multiple reasons, but explicitly causes deadlock in
the follow scenario:
A service is started with `exec` or `exec_start`
The same service sets sys.powerctl indicating to the system to
shutdown
The same service then waits infinitely
In this case, init doesn't process any further commands until the exec
service completes, including the command to reboot the device.
This change causes init to immediately handle sys.powerctl and reboot
the device regardless of the state of the event queue, wait for exec,
or wait for property conditions.
Bug: 37209359
Bug: 37415192
Test: Init reboots normally
Test: Update verifier can reboot the system
Change-Id: Iff2295aed970840f47e56c4bacc93001b791fa35
fs_mgr_update_verity_state() is invoked by 'verity_update_state' in
init.rc. It will then set property "partition.system.verified" and
"partition.vendor.verified" to verify_mode. We should support this for
AVB as well.
Also change the order of static libs in init to fix the build error
after this change:
system/extras/ext4_utils/ext4_crypt.cpp:69: error: undefined reference to 'property_get'
Bug: 35416769
Test: Mount /system and /vendor with vboot 2.0 (AVB), check the following properties exist.
- [partition.system.verified]: [2]
- [partition.vendor.verified]: [2]
Test: Mount /system and /vendor with vboot 1.0, check the following properties exist.
- [partition.system.verified]: [0]
- [partition.vendor.verified]: [0]
Change-Id: I4328d66a8cb93f26e7960e620a0b2292d5f15900
Remove includes of "log.h" that really want <android-base/logging.h>
Fix header include order
Remove headers included in .cpp files that their associated .h already includes
Remove some unused headers
Test: boot bullhead
Change-Id: I2b415adfe86a5c8bbe4fb1ebc53c7b0ee2253824
this will make the implementation more cleaner,
and has error message output when failed on some operations
also add the O_TRUNC flag explicitly for the open function
called in write_file.
And add more test on read_file and write_file functions
Bug: 36726045
Test: manual with hikey
Test: boot and init tests on bullhead
Test: cast with fugu, per b/36726045
Merged-In: If3c30a2fff58cfece2fcd27e69c30382146e6808
Change-Id: If3c30a2fff58cfece2fcd27e69c30382146e6808
Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org>
The content parameter of write_file() previously took a char* that was
then converted to a std::string in WriteStringToFd(). One unfortunate
effect of this, is that it is impossible to write data that contains
'\0' within it, as the new string will only contain characters up
until the '\0'.
This changes write_file() to take an std::string, such that
std::string::size() is used to determine the length of the string,
allowing it to contain null characters.
Also change the path parameter of read_file() and write_file() for
consistency.
Lastly, add a test for handling strings with '\0' in them.
Bug: 36726045
Test: Boot bullhead, run unit tests
Change-Id: Idad60e4228ee2de741ab3ab6a4917065b5e63cd8
init used to block on installkey such that it was unable to
process property events. This lead to a deadlock by which
the Keymaster HAL would wait indefinitely for the
hwservicemanager.ready=true.
This fixes the issue by implementing the builtin in terms of
do_exec, which allows init to stay responsive to properties
while waiting for the child to terminate.
Bug: 36278706
Test: Add a 3s delay into hwservicemanager before it sets the property
hwservicemanager.ready and the device still boots.
Change-Id: Iaefd31156ca01f3a44b4f85a8bf78beee8dfe224