]> Kevux Git Server - controller/commitdiff
Progress: Continue migrating the project, also updating files and licenses.
authorKevin Day <Kevin@kevux.org>
Wed, 10 Jul 2024 02:38:31 +0000 (21:38 -0500)
committerKevin Day <Kevin@kevux.org>
Wed, 10 Jul 2024 02:38:31 +0000 (21:38 -0500)
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.

109 files changed:
data/documentation/man/man1/controller.1
data/documentation/man/man5/controller-actions.5
data/documentation/man/man5/controller-entry.5
data/documentation/man/man5/controller-exit.5
data/documentation/man/man5/controller-packet.5
data/documentation/man/man5/controller-rule.5
data/settings/controller/entries/default.entry [new file with mode: 0644]
data/settings/controller/entries/maintenance.entry [new file with mode: 0644]
data/settings/controller/example/cgroup_example/entries/chromium.entry [new file with mode: 0644]
data/settings/controller/example/cgroup_example/entries/eclipse.entry [new file with mode: 0644]
data/settings/controller/example/cgroup_example/entries/firefox.entry [new file with mode: 0644]
data/settings/controller/example/cgroup_example/entries/setup_cgroups.entry [new file with mode: 0644]
data/settings/controller/example/cgroup_example/rules/program/chromium.rule [new file with mode: 0644]
data/settings/controller/example/cgroup_example/rules/program/eclipse.rule [new file with mode: 0644]
data/settings/controller/example/cgroup_example/rules/program/firefox.rule [new file with mode: 0644]
data/settings/controller/example/cgroup_example/rules/setup/cgroups.rule [new file with mode: 0644]
data/settings/controller/example/entries/asynchronous-serial.entry [new file with mode: 0644]
data/settings/controller/example/entries/asynchronous.entry [new file with mode: 0644]
data/settings/controller/example/entries/delay-program.entry [new file with mode: 0644]
data/settings/controller/example/entries/delay-service.entry [new file with mode: 0644]
data/settings/controller/example/entries/environment.entry [new file with mode: 0644]
data/settings/controller/example/entries/htop-alternate.entry [new file with mode: 0644]
data/settings/controller/example/entries/htop-command.entry [new file with mode: 0644]
data/settings/controller/example/entries/htop.entry [new file with mode: 0644]
data/settings/controller/example/entries/iki.entry [new file with mode: 0644]
data/settings/controller/example/entries/serial-alternate.entry [new file with mode: 0644]
data/settings/controller/example/entries/serial.entry [new file with mode: 0644]
data/settings/controller/example/entries/sshd.entry [new file with mode: 0644]
data/settings/controller/example/entries/test.entry [new file with mode: 0644]
data/settings/controller/example/entries/up.entry [new file with mode: 0644]
data/settings/controller/example/entries/utility.entry [new file with mode: 0644]
data/settings/controller/example/exits/htop-alternate.exit [new file with mode: 0644]
data/settings/controller/example/exits/serial.exit [new file with mode: 0644]
data/settings/controller/example/exits/sshd.exit [new file with mode: 0644]
data/settings/controller/example/rules/asynchronous/sleep_1.rule [new file with mode: 0644]
data/settings/controller/example/rules/asynchronous/sleep_10.rule [new file with mode: 0644]
data/settings/controller/example/rules/asynchronous/sleep_2.rule [new file with mode: 0644]
data/settings/controller/example/rules/asynchronous/sleep_3.rule [new file with mode: 0644]
data/settings/controller/example/rules/asynchronous/sleep_5.rule [new file with mode: 0644]
data/settings/controller/example/rules/asynchronous/sleep_8.rule [new file with mode: 0644]
data/settings/controller/example/rules/command/htop.rule [new file with mode: 0644]
data/settings/controller/example/rules/command/multiple.rule [new file with mode: 0644]
data/settings/controller/example/rules/delay/long.rule [new file with mode: 0644]
data/settings/controller/example/rules/delay/short.rule [new file with mode: 0644]
data/settings/controller/example/rules/environment/default.rule [new file with mode: 0644]
data/settings/controller/example/rules/environment/empty.rule [new file with mode: 0644]
data/settings/controller/example/rules/environment/exported.rule [new file with mode: 0644]
data/settings/controller/example/rules/environment/exporting.rule [new file with mode: 0644]
data/settings/controller/example/rules/environment/fake-nothing.rule [new file with mode: 0644]
data/settings/controller/example/rules/environment/fake-something.rule [new file with mode: 0644]
data/settings/controller/example/rules/maintenance/boom.rule [new file with mode: 0644]
data/settings/controller/example/rules/print/newline.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/create_socket_path.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/fail.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/iki.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/php.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/python.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/require_me.rule [new file with mode: 0644]
data/settings/controller/example/rules/script/succeed.rule [new file with mode: 0644]
data/settings/controller/example/rules/serial/s_1.rule [new file with mode: 0644]
data/settings/controller/example/rules/serial/s_2.rule [new file with mode: 0644]
data/settings/controller/example/rules/serial/s_3.rule [new file with mode: 0644]
data/settings/controller/example/rules/serial/s_4.rule [new file with mode: 0644]
data/settings/controller/example/rules/serial/s_5.rule [new file with mode: 0644]
data/settings/controller/example/rules/serial/s_6.rule [new file with mode: 0644]
data/settings/controller/example/rules/service/sshd.rule [new file with mode: 0644]
data/settings/controller/example/rules/utility/sleeper_1.rule [new file with mode: 0644]
data/settings/controller/example/rules/utility/sleeper_2.rule [new file with mode: 0644]
data/settings/controller/example/rules/utility/sleeper_3.rule [new file with mode: 0644]
data/settings/controller/rules/boot/devices.rule [new file with mode: 0644]
data/settings/controller/rules/boot/file_system.rule [new file with mode: 0644]
data/settings/controller/rules/boot/modules.rule [new file with mode: 0644]
data/settings/controller/rules/boot/proc.rule [new file with mode: 0644]
data/settings/controller/rules/boot/root.rule [new file with mode: 0644]
data/settings/controller/rules/maintenance/console.rule [new file with mode: 0644]
data/settings/controller/rules/net/all.rule [new file with mode: 0644]
data/settings/controller/rules/net/loopback.rule [new file with mode: 0644]
data/settings/controller/rules/service/dbus.rule [new file with mode: 0644]
data/settings/controller/rules/service/logger.rule [new file with mode: 0644]
data/settings/controller/rules/service/mouse.rule [new file with mode: 0644]
data/settings/controller/rules/task/clock.rule [new file with mode: 0644]
data/settings/controller/rules/task/keyboard.rule [new file with mode: 0644]
data/settings/controller/rules/task/ntpdate.rule [new file with mode: 0644]
data/settings/controller/rules/terminal/four.rule [new file with mode: 0644]
data/settings/controller/rules/terminal/one.rule [new file with mode: 0644]
data/settings/controller/rules/terminal/three.rule [new file with mode: 0644]
data/settings/controller/rules/terminal/two.rule [new file with mode: 0644]
documents/actions.txt
documents/entry.txt
documents/exit.txt
documents/packet.txt
documents/rule.txt
documents/simulate.txt
documents/time.txt
sources/c/main/common/define/thread.h
sources/c/main/common/type/entry.h
sources/c/main/instance/wait.c
sources/c/main/lock.c
sources/c/main/rule/execute.c
sources/c/main/thread/entry.c
sources/c/main/thread/instance.c
sources/c/main/thread/instance.h
sources/c/main/thread/signal.c
specifications/entry.txt
specifications/exit.txt
specifications/packet.txt
specifications/rule.txt
specifications/task.txt
specifications/time.txt

index 80c49e5df8cabc6cc49abeb65c20671c748b500f..dd207d1be402cdc4602377296c7697d274167318 100644 (file)
@@ -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.
index eb79f8babb6f6055ac0830f2b053414ad3890168..0c4870bff01853bab76c0f6bf57950c88aeea550 100644 (file)
@@ -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.
index 976bcf3d5a404cc8706296003655df39719a797c..d3311e87ebae3a10e4c358b655a6d08e56024599 100644 (file)
@@ -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.
index a4969ea58bf426227a9ab05828843a052172e72c..de6badae1363e897f7e5e22a989f8ac0a9330e9a 100644 (file)
@@ -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.
index c62cc93a381070f97c35b90c278bb568011a4a52..2850a62bebb027c8e4abfe729e174c982f9813fc 100644 (file)
@@ -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.
index 47b81b554c71d617243e7d857288324fa91f211b..5c8996ba93bf026cb4640907ce3c51ce8015fca3 100644 (file)
@@ -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 (file)
index 0000000..1330803
--- /dev/null
@@ -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 (file)
index 0000000..2c6a6c7
--- /dev/null
@@ -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 (file)
index 0000000..8e41837
--- /dev/null
@@ -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 (file)
index 0000000..7a3aedb
--- /dev/null
@@ -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 (file)
index 0000000..5d5ff15
--- /dev/null
@@ -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 (file)
index 0000000..7a59836
--- /dev/null
@@ -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 (file)
index 0000000..75d10f0
--- /dev/null
@@ -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 (file)
index 0000000..8b1020a
--- /dev/null
@@ -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 (file)
index 0000000..79b19f9
--- /dev/null
@@ -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 (file)
index 0000000..87de765
--- /dev/null
@@ -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 (file)
index 0000000..b6b736f
--- /dev/null
@@ -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 (file)
index 0000000..8d2756e
--- /dev/null
@@ -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 (file)
index 0000000..e5fb3b5
--- /dev/null
@@ -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 (file)
index 0000000..da9ee04
--- /dev/null
@@ -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 (file)
index 0000000..a6978df
--- /dev/null
@@ -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 (file)
index 0000000..3c8bed6
--- /dev/null
@@ -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 (file)
index 0000000..19dae00
--- /dev/null
@@ -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 (file)
index 0000000..ff78686
--- /dev/null
@@ -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 (file)
index 0000000..9a04ab8
--- /dev/null
@@ -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 (file)
index 0000000..ecfabbc
--- /dev/null
@@ -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 (file)
index 0000000..a63fe05
--- /dev/null
@@ -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 (file)
index 0000000..a74cc8d
--- /dev/null
@@ -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 (file)
index 0000000..b68db93
--- /dev/null
@@ -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 (file)
index 0000000..c38b6cd
--- /dev/null
@@ -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 (file)
index 0000000..ebd36ef
--- /dev/null
@@ -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 (file)
index 0000000..3fac642
--- /dev/null
@@ -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 (file)
index 0000000..1245486
--- /dev/null
@@ -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 (file)
index 0000000..79e738a
--- /dev/null
@@ -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 (file)
index 0000000..f722689
--- /dev/null
@@ -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 (file)
index 0000000..8734190
--- /dev/null
@@ -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 (file)
index 0000000..c854695
--- /dev/null
@@ -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 (file)
index 0000000..ad3d8f9
--- /dev/null
@@ -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 (file)
index 0000000..e4ed3db
--- /dev/null
@@ -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 (file)
index 0000000..a9af412
--- /dev/null
@@ -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 (file)
index 0000000..197ad86
--- /dev/null
@@ -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 (file)
index 0000000..8b3fd73
--- /dev/null
@@ -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 (file)
index 0000000..19ebc2a
--- /dev/null
@@ -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 (file)
index 0000000..12e0856
--- /dev/null
@@ -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 (file)
index 0000000..4efe7e4
--- /dev/null
@@ -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 (file)
index 0000000..c041187
--- /dev/null
@@ -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 (file)
index 0000000..d8c204f
--- /dev/null
@@ -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 (file)
index 0000000..d2b3dad
--- /dev/null
@@ -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 (file)
index 0000000..b0e596a
--- /dev/null
@@ -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 (file)
index 0000000..bfe6851
--- /dev/null
@@ -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 (file)
index 0000000..7278506
--- /dev/null
@@ -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 (file)
index 0000000..0f2f489
--- /dev/null
@@ -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 (file)
index 0000000..796b366
--- /dev/null
@@ -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 (file)
index 0000000..dd77b41
--- /dev/null
@@ -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 (file)
index 0000000..c451918
--- /dev/null
@@ -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 (file)
index 0000000..65ed2fc
--- /dev/null
@@ -0,0 +1,21 @@
+# fss-000d
+
+settings:
+  name "PHP script"
+  environment PATH
+  engine php
+
+script:
+  start {
+    <?php
+    print("\nThis is a PHP script.\n\n");
+
+    print(date("Y/m/d h:i:s a") . "\n\n");
+
+    var_dump(getenv());
+    print("\n");
+
+    print("Now executing 'date -u' program, assuming that it exists in \$PATH.\n");
+    passthru("date -u");
+    print("\n");
+  }
diff --git a/data/settings/controller/example/rules/script/python.rule b/data/settings/controller/example/rules/script/python.rule
new file mode 100644 (file)
index 0000000..a486a6a
--- /dev/null
@@ -0,0 +1,14 @@
+# fss-000d
+
+settings:
+  name "Python (Version 3.X) script"
+  environment PATH
+  engine python3
+
+script:
+  start {
+    # Python's indentation design presents problems here and this will likely fail with "IndentationError: unexpected indent"
+    print("This is a Python script.\n");
+
+    # this is simply a design flaw of Python and as such Python scripts must not be tabbed over (making these files less readable).
+  }
diff --git a/data/settings/controller/example/rules/script/require_me.rule b/data/settings/controller/example/rules/script/require_me.rule
new file mode 100644 (file)
index 0000000..bede8df
--- /dev/null
@@ -0,0 +1,14 @@
+# fss-000d
+
+settings:
+  name "Example script for needs, wants, and wishes."
+  environment PATH
+  engine sh
+
+script:
+  start {
+    echo
+    echo "This should be included via a need, want, or wish."
+    echo
+  }
+
diff --git a/data/settings/controller/example/rules/script/succeed.rule b/data/settings/controller/example/rules/script/succeed.rule
new file mode 100644 (file)
index 0000000..fa0df59
--- /dev/null
@@ -0,0 +1,17 @@
+# fss-000d
+
+settings:
+  name "Script #1"
+  environment PATH
+  engine sh
+
+script:
+  start {
+    echo
+    echo "Hello this is script #1 and should succeed."
+    echo
+
+    date -u
+    echo
+  }
+
diff --git a/data/settings/controller/example/rules/serial/s_1.rule b/data/settings/controller/example/rules/serial/s_1.rule
new file mode 100644 (file)
index 0000000..bb84e2d
--- /dev/null
@@ -0,0 +1,18 @@
+# fss-000d
+
+settings:
+  name "Serial 1"
+  on stop need serial s_2
+
+script:
+  start {
+    echo "Serial 1: sleeping $(date -u)"
+    sleep 1
+    echo "Serial 1: slept    $(date -u)"
+  }
+
+  stop {
+    echo "Serial 1: stopping, sleeping $(date -u)"
+    sleep 1
+    echo "Serial 1: stopping, slept    $(date -u)"
+  }
diff --git a/data/settings/controller/example/rules/serial/s_2.rule b/data/settings/controller/example/rules/serial/s_2.rule
new file mode 100644 (file)
index 0000000..5496172
--- /dev/null
@@ -0,0 +1,19 @@
+# fss-000d
+
+settings:
+  name "Serial 2"
+  on start need serial s_1
+  on stop need serial s_3
+
+script:
+  start {
+    echo "Serial 2: sleeping $(date -u)"
+    sleep 1
+    echo "Serial 2: slept    $(date -u)"
+  }
+
+  stop {
+    echo "Serial 2: stopping, sleeping $(date -u)"
+    sleep 1
+    echo "Serial 2: stopping, slept    $(date -u)"
+  }
diff --git a/data/settings/controller/example/rules/serial/s_3.rule b/data/settings/controller/example/rules/serial/s_3.rule
new file mode 100644 (file)
index 0000000..fee1d88
--- /dev/null
@@ -0,0 +1,19 @@
+# fss-000d
+
+settings:
+  name "Serial 3"
+  on start need serial s_2
+  on stop need serial s_4
+
+script:
+  start {
+    echo "Serial 3: sleeping $(date -u)"
+    sleep 1
+    echo "Serial 3: slept    $(date -u)"
+  }
+
+  stop {
+    echo "Serial 3: stopping, sleeping $(date -u)"
+    sleep 1
+    echo "Serial 3: stopping, slept    $(date -u)"
+  }
diff --git a/data/settings/controller/example/rules/serial/s_4.rule b/data/settings/controller/example/rules/serial/s_4.rule
new file mode 100644 (file)
index 0000000..ff7040f
--- /dev/null
@@ -0,0 +1,19 @@
+# fss-000d
+
+settings:
+  name "Serial 4"
+  on start need serial s_3
+  on stop need serial s_5
+
+script:
+  start {
+    echo "Serial 4: sleeping $(date -u)"
+    sleep 1
+    echo "Serial 4: slept    $(date -u)"
+  }
+
+  stop {
+    echo "Serial 4: stopping, sleeping $(date -u)"
+    sleep 1
+    echo "Serial 4: stopping, slept    $(date -u)"
+  }
diff --git a/data/settings/controller/example/rules/serial/s_5.rule b/data/settings/controller/example/rules/serial/s_5.rule
new file mode 100644 (file)
index 0000000..11c7c6c
--- /dev/null
@@ -0,0 +1,19 @@
+# fss-000d
+
+settings:
+  name "Serial 5"
+  on start need serial s_4
+  on stop need serial s_6
+
+script:
+  start {
+    echo "Serial 5: sleeping $(date -u)"
+    sleep 1
+    echo "Serial 5: slept    $(date -u)"
+  }
+
+  stop {
+    echo "Serial 5: stopping, sleeping $(date -u)"
+    sleep 1
+    echo "Serial 5: stopping, slept    $(date -u)"
+  }
diff --git a/data/settings/controller/example/rules/serial/s_6.rule b/data/settings/controller/example/rules/serial/s_6.rule
new file mode 100644 (file)
index 0000000..4eba10d
--- /dev/null
@@ -0,0 +1,18 @@
+# fss-000d
+
+settings:
+  name "Serial 6"
+  on start need serial s_5
+
+script:
+  start {
+    echo "Serial 6: sleeping $(date -u)"
+    sleep 1
+    echo "Serial 6: slept    $(date -u)"
+  }
+
+  stop {
+    echo "Serial 6: stopping, sleeping $(date -u)"
+    sleep 1
+    echo "Serial 6: stopping, slept    $(date -u)"
+  }
diff --git a/data/settings/controller/example/rules/service/sshd.rule b/data/settings/controller/example/rules/service/sshd.rule
new file mode 100644 (file)
index 0000000..3ef5c2e
--- /dev/null
@@ -0,0 +1,14 @@
+# fss-000d
+#
+# Example using the common sshd service.
+# Sshd appears to require a full path.
+#
+
+settings:
+  name "SSH Service"
+  nice 15
+
+service:
+  pid_file /var/run/sshd.pid
+  with full_path
+  start sshd
diff --git a/data/settings/controller/example/rules/utility/sleeper_1.rule b/data/settings/controller/example/rules/utility/sleeper_1.rule
new file mode 100644 (file)
index 0000000..9aafe87
--- /dev/null
@@ -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 #1"
+  nice 10
+
+utility:
+  pid_file /tmp/sleeper_1.pid
+  start {
+    \#!/bin/bash
+
+    main() {
+      if [[ -f /tmp/sleeper_1.pid ]] ; then
+        echo "Failure: pid file '/tmp/sleeper_1.pid' already exists."
+        return 1
+      fi
+
+      echo "$BASHPID" > /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 (file)
index 0000000..2bc5cfc
--- /dev/null
@@ -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 (file)
index 0000000..07ba570
--- /dev/null
@@ -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 (file)
index 0000000..61d3038
--- /dev/null
@@ -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 (file)
index 0000000..41e6932
--- /dev/null
@@ -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 (file)
index 0000000..5572d90
--- /dev/null
@@ -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 (file)
index 0000000..acb9fa5
--- /dev/null
@@ -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 (file)
index 0000000..5f3abf6
--- /dev/null
@@ -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 (file)
index 0000000..1cad18f
--- /dev/null
@@ -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 (file)
index 0000000..79c2819
--- /dev/null
@@ -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 (file)
index 0000000..9377cdd
--- /dev/null
@@ -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 (file)
index 0000000..d32e1e0
--- /dev/null
@@ -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 (file)
index 0000000..6ac54c7
--- /dev/null
@@ -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 (file)
index 0000000..ad97095
--- /dev/null
@@ -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 (file)
index 0000000..663f159
--- /dev/null
@@ -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 (file)
index 0000000..72c7add
--- /dev/null
@@ -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 (file)
index 0000000..5956114
--- /dev/null
@@ -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 (file)
index 0000000..5bc8189
--- /dev/null
@@ -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 (file)
index 0000000..14b0d64
--- /dev/null
@@ -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 (file)
index 0000000..aa90f01
--- /dev/null
@@ -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 (file)
index 0000000..2dde16e
--- /dev/null
@@ -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
index f390621a3c3a7336e97453890231a71067cf6877..dac5c631ba8bb052cf9553541eaebd257aef560b 100644 (file)
@@ -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:
index df26b94162eb4f2a98e073c25c27bdd45759dd61..aee41ea61136cb37e562a0e624d118ec88e1efa0 100644 (file)
@@ -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:
index 0001b3fbaab2743c92ad5e5e14fc89f71ec5dba5..d6bce76135789c169d5f7ab749cb24445131823a 100644 (file)
@@ -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:
index 060a586ec81a3d0bf20bfff84a1b801a8f6d8227..ef83b03efe1a248f7f9469a07546d2d03d078ed6 100644 (file)
@@ -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:
index 6466d24208775b1c9e1989981f5b8807a1b2857e..d305198bb3ee45a99cab2c3edf6e7dd2319b1c22 100644 (file)
@@ -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:
index e576a1fc5419a81746f65af74a485b003c484685..f9e6e06da40711c0779cbc823f45b749c9d64abf 100644 (file)
@@ -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:
index c4cd416330fb221113d3e3479ba2adc02802844f..fcfbee5bef20f75196dcea818fcee4d549427c43 100644 (file)
@@ -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:
index 0a72c81ef2964c8d54897556b84d87705cd285c6..28eca8df323ba4be969d6a684ec37f3a22377d35 100644 (file)
@@ -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
index 2ffcb7e12de15f11455b5421138a27568f86ba71..53b7db848f309e73140e94863e1906327fc2fdf9 100644 (file)
@@ -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, \
index 909121dbd7bf2b5ab583e727d04d4448b0bc6721..6f031fbe7b5dfbcca4f5135aea278ba618edff1d 100644 (file)
@@ -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;
       }
 
index ad3c93a0579ecf3e246fa44a8e671d800d5fe5d4..75b4dc600e67b79058fc4e5d7ca1afbada2c7bea 100644 (file)
@@ -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);
 
index 9dc0fec23659770d4d0e5bf03cdb5c0ead30d407..b19cea0329179a0472de31957ee3af7337073e9e 100644 (file)
@@ -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));
index 26e2f7ba6326ee3d5df3350552ab01eef662e10a..e63c57f14a49c05a04ca9ea7bb100bda4075c19c 100644 (file)
@@ -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);
 
index c48669441ac72fd1be1f6fc286d53827e3b30b8e..f6fa0aea307da19d9f6611cef05f345f7179a06e 100644 (file)
@@ -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) {
index 35fc74247902983c9a5c4cd877bb2c2c6814c19a..ff1e64891a83e50bff27d172d0ea4f9e0726b5d0 100644 (file)
@@ -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
index 5a7b303b26197af8fef806b43b3a45958b5bdf50..010c55d1529abbc32eff5ec9f265ee27ea5b613f 100644 (file)
@@ -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;
 
index 9918f03d5554203fa833a08dc51394157fdbcec3..95c1cf69558eba116c8d44277651ae68423503aa 100644 (file)
@@ -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:
index c202f62da15fa3fbb41539115ff55b50b8148f3a..476687b26b60a556bf455eab11b0a0bfcc11f186 100644 (file)
@@ -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:
index 9150b46d008863ee5a7990ff7535216372039a82..f5dc07bbc69c18c08416a4d5778b889da550f0c7 100644 (file)
@@ -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:
index 276c48b563f40f88707590d53695dd787e58d427..0648378f3f12110ad78688a7b9090f9eac202e4b 100644 (file)
@@ -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:
index 28e4681d6907b81cb375073ee99d1484fbe1d75c..b409917dc9c244b6c9982c1d55ccff9fa84af584 100644 (file)
@@ -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:
index 214110b1b8e318a9467ef0ca122e29500c70895b..ddde71f171349765586a8bf7eb9e50c76627f6b9 100644 (file)
@@ -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 '"' '"'