#!/bin/sh /etc/rc.common # Copyright (C) 2022 jjm2473@gmail.com USE_PROCD=1 START=49 extra_command "task_add" " [] Add and run a task, time_wait is wait time before auto delete stopped task, in seconds, -1 means forever" extra_command "task_del" " Stop and delete task" extra_command "task_status" "[] Dump task status, dump all tasks if no task_id specified" extra_command "task_gc" "Auto delete exipred (stopped and after timw_wait) tasks" extra_command "_task_onstop" " Update stop time, for internal usage" _task_add() { local task_id="${1}" local task_cmd="${2}" local time_wait="${3}" > "/var/log/tasks/$task_id.log" procd_open_instance "$task_id" procd_set_param data start=`date +'%s'` time_wait="$time_wait" procd_set_param command sh -c "exec /usr/libexec/taskd '$task_id' \"\$0\"" "$task_cmd" procd_set_param stderr 1 procd_close_instance } task_add() { local task_id="${1}" local task_cmd="${2}" local time_wait="${3}" [ -z "$task_id" -o -z "$task_cmd" ] && return 127 if service_running "$task_id"; then echo "already running" >&2 return 1 fi if ! mkdir -p /var/log/tasks; then echo "create /var/log/tasks failed!" >&2 return 1 fi rc_procd _task_add "$task_id" "$task_cmd" "$time_wait" return 0 } _task_del() { local service="${1}" local task_id="${2}" procd_kill "$service" "$task_id" > "/var/log/tasks/$task_id.log" rm -f "/var/log/tasks/$task_id.log" } task_del() { local task_id="${1}" [ -z "$task_id" ] && return 127 procd_lock _task_del "$(basename ${basescript:-$initscript})" "$task_id" if [ "$(_task_status "$task_id" | jsonfilter -e '$.running' 2>/dev/null)" = "true" ]; then return 1 else return 0 fi } _task_status() { local service="$(basename ${basescript:-$initscript})" local instance="$1" local data json_init json_add_string name "$service" data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"]') [ -z "$data" ] && return 1 data=$(echo "$data" | jsonfilter -e '$.instances') if [ -z "$data" ]; then if [ -z "$instance" ]; then echo "{}" return 0 fi return 1 fi if [ -z "$instance" ]; then echo "$data" else instance="\"$instance\"" echo "$data" | jsonfilter -e '$['"$instance"']' fi return 0 } task_status() { local task_id="${1}" _task_status "$task_id" } task_gc() { local service="$(basename ${basescript:-$initscript})" local task_id instance time_wait local data json_init [ -n "$service" ] && json_add_string name "$service" data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"]') [ -z "$data" ] && return 1 data=$(echo "$data" | jsonfilter -e '$.instances') [ -z "$data" ] && return 1 procd_lock ls /var/log/tasks/ | sed 's/.log$//g' | while read task_id; do instance=$(echo "$data" | jsonfilter -e '$["'"$task_id"'"]') [ "$(echo "$instance" | jsonfilter -e '$.running')" = "false" ] || continue time_wait=$(echo "$instance" | jsonfilter -e '$.data.time_wait') [ "$time_wait" = "-1" ] && continue [ $(($(date +'%s' -r "/var/log/tasks/$task_id.log") + ${time_wait:-0})) -lt `date +'%s'` ] && _task_del "$service" "$task_id" done } _insert_exit() { local exit_code="$2" eval "`jshn -r "$1" | grep -v json_init`" json_select data || { _procd_set_param data stop=`date +'%s'` exit_code="$exit_code" return } json_add_string stop `date +'%s'` json_add_string exit_code "$exit_code" json_select .. } _task_exit() { local task_id="$1" local exit_code="$2" local inst_json="$3" _procd_call json_add_object "$task_id" _procd_call _insert_exit "$inst_json" "$exit_code" _procd_call json_close_object } _task_onstop() { local task_id="${1}" local exit_code="${2}" [ -z "$task_id" ] && return 127 local service="$(basename ${basescript:-$initscript})" json_init json_add_string name "$service" data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"].instances["'"$task_id"'"]') [ -z "$data" ] && return 1 json_cleanup rc_procd _task_exit "$task_id" "$exit_code" "$data" }