기본 문법
http://www.dreamy.pe.kr/zbxe/CodeClip/164851
설명
http://egloos.zum.com/shadowxx/v/10770478
http://blog.naver.com/PostView.nhn?blogId=multiedit&logNo=40147752143
예제
< class >
class name 을 등록하고 아래와 같이 class 를 start stop 시킬 수 있다.
즉, class_start 를 호출하면 해당 class name 을 등록한 모든 service 들이 시작된다.
Class <name>
Specify a class name for the service. All services in a named class may be started or stopped together.
Class_start <serviceclass>
Start all services of the specified class if they are not already running.
Class_stop <serviceclass>
Stop all services of the specified class if they are currently running.
< on + property:조건 >
on property:ro.kernel.qemu=1
start adbd
property:ro.kernel.qemu 가 1 이면 아래 command 를 실행하겠다.
예를 들면
on property:vold.decrypt=trigger_restart_framework
class_start main
class_start late_start
이렇게 선언해 두면.
나중에 vold.decrypt propoty 가 trigger_restart_framework 로 값이 저장되면,
해당 부분이 호출 된다.
이때 class name 이 main 이거나 late_start 인 service 와 action 들은 모두 실행되게 된다.
< service trigger >
service 들은 기본적으로 init process 에서 모두 순차적으로 실행되지만,
cmd 에 disabled 가 있는 service 는 init process 에 의해서 autostart 되지 않는다.
service fuse_extSdCard /system/bin/sdcard -u 1023 -g 1023 -w 1023 -d -f /mnt/media_rw/extSdCard /storage/extSdCard
class late_start
disabled
oneshot
아래와 같이 ctl.start 에 service 의 name 을 입력하면 해당 service 를 trigger 할 수 있다.
#setprop ctl.start fuse_extSdCard
source code 에서는 아래와 같이..
snprintf(service, 64, "fuse_%s", getLabel());
property_set("ctl.start", service);
on <name>
기본적으로 on 으로 시작하는 section 들은 아래와 같이 trigger 된다.
= init.rc 내에서 script 로 trigger
# Mount filesystems and start core system services. on late-init trigger early-fs trigger fs trigger post-fs trigger post-fs-data # Load properties from /system/ + /factory after fs mount. Place # this in another action so that the load will be scheduled after the prior # issued fs triggers have completed. trigger load_all_props_action # Remove a file to wake up anything waiting for firmware. trigger firmware_mounts_complete trigger early-boot trigger boot |
trigger command 는 init process 에서 다음과 같이 parsing 된다.
KEYWORD(trigger, COMMAND, 1, do_trigger)
int do_trigger(int nargs, char **args)
{
action_for_each_trigger(args[1], action_add_queue_tail);
return 0;
}
= source code 내에서 function 으로 직접 trigger
action_for_each_trigger("fs_selinux", action_add_queue_tail); |
-> inside action_for_each_trigger() function
// on <name> 을 action_list에 추가한다. void action_for_each_trigger(const char *trigger, void (*func)(struct action *act)) { struct listnode *node; struct action *act; list_for_each(node, &action_list) { act = node_to_item(node, struct action, alist); if (!strcmp(act->name, trigger)) { func(act); } } } |
이후 execute_one_command() 함수가 실행될때마다 해당 list 안에 저장된 on section 들이 하나씩 실행된다.
void execute_one_command(void) { int ret, i; char cmd_str[256] = ""; if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) { cur_action = action_remove_queue_head(); cur_command = NULL; if (!cur_action) return; INFO("processing action %p (%s)\n", cur_action, cur_action->name); cur_command = get_first_command(cur_action); } else { cur_command = get_next_command(cur_action, cur_command); } if (!cur_command) return; ret = cur_command->func(cur_command->nargs, cur_command->args); if (klog_get_level() >= KLOG_INFO_LEVEL) { for (i = 0; i < cur_command->nargs; i++) { strlcat(cmd_str, cur_command->args[i], sizeof(cmd_str)); if (i < cur_command->nargs - 1) { strlcat(cmd_str, " ", sizeof(cmd_str)); } } INFO("command '%s' action=%s status=%d (%s:%d)\n", cmd_str, cur_action ? cur_action->name : "", ret, cur_command->filename, cur_command->line); } } |
'Programming > Linux_Platform' 카테고리의 다른 글
TEMP_FAILURE_RETRY (0) | 2015.12.01 |
---|---|
[linux] openat / open 의 차이점 (0) | 2015.10.29 |
fstab & partition images (0) | 2015.10.19 |
linux command : stat, fstat, lstat (0) | 2015.10.19 |
헷갈리는 c string 함수들 (0) | 2015.10.19 |