diff --git a/ssm b/ssm index 2abfbc9..a860acf 100755 --- a/ssm +++ b/ssm @@ -9,7 +9,7 @@ usage() { cat <<- EOF Usage: ssm EOF -} +}; readonly usage; var() { declare var_function=$1; shift @@ -82,6 +82,7 @@ var() { (is_fs_object) [[ -e \"\$_var\" ]];; (is_file) [[ -f \"\$_var\" ]];; (is_dir|is_directory) [[ -d \"\$_var\" ]];; + (is_empty) [[ -z \"\$_var\" ]];; (*) die 71 \"Syntax error in ${var_function}!\";; esac @@ -128,7 +129,7 @@ spawn() { else exec "$@" >"$service_logfile_out" 2>"$service_logfile_err" fi -} +}; readonly spawn; ## Run the command and wait for it to die svc() { @@ -170,7 +171,7 @@ svc() { # We need to wait for the service to write down its pidfile until service_pidfile is file; do (( counter >= service_pidfile_timeout*10 )) && { - printf 'No pidfile' > "$service_failed_flag" + printf '127' > "$service_exit_file" break } counter++ @@ -189,10 +190,10 @@ svc() { else job_success = 0 fail_counter++ - - printf '%s' "$job_exit" > "$service_failed_flag" fi + printf '%s' "$job_exit" > "$service_exit_file" + # Back off if the service exits too much AND too quickly. service_respawn_force || { if (( fail_counter >= 3 )); then @@ -209,9 +210,6 @@ svc() { (on-failure) job_success && break;; esac - # Remove the failed flag, we're going to attempt a restart. - rm -f "$service_failed_flag" - # Record the time every time we restart the loop printf -v last_respawn '%(%s)T' done @@ -257,6 +255,10 @@ timer() { return 0 }; readonly -f timer +## Set a service's ready flag. +set_ready() { printf '1' > "$service_ready_flag"; } +readonly -f set_ready + ## Is a service ready? is_ready() { service_ready_flag is file; } readonly -f is_ready @@ -359,7 +361,7 @@ start() { if service_oneshot; then spawn "${service_command[@]}"; res=$? (( res )) && { - printf '%s' "$res" > "$service_failed_flag" + printf '%s' "$res" > "$service_exit_file" return "$res" } printf '1' > "$service_enabled_flag" @@ -367,7 +369,7 @@ start() { svc "${service_command[@]}" & if timer "$service_ready_timeout" ready; then - printf '1' > "$service_ready_flag" + set_ready else return 5 fi @@ -488,6 +490,7 @@ status() { service_enabled && return 0 service_stopped && return 7 service_failed && return 9 + service_exit_last is empty || return 11 return 1 } @@ -499,7 +502,7 @@ qstatus() { nullexec status; } ready() { :; } ## Reset failes -reset-failed() { rm -f "$service_failed_flag"; } +reset-failed() { rm -f "$service_exit_file"; } # Main code ## Empty declarations @@ -517,7 +520,8 @@ var service_pid \ service_ready_flag \ service_enabled_flag \ service_stopped_flag \ - service_failed_flag \ + service_exit_file \ + service_exit_last \ service_cgroup_name \ service_cgroup_procs \ service_cgroup_path \ @@ -688,7 +692,7 @@ service_logfile_err := "$service_logfile_out" service_ready_flag := "$rundir/$service_name.ready" service_enabled_flag := "$rundir/$service_name.enabled" service_stopped_flag := "$rundir/$service_name.stopped" -service_failed_flag := "$rundir/$service_name.failed" +service_exit_file := "$rundir/$service_name.exit" service_cgroup_name := "$service_name" service_cgroup_path := "$cgroup_home/$service_name" service_success_exit := 0 @@ -721,10 +725,14 @@ if service_stopped_flag is file; then service_stopped = 1 fi -# Maybe it has failed? -if service_failed_flag is file; then - # :( - service_failed = 1 +# Check if the service has failed +if service_exit_file is file; then + read -r service_exit_last < "$service_exit_file" + + if ! service_success_exit u "$service_exit_last"; then + # :( + service_failed = 1 + fi fi # Check cgroups, if enabled @@ -800,7 +808,8 @@ case "$2" in 0 "$service_name is running" \ 1 "$service_name is not running" \ 7 "$service_name was stopped" \ - 9 "$service_name has failed" + 9 "$service_name has failed with code: $service_exit_last" \ + 11 "$service_name has exited with code: $service_exit_last" fi ;; esac