diff options
author | Elliott Hughes <enh@google.com> | 2015-06-12 18:02:20 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2015-06-17 15:21:52 -0700 |
commit | e79d0d556f894696291cef89ccaf64efe45d11ad (patch) | |
tree | 514b5edeefddc7fb615f0304a445b39598b5e62a /init | |
parent | d50393057a6551c3bb498ed3a3bb7bd9eeb48225 (diff) | |
download | system_core-e79d0d556f894696291cef89ccaf64efe45d11ad.zip system_core-e79d0d556f894696291cef89ccaf64efe45d11ad.tar.gz system_core-e79d0d556f894696291cef89ccaf64efe45d11ad.tar.bz2 |
init support for cgroups.
This adds the "writepid" option that instructs init to write the child's
pid to the given filenames (such as /dev/cpuctl/bg_non_interactive/cgroup.procs
and/or /dev/cpuset/foreground/cgroup.procs).
Bug: http://b/21163745
Change-Id: I121bb22aa208bc99c4fb334eb552fdd5bcc47c1a
(cherry picked from commit d62f0608d9d67bf647cf15debbd163e84584fe44)
Diffstat (limited to 'init')
-rw-r--r-- | init/init.cpp | 10 | ||||
-rw-r--r-- | init/init.h | 5 | ||||
-rw-r--r-- | init/init_parser.cpp | 11 | ||||
-rw-r--r-- | init/keywords.h | 25 | ||||
-rw-r--r-- | init/readme.txt | 60 |
5 files changed, 71 insertions, 40 deletions
diff --git a/init/init.cpp b/init/init.cpp index 85d7909..93fe944 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -290,6 +290,16 @@ void service_start(struct service *svc, const char *dynamic_args) freecon(scon); scon = NULL; + if (svc->writepid_files_) { + std::string pid_str = android::base::StringPrintf("%d", pid); + for (auto& file : *svc->writepid_files_) { + if (!android::base::WriteStringToFile(pid_str, file)) { + ERROR("couldn't write %s to %s: %s\n", + pid_str.c_str(), file.c_str(), strerror(errno)); + } + } + } + if (svc->ioprio_class != IoSchedClass_NONE) { if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) { ERROR("Failed to set pid %d ioprio = %d,%d: %s\n", diff --git a/init/init.h b/init/init.h index 1cabb14..c166969 100644 --- a/init/init.h +++ b/init/init.h @@ -19,6 +19,9 @@ #include <sys/types.h> +#include <string> +#include <vector> + #include <cutils/list.h> #include <cutils/iosched_policy.h> @@ -116,6 +119,8 @@ struct service { struct action onrestart; /* Actions to execute on restart. */ + std::vector<std::string>* writepid_files_; + /* keycodes for triggering this service via /dev/keychord */ int *keycodes; int nkeycodes; diff --git a/init/init_parser.cpp b/init/init_parser.cpp index 385b37b..666a86e 100644 --- a/init/init_parser.cpp +++ b/init/init_parser.cpp @@ -206,6 +206,7 @@ static int lookup_keyword(const char *s) break; case 'w': if (!strcmp(s, "rite")) return K_write; + if (!strcmp(s, "ritepid")) return K_writepid; if (!strcmp(s, "ait")) return K_wait; break; } @@ -926,6 +927,16 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args svc->seclabel = args[1]; } break; + case K_writepid: + if (nargs < 2) { + parse_error(state, "writepid option requires at least one filename\n"); + break; + } + svc->writepid_files_ = new std::vector<std::string>; + for (int i = 1; i < nargs; ++i) { + svc->writepid_files_->push_back(args[i]); + } + break; default: parse_error(state, "invalid option '%s'\n", args[0]); diff --git a/init/keywords.h b/init/keywords.h index 37f01b8..e637d7d 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -43,11 +43,15 @@ int do_wait(int nargs, char **args); enum { K_UNKNOWN, #endif + KEYWORD(bootchart_init, COMMAND, 0, do_bootchart_init) + KEYWORD(chmod, COMMAND, 2, do_chmod) + KEYWORD(chown, COMMAND, 2, do_chown) KEYWORD(class, OPTION, 0, 0) + KEYWORD(class_reset, COMMAND, 1, do_class_reset) KEYWORD(class_start, COMMAND, 1, do_class_start) KEYWORD(class_stop, COMMAND, 1, do_class_stop) - KEYWORD(class_reset, COMMAND, 1, do_class_reset) KEYWORD(console, OPTION, 0, 0) + KEYWORD(copy, COMMAND, 2, do_copy) KEYWORD(critical, OPTION, 0, 0) KEYWORD(disabled, OPTION, 0, 0) KEYWORD(domainname, COMMAND, 1, do_domainname) @@ -57,16 +61,20 @@ enum { KEYWORD(group, OPTION, 0, 0) KEYWORD(hostname, COMMAND, 1, do_hostname) KEYWORD(ifup, COMMAND, 1, do_ifup) + KEYWORD(import, SECTION, 1, 0) KEYWORD(insmod, COMMAND, 1, do_insmod) KEYWORD(installkey, COMMAND, 1, do_installkey) - KEYWORD(import, SECTION, 1, 0) + KEYWORD(ioprio, OPTION, 0, 0) KEYWORD(keycodes, OPTION, 0, 0) + KEYWORD(load_all_props, COMMAND, 0, do_load_all_props) + KEYWORD(load_persist_props, COMMAND, 0, do_load_persist_props) + KEYWORD(loglevel, COMMAND, 1, do_loglevel) KEYWORD(mkdir, COMMAND, 1, do_mkdir) KEYWORD(mount_all, COMMAND, 1, do_mount_all) KEYWORD(mount, COMMAND, 3, do_mount) - KEYWORD(on, SECTION, 0, 0) KEYWORD(oneshot, OPTION, 0, 0) KEYWORD(onrestart, OPTION, 0, 0) + KEYWORD(on, SECTION, 0, 0) KEYWORD(powerctl, COMMAND, 1, do_powerctl) KEYWORD(restart, COMMAND, 1, do_restart) KEYWORD(restorecon, COMMAND, 1, do_restorecon) @@ -82,22 +90,15 @@ enum { KEYWORD(start, COMMAND, 1, do_start) KEYWORD(stop, COMMAND, 1, do_stop) KEYWORD(swapon_all, COMMAND, 1, do_swapon_all) - KEYWORD(trigger, COMMAND, 1, do_trigger) KEYWORD(symlink, COMMAND, 1, do_symlink) KEYWORD(sysclktz, COMMAND, 1, do_sysclktz) + KEYWORD(trigger, COMMAND, 1, do_trigger) KEYWORD(user, OPTION, 0, 0) KEYWORD(verity_load_state, COMMAND, 0, do_verity_load_state) KEYWORD(verity_update_state, COMMAND, 0, do_verity_update_state) KEYWORD(wait, COMMAND, 1, do_wait) KEYWORD(write, COMMAND, 2, do_write) - KEYWORD(copy, COMMAND, 2, do_copy) - KEYWORD(chown, COMMAND, 2, do_chown) - KEYWORD(chmod, COMMAND, 2, do_chmod) - KEYWORD(loglevel, COMMAND, 1, do_loglevel) - KEYWORD(load_persist_props, COMMAND, 0, do_load_persist_props) - KEYWORD(load_all_props, COMMAND, 0, do_load_all_props) - KEYWORD(ioprio, OPTION, 0, 0) - KEYWORD(bootchart_init, COMMAND, 0, do_bootchart_init) + KEYWORD(writepid, OPTION, 0, 0) #ifdef __MAKE_KEYWORD_ENUM__ KEYWORD_COUNT, }; diff --git a/init/readme.txt b/init/readme.txt index c213041..9e3394e 100644 --- a/init/readme.txt +++ b/init/readme.txt @@ -60,36 +60,36 @@ Options are modifiers to services. They affect how and when init runs the service. critical - This is a device-critical service. If it exits more than four times in - four minutes, the device will reboot into recovery mode. + This is a device-critical service. If it exits more than four times in + four minutes, the device will reboot into recovery mode. disabled - This service will not automatically start with its class. - It must be explicitly started by name. + This service will not automatically start with its class. + It must be explicitly started by name. setenv <name> <value> - Set the environment variable <name> to <value> in the launched process. + Set the environment variable <name> to <value> in the launched process. 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". - 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. + Create a unix domain socket named /dev/socket/<name> and pass + its fd to the launched process. <type> must be "dgram", "stream" or "seqpacket". + 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. user <username> - Change to username before exec'ing this service. - Currently defaults to root. (??? probably should default to nobody) - Currently, if your process requires linux capabilities then you cannot use - this command. You must instead request the capabilities in-process while - still root, and then drop to your desired uid. + Change to username before exec'ing this service. + Currently defaults to root. (??? probably should default to nobody) + Currently, if your process requires linux capabilities then you cannot use + this command. You must instead request the capabilities in-process while + still root, and then drop to your desired uid. group <groupname> [ <groupname> ]* - Change to groupname before exec'ing this service. Additional - groupnames beyond the (required) first one are used to set the - supplemental groups of the process (via setgroups()). - Currently defaults to root. (??? probably should default to nobody) + Change to groupname before exec'ing this service. Additional + groupnames beyond the (required) first one are used to set the + supplemental groups of the process (via setgroups()). + Currently defaults to root. (??? probably should default to nobody) seclabel <seclabel> Change to 'seclabel' before exec'ing this service. @@ -99,22 +99,26 @@ seclabel <seclabel> If not specified and no transition is defined in policy, defaults to the init context. oneshot - Do not restart the service when it exits. + Do not restart the service when it exits. class <name> - Specify a class name 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. + Specify a class name 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. onrestart - Execute a Command (see below) when service restarts. + Execute a Command (see below) when service restarts. + +writepid <file...> + Write the child's pid to the given files when it forks. Meant for + cgroup/cpuset usage. Triggers -------- - Triggers are strings which can be used to match certain kinds - of events and used to cause an action to occur. +Triggers are strings which can be used to match certain kinds +of events and used to cause an action to occur. boot This is the first trigger that will occur when init starts |