From: Kevin Day Date: Wed, 10 Jul 2024 02:38:31 +0000 (-0500) Subject: Progress: Continue migrating the project, also updating files and licenses. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=1a3e781c12c8d43211e325825ee5aa3a96580e98;p=controller Progress: Continue migrating the project, also updating files and licenses. Synchronize the examples, the license files, the documentations, and the specifications. Fix some problems. I noticed that the example utility is not working as expect and so there will be more migration commits once I identify and solve this problem. --- diff --git a/data/documentation/man/man1/controller.1 b/data/documentation/man/man1/controller.1 index 80c49e5..dd207d1 100644 --- a/data/documentation/man/man1/controller.1 +++ b/data/documentation/man/man1/controller.1 @@ -99,4 +99,4 @@ The name of an \fBentry\fR. Written by Kevin Day. .SH COPYRIGHT .PP -Copyright \(co 2007-2023 Kevin Day, GNU LGPL Version 2.1 or later. +Copyright \(co 2007-2024 Kevin Day, GNU LGPL Version 2.1 or later. diff --git a/data/documentation/man/man5/controller-actions.5 b/data/documentation/man/man5/controller-actions.5 index eb79f8b..0c4870b 100644 --- a/data/documentation/man/man5/controller-actions.5 +++ b/data/documentation/man/man5/controller-actions.5 @@ -86,4 +86,4 @@ Should any \fBcontrol\fR or \fBcontroller\fR program implementation not support Written by Kevin Day. .SH COPYRIGHT .PP -Copyright \(co 2007-2023 Kevin Day, Open Standard License 1.0 or later. +Copyright \(co 2007-2024 Kevin Day, Open Standard License 1.0 or later. diff --git a/data/documentation/man/man5/controller-entry.5 b/data/documentation/man/man5/controller-entry.5 index 976bcf3..d3311e8 100644 --- a/data/documentation/man/man5/controller-entry.5 +++ b/data/documentation/man/man5/controller-entry.5 @@ -349,4 +349,4 @@ The Items: Written by Kevin Day. .SH COPYRIGHT .PP -Copyright \(co 2007-2023 Kevin Day, Open Standard License 1.0 or later. +Copyright \(co 2007-2024 Kevin Day, Open Standard License 1.0 or later. diff --git a/data/documentation/man/man5/controller-exit.5 b/data/documentation/man/man5/controller-exit.5 index a4969ea..de6bada 100644 --- a/data/documentation/man/man5/controller-exit.5 +++ b/data/documentation/man/man5/controller-exit.5 @@ -280,4 +280,4 @@ The Items: Written by Kevin Day. .SH COPYRIGHT .PP -Copyright \(co 2007-2023 Kevin Day, Open Standard License 1.0 or later. +Copyright \(co 2007-2024 Kevin Day, Open Standard License 1.0 or later. diff --git a/data/documentation/man/man5/controller-packet.5 b/data/documentation/man/man5/controller-packet.5 index c62cc93..2850a62 100644 --- a/data/documentation/man/man5/controller-packet.5 +++ b/data/documentation/man/man5/controller-packet.5 @@ -137,4 +137,4 @@ The \fBinit\fR type: Written by Kevin Day. .SH COPYRIGHT .PP -Copyright \(co 2007-2023 Kevin Day, Open Standard License 1.0 or later. +Copyright \(co 2007-2024 Kevin Day, Open Standard License 1.0 or later. diff --git a/data/documentation/man/man5/controller-rule.5 b/data/documentation/man/man5/controller-rule.5 index 47b81b5..5c8996b 100644 --- a/data/documentation/man/man5/controller-rule.5 +++ b/data/documentation/man/man5/controller-rule.5 @@ -242,4 +242,4 @@ The \fBrerun\fR Rule Type Content has the following structure: Written by Kevin Day. .SH COPYRIGHT .PP -Copyright \(co 2007-2023 Kevin Day, Open Standard License 1.0 or later. +Copyright \(co 2007-2024 Kevin Day, Open Standard License 1.0 or later. diff --git a/data/settings/controller/entries/default.entry b/data/settings/controller/entries/default.entry new file mode 100644 index 0000000..1330803 --- /dev/null +++ b/data/settings/controller/entries/default.entry @@ -0,0 +1,64 @@ +# fss-0005 +# +# A very basic boot process. +# + +settings: + pid ready + show init + + control init.socket + control_user 0 + control_group 0 + control_mode ug+rwx,o-rwx + +task: + reboot system reboot + shutdown system shutdown + +main: + timeout start 7 + timeout stop 7 + timeout kill 3 + + failsafe maintenance + + item boot + item net + item time + item keyboard + item console + +boot: + start boot root require + start boot proc asynchronous require + start boot devices asynchronous require + start boot file_system asynchronous + start boot modules wait + + start service logger + start service dbus asynchronous + + ready + +net: + start net all asynchronous + +time: + start task clock asynchronous + +keyboard: + start task keyboard asynchronous + +console: + start service mouse asynchronous + + start terminal two asynchronous + start terminal three asynchronous + start terminal four asynchronous + start terminal one require wait + +maintenance: + #execute /bin/agetty -8 -i -J tty1 linux + #execute /bin/setsid -c /bin/bash --login + execute /bin/bash --login diff --git a/data/settings/controller/entries/maintenance.entry b/data/settings/controller/entries/maintenance.entry new file mode 100644 index 0000000..2c6a6c7 --- /dev/null +++ b/data/settings/controller/entries/maintenance.entry @@ -0,0 +1,13 @@ +# fss-0005 +# +# A boot to bash process. +# + +settings: + pid disable + show init + +main: + #execute /bin/agetty -8 -i -J tty1 linux + #execute /bin/setsid -c /bin/bash --login + execute /bin/bash --login diff --git a/data/settings/controller/example/cgroup_example/entries/chromium.entry b/data/settings/controller/example/cgroup_example/entries/chromium.entry new file mode 100644 index 0000000..8e41837 --- /dev/null +++ b/data/settings/controller/example/cgroup_example/entries/chromium.entry @@ -0,0 +1,7 @@ +# fss-0005 + +settings: + mode helper + +main: + start program chromium asynchronous diff --git a/data/settings/controller/example/cgroup_example/entries/eclipse.entry b/data/settings/controller/example/cgroup_example/entries/eclipse.entry new file mode 100644 index 0000000..7a3aedb --- /dev/null +++ b/data/settings/controller/example/cgroup_example/entries/eclipse.entry @@ -0,0 +1,7 @@ +# fss-0005 + +settings: + mode helper + +main: + start program eclipse asynchronous diff --git a/data/settings/controller/example/cgroup_example/entries/firefox.entry b/data/settings/controller/example/cgroup_example/entries/firefox.entry new file mode 100644 index 0000000..5d5ff15 --- /dev/null +++ b/data/settings/controller/example/cgroup_example/entries/firefox.entry @@ -0,0 +1,7 @@ +# fss-0005 + +settings: + mode helper + +main: + start program firefox asynchronous diff --git a/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry b/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry new file mode 100644 index 0000000..7a59836 --- /dev/null +++ b/data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry @@ -0,0 +1,7 @@ +# fss-0005 + +settings: + mode program + +main: + start setup cgroups diff --git a/data/settings/controller/example/cgroup_example/rules/program/chromium.rule b/data/settings/controller/example/cgroup_example/rules/program/chromium.rule new file mode 100644 index 0000000..75d10f0 --- /dev/null +++ b/data/settings/controller/example/cgroup_example/rules/program/chromium.rule @@ -0,0 +1,8 @@ +# fss-000d + +settings: + name "Run Chromium" + cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/browser + +command: + start chromium --disable-features=UserAgentClientHint diff --git a/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule b/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule new file mode 100644 index 0000000..8b1020a --- /dev/null +++ b/data/settings/controller/example/cgroup_example/rules/program/eclipse.rule @@ -0,0 +1,8 @@ +# fss-000d + +settings: + name "Run Eclipse" + cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/eclipse + +command: + start eclipse diff --git a/data/settings/controller/example/cgroup_example/rules/program/firefox.rule b/data/settings/controller/example/cgroup_example/rules/program/firefox.rule new file mode 100644 index 0000000..79b19f9 --- /dev/null +++ b/data/settings/controller/example/cgroup_example/rules/program/firefox.rule @@ -0,0 +1,8 @@ +# fss-000d + +settings: + name "Run Firefox (ESR)" + cgroup existing user.slice/user-1000.slice/user@1000.service/user_you/group/browser + +command: + start firefox-esr diff --git a/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule b/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule new file mode 100644 index 0000000..87de765 --- /dev/null +++ b/data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule @@ -0,0 +1,122 @@ +# fss-000d +# +# A cgroups2 example for systemd-based system using example user with example subdirectories and example programs. +# +# This uses a 12-core system as an example. +# +# This is intended to be run as the user rather than as root. +# +# Example sizes: +# For 2GB: 2 * 1024 * 1024 * 1024. +# + +settings: + name "Setup Cgroups for User 1000, named "you"" + +script: + + start { + main() { + local user="you" + local group="you" + local path_cgroup="/sys/fs/cgroup/" + local path_slice_1="${path_cgroup}user.slice/" + local path_slice_2="${path_slice_1}user-1000.slice/" + #local path_slice_3="${path_slice_2}" # Some systemd's might work without the service directory. + local path_slice_3="${path_slice_2}user@1000.service/" # Some systemd's only give access to this service directory (the '@' is a problem and requires quoting). + local path_user="${path_slice_3}user_${user}/" + local path_group="${path_user}group/" + local path_top_subtree="${path_cgroup}cgroup.subtree_control" # Modifying this likely requires root privileges. + local directories="browser eclipse untrusted" + local d= + local i= + local subtree="+cpu +cpuset +memory +pids" + + # The user path is for restricting the user and should not grant permissions to user other than read and execute directory. + if [[ ! -d "${path_user}" ]] ; then + mkdir -p "${path_user}" + + if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_user}." ; return 1 ; fi + fi + + chmod -R u+rwX,g+rX-w,o-rwx "${path_user}" && + chgrp -R ${group} "${path_user}" + + if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_group}." ; return 1 ; fi + + # The group path is for the user to restrict processes they run and must have ownership with write access. + if [[ ! -d "${path_group}" ]] ; then + mkdir -p "${path_group}" + + if [[ $? -ne 0 ]] ; then echo "Failed mkdir ${path_group}." ; return 1 ; fi + fi + + # Must have common ancestor with write acces, so fix setup from systemd to work with this one. + chmod -R u+rw+X,g+rX-w,o-rwx "${path_group}" && + chown -R ${user}:${group} "${path_group}" + + if [[ $? -ne 0 ]] ; then echo "Failed change permission on ${path_group}." ; return 1 ; fi + + # Make sure the user can manipulate subtrees (May fail if any path outside of ${path_slice_1} lacks things wanted by ${subtree}). + echo ${subtree} >> "${path_slice_1}cgroup.subtree_control" + if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_1}cgroup.subtree_control." ; return 1 ; fi + + echo ${subtree} >> "${path_slice_2}cgroup.subtree_control" + if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_2}cgroup.subtree_control." ; return 1 ; fi + + echo ${subtree} >> "${path_slice_3}cgroup.subtree_control" + if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_3}cgroup.subtree_control." ; return 1 ; fi + + echo ${subtree} >> "${path_slice_4}cgroup.subtree_control" + if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_slice_4}cgroup.subtree_control." ; return 1 ; fi + + echo ${subtree} >> "${path_user}cgroup.subtree_control" + if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_user}cgroup.subtree_control." ; return 1 ; fi + + echo ${subtree} >> "${path_group}cgroup.subtree_control" + if [[ $? -ne 0 ]] ; then echo "Failed populate subtree of ${path_group}cgroup.subtree_control." ; return 1 ; fi + + for d in ${directories} ; do + i="${path_group}${d}/" + + if [[ ! -d ${i} ]] ; then + echo "Creating cgroup directory '${i}'." + + mkdir -p "${i}" && + chown -R ${user}:${group} "${i}" && + chmod -R u+rw+X,g+rX-w,o-rwx "${i}" && + chmod g+s "${i}" + + if [[ $? -ne 0 ]] ; then echo "Failed change permission on ${i}." ; return 1 ; fi + fi + + if [[ ${d} == "browser" ]] ; then + put_into "7516192768" "${i}memory.high" && + put_into "8589934592" "${i}memory.max" && + put_into "3-6" "${i}cpuset.cpus" + elif [[ ${d} == "eclipse" ]] ; then + put_into "3758096384" "${i}memory.high" && + put_into "4294967296" "${i}memory.max" && + put_into "5-8" "${i}cpuset.cpus" + else + put_into "858993459" "${i}memory.high" && + put_into "1073741824" "${i}memory.max" && + put_into "9-11" "${i}cpuset.cpus" + fi + + if [[ $? -ne 0 ]] ; then echo "Failed to restrictions for ${d} at ${i}." ; return 1 ; fi + done + + return 0 + \} + + put_into() { + if [[ -e ${2} ]] ; then + echo ${1} > ${2} || return 1 + fi + + return 0 + \} + + main + } diff --git a/data/settings/controller/example/entries/asynchronous-serial.entry b/data/settings/controller/example/entries/asynchronous-serial.entry new file mode 100644 index 0000000..b6b736f --- /dev/null +++ b/data/settings/controller/example/entries/asynchronous-serial.entry @@ -0,0 +1,11 @@ +# fss-0005 + +main: + start serial s_1 asynchronous + start serial s_2 asynchronous + start serial s_3 asynchronous + start serial s_4 asynchronous + start serial s_5 asynchronous + start serial s_6 asynchronous + + ready wait diff --git a/data/settings/controller/example/entries/asynchronous.entry b/data/settings/controller/example/entries/asynchronous.entry new file mode 100644 index 0000000..8d2756e --- /dev/null +++ b/data/settings/controller/example/entries/asynchronous.entry @@ -0,0 +1,17 @@ +# fss-0005 + +settings: + mode program + +main: + ready + + consider asynchronous sleep_8 asynchronous + consider asynchronous sleep_10 asynchronous + + start asynchronous sleep_1 asynchronous + start asynchronous sleep_2 asynchronous + start asynchronous sleep_3 asynchronous + start asynchronous sleep_5 asynchronous + start asynchronous sleep_8 asynchronous + start asynchronous sleep_10 asynchronous diff --git a/data/settings/controller/example/entries/delay-program.entry b/data/settings/controller/example/entries/delay-program.entry new file mode 100644 index 0000000..e5fb3b5 --- /dev/null +++ b/data/settings/controller/example/entries/delay-program.entry @@ -0,0 +1,8 @@ +# fss-0005 + +settings: + mode program + +main: + start delay short + start delay long diff --git a/data/settings/controller/example/entries/delay-service.entry b/data/settings/controller/example/entries/delay-service.entry new file mode 100644 index 0000000..da9ee04 --- /dev/null +++ b/data/settings/controller/example/entries/delay-service.entry @@ -0,0 +1,8 @@ +# fss-0005 + +settings: + mode service + +main: + start delay short + start delay long diff --git a/data/settings/controller/example/entries/environment.entry b/data/settings/controller/example/entries/environment.entry new file mode 100644 index 0000000..a6978df --- /dev/null +++ b/data/settings/controller/example/entries/environment.entry @@ -0,0 +1,14 @@ +# fss-0005 + +settings: + mode program + +main: + start environment default + start environment exported + start environment empty + start environment exporting + start environment fake-nothing + start environment fake-something + + start print newline diff --git a/data/settings/controller/example/entries/htop-alternate.entry b/data/settings/controller/example/entries/htop-alternate.entry new file mode 100644 index 0000000..3c8bed6 --- /dev/null +++ b/data/settings/controller/example/entries/htop-alternate.entry @@ -0,0 +1,19 @@ +# fss-0005 +# +# This example shows how htop can be started during the exit process rather than the entry. +# See the htop-alternate.exit example. + +settings: + mode program + + control htop.socket + control_user 0 + control_group 0 + control_mode ug+rwx,o-rwx + +main: + start serial s_1 asynchronous + start serial s_2 asynchronous + start serial s_3 asynchronous + + ready wait diff --git a/data/settings/controller/example/entries/htop-command.entry b/data/settings/controller/example/entries/htop-command.entry new file mode 100644 index 0000000..19dae00 --- /dev/null +++ b/data/settings/controller/example/entries/htop-command.entry @@ -0,0 +1,12 @@ +# fss-0005 + +settings: + mode program + + control htop.socket + control_user 0 + control_group 0 + control_mode ug+rwx,o-rwx + +main: + start command htop diff --git a/data/settings/controller/example/entries/htop.entry b/data/settings/controller/example/entries/htop.entry new file mode 100644 index 0000000..ff78686 --- /dev/null +++ b/data/settings/controller/example/entries/htop.entry @@ -0,0 +1,23 @@ +# fss-0005 + +settings: + mode program + + control htop.socket + control_user 0 + control_group 0 + control_mode ug+rwx,o-rwx + +main: + failsafe start_top + + start serial s_1 asynchronous require + start serial s_2 asynchronous require + start serial s_3 asynchronous require + + ready wait + + execute htop + +start_top: + execute top diff --git a/data/settings/controller/example/entries/iki.entry b/data/settings/controller/example/entries/iki.entry new file mode 100644 index 0000000..9a04ab8 --- /dev/null +++ b/data/settings/controller/example/entries/iki.entry @@ -0,0 +1,9 @@ +# fss-0005 + +settings: + mode program + +main: + ready + + start script iki diff --git a/data/settings/controller/example/entries/serial-alternate.entry b/data/settings/controller/example/entries/serial-alternate.entry new file mode 100644 index 0000000..ecfabbc --- /dev/null +++ b/data/settings/controller/example/entries/serial-alternate.entry @@ -0,0 +1,14 @@ +# fss-0005 + +settings: + mode program + +main: + start serial s_1 + start serial s_2 + start serial s_3 + start serial s_4 + start serial s_5 + start serial s_6 + + ready diff --git a/data/settings/controller/example/entries/serial.entry b/data/settings/controller/example/entries/serial.entry new file mode 100644 index 0000000..a63fe05 --- /dev/null +++ b/data/settings/controller/example/entries/serial.entry @@ -0,0 +1,12 @@ +# fss-0005 + +main: + consider serial s_1 + consider serial s_2 + consider serial s_3 + consider serial s_4 + consider serial s_5 + + start serial s_6 + + ready diff --git a/data/settings/controller/example/entries/sshd.entry b/data/settings/controller/example/entries/sshd.entry new file mode 100644 index 0000000..a74cc8d --- /dev/null +++ b/data/settings/controller/example/entries/sshd.entry @@ -0,0 +1,13 @@ +# fss-0005 + +main: + timeout start 7 + timeout stop 7 + timeout kill 3 + + failsafe explode + + start service sshd + +explode: + start maintenance boom diff --git a/data/settings/controller/example/entries/test.entry b/data/settings/controller/example/entries/test.entry new file mode 100644 index 0000000..b68db93 --- /dev/null +++ b/data/settings/controller/example/entries/test.entry @@ -0,0 +1,27 @@ +# fss-0005 + +main: + timeout start 7 + timeout stop 7 + timeout kill 3 + + failsafe explode + + item first + item last + +first: + consider script require_me + + start script succeed + start script php + start command multiple + + # uncomment python to see it fail. + #start script python + +last: + start script fail require wait + +explode: + start maintenance boom diff --git a/data/settings/controller/example/entries/up.entry b/data/settings/controller/example/entries/up.entry new file mode 100644 index 0000000..c38b6cd --- /dev/null +++ b/data/settings/controller/example/entries/up.entry @@ -0,0 +1,16 @@ +# fss-0005 + +settings: + control controller/run/up.socket + pid ready + pid_file controller/run/up.pid + +main: + failsafe maintenance + + start script create_socket_path + + ready + +maintenance: + start maintenance boom diff --git a/data/settings/controller/example/entries/utility.entry b/data/settings/controller/example/entries/utility.entry new file mode 100644 index 0000000..ebd36ef --- /dev/null +++ b/data/settings/controller/example/entries/utility.entry @@ -0,0 +1,15 @@ +# fss-0005 + +main: + timeout start 7 + timeout stop 7 + timeout kill 3 + + failsafe explode + + start utility sleeper_1 + start utility sleeper_2 + start utility sleeper_3 + +explode: + start maintenance boom diff --git a/data/settings/controller/example/exits/htop-alternate.exit b/data/settings/controller/example/exits/htop-alternate.exit new file mode 100644 index 0000000..3fac642 --- /dev/null +++ b/data/settings/controller/example/exits/htop-alternate.exit @@ -0,0 +1,21 @@ +# fss-0005 +# +# This example shows how htop can be started during the exit process rather than the entry. +# See the htop-alternate.entry example. + +main: + failsafe "start top" + + consider serial s_5 + consider serial s_6 + + stop serial s_4 asynchronous + stop serial s_5 asynchronous + stop serial s_6 asynchronous + + ready wait + + execute htop + +start top: + execute top diff --git a/data/settings/controller/example/exits/serial.exit b/data/settings/controller/example/exits/serial.exit new file mode 100644 index 0000000..1245486 --- /dev/null +++ b/data/settings/controller/example/exits/serial.exit @@ -0,0 +1,13 @@ +# fss-0005 + +main: + consider serial s_1 + consider serial s_2 + consider serial s_3 + consider serial s_4 + consider serial s_5 + consider serial s_6 + + stop serial s_1 + + ready diff --git a/data/settings/controller/example/exits/sshd.exit b/data/settings/controller/example/exits/sshd.exit new file mode 100644 index 0000000..79e738a --- /dev/null +++ b/data/settings/controller/example/exits/sshd.exit @@ -0,0 +1,13 @@ +# fss-0005 + +main: + timeout start 7 + timeout stop 7 + timeout kill 3 + + failsafe boom + + stop service sshd + +boom: + stop maintenance explode diff --git a/data/settings/controller/example/rules/asynchronous/sleep_1.rule b/data/settings/controller/example/rules/asynchronous/sleep_1.rule new file mode 100644 index 0000000..f722689 --- /dev/null +++ b/data/settings/controller/example/rules/asynchronous/sleep_1.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Note: The example setting "limit nice 1 2" may cause this rule to fail if the user has insufficient privileges granted by ulimits or some other system security measure. +# + +settings: + name "Sleep 1 Seconds." + nice 15 + limit nice 1 2 + on start need asynchronous sleep_10 + +script: + start echo "Sleeping 1: $(date -u), depends: 10" + +script: + start sleep 1 + +script: + start echo "Slept 1: $(date -u)" diff --git a/data/settings/controller/example/rules/asynchronous/sleep_10.rule b/data/settings/controller/example/rules/asynchronous/sleep_10.rule new file mode 100644 index 0000000..8734190 --- /dev/null +++ b/data/settings/controller/example/rules/asynchronous/sleep_10.rule @@ -0,0 +1,18 @@ +# fss-000d +# +# Note: The example setting "limit nice 1 2" may cause this rule to fail if the user has insufficient privileges granted by ulimits or some other system security measure. +# + +settings: + name "Sleep 10 Seconds." + nice 15 + limit nice 1 2 + +script: + start echo "Sleeping 10: $(date -u), depends: none" + +script: + start sleep 10 + +script: + start echo "Slept 10: $(date -u)" diff --git a/data/settings/controller/example/rules/asynchronous/sleep_2.rule b/data/settings/controller/example/rules/asynchronous/sleep_2.rule new file mode 100644 index 0000000..c854695 --- /dev/null +++ b/data/settings/controller/example/rules/asynchronous/sleep_2.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Note: The example setting "limit nice 1 2" may cause this rule to fail if the user has insufficient privileges granted by ulimits or some other system security measure. +# + +settings: + name "Sleep 2 Seconds." + nice 15 + limit nice 1 2 + on start need asynchronous sleep_10 + +script: + start echo "Sleeping 2: $(date -u), depends: 10" + +script: + start sleep 2 + +script: + start echo "Slept 2: $(date -u)" diff --git a/data/settings/controller/example/rules/asynchronous/sleep_3.rule b/data/settings/controller/example/rules/asynchronous/sleep_3.rule new file mode 100644 index 0000000..ad3d8f9 --- /dev/null +++ b/data/settings/controller/example/rules/asynchronous/sleep_3.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Note: The example setting "limit nice 1 2" may cause this rule to fail if the user has insufficient privileges granted by ulimits or some other system security measure. +# + +settings: + name "Sleep 3 Seconds." + nice 15 + limit nice 1 2 + on start need asynchronous sleep_8 + +script: + start echo "Sleeping 3: $(date -u), depends: 8" + +script: + start sleep 3 + +script: + start echo "Slept 3: $(date -u)" diff --git a/data/settings/controller/example/rules/asynchronous/sleep_5.rule b/data/settings/controller/example/rules/asynchronous/sleep_5.rule new file mode 100644 index 0000000..e4ed3db --- /dev/null +++ b/data/settings/controller/example/rules/asynchronous/sleep_5.rule @@ -0,0 +1,18 @@ +# fss-000d +# +# Note: The example setting "limit nice 1 2" may cause this rule to fail if the user has insufficient privileges granted by ulimits or some other system security measure. +# + +settings: + name "Sleep 5 Seconds." + nice 15 + limit nice 1 2 + +script: + start echo "Sleeping 5: $(date -u), depends: none" + +script: + start sleep 5 + +script: + start echo "Slept 5: $(date -u)" diff --git a/data/settings/controller/example/rules/asynchronous/sleep_8.rule b/data/settings/controller/example/rules/asynchronous/sleep_8.rule new file mode 100644 index 0000000..a9af412 --- /dev/null +++ b/data/settings/controller/example/rules/asynchronous/sleep_8.rule @@ -0,0 +1,18 @@ +# fss-000d +# +# Note: The example setting "limit nice 1 2" may cause this rule to fail if the user has insufficient privileges granted by ulimits or some other system security measure. +# + +settings: + name "Sleep 8 Seconds." + nice 15 + limit nice 1 2 + +script: + start echo "Sleeping 8: $(date -u), depends: none" + +script: + start sleep 8 + +script: + start echo "Slept 8: $(date -u)" diff --git a/data/settings/controller/example/rules/command/htop.rule b/data/settings/controller/example/rules/command/htop.rule new file mode 100644 index 0000000..197ad86 --- /dev/null +++ b/data/settings/controller/example/rules/command/htop.rule @@ -0,0 +1,9 @@ +# fss-000d + +settings: + name "Run htop" + +command: + start htop + + rerun start success delay 3000 max 3 diff --git a/data/settings/controller/example/rules/command/multiple.rule b/data/settings/controller/example/rules/command/multiple.rule new file mode 100644 index 0000000..8b3fd73 --- /dev/null +++ b/data/settings/controller/example/rules/command/multiple.rule @@ -0,0 +1,57 @@ +# fss-000d + +settings: + name "Multiple Commands: id, whoami, date, etc.." + capability "all=" + control_group new memory/example + nice 15 + scheduler batch 0 + #user kevin + #group list 8 root + + limit nofile 5000 10000 + limit nproc 1000 2000 + limit nice 1 2 + + affinity 0 + + on start need script require_me + +script: + start { + echo + echo "Current ulimit is" + ulimit -a + sleep 5 + + echo + echo "Current cgroup for self (PPID $PPID, PID $$) is: '$(cat /proc/self/cgroup)'" + sleep 5 + } + +command: + start { + id + sleep 5 + } + +script: + start echo + +command: + start whoami + +script: + start echo + +command: + start sleep 5 + +command: + start date -u + +script: + start echo + +script: + start sleep 5 diff --git a/data/settings/controller/example/rules/delay/long.rule b/data/settings/controller/example/rules/delay/long.rule new file mode 100644 index 0000000..19ebc2a --- /dev/null +++ b/data/settings/controller/example/rules/delay/long.rule @@ -0,0 +1,10 @@ +# fss-000d +# +# Rule for a long delay. +# + +settings: + name "Delay for 3 minutes." + +script: + start sleep 3m diff --git a/data/settings/controller/example/rules/delay/short.rule b/data/settings/controller/example/rules/delay/short.rule new file mode 100644 index 0000000..12e0856 --- /dev/null +++ b/data/settings/controller/example/rules/delay/short.rule @@ -0,0 +1,10 @@ +# fss-000d +# +# Rule for a short delay. +# + +settings: + name "Delay for 3 seconds." + +script: + start sleep 3s diff --git a/data/settings/controller/example/rules/environment/default.rule b/data/settings/controller/example/rules/environment/default.rule new file mode 100644 index 0000000..4efe7e4 --- /dev/null +++ b/data/settings/controller/example/rules/environment/default.rule @@ -0,0 +1,18 @@ +# fss-000d +# +# Note: bash automatically creates PWD, SHLVL, and _ environment variables. +# + +settings: + name "Environment default" + engine bash + +script: + start { + echo + echo "===================================" + echo "Environment using default settings." + echo "===================================" + + env + } diff --git a/data/settings/controller/example/rules/environment/empty.rule b/data/settings/controller/example/rules/environment/empty.rule new file mode 100644 index 0000000..c041187 --- /dev/null +++ b/data/settings/controller/example/rules/environment/empty.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Note: bash automatically creates PWD, SHLVL, and _ environment variables. +# + +settings: + name "Environment set to nothing" + environment + engine bash + +script: + start { + echo + echo "=============================" + echo "Environment allowing nothing." + echo "=============================" + + env + } diff --git a/data/settings/controller/example/rules/environment/exported.rule b/data/settings/controller/example/rules/environment/exported.rule new file mode 100644 index 0000000..d8c204f --- /dev/null +++ b/data/settings/controller/example/rules/environment/exported.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Note: bash automatically creates PWD, SHLVL, and _ environment variables. +# + +settings: + name "Environment with PATH" + environment PATH + engine bash + +script: + start { + echo + echo "==========================" + echo "Environment allowing PATH." + echo "==========================" + + env + } diff --git a/data/settings/controller/example/rules/environment/exporting.rule b/data/settings/controller/example/rules/environment/exporting.rule new file mode 100644 index 0000000..d2b3dad --- /dev/null +++ b/data/settings/controller/example/rules/environment/exporting.rule @@ -0,0 +1,25 @@ +# fss-000d +# +# Note: bash automatically creates PWD, SHLVL, and _ environment variables. +# + +settings: + name "Environment with PATH" + environment PATH custom_variable + engine bash + +script: + start { + echo + echo "=================================" + echo "Exported Environment is isolated." + echo "=================================" + + export custom_variable="is not retained" + echo "export custom_variable='$custom_variable'" + echo + echo "Now for 'env' command:" + } + +command: + start env diff --git a/data/settings/controller/example/rules/environment/fake-nothing.rule b/data/settings/controller/example/rules/environment/fake-nothing.rule new file mode 100644 index 0000000..b0e596a --- /dev/null +++ b/data/settings/controller/example/rules/environment/fake-nothing.rule @@ -0,0 +1,22 @@ +# fss-000d + +settings: + name "Environment using fake as an engine" + engine fake ++quiet + + # PATH must be expoted so that "run env" works. + environment PATH + +script: + start { + settings\: + environment + + main\: + print + print "========================================" + print "Environment allowing nothing using fake." + print "========================================" + + run env + } diff --git a/data/settings/controller/example/rules/environment/fake-something.rule b/data/settings/controller/example/rules/environment/fake-something.rule new file mode 100644 index 0000000..bfe6851 --- /dev/null +++ b/data/settings/controller/example/rules/environment/fake-something.rule @@ -0,0 +1,18 @@ +# fss-000d + +settings: + name "Environment using fake as an engine" + engine fake ++quiet + + environment PATH PWD + +script: + start { + main\: + print + print "=============================================" + print "Environment allowing PATH and PWD using fake." + print "=============================================" + + run env + } diff --git a/data/settings/controller/example/rules/maintenance/boom.rule b/data/settings/controller/example/rules/maintenance/boom.rule new file mode 100644 index 0000000..7278506 --- /dev/null +++ b/data/settings/controller/example/rules/maintenance/boom.rule @@ -0,0 +1,11 @@ +# fss-000d + +settings: + name "Explosion!" + engine sh + +script: + start { + echo "kaboooom!" + } + diff --git a/data/settings/controller/example/rules/print/newline.rule b/data/settings/controller/example/rules/print/newline.rule new file mode 100644 index 0000000..0f2f489 --- /dev/null +++ b/data/settings/controller/example/rules/print/newline.rule @@ -0,0 +1,8 @@ +# fss-000d + +settings: + name "Print New Line" + engine bash + +script: + start echo diff --git a/data/settings/controller/example/rules/script/create_socket_path.rule b/data/settings/controller/example/rules/script/create_socket_path.rule new file mode 100644 index 0000000..796b366 --- /dev/null +++ b/data/settings/controller/example/rules/script/create_socket_path.rule @@ -0,0 +1,14 @@ +# fss-000d + +settings: + name "Create Socket Path" + + parameter verbose -v + parameter socket controller/run/ + +script: + start { + if [[ ! -d "parameter:"socket"" ]] ; then + mkdir parameter:"verbose" -p parameter:"socket" + fi + } diff --git a/data/settings/controller/example/rules/script/fail.rule b/data/settings/controller/example/rules/script/fail.rule new file mode 100644 index 0000000..dd77b41 --- /dev/null +++ b/data/settings/controller/example/rules/script/fail.rule @@ -0,0 +1,16 @@ +# fss-000d + +settings: + name "Script #2" + on start need script succeed + +script: + start { + \#!/bin/bash + my_function() { + echo "Hello this is the last script, it should trigger failure." + return 1; + \} + + my_function + } diff --git a/data/settings/controller/example/rules/script/iki.rule b/data/settings/controller/example/rules/script/iki.rule new file mode 100644 index 0000000..c451918 --- /dev/null +++ b/data/settings/controller/example/rules/script/iki.rule @@ -0,0 +1,30 @@ +# fss-000d + +settings: + name "IKI Variable Substitution" + environment PATH IKI_TEST + define IKI_TEST "This is iki data in an environment variable." + parameter some "Some Parameter Value" + +script: + start { + \#!/bin/bash + echo "=====================================" + env + echo "=====================================" + echo "IKI Path is 'define:"PATH"'" + echo "IKI define IKI_TEST 'define:"IKI_TEST"'" + echo "ENV IKI_TEST '$IKI_TEST'" + echo "Some Parameter is 'parameter:"some"'" + echo "Unknown parameter is: 'parameter:"unknown"'" + echo "Unknown environment is: 'define:"unknown"'" + echo "Unavailable environment via IKI: 'define:"USER"'" + echo "Unavailable environment via ENV: '$USER'" + echo "Program parameter verbose: 'program:"verbose"'" + echo "Program parameter verbose(option): 'program:"verbose:option"'" + echo "Program parameter verbose(value): 'program:"verbose:value"'" + echo "Program parameter PID: 'program:"pid"'" + echo "Program parameter PID(option): 'program:"pid:option"'" + echo "Program parameter PID(value): 'program:"pid:value"'" + echo "=====================================" + } diff --git a/data/settings/controller/example/rules/script/php.rule b/data/settings/controller/example/rules/script/php.rule new file mode 100644 index 0000000..65ed2fc --- /dev/null +++ b/data/settings/controller/example/rules/script/php.rule @@ -0,0 +1,21 @@ +# fss-000d + +settings: + name "PHP script" + environment PATH + engine php + +script: + start { + /tmp/sleeper_1.pid + + echo "Sleeper 1, now sleeping." + sleep 20m + + echo "Sleeper 1, done sleeping." + rm -f /tmp/sleeper_1.pid + return 0 + \} + + main & + } diff --git a/data/settings/controller/example/rules/utility/sleeper_2.rule b/data/settings/controller/example/rules/utility/sleeper_2.rule new file mode 100644 index 0000000..2bc5cfc --- /dev/null +++ b/data/settings/controller/example/rules/utility/sleeper_2.rule @@ -0,0 +1,30 @@ +# fss-000d +# sleeper rule whose program creates its own PID file, runs in the background, sleep for a while, removes PID file, and returns. + +settings: + name "Sleeper #2" + nice 10 + +utility: + pid_file /tmp/sleeper_2.pid + start { + \#!/bin/bash + + main() { + if [[ -f /tmp/sleeper_2.pid ]] ; then + echo "Failure: pid file '/tmp/sleeper_2.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 & + } diff --git a/data/settings/controller/example/rules/utility/sleeper_3.rule b/data/settings/controller/example/rules/utility/sleeper_3.rule new file mode 100644 index 0000000..07ba570 --- /dev/null +++ b/data/settings/controller/example/rules/utility/sleeper_3.rule @@ -0,0 +1,54 @@ +# fss-000d +# sleeper rule whose program creates its own PID file, runs in the background, sleep for a while, removes PID file, and returns. + +settings: + name "Sleeper #2" + nice 10 + +utility: + pid_file /tmp/sleeper_3.1.pid + start { + \#!/bin/bash + + main() { + if [[ -f /tmp/sleeper_3.1.pid ]] ; then + echo "Failure: pid file '/tmp/sleeper_3.1.pid' already exists." + return 1 + fi + + echo "$BASHPID" > /tmp/sleeper_3.1.pid + + echo "Sleeper 3.1, now sleeping." + sleep 15 + + echo "Sleeper 3.1, done sleeping." + rm -f /tmp/sleeper_3.1.pid + return 0 + \} + + main & + } + +utility: + pid_file /tmp/sleeper_3.2.pid + start { + \#!/bin/bash + + main() { + if [[ -f /tmp/sleeper_3.2.pid ]] ; then + echo "Failure: pid file '/tmp/sleeper_3.2.pid' already exists." + return 1 + fi + + echo "$BASHPID" > /tmp/sleeper_3.2.pid + + echo "Sleeper 3.2, now sleeping." + sleep 20 + + echo "Sleeper 3.2, done sleeping." + rm -f /tmp/sleeper_3.2.pid + return 0 + \} + + main & + } diff --git a/data/settings/controller/rules/boot/devices.rule b/data/settings/controller/rules/boot/devices.rule new file mode 100644 index 0000000..61d3038 --- /dev/null +++ b/data/settings/controller/rules/boot/devices.rule @@ -0,0 +1,34 @@ +# fss-000d +# +# Rule for initializing the /dev file system. +# + +settings: + name "Setup /dev file system" + + on start need boot root + +# Newer kernels automount a devpts file system on /dev, so this may not be needed. +#command: +# start mount /dev + +script: + start { + if [[ ! -d /dev/pts ]] ; then + mkdir /dev/pts + fi + + if [[ ! -d /dev/shm ]] ; then + mkdir /dev/shm + fi + + exit 0 + } + +command: + start mount /dev/pts + stop umount -l /dev/pts + +command: + start mount /dev/shm + stop umount -l /dev/shm diff --git a/data/settings/controller/rules/boot/file_system.rule b/data/settings/controller/rules/boot/file_system.rule new file mode 100644 index 0000000..41e6932 --- /dev/null +++ b/data/settings/controller/rules/boot/file_system.rule @@ -0,0 +1,29 @@ +# fss-000d +# +# Rule for initializing the filesystem. +# + +settings: + name "Setup Filesystem" + + on start need boot root + on start need boot proc + on start need boot devices + + on stop need boot proc + on stop need boot devices + +command: + start mount -n -a -O no_netdev + stop umount -n -arf -O no_netdev + +command: + start swapon -a + stop swapoff -a + +script: + start { + if [[ ! -d /var/run/init ]] ; then + mkdir /var/run/init + fi + } diff --git a/data/settings/controller/rules/boot/modules.rule b/data/settings/controller/rules/boot/modules.rule new file mode 100644 index 0000000..5572d90 --- /dev/null +++ b/data/settings/controller/rules/boot/modules.rule @@ -0,0 +1,28 @@ +# fss-000d +# +# Rule for initializing the kernel modules. +# + +settings: + name "Setup Kernel Modules" + + on start need boot root + on start need boot proc + on start want boot filesystem + +script: + start { + if [[ ! -f /proc/modules ]] ; then + exit 0 + fi + + if [[ -d /modules ]] ; then + if [[ ! -e /modules/$(uname -r)/modules.dep ]] ; then + depmod + else + depmod -A + fi + fi + + exit 0 + } diff --git a/data/settings/controller/rules/boot/proc.rule b/data/settings/controller/rules/boot/proc.rule new file mode 100644 index 0000000..acb9fa5 --- /dev/null +++ b/data/settings/controller/rules/boot/proc.rule @@ -0,0 +1,29 @@ +# fss-000d +# +# Rule for initializing the /proc filesystem. +# + +settings: + name "Setup /proc Filesystem" + + on start need boot root + +command: + start mount /proc + +script: + start { + if [[ -d /proc/bus/usb ]] ; then + mount /proc/bus/usb + fi + + exit 0 + } + + stop { + if [[ -d /proc/bus/usb ]] ; then + umount -l /proc/bus/usb + fi + + exit 0 + } diff --git a/data/settings/controller/rules/boot/root.rule b/data/settings/controller/rules/boot/root.rule new file mode 100644 index 0000000..5f3abf6 --- /dev/null +++ b/data/settings/controller/rules/boot/root.rule @@ -0,0 +1,67 @@ +# fss-000d +# +# Rule for initializing the root filesystem, assuring certain directories always exist. +# + +settings: + name "Setup Root Filesystem" + +command: + start mount -o remount,rw / + +script: + start { + if [[ ! -d /dev ]] ; then + mkdir /dev + fi + + if [[ ! -d /dev/pts ]] ; then + mkdir /dev/pts + fi + + if [[ ! -d /dev/shm ]] ; then + mkdir /dev/shm + fi + + if [[ ! -d /firmware ]] ; then + mkdir /firmware + fi + + if [[ ! -d /mnt ]] ; then + mkdir /mnt + fi + + if [[ ! -d /modules ]] ; then + mkdir /modules + fi + + if [[ ! -d /proc ]] ; then + mkdir /proc + fi + + if [[ ! -d /sys ]] ; then + mkdir /sys + fi + + if [[ ! -d /tmp ]] ; then + mkdir /tmp + fi + + if [[ ! -d /var ]] ; then + mkdir /var + fi + + if [[ ! -d /var/log ]] ; then + mkdir /var/log + fi + + if [[ ! -d /var/run ]] ; then + mkdir /var/run + fi + + if [[ ! -d /var/tmp ]] ; then + mkdir /var/tmp + fi + + exit 0 + } diff --git a/data/settings/controller/rules/maintenance/console.rule b/data/settings/controller/rules/maintenance/console.rule new file mode 100644 index 0000000..1cad18f --- /dev/null +++ b/data/settings/controller/rules/maintenance/console.rule @@ -0,0 +1,13 @@ +# fss-000d +# +# Rule for maintenance/failsafe console. +# + +settings: + name "Maintenance Console" + +command: + #start setsid -c bash --login + start bash --login + + with session diff --git a/data/settings/controller/rules/net/all.rule b/data/settings/controller/rules/net/all.rule new file mode 100644 index 0000000..79c2819 --- /dev/null +++ b/data/settings/controller/rules/net/all.rule @@ -0,0 +1,13 @@ +# fss-000d +# +# Rule for starting all network devices. +# + +settings: + name "System Network" + capability cap_net_admin= + +command: + start network start + stop network stop + restart network restart diff --git a/data/settings/controller/rules/net/loopback.rule b/data/settings/controller/rules/net/loopback.rule new file mode 100644 index 0000000..9377cdd --- /dev/null +++ b/data/settings/controller/rules/net/loopback.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Rule for loopback device. +# + +settings: + name "Loopback Device" + + on start need boot modules + +script: + start { + ip addr add 127.0.0.1/8 label lo dev lo + ip link set lo up + } + + stop { + ip link set lo down + } diff --git a/data/settings/controller/rules/service/dbus.rule b/data/settings/controller/rules/service/dbus.rule new file mode 100644 index 0000000..d32e1e0 --- /dev/null +++ b/data/settings/controller/rules/service/dbus.rule @@ -0,0 +1,14 @@ +# fss-000d +# +# Rule for D-Bus service. +# + +settings: + name "D-BUS" + capability all= + nice 15 + +service: + pid_file /var/run/dbus/dbus.pid + + start dbus-daemon --system --fork diff --git a/data/settings/controller/rules/service/logger.rule b/data/settings/controller/rules/service/logger.rule new file mode 100644 index 0000000..6ac54c7 --- /dev/null +++ b/data/settings/controller/rules/service/logger.rule @@ -0,0 +1,16 @@ +# fss-000d +# +# Rule for system logger service. +# + +settings: + name "System Logger" + capability all= + nice 19 + scheduler idle + +service: + # @todo consider adding support for IKI to make "/var/run/logger/logger.pid" a variable. + pid_file /var/run/logger/logger.pid + + start metalog -B -p /var/run/logger/logger.pid -C /etc/logger.conf diff --git a/data/settings/controller/rules/service/mouse.rule b/data/settings/controller/rules/service/mouse.rule new file mode 100644 index 0000000..ad97095 --- /dev/null +++ b/data/settings/controller/rules/service/mouse.rule @@ -0,0 +1,32 @@ +# fss-000d +# +# Rule for console mouse. +# + +settings: + name "Console Mouse" + capability all= + nice 15 + +script: + start { + # This works if gpm service is run as root, but if not then this should be in a separate rule file with appropriate access to write to /var/run (don't forget to chown!). + if [[ ! -d /var/run/mouse/ && -d /var/run ]] ; then + mkdir /var/run/mouse/ + fi + } + +service: + pid_file /var/run/mouse/mouse.pid + + # @todo consider a new type, such as "variable" than can be used to get the variable and store it in an iki parseable variable. + # This, however, may be too complicated than desirable (in terms of passing output back to the parent process). + # such as: + #variable device command fss_basic_read -can 0 device /etc/mouse + #variable protocal script { + # fss_basic_read -can 0 device /etc/mouse + #} + #variable options set "" + + # @todo + start gpm -m variable:"device" -t variable:"protocol" variable:"options" diff --git a/data/settings/controller/rules/task/clock.rule b/data/settings/controller/rules/task/clock.rule new file mode 100644 index 0000000..663f159 --- /dev/null +++ b/data/settings/controller/rules/task/clock.rule @@ -0,0 +1,39 @@ +# fss-000d +# +# Rule for setting the clock. +# + +settings: + name "Setup Clock" + capability cap_sys_time= + nice 15 + + on start want boot filesystem + on start want net all + +script: + start { + clock_file=/etc/clock + clock_mode= + clock_server= + clock_ntpdate= + + if [[ -f $clock_file ]] ; then + clock_mode=$(fss_basic_read -can 0 mode $clock_file); + clock_server=$(fss_basic_read -can 0 server $clock_file) + clock_ntpdate=$(fss_basic_read -can 0 ntpdate $clock_file) + fi + + if [[ $clock_mode == "local" ]] ; then + hwclock --hctosys; + elif [[ $clock_mode == "ntp" ]] ; then + if [[ $clock_ntpdate == "yes" ]] ; then + ntpdate $clock_server && + hwclock --systohc --utc + fi + elif [[ $clock_mode == "ntpdate" && $clock_host != "" ]] ; then + ntpdate $clock_server + elif [[ $clock_mode == "utc" ]] ; then + hwclock --hctosys --utc; + fi + } diff --git a/data/settings/controller/rules/task/keyboard.rule b/data/settings/controller/rules/task/keyboard.rule new file mode 100644 index 0000000..72c7add --- /dev/null +++ b/data/settings/controller/rules/task/keyboard.rule @@ -0,0 +1,8 @@ +# fss-000d +# +# Rule for setting the keyboard. +# + +settings: + name "System Keyboard" + nice 15 diff --git a/data/settings/controller/rules/task/ntpdate.rule b/data/settings/controller/rules/task/ntpdate.rule new file mode 100644 index 0000000..5956114 --- /dev/null +++ b/data/settings/controller/rules/task/ntpdate.rule @@ -0,0 +1,28 @@ +# fss-000d +# +# Rule for executing ntpdate. +# + +settings: + name "System Clock Using NTP Date" + capability cap_sys_time= + nice 15 + + on start want boot filesystem + on start need net all + +script: + start { + clock_file=/etc/clock + clock_mode= + clock_server= + + if [[ -f $clock_file ]] ; then + clock_mode=$(fss_basic_read -can 0 mode $clock_file); + clock_server=$(fss_basic_read -can 0 server $clock_file) + fi + + if [[ $clock_mode == "ntpdate" && $clock_host != "" ]] ; then + ntpdate $clock_server + fi + } diff --git a/data/settings/controller/rules/terminal/four.rule b/data/settings/controller/rules/terminal/four.rule new file mode 100644 index 0000000..5bc8189 --- /dev/null +++ b/data/settings/controller/rules/terminal/four.rule @@ -0,0 +1,16 @@ +# fss-000d +# +# Rule for the terminal programs. +# +# -m = don't prompt for login. +# -J = don't clear on start, good for debugging. +# 9600 and 115200 are common frequencies. + +settings: + name "System Terminal 4" + +command: + start agetty -8 tty4 linux + + rerun start success delay 1000 reset + rerun start failure delay 5000 max 100 diff --git a/data/settings/controller/rules/terminal/one.rule b/data/settings/controller/rules/terminal/one.rule new file mode 100644 index 0000000..14b0d64 --- /dev/null +++ b/data/settings/controller/rules/terminal/one.rule @@ -0,0 +1,16 @@ +# fss-000d +# +# Rule for the terminal programs. +# +# -m = don't prompt for login. +# -J = don't clear on start, good for debugging. +# 9600 and 115200 are common frequencies. + +settings: + name "System Terminal 1" + +command: + start agetty -8 -i -J - linux + + rerun start success delay 1000 reset + rerun start failure delay 5000 diff --git a/data/settings/controller/rules/terminal/three.rule b/data/settings/controller/rules/terminal/three.rule new file mode 100644 index 0000000..aa90f01 --- /dev/null +++ b/data/settings/controller/rules/terminal/three.rule @@ -0,0 +1,16 @@ +# fss-000d +# +# Rule for the terminal programs. +# +# -m = don't prompt for login. +# -J = don't clear on start, good for debugging. +# 9600 and 115200 are common frequencies. + +settings: + name "System Terminal 3" + +command: + start agetty -8 tty3 linux + + rerun start success delay 1000 reset + rerun start failure delay 5000 max 100 diff --git a/data/settings/controller/rules/terminal/two.rule b/data/settings/controller/rules/terminal/two.rule new file mode 100644 index 0000000..2dde16e --- /dev/null +++ b/data/settings/controller/rules/terminal/two.rule @@ -0,0 +1,16 @@ +# fss-000d +# +# Rule for the terminal programs. +# +# -m = don't prompt for login. +# -J = don't clear on start, good for debugging. +# 9600 and 115200 are common frequencies. + +settings: + name "System Terminal 2" + +command: + start agetty -8 tty2 linux + + rerun start success delay 1000 reset + rerun start failure delay 5000 max 100 diff --git a/documents/actions.txt b/documents/actions.txt index f390621..dac5c63 100644 --- a/documents/actions.txt +++ b/documents/actions.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named actions.txt) can be more easily read using the following iki_read commands: diff --git a/documents/entry.txt b/documents/entry.txt index df26b94..aee41ea 100644 --- a/documents/entry.txt +++ b/documents/entry.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named entry.txt) can be more easily read using the following iki_read commands: diff --git a/documents/exit.txt b/documents/exit.txt index 0001b3f..d6bce76 100644 --- a/documents/exit.txt +++ b/documents/exit.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named exit.txt) can be more easily read using the following iki_read commands: diff --git a/documents/packet.txt b/documents/packet.txt index 060a586..ef83b03 100644 --- a/documents/packet.txt +++ b/documents/packet.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named packet.txt) can be more easily read using the following iki_read commands: diff --git a/documents/rule.txt b/documents/rule.txt index 6466d24..d305198 100644 --- a/documents/rule.txt +++ b/documents/rule.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named rule.txt) can be more easily read using the following iki_read commands: diff --git a/documents/simulate.txt b/documents/simulate.txt index e576a1f..f9e6e06 100644 --- a/documents/simulate.txt +++ b/documents/simulate.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named simulate.txt) can be more easily read using the following iki_read commands: diff --git a/documents/time.txt b/documents/time.txt index c4cd416..fcfbee5 100644 --- a/documents/time.txt +++ b/documents/time.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0-or-later +# license: cc-by-sa-4.0 # version 2024/07/02 # # This file (assumed to be named time.txt) can be more easily read using the following iki_read commands: diff --git a/sources/c/main/common/define/thread.h b/sources/c/main/common/define/thread.h index 0a72c81..28eca8d 100644 --- a/sources/c/main/common/define/thread.h +++ b/sources/c/main/common/define/thread.h @@ -18,43 +18,86 @@ extern "C" { /** * Thread related defines. + * + * controller_thread_cleanup_interval_*_d: + * - long: How many seconds to wait for clean up for long waits. + * - short: How many seconds to wait for clean up for short waits. + * + * controller_thread_exit_*_d: + * - disable_force_times: The number of times to retry apply lock aon exit before forcibly setting state to disabled on exit. + * - process_cancel_total: The number of nanoseconds to wait when cancelling a process. + * - process_cancel_wait: The total number of times to wait when cancelling a process (multiply this by wait time to get total nanoseconds). */ #ifndef _di_controller_thread_d_ - #define controller_thread_cleanup_interval_long_d 3600 // 1 hour in seconds. - #define controller_thread_cleanup_interval_short_d 180 // 3 minutes in seconds. - #define controller_thread_exit_timeout_d 500 // 0.5 seconds in milliseconds. + #define controller_thread_cleanup_interval_long_d 3600 // 1 hour in seconds. + #define controller_thread_cleanup_interval_short_d 180 // 3 minutes in seconds. + + #define controller_thread_exit_disable_force_times 12 #define controller_thread_exit_process_cancel_wait_d 600000000 // 0.6 seconds in nanoseconds. #define controller_thread_exit_process_cancel_total_d 150 // 90 seconds in multiples of wait. - #define controller_thread_simulation_timeout_d 200 // 0.2 seconds in milliseconds. - - #define controller_thread_signal_wait_timeout_seconds_d 70 - #define controller_thread_signal_wait_timeout_nanoseconds_d 0 - - #define controller_thread_lock_read_timeout_seconds_d 3 - #define controller_thread_lock_read_timeout_nanoseconds_d 0 - #define controller_thread_lock_write_timeout_seconds_d 3 - #define controller_thread_lock_write_timeout_nanoseconds_d 0 - - #define controller_thread_wait_timeout_1_before_d 4 - #define controller_thread_wait_timeout_2_before_d 12 - #define controller_thread_wait_timeout_3_before_d 28 - - #define controller_thread_wait_timeout_1_seconds_d 0 - #define controller_thread_wait_timeout_1_nanoseconds_d 20000000 // 0.02 seconds in nanoseconds. - #define controller_thread_wait_timeout_2_seconds_d 0 - #define controller_thread_wait_timeout_2_nanoseconds_d 200000000 // 0.2 seconds in nanoseconds. - #define controller_thread_wait_timeout_3_seconds_d 2 - #define controller_thread_wait_timeout_3_nanoseconds_d 0 - #define controller_thread_wait_timeout_4_seconds_d 20 - #define controller_thread_wait_timeout_4_nanoseconds_d 0 - - #define controller_thread_exit_helper_timeout_seconds_d 0 - #define controller_thread_exit_helper_timeout_nanoseconds_d 100000000 // 0.1 seconds in nanoseconds. - - #define controller_thread_exit_ready_timeout_seconds_d 0 - #define controller_thread_exit_ready_timeout_nanoseconds_d 500000000 // 0.5 seconds in nanoseconds. #endif // _di_controller_thread_d_ +/** + * Thread related timeout defines. + * + * controller_thread_timeout_*_d: + * - exit: The number of milliseconds to wait before exit times out (before a terminate/kill signal is sent). + * - exit_disable_force_nanoseconds: The nanoseconds to wait between each attempt to lock and set disable state. + * - exit_disable_force_seconds: The seconds to wait between each attempt to lock and set disable state. + * - exit_helper_nanoseconds: The nanoseconds to wait before the exit helper times out. + * - exit_helper_seconds: The seconds to wait before the exit helper times out. + * - exit_ready_nanoseconds: The nanoseconds to wait before the exit ready times out. + * - exit_ready_seconds: The seconds to wait before the exit ready times out. + * - lock_read_nanoseconds: The nanoseconds to wait before the read lock times out. + * - lock_read_seconds: The seconds to wait before the read lock times out. + * - lock_write_nanoseconds: The nanoseconds to wait before the write lock times out. + * - lock_write_seconds: The seconds to wait before the write lock times out. + * - simulation: The number of milliseconds to wait to simulate a pause due to a process execution. + * - wait_signal_nanoseconds: The nanoseconds to wait before waiting for the signal times out. + * - wait_signal_seconds: The seconds to wait before waiting for the signal times out. + * - wait_1_before: The max number of retries to perform set 1 wait timeouts. + * - wait_1_nanoseconds: The nanoseconds to wait in set 1 timeouts while waiting for an Instance. + * - wait_1_seconds: The seconds to wait in set 1 timeouts while waiting for an Instance. + * - wait_2_before: The max number of retries to perform set 2 wait timeouts (after set 1 wait before is exceeded). + * - wait_2_nanoseconds: The nanoseconds to wait in set 2 timeouts while waiting for an Instance. + * - wait_2_seconds: The seconds to wait in set 2 timeouts while waiting for an Instance. + * - wait_3_before: The max number of retries to perform set 3 wait timeouts (after set 2 wait before is exceeded). + * - wait_3_nanoseconds: The nanoseconds to wait in set 3 timeouts while waiting for an Instance. + * - wait_3_seconds: The seconds to wait in set 3 timeouts while waiting for an Instance. + * - wait_4_nanoseconds: The nanoseconds to wait in set 4 timeouts while waiting for an Instance. + * - wait_4_seconds: The seconds to wait in set 4 timeouts while waiting for an Instance. + */ +#ifndef _di_controller_thread_timeout_d_ + #define controller_thread_timeout_exit_d 500 // 0.5 seconds in milliseconds. + #define controller_thread_timeout_exit_disable_force_nanoseconds_d 10000000 // 0.01 seconds in nanoseconds. + #define controller_thread_timeout_exit_disable_force_seconds_d 0 + #define controller_thread_timeout_exit_helper_nanoseconds_d 100000000 // 0.1 seconds in nanoseconds. + #define controller_thread_timeout_exit_helper_seconds_d 0 + #define controller_thread_timeout_exit_ready_nanoseconds_d 500000000 // 0.5 seconds in nanoseconds. + #define controller_thread_timeout_exit_ready_seconds_d 0 + + #define controller_thread_timeout_lock_read_nanoseconds_d 0 + #define controller_thread_timeout_lock_read_seconds_d 3 + #define controller_thread_timeout_lock_write_nanoseconds_d 0 + #define controller_thread_timeout_lock_write_seconds_d 3 + + #define controller_thread_timeout_simulation_d 200 // 0.2 seconds in milliseconds. + + #define controller_thread_timeout_wait_1_before_d 4 + #define controller_thread_timeout_wait_1_nanoseconds_d 20000000 // 0.02 seconds in nanoseconds. + #define controller_thread_timeout_wait_1_seconds_d 0 + #define controller_thread_timeout_wait_2_before_d 12 + #define controller_thread_timeout_wait_2_nanoseconds_d 200000000 // 0.2 seconds in nanoseconds. + #define controller_thread_timeout_wait_2_seconds_d 0 + #define controller_thread_timeout_wait_3_before_d 28 + #define controller_thread_timeout_wait_3_nanoseconds_d 0 + #define controller_thread_timeout_wait_3_seconds_d 2 + #define controller_thread_timeout_wait_4_nanoseconds_d 0 + #define controller_thread_timeout_wait_4_seconds_d 20 + #define controller_thread_timeout_wait_signal_nanoseconds_d 0 + #define controller_thread_timeout_wait_signal_seconds_d 70 +#endif // _di_controller_thread_timeout_d_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/main/common/type/entry.h b/sources/c/main/common/type/entry.h index 2ffcb7e..53b7db8 100644 --- a/sources/c/main/common/type/entry.h +++ b/sources/c/main/common/type/entry.h @@ -176,7 +176,7 @@ extern "C" { 0, \ 0, \ 0, \ - controller_thread_exit_timeout_d, \ + controller_thread_timeout_exit_d, \ 0, \ 0, \ 0, \ @@ -191,7 +191,7 @@ extern "C" { 0, \ 0, \ flag, \ - controller_thread_exit_timeout_d, \ + controller_thread_timeout_exit_d, \ 0, \ 0, \ 0, \ diff --git a/sources/c/main/instance/wait.c b/sources/c/main/instance/wait.c index 909121d..6f031fb 100644 --- a/sources/c/main/instance/wait.c +++ b/sources/c/main/instance/wait.c @@ -20,17 +20,17 @@ extern "C" { do { f_thread_mutex_lock(&instance->wait_lock); - if (count < controller_thread_wait_timeout_1_before_d) { - controller_time_now(controller_thread_wait_timeout_1_seconds_d, controller_thread_wait_timeout_1_nanoseconds_d, &time); + if (count < controller_thread_timeout_wait_1_before_d) { + controller_time_now(controller_thread_timeout_wait_1_seconds_d, controller_thread_timeout_wait_1_nanoseconds_d, &time); } - else if (count < controller_thread_wait_timeout_2_before_d) { - controller_time_now(controller_thread_wait_timeout_2_seconds_d, controller_thread_wait_timeout_2_nanoseconds_d, &time); + else if (count < controller_thread_timeout_wait_2_before_d) { + controller_time_now(controller_thread_timeout_wait_2_seconds_d, controller_thread_timeout_wait_2_nanoseconds_d, &time); } - else if (count < controller_thread_wait_timeout_3_before_d) { - controller_time_now(controller_thread_wait_timeout_3_seconds_d, controller_thread_wait_timeout_3_nanoseconds_d, &time); + else if (count < controller_thread_timeout_wait_3_before_d) { + controller_time_now(controller_thread_timeout_wait_3_seconds_d, controller_thread_timeout_wait_3_nanoseconds_d, &time); } else { - controller_time_now(controller_thread_wait_timeout_4_seconds_d, controller_thread_wait_timeout_4_nanoseconds_d, &time); + controller_time_now(controller_thread_timeout_wait_4_seconds_d, controller_thread_timeout_wait_4_nanoseconds_d, &time); } status = f_thread_condition_wait_timed(&time, &instance->wait, &instance->wait_lock); @@ -57,20 +57,20 @@ extern "C" { if (status != F_time) { // move up the wait timer after a trigger was received. - if (count < controller_thread_wait_timeout_2_before_d) { + if (count < controller_thread_timeout_wait_2_before_d) { count = 0; } - else if (count < controller_thread_wait_timeout_3_before_d) { - count = controller_thread_wait_timeout_1_before_d; + else if (count < controller_thread_timeout_wait_3_before_d) { + count = controller_thread_timeout_wait_1_before_d; } else { - count = controller_thread_wait_timeout_2_before_d; + count = controller_thread_timeout_wait_2_before_d; } } f_thread_unlock(&instance->lock); - if (count < controller_thread_wait_timeout_3_before_d) { + if (count < controller_thread_timeout_wait_3_before_d) { ++count; } diff --git a/sources/c/main/lock.c b/sources/c/main/lock.c index ad3c93a..75b4dc6 100644 --- a/sources/c/main/lock.c +++ b/sources/c/main/lock.c @@ -50,7 +50,7 @@ extern "C" { memset(&time, 0, sizeof(f_time_spec_t)); - controller_time_now(controller_thread_lock_read_timeout_seconds_d, controller_thread_lock_read_timeout_nanoseconds_d, &time); + controller_time_now(controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, &time); status = f_thread_lock_read_timed(&time, lock); @@ -93,7 +93,7 @@ extern "C" { for (f_time_spec_t time; ; ) { - controller_time_now(controller_thread_lock_write_timeout_seconds_d, controller_thread_lock_write_timeout_nanoseconds_d, &time); + controller_time_now(controller_thread_timeout_lock_write_seconds_d, controller_thread_timeout_lock_write_nanoseconds_d, &time); status = f_thread_lock_write_timed(&time, lock); diff --git a/sources/c/main/rule/execute.c b/sources/c/main/rule/execute.c index 9dc0fec..b19cea0 100644 --- a/sources/c/main/rule/execute.c +++ b/sources/c/main/rule/execute.c @@ -470,7 +470,7 @@ extern "C" { { f_time_spec_t delay = f_time_spec_t_initialize; - status = f_time_spec_millisecond(0, controller_thread_simulation_timeout_d, &delay); + status = f_time_spec_millisecond(0, controller_thread_timeout_simulation_d, &delay); if (F_status_is_error(status)) { controller_print_error_status(&main->program.error, macro_controller_f(f_time_spec_millisecond), F_status_set_fine(status)); @@ -679,7 +679,7 @@ extern "C" { { f_time_spec_t delay = f_time_spec_t_initialize; - status = f_time_spec_millisecond(0, controller_thread_simulation_timeout_d, &delay); + status = f_time_spec_millisecond(0, controller_thread_timeout_simulation_d, &delay); if (F_status_is_error(status)) { controller_print_error_status(&main->program.error, macro_controller_f(f_time_spec_millisecond), F_status_set_fine(status)); diff --git a/sources/c/main/thread/entry.c b/sources/c/main/thread/entry.c index 26e2f7b..e63c57f 100644 --- a/sources/c/main/thread/entry.c +++ b/sources/c/main/thread/entry.c @@ -96,8 +96,8 @@ extern "C" { if (F_status_is_error_not(*status) && *status != F_child && main->program.parameters.array[controller_parameter_validate_e].result == f_console_result_none_e && main->process.mode == controller_process_mode_helper_e) { f_time_spec_t time; - time.tv_sec = controller_thread_exit_helper_timeout_seconds_d; - time.tv_nsec = controller_thread_exit_helper_timeout_nanoseconds_d; + time.tv_sec = controller_thread_timeout_exit_helper_seconds_d; + time.tv_nsec = controller_thread_timeout_exit_helper_nanoseconds_d; nanosleep(&time, 0); @@ -217,11 +217,7 @@ extern "C" { return 0; } - if (F_status_is_error_not(f_thread_mutex_lock(&main->thread.lock.alert))) { - main->thread.enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&main->thread.lock.alert); - } + controller_thread_instance_force_set_disable(main); f_thread_condition_signal_all(&main->thread.lock.alert_condition); diff --git a/sources/c/main/thread/instance.c b/sources/c/main/thread/instance.c index c486694..f6fa0ae 100644 --- a/sources/c/main/thread/instance.c +++ b/sources/c/main/thread/instance.c @@ -12,8 +12,8 @@ extern "C" { const f_status_t status = controller_rule_instance_perform(controller_instance_option_asynchronous_e, instance); - // A forked child instance should de-allocate memory on exit. - // It seems that this function doesn't return to the calling thread for a forked child instance, even with the "return 0;" below. + // A forked child Instance should de-allocate memory on exit. + // It seems that this function doesn't return to the calling thread for a forked child Instance, even with the "return 0;" below. if (status == F_child) { controller_delete(instance->main); @@ -125,7 +125,7 @@ extern "C" { instance = main->thread.instances.array[i]; - // Do not cancel Exit instances, when not performing "execute" during exit. + // Do not cancel Exit Instances, when not performing "execute" during exit. if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) { continue; } @@ -158,7 +158,7 @@ extern "C" { instance = main->thread.instances.array[i]; - // Do not wait for instances, when not performing "execute" during exit. + // Do not wait for Instances, when not performing "execute" during exit. if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) { continue; } @@ -167,7 +167,7 @@ extern "C" { while (instance->childs.array[j] > 0 && lapsed < entry->timeout_exit) { - // A hackish way to determine if the child instance exists while waiting (@todo look into pidfd() and epoll_wait()). + // A hackish way to determine if the child Instance exists while waiting (@todo look into pidfd() and epoll_wait()). if (getpgid(instance->childs.array[j]) >= 0) { time.tv_sec = 0; time.tv_nsec = interval_nanoseconds; @@ -192,7 +192,7 @@ extern "C" { if (pid) { while (lapsed < entry->timeout_exit) { - // A hackish way to determine if the instance exists while waiting (@todo look into pidfd() and epoll_wait()). + // A hackish way to determine if the Instance exists while waiting (@todo look into pidfd() and epoll_wait()). if (getpgid(pid) >= 0) { time.tv_sec = 0; time.tv_nsec = interval_nanoseconds; @@ -219,7 +219,7 @@ extern "C" { instance = main->thread.instances.array[i]; - // Do not kill Exit instances, when not performing "execute" during exit. + // Do not kill Exit Instances, when not performing "execute" during exit. if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) continue; if (instance->id_thread) { @@ -284,7 +284,7 @@ extern "C" { // Shrink the child pids as much as possible. while (instance->childs.used) { - // Do not shrink below an Exit instances, when not performing "execute" during exit. + // Do not shrink below an Exit Instances, when not performing "execute" during exit. if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) break; if (instance->childs.array[j] > 0) break; @@ -294,7 +294,7 @@ extern "C" { // Shrink the path pids as much as possible. while (instance->path_pids.used) { - // Do not shrink below an Exit instances, when not performing "execute" during exit. + // Do not shrink below an Exit Instances, when not performing "execute" during exit. if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) break; if (instance->path_pids.array[j].used) break; @@ -333,11 +333,7 @@ extern "C" { controller_print_error_status(&main->program.error, macro_controller_f(f_thread_create), F_status_set_fine(status)); } - if (F_status_is_error_not(f_thread_mutex_lock(&main->thread.lock.alert))) { - main->thread.enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&main->thread.lock.alert); - } + controller_thread_instance_force_set_disable(main); } else { f_time_spec_t time = f_time_spec_t_initialize; @@ -346,7 +342,7 @@ extern "C" { status = f_thread_mutex_lock(&main->thread.lock.alert); if (F_status_is_error(status)) break; - controller_time_now(controller_thread_exit_ready_timeout_seconds_d, controller_thread_exit_ready_timeout_nanoseconds_d, &time); + controller_time_now(controller_thread_timeout_exit_ready_seconds_d, controller_thread_timeout_exit_ready_nanoseconds_d, &time); status = f_thread_condition_wait_timed(&time, &main->thread.lock.alert_condition, &main->thread.lock.alert); @@ -354,13 +350,7 @@ extern "C" { } while (F_status_is_error_not(status) && main->thread.enabled == controller_thread_enabled_exit_e); - if (F_status_is_error(status)) { - if (F_status_is_error_not(f_thread_mutex_lock(&main->thread.lock.alert))) { - main->thread.enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&main->thread.lock.alert); - } - } + if (F_status_is_error(status)) controller_thread_instance_force_set_disable(main); } // The sigtimedwait() function that is run inside of signal must be interrupted via the f_thread_cancel(). @@ -374,14 +364,45 @@ extern "C" { controller_thread_instance_cancel(main, F_false, controller_thread_cancel_exit_e); } else { - if (F_status_is_error_not(f_thread_mutex_lock(&main->thread.lock.alert))) { + controller_thread_instance_force_set_disable(main); + } + } +#endif // _di_controller_thread_instance_exit_ + +#ifndef _di_controller_thread_instance_force_set_disable_ + void controller_thread_instance_force_set_disable(controller_t * const main) { + + if (!main) return; + + if (F_status_is_error_not(f_thread_mutex_lock(&main->thread.lock.alert))) { + main->thread.enabled = controller_thread_enabled_not_e; + + f_thread_mutex_unlock(&main->thread.lock.alert); + + return; + } + + f_time_spec_t time; + + for (uint8_t i = 0; i < controller_thread_exit_disable_force_times; ++i) { + + memset((void *) &time, 0, sizeof(struct timespec)); + + controller_time_now(controller_thread_timeout_exit_disable_force_seconds_d, controller_thread_timeout_exit_disable_force_nanoseconds_d, &time); + + if (F_status_is_error_not(f_thread_mutex_lock_timed(&time, &main->thread.lock.alert))) { main->thread.enabled = controller_thread_enabled_not_e; f_thread_mutex_unlock(&main->thread.lock.alert); + + return; } - } + } // for + + // Forcibly set disable regardless of the risk. + main->thread.enabled = controller_thread_enabled_not_e; } -#endif // _di_controller_thread_instance_exit_ +#endif // _di_controller_thread_instance_force_set_disable_ #ifndef _di_controller_thread_instance_normal_ void * controller_thread_instance_normal(void * const argument) { diff --git a/sources/c/main/thread/instance.h b/sources/c/main/thread/instance.h index 35fc742..ff1e648 100644 --- a/sources/c/main/thread/instance.h +++ b/sources/c/main/thread/instance.h @@ -71,6 +71,28 @@ extern "C" { #endif // _di_controller_thread_instance_exit_ /** + * Set the execution state to disabled during exiting and force the case if need be. + * + * The program must exit during the Exit process. + * The state must be properly set. + * Perform a limited number of attempts to set the state to exiting. + * Should this fail, then force the case regardless of the risk. + * + * @param main + * The main program data. + * + * Must not be NULL. + * + * This does not alter main.setting.state.status. + * + * The main.thread.lock.alert lock will be set and then unset if possible. + * The main.thread.enabled will be updated and set to controller_thread_enabled_not_e. + */ +#ifndef _di_controller_thread_instance_force_set_disable_ + extern void controller_thread_instance_force_set_disable(controller_t * const main); +#endif // _di_controller_thread_instance_force_set_disable_ + +/** * Asynchronously execute a Rule process during normal operations. * * @param argument diff --git a/sources/c/main/thread/signal.c b/sources/c/main/thread/signal.c index 5a7b303..010c55d 100644 --- a/sources/c/main/thread/signal.c +++ b/sources/c/main/thread/signal.c @@ -18,7 +18,7 @@ extern "C" { memset((void *) &information, 0, sizeof(siginfo_t)); - controller_time_now(controller_thread_exit_ready_timeout_seconds_d, controller_thread_exit_ready_timeout_nanoseconds_d, &time); + controller_time_now(controller_thread_timeout_exit_ready_seconds_d, controller_thread_timeout_exit_ready_nanoseconds_d, &time); if (f_signal_wait_until(&main->program.signal.set, &time, &information) == F_time_out) continue; diff --git a/specifications/entry.txt b/specifications/entry.txt index 9918f03..95c1cf6 100644 --- a/specifications/entry.txt +++ b/specifications/entry.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named entry.txt) can be more easily read using the following iki_read commands: diff --git a/specifications/exit.txt b/specifications/exit.txt index c202f62..476687b 100644 --- a/specifications/exit.txt +++ b/specifications/exit.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named exit.txt) can be more easily read using the following iki_read commands: diff --git a/specifications/packet.txt b/specifications/packet.txt index 9150b46..f5dc07b 100644 --- a/specifications/packet.txt +++ b/specifications/packet.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named packet.txt) can be more easily read using the following iki_read commands: diff --git a/specifications/rule.txt b/specifications/rule.txt index 276c48b..0648378 100644 --- a/specifications/rule.txt +++ b/specifications/rule.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named rule.txt) can be more easily read using the following iki_read commands: diff --git a/specifications/task.txt b/specifications/task.txt index 28e4681..b409917 100644 --- a/specifications/task.txt +++ b/specifications/task.txt @@ -1,6 +1,6 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 +# license: open-standard-license-1.0-or-later # version 2024/07/02 # # This file (assumed to be named task.txt) can be more easily read using the following iki_read commands: diff --git a/specifications/time.txt b/specifications/time.txt index 214110b..ddde71f 100644 --- a/specifications/time.txt +++ b/specifications/time.txt @@ -1,7 +1,7 @@ # fss-0002 iki-0000 # -# license: open-standard-license-1.0 -# version 2023/12/16 +# license: open-standard-license-1.0-or-later +# version 2024/07/02 # # This file (assumed to be named time.txt) can be more easily read using the following iki_read commands: # iki_read time.txt +Q -r UTC UTC -w -WW character "'" "'" code '"' '"'