[SCM] Samba Shared Repository - branch master updated

Amitay Isaacs amitay at samba.org
Sat Jul 28 18:04:02 UTC 2018


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 <martin at 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 <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    Autobuild-User(master): Amitay Isaacs <amitay at samba.org>
    Autobuild-Date(master): Sat Jul 28 20:03:52 CEST 2018 on sn-devel-144

commit 5017325c2ef84b10ccd23328f5d62ac5b246bbb3
Author: Martin Schwenke <martin at 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 <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 295826f1b83b6e59d24e4da43b290242c17f44af
Author: Martin Schwenke <martin at 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 <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 82e62488027302e541739628210292c2d95717e1
Author: Martin Schwenke <martin at 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 <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit a7a4ee439dc1cf262b4da9fbcb38a2f69c62744c
Author: Martin Schwenke <martin at 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 <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 56e248de6072063308786ea83282aaecc8d7e62a
Author: Martin Schwenke <martin at 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 <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at 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



More information about the samba-cvs mailing list