]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-common: Map ENOENT for a missing event script to ENOEXEC
authorMartin Schwenke <mschwenke@ddn.com>
Wed, 20 Nov 2024 03:37:09 +0000 (14:37 +1100)
committerAmitay Isaacs <amitay@samba.org>
Thu, 21 Nov 2024 01:42:09 +0000 (01:42 +0000)
This handles the case where an event script is disabled by unlinking,
while an event is being run, after the script list has been created.
Without this change the script will fail.  With this change the script
will be marked as DISABLED.  See the comment added by this commit for
more details.

Add a testcase to simulate the race, using an event script to disable
subsequent ones.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15755

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Autobuild-User(master): Amitay Isaacs <amitay@samba.org>
Autobuild-Date(master): Thu Nov 21 01:42:09 UTC 2024 on atb-devel-224

ctdb/common/run_event.c
ctdb/tests/UNIT/eventd/etc-ctdb/share/events/data/01.dummy.script
ctdb/tests/UNIT/eventd/eventd_009.sh

index d283664e2cfac47d0a1bdbf4af3fa849f24fc5d7..30369eeff228a861685de0827185089da6251d4e 100644 (file)
@@ -268,8 +268,27 @@ static int run_event_script_status(struct run_event_script *script)
        if (script->result.sig > 0) {
                ret = -EINTR;
        } else if (script->result.err > 0) {
-               if (script->result.err == EACCES) {
-                       /* Map EACCESS to ENOEXEC */
+               if (script->result.err == EACCES ||
+                   script->result.err == ENOENT) {
+                       /*
+                        * Map EACCESS/ENOENT to ENOEXEC
+                        *
+                        * ENOENT: Disabling a standard event script
+                        * by removing its symlink can result in
+                        * ENOENT.  This happens when the script list
+                        * is built while the link exists, but the
+                        * link is removed before the attempt to run
+                        * it.  Map it to ENOEXEC (which causes a
+                        * script to be shown as DISABLED).  This
+                        * makes it impossible to distinguish a
+                        * removed symlink from a dangling
+                        * symlink... but the latter can just be
+                        * defined as disabled.  It should be rare
+                        * because it shouldn't happen if event
+                        * scripts are properly managed.  If someone
+                        * is doing weird things then they can easily
+                        * debug such issues by looking at the link.
+                        */
                        ret = -ENOEXEC;
                } else {
                        ret = -script->result.err;
index 9c56f5b968b9be779d233368bb2f89f02911f9eb..b7b5945714cd8b08fbade5e6ab8a0d41d72811a2 100755 (executable)
@@ -2,5 +2,9 @@
 
 case "$1" in
 "failure") exit 1 ;;
+"disablehack")
+       ctdb-event script disable data 02.disabled
+       ctdb-event script disable data 03.notalink
+       ;;
 *) exit 0 ;;
 esac
index 39e5cd658cc3706f708b1d9f18f99ef2d6c9876e..8ac14d952fe49dbaa07ca69495cb59a81a6ac869 100755 (executable)
@@ -153,3 +153,40 @@ ok <<EOF
 * 03.notalink
 EOF
 simple_test script list data
+
+#
+# Test disabling of scripts after the script list has been
+# built. Normally this would be an admin racing with eventd instead of
+# one script disabling subsequent ones.
+#
+
+# First enable all scripts - this might repeat some previous stuff
+ok_null
+simple_test script enable data 01.dummy
+ok_null
+simple_test script enable data 02.disabled
+ok_null
+simple_test script enable data 03.notalink
+
+# Confirm expected state
+ok <<EOF
+* 01.dummy
+* 02.disabled
+
+* 03.notalink
+EOF
+simple_test script list data
+
+# Now run the event that disables the subsequent scripts:
+# - 02.disabled has its link removed
+# - 03.notalink effectively has "chmod -x" applied
+ok_null
+simple_test run 10 data disablehack
+
+# Confirm that both subsequent 
+ok <<EOF
+01.dummy             OK         DURATION DATETIME
+02.disabled          DISABLED  
+03.notalink          DISABLED  
+EOF
+simple_test status data disablehack