diff --git a/init/init.cpp b/init/init.cpp index 8ea60dd80..f48016f6d 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -288,6 +288,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 1cabb147e..c1669694b 100644 --- a/init/init.h +++ b/init/init.h @@ -19,6 +19,9 @@ #include +#include +#include + #include #include @@ -116,6 +119,8 @@ struct service { struct action onrestart; /* Actions to execute on restart. */ + std::vector* 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 358d6d414..ed77b6f2f 100644 --- a/init/init_parser.cpp +++ b/init/init_parser.cpp @@ -207,6 +207,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; } @@ -925,6 +926,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; + 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 04229f29a..d5c766749 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -44,11 +44,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) @@ -58,16 +62,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) @@ -84,22 +92,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 4cbe600a1..4dda34032 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 - Set the environment variable to in the launched process. + Set the environment variable to in the launched process. socket [ [ [ ] ] ] - Create a unix domain socket named /dev/socket/ and pass - its fd to the launched process. 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/ and pass + its fd to the launched process. 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 - 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 [ ]* - 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 Change to 'seclabel' before exec'ing this service. @@ -99,22 +99,26 @@ 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 - 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 + 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