Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 641ff0a4 authored by Wei Wang's avatar Wei Wang
Browse files

init: add support of multiple class names

Add support of multiple class names in service, so that related services
can be grouped together. By doing this, we can start/stop some services
for special purpose. For example, early zygote, early boot animation
and etc.

Bug: 36535312
Test: marlin boots with defined classes
Change-Id: Ifeaaf034fd836816e24f3775bece53ea83faada6
parent ca622b4e
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -192,11 +192,12 @@ runs the service.
`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.
+43 −24
Original line number Diff line number Diff line
@@ -149,27 +149,44 @@ ServiceEnvironmentInfo::ServiceEnvironmentInfo(const std::string& name,
    : 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 @@ bool Service::Reap() {

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::ParseCapabilities(const std::vector<std::string>& args, std::strin
}

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 @@ private:

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 @@ Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
        {"user",        {1,     1,    &Service::ParseUser}},
        {"writepid",    {1,     kMax, &Service::ParseWritepid}},
    };
    // clang-format on
    return option_parsers;
}

@@ -889,8 +908,8 @@ Service* ServiceManager::MakeExecOneshotService(const std::vector<std::string>&
        }
    }

    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::ForEachService(const std::function<void(Service*)>& callbac
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 @@ bool ServiceParser::ParseSection(const std::vector<std::string>& args,
    }

    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;
}

+8 −9
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <cutils/iosched_policy.h>

#include <memory>
#include <set>
#include <string>
#include <vector>

@@ -62,11 +63,9 @@ struct ServiceEnvironmentInfo {

class Service {
  public:
    Service(const std::string& name, const std::string& classname,
            const std::vector<std::string>& args);
    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 @@ public:
    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_; }
@@ -136,7 +135,7 @@ private:
    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_;