X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=package%2Fsystem%2Fprocd%2Ffiles%2Fprocd.sh;h=a9d2b341beab58658ceb245e62d426d3c49b1258;hp=d2c5b424a7f88e45568c81177078116128f39e7a;hb=7519a36774ca;hpb=b22a20af450b19fb47235e684afcddb301221def diff --git a/package/system/procd/files/procd.sh b/package/system/procd/files/procd.sh index d2c5b424a7..a9d2b341be 100644 --- a/package/system/procd/files/procd.sh +++ b/package/system/procd/files/procd.sh @@ -18,23 +18,47 @@ # file: configuration files (array) # netdev: bound network device (detects ifindex changes) # limits: resource limits (passed to the process) -# user info: array with 1 values $username +# user: $username to run service as +# group: $groupname to run service as # pidfile: file name to write pid into +# stdout: boolean whether to redirect commands stdout to syslog (default: 0) +# stderr: boolean whether to redirect commands stderr to syslog (default: 0) +# facility: syslog facility used when logging to syslog (default: daemon) # # No space separation is done for arrays/tables - use one function argument per command line argument # # procd_close_instance(): # Complete the instance being prepared # +# procd_running(service, [instance]): +# Checks if service/instance is currently running +# # procd_kill(service, [instance]): # Kill a service instance (or all instances) # +# procd_send_signal(service, [instance], [signal]) +# Send a signal to a service instance (or all instances) +# -. $IPKG_INSTROOT/usr/share/libubox/jshn.sh +. "$IPKG_INSTROOT/usr/share/libubox/jshn.sh" PROCD_RELOAD_DELAY=1000 _PROCD_SERVICE= +procd_lock() { + local basescript=$(readlink "$initscript") + local service_name="$(basename ${basescript:-$initscript})" + + flock -n 1000 &> /dev/null + if [ "$?" != "0" ]; then + exec 1000>"$IPKG_INSTROOT/var/lock/procd_${service_name}.lock" + flock 1000 + if [ "$?" != "0" ]; then + logger "warning: procd flock for $service_name failed" + fi + fi +} + _procd_call() { local old_cb @@ -44,6 +68,7 @@ _procd_call() { } _procd_wrapper() { + procd_lock while [ -n "$1" ]; do eval "$1() { _procd_call _$1 \"\$@\"; }" shift @@ -76,6 +101,9 @@ _procd_close_service() { _procd_open_trigger service_triggers _procd_close_trigger + _procd_open_data + service_data + _procd_close_data _procd_ubus_call ${1:-set} } @@ -131,6 +159,18 @@ _procd_close_trigger() { json_close_array } +_procd_open_data() { + let '_procd_data_open = _procd_data_open + 1' + [ "$_procd_data_open" -gt 1 ] && return + json_add_object "data" +} + +_procd_close_data() { + let '_procd_data_open = _procd_data_open - 1' + [ "$_procd_data_open" -lt 1 ] || return + json_close_object +} + _procd_open_validate() { json_select .. json_add_array "validate" @@ -210,10 +250,13 @@ _procd_set_param() { json_add_string "" "$@" json_close_array ;; - nice|reload_signal) + nice|term_timeout) json_add_int "$type" "$1" ;; - pidfile|user|seccomp|capabilities) + reload_signal) + json_add_int "$type" $(kill -l "$1") + ;; + pidfile|user|group|seccomp|capabilities|facility) json_add_string "$type" "$1" ;; stdout|stderr|no_new_privs) @@ -245,9 +288,8 @@ _procd_add_interface_trigger() { json_close_array json_close_array - json_close_array - _procd_add_timeout + json_close_array } _procd_add_reload_interface_trigger() { @@ -277,10 +319,8 @@ _procd_add_config_trigger() { json_close_array json_close_array - - json_close_array - _procd_add_timeout + json_close_array } _procd_add_raw_trigger() { @@ -348,8 +388,10 @@ _procd_close_instance() { if json_select respawn ; then json_get_values respawn_vals if [ -z "$respawn_vals" ]; then + local respawn_threshold=$(uci_get system.@service[0].respawn_threshold) + local respawn_timeout=$(uci_get system.@service[0].respawn_timeout) local respawn_retry=$(uci_get system.@service[0].respawn_retry) - _procd_add_array_data 3600 5 ${respawn_retry:-5} + _procd_add_array_data ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} fi json_select .. fi @@ -363,6 +405,18 @@ _procd_add_instance() { _procd_close_instance } +procd_running() { + local service="$1" + local instance="${2:-instance1}" + local running + + json_init + json_add_string name "$service" + running=$(_procd_ubus_call list | jsonfilter -e "@.$service.instances.${instance}.running") + + [ "$running" = "true" ] +} + _procd_kill() { local service="$1" local instance="$2" @@ -373,6 +427,47 @@ _procd_kill() { _procd_ubus_call delete } +_procd_send_signal() { + local service="$1" + local instance="$2" + local signal="$3" + + case "$signal" in + [A-Z]*) signal="$(kill -l "$signal" 2>/dev/null)" || return 1;; + esac + + json_init + json_add_string name "$service" + [ -n "$instance" -a "$instance" != "*" ] && json_add_string instance "$instance" + [ -n "$signal" ] && json_add_int signal "$signal" + _procd_ubus_call signal +} + +_procd_status() { + local service="$1" + local instance="$2" + local data + + json_init + [ -n "$service" ] && json_add_string name "$service" + + data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"]') + [ -z "$data" ] && { echo "inactive"; return 3; } + + data=$(echo "$data" | jsonfilter -e '$.instances') + if [ -z "$data" ]; then + [ -z "$instance" ] && { echo "active with no instances"; return 0; } + data="[]" + fi + + [ -n "$instance" ] && instance="\"$instance\"" || instance='*' + if [ -z "$(echo "$data" | jsonfilter -e '$['"$instance"']')" ]; then + echo "unknown instance $instance"; return 4 + else + echo "running"; return 0 + fi +} + procd_open_data() { local name="$1" json_set_namespace procd __procd_old_cb @@ -406,7 +501,7 @@ procd_add_mdns_service() { json_add_int port "$port" [ -n "$1" ] && { json_add_array txt - for txt in $@; do json_add_string "" $txt; done + for txt in "$@"; do json_add_string "" "$txt"; done json_select .. } json_select .. @@ -415,7 +510,7 @@ procd_add_mdns_service() { procd_add_mdns() { procd_open_data json_add_object "mdns" - procd_add_mdns_service $@ + procd_add_mdns_service "$@" json_close_object procd_close_data } @@ -435,6 +530,23 @@ uci_validate_section() return $_error } +uci_load_validate() { + local _package="$1" + local _type="$2" + local _name="$3" + local _function="$4" + local _option + local _result + shift; shift; shift; shift + for _option in "$@"; do + eval "local ${_option%%:*}" + done + uci_validate_section "$_package" "$_type" "$_name" "$@" + _result=$? + [ -n "$_function" ] || return $_result + eval "$_function \"\$_name\" \"\$_result\"" +} + _procd_wrapper \ procd_open_service \ procd_close_service \ @@ -457,4 +569,5 @@ _procd_wrapper \ procd_append_param \ procd_add_validation \ procd_set_config_changed \ - procd_kill + procd_kill \ + procd_send_signal