Merge "init: add support of multiple class names" am: 3c1568aa13
am: fd450bb95a
Change-Id: Ia859d1817eb80a34f339fe99894bffa4163440ce
diff --git a/init/README.md b/init/README.md
index 709c667..65d6543 100644
--- a/init/README.md
+++ b/init/README.md
@@ -192,11 +192,12 @@
`oneshot`
> Do not restart the service when it exits.
-`class <name>`
-> Specify a class name for the service. All services in a
+`class <name> [ <name>\* ]`
+> Specify class names for the service. All services in a
named class may be started or stopped together. A service
is in the class "default" if one is not specified via the
- class option.
+ class option. Additional classnames beyond the (required) first
+ one are used to group services.
`onrestart`
> Execute a Command (see below) when service restarts.
diff --git a/init/service.cpp b/init/service.cpp
index c8d1cb1..c6ef838 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -149,27 +149,44 @@
: name(name), value(value) {
}
-Service::Service(const std::string& name, const std::string& classname,
- const std::vector<std::string>& args)
- : name_(name), classname_(classname), flags_(0), pid_(0),
- crash_count_(0), uid_(0), gid_(0), namespace_flags_(0),
- seclabel_(""), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0),
- priority_(0), oom_score_adjust_(-1000), args_(args) {
+Service::Service(const std::string& name, const std::vector<std::string>& args)
+ : name_(name),
+ classnames_({"default"}),
+ flags_(0),
+ pid_(0),
+ crash_count_(0),
+ uid_(0),
+ gid_(0),
+ namespace_flags_(0),
+ seclabel_(""),
+ ioprio_class_(IoSchedClass_NONE),
+ ioprio_pri_(0),
+ priority_(0),
+ oom_score_adjust_(-1000),
+ args_(args) {
onrestart_.InitSingleTrigger("onrestart");
}
-Service::Service(const std::string& name, const std::string& classname,
- unsigned flags, uid_t uid, gid_t gid,
- const std::vector<gid_t>& supp_gids,
- const CapSet& capabilities, unsigned namespace_flags,
- const std::string& seclabel,
+Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
+ const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
+ unsigned namespace_flags, const std::string& seclabel,
const std::vector<std::string>& args)
- : name_(name), classname_(classname), flags_(flags), pid_(0),
- crash_count_(0), uid_(uid), gid_(gid),
- supp_gids_(supp_gids), capabilities_(capabilities),
- namespace_flags_(namespace_flags), seclabel_(seclabel),
- ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0),
- oom_score_adjust_(-1000), args_(args) {
+ : name_(name),
+ classnames_({"default"}),
+ flags_(flags),
+ pid_(0),
+ crash_count_(0),
+ uid_(uid),
+ gid_(gid),
+ supp_gids_(supp_gids),
+ capabilities_(capabilities),
+ namespace_flags_(namespace_flags),
+ seclabel_(seclabel),
+ ioprio_class_(IoSchedClass_NONE),
+ ioprio_pri_(0),
+ priority_(0),
+ oom_score_adjust_(-1000),
+ args_(args) {
onrestart_.InitSingleTrigger("onrestart");
}
@@ -297,7 +314,7 @@
void Service::DumpState() const {
LOG(INFO) << "service " << name_;
- LOG(INFO) << " class '" << classname_ << "'";
+ LOG(INFO) << " class '" << android::base::Join(classnames_, " ") << "'";
LOG(INFO) << " exec "<< android::base::Join(args_, " ");
std::for_each(descriptors_.begin(), descriptors_.end(),
[] (const auto& info) { LOG(INFO) << *info; });
@@ -334,7 +351,7 @@
}
bool Service::ParseClass(const std::vector<std::string>& args, std::string* err) {
- classname_ = args[1];
+ classnames_ = std::set<std::string>(args.begin() + 1, args.end());
return true;
}
@@ -516,10 +533,11 @@
Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
+ // clang-format off
static const Map option_parsers = {
{"capabilities",
{1, kMax, &Service::ParseCapabilities}},
- {"class", {1, 1, &Service::ParseClass}},
+ {"class", {1, kMax, &Service::ParseClass}},
{"console", {0, 1, &Service::ParseConsole}},
{"critical", {0, 0, &Service::ParseCritical}},
{"disabled", {0, 0, &Service::ParseDisabled}},
@@ -539,6 +557,7 @@
{"user", {1, 1, &Service::ParseUser}},
{"writepid", {1, kMax, &Service::ParseWritepid}},
};
+ // clang-format on
return option_parsers;
}
@@ -889,8 +908,8 @@
}
}
- auto svc_p = std::make_unique<Service>(name, "default", flags, uid, gid, supp_gids,
- no_capabilities, namespace_flags, seclabel, str_args);
+ auto svc_p = std::make_unique<Service>(name, flags, uid, gid, supp_gids, no_capabilities,
+ namespace_flags, seclabel, str_args);
Service* svc = svc_p.get();
services_.emplace_back(std::move(svc_p));
@@ -940,7 +959,7 @@
void ServiceManager::ForEachServiceInClass(const std::string& classname,
void (*func)(Service* svc)) const {
for (const auto& s : services_) {
- if (classname == s->classname()) {
+ if (s->classnames().find(classname) != s->classnames().end()) {
func(s.get());
}
}
@@ -1034,7 +1053,7 @@
}
std::vector<std::string> str_args(args.begin() + 2, args.end());
- service_ = std::make_unique<Service>(name, "default", str_args);
+ service_ = std::make_unique<Service>(name, str_args);
return true;
}
diff --git a/init/service.h b/init/service.h
index 08388e2..9a9046b 100644
--- a/init/service.h
+++ b/init/service.h
@@ -22,6 +22,7 @@
#include <cutils/iosched_policy.h>
#include <memory>
+#include <set>
#include <string>
#include <vector>
@@ -61,12 +62,10 @@
};
class Service {
-public:
- Service(const std::string& name, const std::string& classname,
- const std::vector<std::string>& args);
+ public:
+ Service(const std::string& name, const std::vector<std::string>& args);
- Service(const std::string& name, const std::string& classname,
- unsigned flags, uid_t uid, gid_t gid,
+ Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
unsigned namespace_flags, const std::string& seclabel,
const std::vector<std::string>& args);
@@ -84,10 +83,10 @@
bool Reap();
void DumpState() const;
void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
- bool IsShutdownCritical() { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
+ bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
const std::string& name() const { return name_; }
- const std::string& classname() const { return classname_; }
+ const std::set<std::string>& classnames() const { return classnames_; }
unsigned flags() const { return flags_; }
pid_t pid() const { return pid_; }
uid_t uid() const { return uid_; }
@@ -100,7 +99,7 @@
void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; }
const std::vector<std::string>& args() const { return args_; }
-private:
+ private:
using OptionParser = bool (Service::*) (const std::vector<std::string>& args,
std::string* err);
class OptionParserMap;
@@ -136,7 +135,7 @@
bool AddDescriptor(const std::vector<std::string>& args, std::string* err);
std::string name_;
- std::string classname_;
+ std::set<std::string> classnames_;
std::string console_;
unsigned flags_;