From: Kevin Day Date: Sat, 17 Apr 2021 23:44:52 +0000 (-0500) Subject: Update: implement with pid execution, simplify related rules. X-Git-Tag: 0.5.3~32 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=dba1a6e31854be4f60716a7126e96a9f882cb600;p=fll Update: implement with pid execution, simplify related rules. Implement the with pid execution. This expects the process to be spawned in the background. After some review, I decided to remove "use" and "create", replacing those with "pid_file". The reasons are: - For "use", the spawned service manages the pid file, so it would be overly complicated to try and manage it in addition to the spawned service. - For "create", if the process is to go into the background, in order to manage it then there would still need to be a running process (this defeats the purpose). When the termination signal is received, then inform any background process spawned by the controller program to exit, based on the existence of the pid file. --- diff --git a/level_3/controller/c/private-common.c b/level_3/controller/c/private-common.c index a23e5bb..cd5d5b7 100644 --- a/level_3/controller/c/private-common.c +++ b/level_3/controller/c/private-common.c @@ -306,6 +306,8 @@ extern "C" { controller_cache_delete_simple(&process->cache); controller_rule_delete_simple(&process->rule); + f_string_dynamic_resize(0, &process->path_pid); + f_macro_array_lengths_t_delete_simple(process->stack) } #endif // _di_controller_process_delete_simple_ diff --git a/level_3/controller/c/private-common.h b/level_3/controller/c/private-common.h index 7cb9b31..beecce0 100644 --- a/level_3/controller/c/private-common.h +++ b/level_3/controller/c/private-common.h @@ -71,7 +71,7 @@ extern "C" { #define controller_string_parameter "parameter" #define controller_string_path "path" #define controller_string_pause "pause" - #define controller_string_pid "pid" + #define controller_string_pid_file "pid_file" #define controller_string_processor "processor" #define controller_string_program "program" #define controller_string_ready "ready" @@ -160,7 +160,7 @@ extern "C" { #define controller_string_parameter_length 9 #define controller_string_path_length 4 #define controller_string_pause_length 5 - #define controller_string_pid_length 3 + #define controller_string_pid_file_length 8 #define controller_string_processor_length 9 #define controller_string_program_length 7 #define controller_string_ready_length 5 @@ -250,7 +250,7 @@ extern "C" { const static f_string_t controller_string_parameter_s = controller_string_parameter; const static f_string_t controller_string_path_s = controller_string_path; const static f_string_t controller_string_pause_s = controller_string_pause; - const static f_string_t controller_string_pid_s = controller_string_pid; + const static f_string_t controller_string_pid_file_s = controller_string_pid_file; const static f_string_t controller_string_processor_s = controller_string_processor; const static f_string_t controller_string_program_s = controller_string_program; const static f_string_t controller_string_ready_s = controller_string_ready; @@ -487,18 +487,17 @@ extern "C" { }; enum { - controller_rule_action_type_create = 1, - controller_rule_action_type_freeze, + controller_rule_action_type_freeze = 1, controller_rule_action_type_group, controller_rule_action_type_kill, controller_rule_action_type_pause, + controller_rule_action_type_pid_file, controller_rule_action_type_reload, controller_rule_action_type_restart, controller_rule_action_type_resume, controller_rule_action_type_start, controller_rule_action_type_stop, controller_rule_action_type_thaw, - controller_rule_action_type_use, controller_rule_action_type_user, controller_rule_action_type_with, }; @@ -743,6 +742,13 @@ extern "C" { #endif // _di_controller_rules_t_ /** + * A set of codes representing different with flags. + */ +#ifndef _di_controller_with_defines_ + #define controller_with_full_path 0x1 +#endif // _di_controller_with_defines_ + +/** * A Rule Process. * * This refers to "process" as in the processing of a single rule for the given Rule ID and does not refer to "process" as in a CPU Process. @@ -805,6 +811,8 @@ extern "C" { controller_cache_t cache; f_array_lengths_t stack; + f_string_dynamic_t path_pid; + controller_rule_t rule; void *main_data; @@ -824,6 +832,7 @@ extern "C" { f_thread_condition_t_initialize, \ controller_cache_t_initialize, \ f_array_lengths_t_initialize, \ + f_string_dynamic_t_initialize, \ controller_rule_t_initialize, \ 0, \ 0, \ diff --git a/level_3/controller/c/private-controller.c b/level_3/controller/c/private-controller.c index 8776cf6..63469fb 100644 --- a/level_3/controller/c/private-controller.c +++ b/level_3/controller/c/private-controller.c @@ -246,6 +246,56 @@ extern "C" { } #endif // _di_controller_file_pid_delete_ +#ifndef _di_controller_file_pid_read_ + f_status_t controller_file_pid_read(const f_string_static_t path, pid_t *pid) { + + *pid = 0; + + f_status_t status = f_file_exists(path.string); + if (F_status_is_error(status)) return status; + + if (status != F_true) { + return F_data_not; + } + + f_file_t pid_file = f_file_t_initialize; + + status = f_file_stream_open(path.string, f_file_open_mode_read_s, &pid_file); + if (F_status_is_error(status)) return status; + + f_string_dynamic_t pid_buffer = f_string_dynamic_t_initialize; + + status = f_file_stream_read(pid_file, 1, &pid_buffer); + + if (F_status_is_error_not(status)) { + status = f_file_stream_close(F_true, &pid_file); + } + + if (F_status_is_error_not(status)) { + f_number_unsigned_t number = 0; + f_string_range_t range = f_macro_string_range_t_initialize(pid_buffer.used); + + for (; range.start < pid_buffer.used; ++range.start) { + if (!isspace(pid_buffer.string[range.start])) break; + } // for + + for (; range.stop > 0; --range.stop) { + if (!isspace(pid_buffer.string[range.stop])) break; + } // for + + status = fl_conversion_string_to_decimal_unsigned(pid_buffer.string, range, &number); + + if (F_status_is_error_not(status)) { + *pid = (pid_t) number; + } + } + + f_macro_string_dynamic_t_delete_simple(pid_buffer); + + return status; + } +#endif // _di_controller_file_pid_read_ + #ifndef _di_controller_find_process_ f_status_t controller_find_process(const f_string_static_t alias, const controller_processs_t processs, f_array_length_t *at) { diff --git a/level_3/controller/c/private-controller.h b/level_3/controller/c/private-controller.h index 5d1edfc..09d5b7e 100644 --- a/level_3/controller/c/private-controller.h +++ b/level_3/controller/c/private-controller.h @@ -160,12 +160,33 @@ extern "C" { * Errors (with error bit) from: f_file_stream_close(). * Errors (with error bit) from: f_file_stream_open(). * Errors (with error bit) from: f_file_stream_read(). + * Errors (with error bit) from: fl_conversion_string_to_decimal_unsigned() */ #ifndef _di_controller_file_pid_delete_ f_status_t controller_file_pid_delete(const pid_t pid, const f_string_static_t path) f_gcc_attribute_visibility_internal; #endif // _di_controller_file_pid_delete_ /** + * Read the PID from a PID file. + * + * @param path + * The file path to the pid file to create. + * @param pid + * The PID to be read. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_file_stream_close(). + * Errors (with error bit) from: f_file_stream_open(). + * Errors (with error bit) from: f_file_stream_read(). + * Errors (with error bit) from: fl_conversion_string_to_decimal_unsigned() + */ +#ifndef _di_controller_file_pid_read_ + f_status_t controller_file_pid_read(const f_string_static_t path, pid_t *pid) f_gcc_attribute_visibility_internal; +#endif // _di_controller_file_pid_read_ + +/** * Find an existing process. * * Do not confuse this with a process in the context of a PID. diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index 9a203c3..95f5ea7 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -134,11 +134,6 @@ extern "C" { f_string_static_t buffer = f_string_static_t_initialize; switch (type) { - case controller_rule_action_type_create: - buffer.string = controller_string_create_s; - buffer.used = controller_string_create_length; - break; - case controller_rule_action_type_group: buffer.string = controller_string_group_s; buffer.used = controller_string_group_length; @@ -149,6 +144,11 @@ extern "C" { buffer.used = controller_string_kill_length; break; + case controller_rule_action_type_pid_file: + buffer.string = controller_string_pid_file_s; + buffer.used = controller_string_pid_file_length; + break; + case controller_rule_action_type_restart: buffer.string = controller_string_restart_s; buffer.used = controller_string_restart_length; @@ -169,11 +169,6 @@ extern "C" { buffer.used = controller_string_stop_length; break; - case controller_rule_action_type_use: - buffer.string = controller_string_use_s; - buffer.used = controller_string_use_length; - break; - case controller_rule_action_type_user: buffer.string = controller_string_user_s; buffer.used = controller_string_user_length; @@ -771,9 +766,8 @@ extern "C" { f_array_length_t k = 0; f_string_dynamic_t *pid_file = 0; - uint8_t pid_type = 0; - bool with_full_path = F_false; + uint8_t with = 0; // child processes should receive all signals and handle the signals as they see fit. f_signal_how_t signals = f_signal_how_t_initialize; @@ -845,7 +839,7 @@ extern "C" { if (process->rule.items.array[i].type == controller_rule_item_type_setting) continue; - with_full_path = F_false; + with = 0; for (j = 0; j < process->rule.items.array[i].actions.used; ++j) { @@ -853,13 +847,9 @@ extern "C" { for (k = 0; k < process->rule.items.array[i].actions.array[j].parameters.used; ++k) { if (fl_string_dynamic_compare_string(controller_string_full_path_s, process->rule.items.array[i].actions.array[j].parameters.array[k], controller_string_full_path_length) == F_equal_to) { - with_full_path = F_true; - - break; + with |= controller_with_full_path; } } // for - - if (with_full_path) break; } } // for @@ -875,7 +865,7 @@ extern "C" { execute_set.parameter.data = 0; execute_set.parameter.option = fl_execute_parameter_option_threadsafe | fl_execute_parameter_option_return; - if (with_full_path) { + if (with & controller_with_full_path) { execute_set.parameter.option |= fl_execute_parameter_option_path; } @@ -915,11 +905,10 @@ extern "C" { } else if (process->rule.items.array[i].type == controller_rule_item_type_service) { pid_file = 0; - pid_type = 0; for (k = 0; k < process->rule.items.array[i].actions.used; ++k) { - if (process->rule.items.array[i].actions.array[k].type != controller_rule_action_type_create && process->rule.items.array[i].actions.array[k].type != controller_rule_action_type_use) { + if (process->rule.items.array[i].actions.array[k].type != controller_rule_action_type_pid_file) { continue; } @@ -928,11 +917,10 @@ extern "C" { } pid_file = &process->rule.items.array[i].actions.array[k].parameters.array[0]; - pid_type = process->rule.items.array[i].actions.array[k].type; } // for if (pid_file) { - status = controller_rule_execute_pid_with(pid_file, pid_type, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], 0, process->rule.items.array[i].actions.array[j].parameters, options, main, &execute_set, process); + status = controller_rule_execute_pid_with(*pid_file, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], 0, process->rule.items.array[i].actions.array[j].parameters, options, with, main, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; @@ -956,11 +944,10 @@ extern "C" { } else if (process->rule.items.array[i].type == controller_rule_item_type_utility) { pid_file = 0; - pid_type = 0; for (k = 0; k < process->rule.items.array[i].actions.used; ++k) { - if (process->rule.items.array[i].actions.array[k].type != controller_rule_action_type_create && process->rule.items.array[i].actions.array[k].type != controller_rule_action_type_use) { + if (process->rule.items.array[i].actions.array[k].type != controller_rule_action_type_pid_file) { continue; } @@ -969,13 +956,12 @@ extern "C" { } pid_file = &process->rule.items.array[i].actions.array[k].parameters.array[0]; - pid_type = process->rule.items.array[i].actions.array[k].type; } // for if (pid_file) { execute_set.parameter.data = &process->rule.items.array[i].actions.array[j].parameters.array[0]; - status = controller_rule_execute_pid_with(pid_file, pid_type, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, main, &execute_set, process); + status = controller_rule_execute_pid_with(*pid_file, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, with, main, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; @@ -1172,6 +1158,9 @@ extern "C" { if (!WIFEXITED(result)) { status = F_status_set_error(F_failure); } + else { + status = F_none; + } } else { if (!main.thread->enabled) { @@ -1223,7 +1212,7 @@ extern "C" { #endif // _di_controller_rule_execute_foreground_ #ifndef _di_controller_rule_execute_pid_with_ - f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t *pid_file, const uint8_t pid_type, const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const controller_main_t main, controller_execute_set_t * const execute_set, controller_process_t *process) { + f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const uint8_t with, const controller_main_t main, controller_execute_set_t * const execute_set, controller_process_t *process) { f_status_t status = F_none; f_status_t status_lock = F_none; @@ -1231,7 +1220,29 @@ extern "C" { int result = 0; pid_t id_child = 0; - // @todo check to see if pid file exists. + process->path_pid.used = 0; + + status = f_file_exists(pid_file.string); + + if (F_status_is_error(status)) { + fll_error_file_print(main.data->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file); + + return status; + } + + if (status == F_true) { + fll_error_file_print(main.data->error, F_file_found, "f_file_exists", F_true, pid_file.string, "create PID", fll_error_file_type_file); + + return F_status_set_error(F_file_found); + } + + status = controller_string_dynamic_append_terminated(pid_file, &process->path_pid); + + if (F_status_is_error(status)) { + fll_error_print(main.data->error, F_status_set_fine(status), "controller_string_dynamic_append_terminated", F_true); + + return status; + } if (options & controller_process_option_simulate) { @@ -1297,7 +1308,7 @@ extern "C" { controller_lock_error_critical_print(main.data->error, F_status_set_fine(status_lock), F_true, main.thread); } - // have the parent wait for the child process to finish. @todo do not wait, this is a background execution! instead, wait for pid file or timeout (or perhaps optional create the pid file). + // the child process should perform the change into background, therefore it is safe to wait for the child to exit (another process is spawned). waitpid(id_child, &result, 0); if (!main.thread->enabled) { @@ -1327,7 +1338,7 @@ extern "C" { return F_status_set_error(F_lock); } - // remove the pid now that waidpid() has returned. @todo do not clear until forked execution is known to have exited, this is a background execution + // remove the pid now that waidpid() has returned. process->child = 0; f_thread_unlock(&process->lock); @@ -1340,11 +1351,13 @@ extern "C" { } // this must explicitly check for 0 (as opposed to checking (!result)). + // @todo expand this to provide user more control over what is or is not an error to designate as a failure. if (!WIFEXITED(result)) { status = F_status_set_error(F_failure); } - - // @fixme needs a custom option to desginate what is an error. + else { + status = F_none; + } } else { if (!main.thread->enabled) { @@ -1504,10 +1517,7 @@ extern "C" { break; } - if (fl_string_dynamic_compare_string(controller_string_create_s, cache->action.name_action, controller_string_create_length) == F_equal_to) { - type = controller_rule_action_type_create; - } - else if (fl_string_dynamic_compare_string(controller_string_group_s, cache->action.name_action, controller_string_group_length) == F_equal_to) { + if (fl_string_dynamic_compare_string(controller_string_group_s, cache->action.name_action, controller_string_group_length) == F_equal_to) { type = controller_rule_action_type_group; } else if (fl_string_dynamic_compare_string(controller_string_kill_s, cache->action.name_action, controller_string_kill_length) == F_equal_to) { @@ -1516,6 +1526,9 @@ extern "C" { else if (fl_string_dynamic_compare_string(controller_string_pause_s, cache->action.name_action, controller_string_pause_length) == F_equal_to) { type = controller_rule_action_type_pause; } + else if (fl_string_dynamic_compare_string(controller_string_pid_file_s, cache->action.name_action, controller_string_pid_file_length) == F_equal_to) { + type = controller_rule_action_type_pid_file; + } else if (fl_string_dynamic_compare_string(controller_string_restart_s, cache->action.name_action, controller_string_restart_length) == F_equal_to) { type = controller_rule_action_type_restart; } @@ -1531,9 +1544,6 @@ extern "C" { else if (fl_string_dynamic_compare_string(controller_string_stop_s, cache->action.name_action, controller_string_stop_length) == F_equal_to) { type = controller_rule_action_type_stop; } - else if (fl_string_dynamic_compare_string(controller_string_use_s, cache->action.name_action, controller_string_use_length) == F_equal_to) { - type = controller_rule_action_type_use; - } else if (fl_string_dynamic_compare_string(controller_string_user_s, cache->action.name_action, controller_string_user_length) == F_equal_to) { type = controller_rule_action_type_user; } @@ -1560,7 +1570,7 @@ extern "C" { } if (multiple) { - if (type == controller_rule_action_type_create || type == controller_rule_action_type_group || type == controller_rule_action_type_use || type == controller_rule_action_type_user) { + if (type == controller_rule_action_type_group || type == controller_rule_action_type_pid_file || type == controller_rule_action_type_user) { if (main.data->error.verbosity != f_console_verbosity_quiet) { f_thread_mutex_lock(&main.thread->lock.print); diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h index f32b12c..2eb8c87 100644 --- a/level_3/controller/c/private-rule.h +++ b/level_3/controller/c/private-rule.h @@ -428,8 +428,6 @@ extern "C" { * * @param pid_file * The path to the PID file. - * @param pid_type - * The type of the PID file, either "controller_rule_action_type_create" or "controller_rule_action_type_use". * @param type * The item type code. * @param action @@ -448,6 +446,8 @@ extern "C" { * @param options * A number using bits to represent specific boolean options. * If bit controller_process_option_simulate, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). + * @param with + * The "with" option flags. * @param main * The main data. * @param execute_set @@ -457,18 +457,18 @@ extern "C" { * * @return * F_none on success. - * F_busy on successful execute in asynchronous mode (executed process may or may not fail later on). * F_child on child process exiting. * F_signal on (exit) signal received. * * F_lock (with error bit) if failed to re-establish read lock on process->lock while returning. + * F_file_found (with error bit) if the PID file already exists. * * Errors (with error bit) from: fll_execute_program(). * * @see fll_execute_program() */ #ifndef _di_controller_rule_execute_pid_with_ - extern f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t *pid_file, const uint8_t pid_type, const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const controller_main_t main, controller_execute_set_t * const execute_set, controller_process_t *process) f_gcc_attribute_visibility_internal; + extern f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, const uint8_t with, const controller_main_t main, controller_execute_set_t * const execute_set, controller_process_t *process) f_gcc_attribute_visibility_internal; #endif // _di_controller_rule_execute_pid_with_ /** diff --git a/level_3/controller/c/private-thread.c b/level_3/controller/c/private-thread.c index 077d93d..a11f091 100644 --- a/level_3/controller/c/private-thread.c +++ b/level_3/controller/c/private-thread.c @@ -57,6 +57,14 @@ extern "C" { continue; } + // if process has a pid file, then it is running in the background, only cleanup if the pid file no longer exists. + if (process->path_pid.used && f_file_exists(process->path_pid.string) == F_true) { + f_thread_unlock(&process->active); + f_thread_unlock(&process->lock); + + continue; + } + f_thread_unlock(&process->lock); // close any still open thread. @@ -88,6 +96,12 @@ extern "C" { controller_cache_delete_simple(&process->cache); f_type_array_lengths_resize(0, &process->stack); + // deallocate the pid file. + if (process->path_pid.used) { + process->path_pid.used = 0; + f_string_dynamic_resize(0, &process->path_pid); + } + // deallocate any rules in the space that is declared to be unused. if (i >= main->thread->processs.used) { controller_rule_delete_simple(&process->rule); @@ -349,6 +363,7 @@ extern "C" { controller_process_t *process = 0; f_array_length_t i = 0; + pid_t pid = 0; if (main->thread->id_cleanup) { f_thread_cancel(main->thread->id_cleanup); @@ -371,6 +386,14 @@ extern "C" { if (process->child > 0) { f_signal_send(F_signal_termination, process->child); } + + if (process->path_pid.used && f_file_exists(process->path_pid.string) == F_true) { + status = controller_file_pid_read(process->path_pid, &pid); + + if (pid) { + f_signal_send(F_signal_termination, pid); + } + } } // for for (i = 0; i < main->thread->processs.used; ++i) { @@ -401,6 +424,8 @@ extern "C" { process = main->thread->processs.array[i]; do { + if (!process->id_thread) break; + controller_time(0, controller_thread_exit_process_cancel_wait, &time); status = f_thread_join_timed(process->id_thread, time, 0); @@ -410,9 +435,41 @@ extern "C" { process->id_thread = 0; } - spent++; + ++spent; } while (status == F_time && spent < controller_thread_exit_process_cancel_total); + + if (process->path_pid.used) { + for (; spent < controller_thread_exit_process_cancel_total; ++spent) { + + if (f_file_exists(process->path_pid.string) == F_true) { + status = controller_file_pid_read(process->path_pid, &pid); + + if (pid) { + + // a hackish way to determine if the pid exists while waiting. + if (getpgid(pid) >= 0) { + time.tv_sec = 0; + time.tv_nsec = controller_thread_exit_process_cancel_wait; + + nanosleep(&time, 0); + } + else { + f_file_remove(process->path_pid.string); + process->path_pid.used = 0; + + break; + } + } + else { + break; + } + } + else { + break; + } + } // for + } } // for for (i = 0; i < main->thread->processs.size; ++i) { @@ -436,6 +493,19 @@ extern "C" { process->child = 0; process->id_thread = 0; } + + if (process->path_pid.used) { + if (f_file_exists(process->path_pid.string) == F_true) { + status = controller_file_pid_read(process->path_pid, &pid); + + if (pid) { + f_signal_send(F_signal_kill, pid); + } + + f_file_remove(process->path_pid.string); + process->path_pid.used = 0; + } + } } // for } #endif // _di_controller_thread_process_cancel_ diff --git a/level_3/controller/data/settings/example/rules/service/sshd.rule b/level_3/controller/data/settings/example/rules/service/sshd.rule index 2961de4..5a5f3b6 100644 --- a/level_3/controller/data/settings/example/rules/service/sshd.rule +++ b/level_3/controller/data/settings/example/rules/service/sshd.rule @@ -9,6 +9,6 @@ setting: nice 15 service: - use /var/run/sshd.pid + pid_file /var/run/sshd.pid with full_path start sshd diff --git a/level_3/controller/data/settings/example/rules/utility/sleeper_1.rule b/level_3/controller/data/settings/example/rules/utility/sleeper_1.rule index d68a12c..f90ceca 100644 --- a/level_3/controller/data/settings/example/rules/utility/sleeper_1.rule +++ b/level_3/controller/data/settings/example/rules/utility/sleeper_1.rule @@ -1,12 +1,12 @@ # fss-000d -# sleeper rule whose program creates its own PID file, sleep for a while, removes PID file, and returns. +# sleeper rule whose program creates its own PID file, runs in the background, sleep for a while, removes PID file, and returns. setting: name "Sleeper #1" nice 10 utility: - use /tmp/sleeper_1.pid + pid_file /tmp/sleeper_1.pid start { \#!/bin/bash @@ -16,7 +16,7 @@ utility: return 1 fi - echo "$$" > /tmp/sleeper_1.pid + echo "$BASHPID" > /tmp/sleeper_1.pid echo "Sleeper 1, now sleeping." sleep 20m @@ -26,5 +26,5 @@ utility: return 0 \} - main + main & } diff --git a/level_3/controller/data/settings/example/rules/utility/sleeper_2.rule b/level_3/controller/data/settings/example/rules/utility/sleeper_2.rule index 7eb1cae..be70fe1 100644 --- a/level_3/controller/data/settings/example/rules/utility/sleeper_2.rule +++ b/level_3/controller/data/settings/example/rules/utility/sleeper_2.rule @@ -1,22 +1,30 @@ # fss-000d -# sleeper rule whose program does not create its own PID file, sleeps for a while and returns. +# sleeper rule whose program creates its own PID file, runs in the background, sleep for a while, removes PID file, and returns. setting: name "Sleeper #2" nice 10 utility: - create /tmp/sleeper_2.pid + pid_file /tmp/sleeper_2.pid start { \#!/bin/bash main() { + if [[ -f /tmp/sleeper_2.pid ]] ; then + echo "Failure: pid file '/tmp/sleeper_1.pid' already exists." + return 1 + fi + + echo "$BASHPID" > /tmp/sleeper_2.pid + echo "Sleeper 2, now sleeping." sleep 25m echo "Sleeper 2, done sleeping." + rm -f /tmp/sleeper_2.pid return 0 \} - main + main & } diff --git a/level_3/controller/data/settings/rules/program/terminal.rule b/level_3/controller/data/settings/rules/program/terminal.rule index c4d3b6e..50fbcb3 100644 --- a/level_3/controller/data/settings/rules/program/terminal.rule +++ b/level_3/controller/data/settings/rules/program/terminal.rule @@ -8,21 +8,21 @@ setting: capability "all=" service: - use /var/run/tty/tty1.pid + pid_file /var/run/tty/tty1.pid start qingy tty1 -d -l -n -t service: - use /var/run/tty/tty2.pid + pid_file /var/run/tty/tty2.pid start qingy tty2 -d -l -n -t service: - use /var/run/tty/tty3.pid + pid_file /var/run/tty/tty3.pid start qingy tty3 -d -l -n -t service: - use /var/run/tty/tty4.pid + pid_file /var/run/tty/tty4.pid start qingy tty4 -d -l -n -t diff --git a/level_3/controller/data/settings/rules/service/dbus.rule b/level_3/controller/data/settings/rules/service/dbus.rule index ed434be..d9cdb11 100644 --- a/level_3/controller/data/settings/rules/service/dbus.rule +++ b/level_3/controller/data/settings/rules/service/dbus.rule @@ -9,6 +9,6 @@ setting: nice 15 service: - use /var/run/dbus/dbus.pid + pid_file /var/run/dbus/dbus.pid start dbus-daemon --system --fork diff --git a/level_3/controller/data/settings/rules/service/logger.rule b/level_3/controller/data/settings/rules/service/logger.rule index 23abe8f..3d0f7cd 100644 --- a/level_3/controller/data/settings/rules/service/logger.rule +++ b/level_3/controller/data/settings/rules/service/logger.rule @@ -11,6 +11,6 @@ setting: service: # @todo consider adding support for IKI to make "/var/run/logger/logger.pid" a variable. - use /var/run/logger/logger.pid + pid_file /var/run/logger/logger.pid start metalog -B -p /var/run/logger/logger.pid -C /etc/logger.conf diff --git a/level_3/controller/data/settings/rules/service/mouse.rule b/level_3/controller/data/settings/rules/service/mouse.rule index f2e0061..06a392c 100644 --- a/level_3/controller/data/settings/rules/service/mouse.rule +++ b/level_3/controller/data/settings/rules/service/mouse.rule @@ -16,7 +16,7 @@ script: } service: - use /var/run/mouse/mouse.pid + pid_file /var/run/mouse/mouse.pid # @todo start gpm -m [device] -t [protocol] [options] diff --git a/level_3/controller/documents/rule.txt b/level_3/controller/documents/rule.txt index 8726e04..b0eb336 100644 --- a/level_3/controller/documents/rule.txt +++ b/level_3/controller/documents/rule.txt @@ -86,9 +86,7 @@ Rule Documentation: When "reload", "start", or "stop" Content are not provided, then no respective action is performed. Commands are conditionally available depending on the presence of these, such as if "stop" is not provided then "stop" (and "restart") will not be available for the "control" program(s) to use. - The "create" Content designates that this controller program to create the PID file after successfully starting a Service or Utility. - The "use" Content designates that the called program will provide the PID file after successfully starting the Service or Utility. - For both "create" and "program" the PID file is expected to only exist on success and the existence thereof designates the success or failure. + The "pid_file" Content designates the path to the PID file created by the called program. The "with" Content designates special flags designating very specific behavior to be applied to any single Rule Type. The following flags are supported: diff --git a/level_3/controller/specifications/rule.txt b/level_3/controller/specifications/rule.txt index c880022..6cc4e63 100644 --- a/level_3/controller/specifications/rule.txt +++ b/level_3/controller/specifications/rule.txt @@ -58,8 +58,7 @@ Rule Specification: "with": One or more Content representing special options for the Rule Type. The "service" and "utility" Rule Types allow the following the FSS-0001 (Extended)\: - "create": One Content representing the path to a PID file. - "use": One Content representing the path to a PID file. + "pid_file": One Content representing the path to a PID file. "with": One or more Content representing special options for the Rule Type. The "command" and "service" Rule Types allow the following the FSS-0003 (Extended List)\: