The branch, master has been updated
       via  e3ce1a2 ctdb-docs: Update documentation for "ctdb event" command
       via  5017325 ctdb-event: Implement event tool "script list" command
       via  295826f ctdb-event: Change event-tool script enable/disable to 
chmod file directly
       via  82e6248 ctdb-common: Use script abstraction in run_event
       via  a7a4ee4 ctdb-common: Factor out basic script abstraction
       via  56e248d ctdb-event: Fix "ctdb event status" usage message
      from  a44e698 ctdb-docs: Replace obsolete reference to 
CTDB_DEBUG_HUNG_SCRIPT option

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e3ce1a2dfc4cbba4bf22381b91e9a14c8f240f5d
Author: Martin Schwenke <mar...@meltin.net>
Date:   Mon Jul 23 14:07:08 2018 +1000

    ctdb-docs: Update documentation for "ctdb event" command
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13551
    
    Signed-off-by: Martin Schwenke <mar...@meltin.net>
    Reviewed-by: Amitay Isaacs <ami...@gmail.com>
    
    Autobuild-User(master): Amitay Isaacs <ami...@samba.org>
    Autobuild-Date(master): Sat Jul 28 20:03:52 CEST 2018 on sn-devel-144

commit 5017325c2ef84b10ccd23328f5d62ac5b246bbb3
Author: Martin Schwenke <mar...@meltin.net>
Date:   Thu Jul 12 13:47:51 2018 +1000

    ctdb-event: Implement event tool "script list" command
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13551
    
    Signed-off-by: Martin Schwenke <mar...@meltin.net>
    Reviewed-by: Amitay Isaacs <ami...@gmail.com>

commit 295826f1b83b6e59d24e4da43b290242c17f44af
Author: Martin Schwenke <mar...@meltin.net>
Date:   Thu Jul 12 13:27:16 2018 +1000

    ctdb-event: Change event-tool script enable/disable to chmod file directly
    
    They no longer go over the socket to eventd to enable and disable
    scripts.  Use the event script abstraction to chmod them directly.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13551
    
    Signed-off-by: Martin Schwenke <mar...@meltin.net>
    Reviewed-by: Amitay Isaacs <ami...@gmail.com>

commit 82e62488027302e541739628210292c2d95717e1
Author: Martin Schwenke <mar...@meltin.net>
Date:   Thu Jul 12 13:26:27 2018 +1000

    ctdb-common: Use script abstraction in run_event
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13551
    
    Signed-off-by: Martin Schwenke <mar...@meltin.net>
    Reviewed-by: Amitay Isaacs <ami...@gmail.com>

commit a7a4ee439dc1cf262b4da9fbcb38a2f69c62744c
Author: Martin Schwenke <mar...@meltin.net>
Date:   Thu Jul 12 13:20:55 2018 +1000

    ctdb-common: Factor out basic script abstraction
    
    Provides for listing of scripts and chmod enable/disable.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13551
    
    Signed-off-by: Martin Schwenke <mar...@meltin.net>
    Reviewed-by: Amitay Isaacs <ami...@gmail.com>

commit 56e248de6072063308786ea83282aaecc8d7e62a
Author: Martin Schwenke <mar...@meltin.net>
Date:   Thu Jul 12 10:44:20 2018 +1000

    ctdb-event: Fix "ctdb event status" usage message
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13551
    
    Signed-off-by: Martin Schwenke <mar...@meltin.net>
    Reviewed-by: Amitay Isaacs <ami...@gmail.com>

-----------------------------------------------------------------------

Summary of changes:
 ctdb/common/event_script.c                         | 246 +++++++++++++++++++++
 ctdb/common/event_script.h                         |  72 ++++++
 ctdb/common/run_event.c                            | 217 +++++-------------
 ctdb/doc/ctdb.1.xml                                |  95 ++++----
 ctdb/event/event_tool.c                            | 228 ++++++++++++++++---
 ctdb/tests/cunit/event_script_test_001.sh          | 125 +++++++++++
 .../01.disabled.script => data/03.notalink.script} |   1 -
 .../data/{01.dummy.script => 02.disabled.script}   |   0
 .../etc-ctdb/{ => share}/events/empty/README       |   0
 .../{ => share}/events/random/01.disabled.script   |   0
 .../{ => share}/events/random/02.enabled.script    |   0
 .../{ => share}/events/random/README.script        |   0
 .../etc-ctdb/{ => share}/events/random/a.script    |   0
 ctdb/tests/eventd/eventd_001.sh                    |   5 +
 ctdb/tests/eventd/eventd_002.sh                    |   2 +
 ctdb/tests/eventd/eventd_003.sh                    |   9 +
 ctdb/tests/eventd/eventd_009.sh                    | 116 ++++++++++
 ctdb/tests/src/event_script_test.c                 | 119 ++++++++++
 ctdb/tests/src/run_event_test.c                    |   1 +
 ctdb/wscript                                       |   4 +-
 20 files changed, 1000 insertions(+), 240 deletions(-)
 create mode 100644 ctdb/common/event_script.c
 create mode 100644 ctdb/common/event_script.h
 create mode 100755 ctdb/tests/cunit/event_script_test_001.sh
 copy ctdb/tests/eventd/etc-ctdb/events/{random/01.disabled.script => 
data/03.notalink.script} (94%)
 copy ctdb/tests/eventd/etc-ctdb/share/events/data/{01.dummy.script => 
02.disabled.script} (100%)
 copy ctdb/tests/eventd/etc-ctdb/{ => share}/events/empty/README (100%)
 copy ctdb/tests/eventd/etc-ctdb/{ => share}/events/random/01.disabled.script 
(100%)
 copy ctdb/tests/eventd/etc-ctdb/{ => share}/events/random/02.enabled.script 
(100%)
 copy ctdb/tests/eventd/etc-ctdb/{ => share}/events/random/README.script (100%)
 copy ctdb/tests/eventd/etc-ctdb/{ => share}/events/random/a.script (100%)
 create mode 100644 ctdb/tests/src/event_script_test.c


Changeset truncated at 500 lines:

diff --git a/ctdb/common/event_script.c b/ctdb/common/event_script.c
new file mode 100644
index 0000000..8978d14
--- /dev/null
+++ b/ctdb/common/event_script.c
@@ -0,0 +1,246 @@
+/*
+   Low level event script handling
+
+   Copyright (C) Amitay Isaacs  2017
+   Copyright (C) Martin Schwenke  2018
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/dir.h"
+#include "system/glob.h"
+
+#include <talloc.h>
+
+#include "common/event_script.h"
+
+static int script_filter(const struct dirent *de)
+{
+       int ret;
+
+       /* Match a script pattern */
+       ret = fnmatch("[0-9][0-9].*.script", de->d_name, 0);
+       if (ret == 0) {
+               return 1;
+       }
+
+       return 0;
+}
+
+int event_script_get_list(TALLOC_CTX *mem_ctx,
+                         const char *script_dir,
+                         struct event_script_list **out)
+{
+       struct dirent **namelist = NULL;
+       struct event_script_list *script_list = NULL;
+       size_t ds_len;
+       int count, ret;
+       int i;
+
+       count = scandir(script_dir, &namelist, script_filter, alphasort);
+       if (count == -1) {
+               ret = errno;
+               goto done;
+       }
+
+       script_list = talloc_zero(mem_ctx, struct event_script_list);
+       if (script_list == NULL) {
+               goto nomem;
+       }
+
+       if (count == 0) {
+               ret = 0;
+               *out = script_list;
+               goto done;
+       }
+
+       script_list->num_scripts = count;
+       script_list->script = talloc_zero_array(script_list,
+                                               struct event_script *,
+                                               count);
+       if (script_list->script == NULL) {
+               goto nomem;
+       }
+
+       ds_len = strlen(".script");
+       for (i = 0; i < count; i++) {
+               struct event_script *s;
+               struct stat statbuf;
+
+               s = talloc_zero(script_list->script, struct event_script);
+               if (s == NULL) {
+                       goto nomem;
+               }
+
+               script_list->script[i] = s;
+
+               s->name = talloc_strndup(script_list->script,
+                                        namelist[i]->d_name,
+                                        strlen(namelist[i]->d_name) - ds_len);
+               if (s->name == NULL) {
+                       goto nomem;
+               }
+
+               s->path = talloc_asprintf(script_list->script,
+                                         "%s/%s",
+                                         script_dir,
+                                         namelist[i]->d_name);
+               if (s->path == NULL) {
+                       goto nomem;
+               }
+
+               ret = stat(s->path, &statbuf);
+               if (ret == 0) {
+                       /*
+                        * If ret != 0 this is either a dangling
+                        * symlink or it has just disappeared.  Either
+                        * way, it isn't executable.  See the note
+                        * below about things that have disappeared.
+                        */
+                       if (statbuf.st_mode & S_IXUSR) {
+                               s->enabled = true;
+                       }
+               }
+       }
+
+       *out = script_list;
+       return 0;
+
+nomem:
+       ret = ENOMEM;
+       talloc_free(script_list);
+
+done:
+       if (namelist != NULL && count != -1) {
+               for (i=0; i<count; i++) {
+                       free(namelist[i]);
+               }
+               free(namelist);
+       }
+
+       return ret;
+}
+
+int event_script_chmod(const char *script_dir,
+                      const char *script_name,
+                      bool enable)
+{
+       const char *dot_script = ".script";
+       size_t ds_len = strlen(dot_script);
+       size_t sn_len = strlen(script_name);
+       DIR *dirp;
+       struct dirent *de;
+       char buf[PATH_MAX];
+       const char *script_file;
+       int ret, new_mode;
+       char filename[PATH_MAX];
+       struct stat st;
+       bool found;
+       ino_t found_inode;
+       int fd = -1;
+
+       /* Allow script_name to already have ".script" suffix */
+       if (sn_len > ds_len &&
+           strcmp(&script_name[sn_len - ds_len], dot_script) == 0) {
+               script_file = script_name;
+       } else {
+               ret = snprintf(buf, sizeof(buf), "%s.script", script_name);
+               if (ret >= sizeof(buf)) {
+                       return ENAMETOOLONG;
+               }
+               script_file = buf;
+       }
+
+       dirp = opendir(script_dir);
+       if (dirp == NULL) {
+               return errno;
+       }
+
+       found = false;
+       while ((de = readdir(dirp)) != NULL) {
+               if (strcmp(de->d_name, script_file) == 0) {
+                       /* check for valid script names */
+                       ret = script_filter(de);
+                       if (ret == 0) {
+                               closedir(dirp);
+                               return EINVAL;
+                       }
+
+                       found = true;
+                       found_inode = de->d_ino;
+                       break;
+               }
+       }
+       closedir(dirp);
+
+       if (! found) {
+               return ENOENT;
+       }
+
+       ret = snprintf(filename,
+                      sizeof(filename),
+                      "%s/%s",
+                      script_dir,
+                      script_file);
+       if (ret >= sizeof(filename)) {
+               return ENAMETOOLONG;
+       }
+
+       fd = open(filename, O_RDWR);
+       if (fd == -1) {
+               ret = errno;
+               goto done;
+       }
+
+       ret = fstat(fd, &st);
+       if (ret != 0) {
+               ret = errno;
+               goto done;
+       }
+
+       /*
+        * If the directory entry inode number doesn't match the one
+        * returned by fstat() then this is probably a symlink, so the
+        * caller should not be calling this function.  Note that this
+        * is a cheap sanity check to catch most programming errors.
+        * This doesn't cost any extra system calls but can still miss
+        * the unlikely case where the symlink is to a file on a
+        * different filesystem with the same inode number as the
+        * symlink.
+        */
+       if (found && found_inode != st.st_ino) {
+               ret = EINVAL;
+               goto done;
+       }
+
+       if (enable) {
+               new_mode = st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH);
+       } else {
+               new_mode = st.st_mode & ~(S_IXUSR | S_IXGRP | S_IXOTH);
+       }
+
+       ret = fchmod(fd, new_mode);
+       if (ret != 0) {
+               ret = errno;
+               goto done;
+       }
+
+done:
+       if (fd != -1) {
+               close(fd);
+       }
+       return ret;
+}
diff --git a/ctdb/common/event_script.h b/ctdb/common/event_script.h
new file mode 100644
index 0000000..bf5a8fd
--- /dev/null
+++ b/ctdb/common/event_script.h
@@ -0,0 +1,72 @@
+/*
+   Low level event script handling
+
+   Copyright (C) Amitay Isaacs  2017
+   Copyright (C) Martin Schwenke  2018
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CTDB_SCRIPT_H__
+#define __CTDB_SCRIPT_H__
+
+#include "replace.h"
+#include "system/filesys.h"
+
+#include <talloc.h>
+
+/**
+ * @file script.h
+ *
+ * @brief Script listing and manipulation
+ */
+
+
+struct event_script {
+       char *name;
+       char *path;
+       bool enabled;
+};
+
+struct event_script_list {
+       unsigned int num_scripts;
+       struct event_script **script;
+};
+
+
+/**
+ * @brief Retrieve a list of scripts
+ *
+ * @param[in] mem_ctx Talloc memory context
+ * @param[in] script_dir Directory containing scripts
+ * @param[out] out List of scripts
+ * @return 0 on success, errno on failure
+ */
+int event_script_get_list(TALLOC_CTX *mem_ctx,
+                         const char *script_dir,
+                         struct event_script_list **out);
+
+/**
+ * @brief Make a script executable or not executable
+ *
+ * @param[in] script_dir Directory containing script
+ * @param[in] script_name Name of the script to enable
+ * @param[in] executable True if script should be made executable
+ * @return 0 on success, errno on failure
+ */
+int event_script_chmod(const char *script_dir,
+                      const char *script_name,
+                      bool executable);
+
+#endif /* __CTDB_SCRIPT_H__ */
diff --git a/ctdb/common/run_event.c b/ctdb/common/run_event.c
index a215550..91b3dd3 100644
--- a/ctdb/common/run_event.c
+++ b/ctdb/common/run_event.c
@@ -31,177 +31,70 @@
 
 #include "common/logging.h"
 #include "common/run_proc.h"
+#include "common/event_script.h"
+
 #include "common/run_event.h"
 
 /*
  * Utility functions
  */
 
-static int script_filter(const struct dirent *de)
-{
-       int ret;
-
-       /* Match a script pattern */
-       ret = fnmatch("[0-9][0-9].*.script", de->d_name, 0);
-       if (ret == 0) {
-               return 1;
-       }
-
-       return 0;
-}
-
 static int get_script_list(TALLOC_CTX *mem_ctx,
                           const char *script_dir,
                           struct run_event_script_list **out)
 {
-       struct dirent **namelist = NULL;
+       struct event_script_list *s_list;
        struct run_event_script_list *script_list;
-       size_t ls;
-       int count, ret;
-       int i;
+       unsigned int i;
+       int ret;
 
-       count = scandir(script_dir, &namelist, script_filter, alphasort);
-       if (count == -1) {
-               ret = errno;
+       ret = event_script_get_list(mem_ctx, script_dir, &s_list);
+       if (ret != 0) {
                if (ret == ENOENT) {
                        D_WARNING("event script dir %s removed\n", script_dir);
                } else {
-                       D_WARNING("scandir() failed on %s, ret=%d\n",
+                       D_WARNING("failed to get script list for %s, ret=%d\n",
                                  script_dir, ret);
                }
-               *out = NULL;
-               goto done;
+               return ret;
        }
 
-       if (count == 0) {
+       if (s_list->num_scripts == 0) {
                *out = NULL;
-               ret = 0;
-               goto done;
+               talloc_free(s_list);
+               return 0;
        }
 
        script_list = talloc_zero(mem_ctx, struct run_event_script_list);
        if (script_list == NULL) {
+               talloc_free(s_list);
                return ENOMEM;
        }
 
-       script_list->num_scripts = count;
+       script_list->num_scripts = s_list->num_scripts;
        script_list->script = talloc_zero_array(script_list,
                                                struct run_event_script,
-                                               count);
+                                               script_list->num_scripts);
        if (script_list->script == NULL) {
-               ret = ENOMEM;
+               talloc_free(s_list);
                talloc_free(script_list);
-               goto done;
-       }
-
-       ls = strlen(".script");
-       for (i=0; i<count; i++) {
-               struct run_event_script *s = &script_list->script[i];
-
-               s->name = talloc_strndup(script_list,
-                                        namelist[i]->d_name,
-                                        strlen(namelist[i]->d_name) - ls);
-               if (s->name == NULL) {
-                       ret = ENOMEM;
-                       talloc_free(script_list);
-                       goto done;
-               }
-       }
-
-       *out = script_list;
-       ret = 0;
-
-done:
-       if (namelist != NULL && count != -1) {
-               for (i=0; i<count; i++) {
-                       free(namelist[i]);
-               }
-               free(namelist);
-       }
-       return ret;
-}
-
-static int script_chmod(TALLOC_CTX *mem_ctx, const char *script_dir,
-                       const char *script_name, bool enable)
-{
-       DIR *dirp;
-       struct dirent *de;
-       char script_file[PATH_MAX];
-       int ret, new_mode;
-       char *filename;
-       struct stat st;
-       bool found;
-       int fd = -1;
-
-       ret = snprintf(script_file,
-                      sizeof(script_file),
-                      "%s.script",
-                      script_name);
-       if (ret >= sizeof(script_file)) {
-               return ENAMETOOLONG;
-       }
-
-       dirp = opendir(script_dir);
-       if (dirp == NULL) {
-               return errno;
-       }
-
-       found = false;
-       while ((de = readdir(dirp)) != NULL) {
-               if (strcmp(de->d_name, script_file) == 0) {
-
-                       /* check for valid script names */
-                       ret = script_filter(de);
-                       if (ret == 0) {
-                               closedir(dirp);
-                               return EINVAL;
-                       }
-
-                       found = true;
-                       break;
-               }
-       }
-       closedir(dirp);
-
-       if (! found) {
-               return ENOENT;
-       }
-
-       filename = talloc_asprintf(mem_ctx, "%s/%s", script_dir, script_file);
-       if (filename == NULL) {
                return ENOMEM;
        }
 
-       fd = open(filename, O_RDWR);
-       if (fd == -1) {
-               ret = errno;
-               goto done;
-       }


-- 
Samba Shared Repository

Reply via email to