summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-06-12 18:02:20 -0700
committerElliott Hughes <enh@google.com>2015-06-17 15:21:52 -0700
commite79d0d556f894696291cef89ccaf64efe45d11ad (patch)
tree514b5edeefddc7fb615f0304a445b39598b5e62a /init
parentd50393057a6551c3bb498ed3a3bb7bd9eeb48225 (diff)
downloadsystem_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.cpp10
-rw-r--r--init/init.h5
-rw-r--r--init/init_parser.cpp11
-rw-r--r--init/keywords.h25
-rw-r--r--init/readme.txt60
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