Merge "init: Add option to listen on sockets before starting service." into tm-qpr-dev
This commit is contained in:
commit
0024d68287
7 changed files with 22 additions and 12 deletions
|
|
@ -352,9 +352,10 @@ runs the service.
|
|||
|
||||
`socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]`
|
||||
> Create a UNIX domain socket named /dev/socket/_name_ and pass its fd to the
|
||||
launched process. _type_ must be "dgram", "stream" or "seqpacket". _type_
|
||||
may end with "+passcred" to enable SO_PASSCRED on the socket. User and
|
||||
group default to 0. 'seclabel' is the SELinux security context for the
|
||||
launched process. The socket is created synchronously when the service starts.
|
||||
_type_ must be "dgram", "stream" or "seqpacket". _type_ may end with "+passcred"
|
||||
to enable SO_PASSCRED on the socket or "+listen" to synchronously make it a listening socket.
|
||||
User and group default to 0. 'seclabel' is the SELinux security context for the
|
||||
socket. It defaults to the service security context, as specified by
|
||||
seclabel or computed based on the service executable file security context.
|
||||
For native executables see libcutils android\_get\_control\_socket().
|
||||
|
|
|
|||
|
|
@ -1379,7 +1379,8 @@ void StartPropertyService(int* epoll_socket) {
|
|||
StartSendingMessages();
|
||||
|
||||
if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
|
||||
false, 0666, 0, 0, {});
|
||||
/*passcred=*/false, /*should_listen=*/false, 0666, /*uid=*/0,
|
||||
/*gid=*/0, /*socketcon=*/{});
|
||||
result.ok()) {
|
||||
property_set_fd = *result;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -434,11 +434,14 @@ Result<void> ServiceParser::ParseSocket(std::vector<std::string>&& args) {
|
|||
<< "' instead.";
|
||||
}
|
||||
|
||||
if (types.size() > 1) {
|
||||
if (types.size() == 2 && types[1] == "passcred") {
|
||||
for (size_t i = 1; i < types.size(); i++) {
|
||||
if (types[i] == "passcred") {
|
||||
socket.passcred = true;
|
||||
} else if (types[i] == "listen") {
|
||||
socket.listen = true;
|
||||
} else {
|
||||
return Error() << "Only 'passcred' may be used to modify the socket type";
|
||||
return Error() << "Unknown socket type decoration '" << types[i]
|
||||
<< "'. Known values are ['passcred', 'listen']";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ void Descriptor::Publish() const {
|
|||
|
||||
Result<Descriptor> SocketDescriptor::Create(const std::string& global_context) const {
|
||||
const auto& socket_context = context.empty() ? global_context : context;
|
||||
auto result = CreateSocket(name, type | SOCK_CLOEXEC, passcred, perm, uid, gid, socket_context);
|
||||
auto result = CreateSocket(name, type | SOCK_CLOEXEC, passcred, listen, perm, uid, gid,
|
||||
socket_context);
|
||||
if (!result.ok()) {
|
||||
return result.error();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ struct SocketDescriptor {
|
|||
int perm = 0;
|
||||
std::string context;
|
||||
bool passcred = false;
|
||||
bool listen = false;
|
||||
bool persist = false;
|
||||
|
||||
// Create() creates the named unix domain socket in /dev/socket and returns a Descriptor object.
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ Result<uid_t> DecodeUid(const std::string& name) {
|
|||
* daemon. We communicate the file descriptor's value via the environment
|
||||
* variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").
|
||||
*/
|
||||
Result<int> CreateSocket(const std::string& name, int type, bool passcred, mode_t perm, uid_t uid,
|
||||
gid_t gid, const std::string& socketcon) {
|
||||
Result<int> CreateSocket(const std::string& name, int type, bool passcred, bool should_listen,
|
||||
mode_t perm, uid_t uid, gid_t gid, const std::string& socketcon) {
|
||||
if (!socketcon.empty()) {
|
||||
if (setsockcreatecon(socketcon.c_str()) == -1) {
|
||||
return ErrnoError() << "setsockcreatecon(\"" << socketcon << "\") failed";
|
||||
|
|
@ -142,6 +142,9 @@ Result<int> CreateSocket(const std::string& name, int type, bool passcred, mode_
|
|||
if (fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW)) {
|
||||
return ErrnoError() << "Failed to fchmodat socket '" << addr.sun_path << "'";
|
||||
}
|
||||
if (should_listen && listen(fd, /* use OS maximum */ 1 << 30)) {
|
||||
return ErrnoError() << "Failed to listen on socket '" << addr.sun_path << "'";
|
||||
}
|
||||
|
||||
LOG(INFO) << "Created socket '" << addr.sun_path << "'"
|
||||
<< ", mode " << std::oct << perm << std::dec
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ static const char kColdBootDoneProp[] = "ro.cold_boot_done";
|
|||
|
||||
extern void (*trigger_shutdown)(const std::string& command);
|
||||
|
||||
Result<int> CreateSocket(const std::string& name, int type, bool passcred, mode_t perm, uid_t uid,
|
||||
gid_t gid, const std::string& socketcon);
|
||||
Result<int> CreateSocket(const std::string& name, int type, bool passcred, bool should_listen,
|
||||
mode_t perm, uid_t uid, gid_t gid, const std::string& socketcon);
|
||||
|
||||
Result<std::string> ReadFile(const std::string& path);
|
||||
Result<void> WriteFile(const std::string& path, const std::string& content);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue