Merge "init: always expand args in subcontext" am: c64c006991
am: a89077ad35
Change-Id: I7035d572fe1055bc3a98ee8c8ba1da057918525e
This commit is contained in:
commit
adcfcca845
|
@ -50,12 +50,19 @@ Command::Command(BuiltinFunction f, bool execute_in_subcontext,
|
|||
: func_(std::move(f)), execute_in_subcontext_(execute_in_subcontext), args_(args), line_(line) {}
|
||||
|
||||
Result<Success> Command::InvokeFunc(Subcontext* subcontext) const {
|
||||
if (execute_in_subcontext_ && subcontext) {
|
||||
return subcontext->Execute(args_);
|
||||
} else {
|
||||
const std::string& context = subcontext ? subcontext->context() : kInitContext;
|
||||
return RunBuiltinFunction(func_, args_, context);
|
||||
if (subcontext) {
|
||||
if (execute_in_subcontext_) {
|
||||
return subcontext->Execute(args_);
|
||||
}
|
||||
|
||||
auto expanded_args = subcontext->ExpandArgs(args_);
|
||||
if (!expanded_args) {
|
||||
return expanded_args.error();
|
||||
}
|
||||
return RunBuiltinFunction(func_, *expanded_args, subcontext->context());
|
||||
}
|
||||
|
||||
return RunBuiltinFunction(func_, args_, kInitContext);
|
||||
}
|
||||
|
||||
std::string Command::BuildCommandString() const {
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "action.h"
|
||||
#include "selinux.h"
|
||||
#include "system/core/init/subcontext.pb.h"
|
||||
#include "util.h"
|
||||
|
||||
using android::base::GetExecutablePath;
|
||||
|
@ -84,7 +83,9 @@ class SubcontextProcess {
|
|||
|
||||
private:
|
||||
void RunCommand(const SubcontextCommand::ExecuteCommand& execute_command,
|
||||
SubcontextReply::ResultMessage* result_message) const;
|
||||
SubcontextReply* reply) const;
|
||||
void ExpandArgs(const SubcontextCommand::ExpandArgsCommand& expand_args_command,
|
||||
SubcontextReply* reply) const;
|
||||
|
||||
const KeywordFunctionMap* function_map_;
|
||||
const std::string context_;
|
||||
|
@ -92,7 +93,7 @@ class SubcontextProcess {
|
|||
};
|
||||
|
||||
void SubcontextProcess::RunCommand(const SubcontextCommand::ExecuteCommand& execute_command,
|
||||
SubcontextReply::ResultMessage* result_message) const {
|
||||
SubcontextReply* reply) const {
|
||||
// Need to use ArraySplice instead of this code.
|
||||
auto args = std::vector<std::string>();
|
||||
for (const auto& string : execute_command.args()) {
|
||||
|
@ -108,11 +109,27 @@ void SubcontextProcess::RunCommand(const SubcontextCommand::ExecuteCommand& exec
|
|||
}
|
||||
|
||||
if (result) {
|
||||
result_message->set_success(true);
|
||||
reply->set_success(true);
|
||||
} else {
|
||||
result_message->set_success(false);
|
||||
result_message->set_error_string(result.error_string());
|
||||
result_message->set_error_errno(result.error_errno());
|
||||
auto* failure = reply->mutable_failure();
|
||||
failure->set_error_string(result.error_string());
|
||||
failure->set_error_errno(result.error_errno());
|
||||
}
|
||||
}
|
||||
|
||||
void SubcontextProcess::ExpandArgs(const SubcontextCommand::ExpandArgsCommand& expand_args_command,
|
||||
SubcontextReply* reply) const {
|
||||
for (const auto& arg : expand_args_command.args()) {
|
||||
auto expanded_prop = std::string{};
|
||||
if (!expand_props(arg, &expanded_prop)) {
|
||||
auto* failure = reply->mutable_failure();
|
||||
failure->set_error_string("Failed to expand '" + arg + "'");
|
||||
failure->set_error_errno(0);
|
||||
return;
|
||||
} else {
|
||||
auto* expand_args_reply = reply->mutable_expand_args_reply();
|
||||
expand_args_reply->add_expanded_args(expanded_prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +159,11 @@ void SubcontextProcess::MainLoop() {
|
|||
auto reply = SubcontextReply();
|
||||
switch (subcontext_command.command_case()) {
|
||||
case SubcontextCommand::kExecuteCommand: {
|
||||
RunCommand(subcontext_command.execute_command(), reply.mutable_result());
|
||||
RunCommand(subcontext_command.execute_command(), &reply);
|
||||
break;
|
||||
}
|
||||
case SubcontextCommand::kExpandArgsCommand: {
|
||||
ExpandArgs(subcontext_command.expand_args_command(), &reply);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -219,12 +240,7 @@ void Subcontext::Restart() {
|
|||
Fork();
|
||||
}
|
||||
|
||||
Result<Success> Subcontext::Execute(const std::vector<std::string>& args) {
|
||||
auto subcontext_command = SubcontextCommand();
|
||||
std::copy(
|
||||
args.begin(), args.end(),
|
||||
RepeatedPtrFieldBackInserter(subcontext_command.mutable_execute_command()->mutable_args()));
|
||||
|
||||
Result<SubcontextReply> Subcontext::TransmitMessage(const SubcontextCommand& subcontext_command) {
|
||||
if (auto result = SendMessage(socket_, subcontext_command); !result) {
|
||||
Restart();
|
||||
return ErrnoError() << "Failed to send message to subcontext";
|
||||
|
@ -236,25 +252,59 @@ Result<Success> Subcontext::Execute(const std::vector<std::string>& args) {
|
|||
return Error() << "Failed to receive result from subcontext: " << subcontext_message.error();
|
||||
}
|
||||
|
||||
auto subcontext_reply = SubcontextReply();
|
||||
auto subcontext_reply = SubcontextReply{};
|
||||
if (!subcontext_reply.ParseFromString(*subcontext_message)) {
|
||||
Restart();
|
||||
return Error() << "Unable to parse message from subcontext";
|
||||
}
|
||||
|
||||
switch (subcontext_reply.reply_case()) {
|
||||
case SubcontextReply::kResult: {
|
||||
auto result = subcontext_reply.result();
|
||||
if (result.success()) {
|
||||
return Success();
|
||||
} else {
|
||||
return ResultError(result.error_string(), result.error_errno());
|
||||
}
|
||||
}
|
||||
default:
|
||||
return Error() << "Unknown message type from subcontext: "
|
||||
<< subcontext_reply.reply_case();
|
||||
if (subcontext_reply.reply_case() == SubcontextReply::kFailure) {
|
||||
auto& failure = subcontext_reply.failure();
|
||||
return ResultError(failure.error_string(), failure.error_errno());
|
||||
}
|
||||
return subcontext_reply;
|
||||
}
|
||||
|
||||
Result<Success> Subcontext::Execute(const std::vector<std::string>& args) {
|
||||
auto subcontext_command = SubcontextCommand();
|
||||
std::copy(
|
||||
args.begin(), args.end(),
|
||||
RepeatedPtrFieldBackInserter(subcontext_command.mutable_execute_command()->mutable_args()));
|
||||
|
||||
auto subcontext_reply = TransmitMessage(subcontext_command);
|
||||
if (!subcontext_reply) {
|
||||
return subcontext_reply.error();
|
||||
}
|
||||
|
||||
if (subcontext_reply->reply_case() != SubcontextReply::kSuccess) {
|
||||
return Error() << "Unexpected message type from subcontext: "
|
||||
<< subcontext_reply->reply_case();
|
||||
}
|
||||
|
||||
return Success();
|
||||
}
|
||||
|
||||
Result<std::vector<std::string>> Subcontext::ExpandArgs(const std::vector<std::string>& args) {
|
||||
auto subcontext_command = SubcontextCommand{};
|
||||
std::copy(args.begin(), args.end(),
|
||||
RepeatedPtrFieldBackInserter(
|
||||
subcontext_command.mutable_expand_args_command()->mutable_args()));
|
||||
|
||||
auto subcontext_reply = TransmitMessage(subcontext_command);
|
||||
if (!subcontext_reply) {
|
||||
return subcontext_reply.error();
|
||||
}
|
||||
|
||||
if (subcontext_reply->reply_case() != SubcontextReply::kExpandArgsReply) {
|
||||
return Error() << "Unexpected message type from subcontext: "
|
||||
<< subcontext_reply->reply_case();
|
||||
}
|
||||
|
||||
auto& reply = subcontext_reply->expand_args_reply();
|
||||
auto expanded_args = std::vector<std::string>{};
|
||||
for (const auto& string : reply.expanded_args()) {
|
||||
expanded_args.emplace_back(string);
|
||||
}
|
||||
return expanded_args;
|
||||
}
|
||||
|
||||
static std::vector<Subcontext> subcontexts;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <android-base/unique_fd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "system/core/init/subcontext.pb.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
@ -39,7 +40,8 @@ class Subcontext {
|
|||
Fork();
|
||||
}
|
||||
|
||||
Result<Success> Execute(const std::vector<std::string>& command);
|
||||
Result<Success> Execute(const std::vector<std::string>& args);
|
||||
Result<std::vector<std::string>> ExpandArgs(const std::vector<std::string>& args);
|
||||
void Restart();
|
||||
|
||||
const std::string& path_prefix() const { return path_prefix_; }
|
||||
|
@ -48,6 +50,7 @@ class Subcontext {
|
|||
|
||||
private:
|
||||
void Fork();
|
||||
Result<SubcontextReply> TransmitMessage(const SubcontextCommand& subcontext_command);
|
||||
|
||||
std::string path_prefix_;
|
||||
std::string context_;
|
||||
|
|
|
@ -19,15 +19,23 @@ option optimize_for = LITE_RUNTIME;
|
|||
|
||||
message SubcontextCommand {
|
||||
message ExecuteCommand { repeated string args = 1; }
|
||||
oneof command { ExecuteCommand execute_command = 1; }
|
||||
message ExpandArgsCommand { repeated string args = 1; }
|
||||
oneof command {
|
||||
ExecuteCommand execute_command = 1;
|
||||
ExpandArgsCommand expand_args_command = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message SubcontextReply {
|
||||
message ResultMessage {
|
||||
optional bool success = 1;
|
||||
optional string error_string = 2;
|
||||
optional int32 error_errno = 3;
|
||||
message Failure {
|
||||
optional string error_string = 1;
|
||||
optional int32 error_errno = 2;
|
||||
}
|
||||
message ExpandArgsReply { repeated string expanded_args = 1; }
|
||||
|
||||
oneof reply { ResultMessage result = 1; }
|
||||
oneof reply {
|
||||
bool success = 1;
|
||||
Failure failure = 2;
|
||||
ExpandArgsReply expand_args_reply = 3;
|
||||
}
|
||||
}
|
|
@ -143,6 +143,34 @@ TEST(subcontext, ContextString) {
|
|||
});
|
||||
}
|
||||
|
||||
TEST(subcontext, ExpandArgs) {
|
||||
RunTest([](auto& subcontext, auto& context_string) {
|
||||
auto args = std::vector<std::string>{
|
||||
"first",
|
||||
"${ro.hardware}",
|
||||
"$$third",
|
||||
};
|
||||
auto result = subcontext.ExpandArgs(args);
|
||||
ASSERT_TRUE(result) << result.error();
|
||||
ASSERT_EQ(3U, result->size());
|
||||
EXPECT_EQ(args[0], result->at(0));
|
||||
EXPECT_EQ(GetProperty("ro.hardware", ""), result->at(1));
|
||||
EXPECT_EQ("$third", result->at(2));
|
||||
});
|
||||
}
|
||||
|
||||
TEST(subcontext, ExpandArgsFailure) {
|
||||
RunTest([](auto& subcontext, auto& context_string) {
|
||||
auto args = std::vector<std::string>{
|
||||
"first",
|
||||
"${",
|
||||
};
|
||||
auto result = subcontext.ExpandArgs(args);
|
||||
ASSERT_FALSE(result);
|
||||
EXPECT_EQ("Failed to expand '" + args[1] + "'", result.error_string());
|
||||
});
|
||||
}
|
||||
|
||||
TestFunctionMap BuildTestFunctionMap() {
|
||||
TestFunctionMap test_function_map;
|
||||
// For CheckDifferentPid
|
||||
|
|
Loading…
Reference in New Issue