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