summaryrefslogtreecommitdiffstats
path: root/community-scripts/rename/atomic
diff options
context:
space:
mode:
Diffstat (limited to 'community-scripts/rename/atomic')
-rw-r--r--community-scripts/rename/atomic/bug1034.tarbin0 -> 20480 bytes
-rw-r--r--community-scripts/rename/atomic/bug1034/README88
-rw-r--r--community-scripts/rename/atomic/bug1034/gt.h12
-rw-r--r--community-scripts/rename/atomic/bug1034/gt_init.c114
-rw-r--r--community-scripts/rename/atomic/bug1034/gt_read.c131
-rw-r--r--community-scripts/rename/atomic/bug1034/gt_rename.c86
-rw-r--r--community-scripts/rename/atomic/bug1034/volume.info10
-rw-r--r--community-scripts/rename/atomic/reader.c23
-rw-r--r--community-scripts/rename/atomic/writer.c48
9 files changed, 512 insertions, 0 deletions
diff --git a/community-scripts/rename/atomic/bug1034.tar b/community-scripts/rename/atomic/bug1034.tar
new file mode 100644
index 0000000..88b5eb5
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034.tar
Binary files differ
diff --git a/community-scripts/rename/atomic/bug1034/README b/community-scripts/rename/atomic/bug1034/README
new file mode 100644
index 0000000..fd0acd7
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034/README
@@ -0,0 +1,88 @@
+*** Cluster and Gluster Configuration
+
+The cluster has MAX nodes. Each node has a gluster brick.
+The bricks are assembled into a single gluster volume, using
+pure replication. The gluster volume is mounted at the same
+BASE_PATH on each node.
+
+Edit BASE_PATH in gt.h to the appropriate path before
+compiling.
+
+Compile the test programs
+ cc gt_init.c -o gt_init
+ cc gt_rename.c -o gt_rename
+ cc gt_read.c -o gt_read
+And distribute them to all nodes of the cluster.
+
+*** Test Configuration
+
+There are three test programs.
+
+One instance of gt_init is run once, on any node in
+the cluster, before the other test processes are started.
+This cleans up and initializes the contents of BASE_PATH,
+then terminates.
+
+An instance of gt_rename runs on every node. Each instance is
+started with a numeral from 1 to MAX as a command line argument.
+These continuously replace a set of files by renaming a temp
+file on top of existing files.
+
+An instance of gt_read runs on every node. Each instance is
+started with a numeral from 1 to MAX as a command line argument.
+These continuously read all the files touched by the set of
+gt_rename processes.
+
+I.e., with cluster nodes numbered 1 to MAX, on node n start:
+ gt_rename n &
+ gt_read MAX &
+
+*** File Structure
+
+BASE_PATH/1/WA_RC_0
+ /WA_RC_1
+ /WA_RC_2
+ /...
+ /MAX/WA_RC_0
+ /WA_RC_1
+ /WA_RC_2
+
+There is a directory under BASE_PATH for each node,
+numbered 1 through MAX.
+
+gt_rename processes manipulate files only within
+their node's directory.
+
+gt_read test process reads all files and writes no
+file.
+
+Every file is written by only one test process.
+The contents of every directory (not directory tree)
+is written by only one test process.
+
+Every file is read by MAX test processes other than
+the single writing test process.
+
+*** Test Operation
+
+The gt_init process destroys any existing file structure
+under BASE_PATH, then creates and initializes the contents
+of the file structure.
+
+The gt_rename processes always write a fixed distinctive
+value into each file they write. They open a temp file, write a
+fixed value, and rename the file onto the standard file.
+The fixed value is different for every standard file.
+
+The gt_rename and gt_read processes always test each file for
+existence, then check the contents for the expected distinctive
+value, for each file they access. Apparently missing files or
+unexpected contents are logged.
+
+The gt_rename and gt_read processes iterate every CYCLE_TIME
++[0..CYCLE_JITTER) milliseconds until terminated.
+
+By observing the output of the gt_read processes, the
+characteristics of bug1034 can be seen. On node n, gt_read
+gets ENOENT for open and for read-after-successful-open on
+BASE_PATH/n/*.
diff --git a/community-scripts/rename/atomic/bug1034/gt.h b/community-scripts/rename/atomic/bug1034/gt.h
new file mode 100644
index 0000000..da6a57c
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034/gt.h
@@ -0,0 +1,12 @@
+#ifndef _BUG1034_TEST_
+#define _BUG1034_TEST_
+
+// #define BASE_PATH "/common_mount_point/test_directory"
+#define BASE_PATH "/sme_cluster/global/bug1034_test"
+
+#define CYCLE_TIME 5
+#define CYCLE_JITTER 5
+
+#define SUBDIR_FILES 3
+
+#endif /* ! _BUG1034_TEST_ */
diff --git a/community-scripts/rename/atomic/bug1034/gt_init.c b/community-scripts/rename/atomic/bug1034/gt_init.c
new file mode 100644
index 0000000..f3dadf0
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034/gt_init.c
@@ -0,0 +1,114 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gt.h"
+
+static void
+usage(char *progname)
+{
+ fprintf(stderr, "usage: %s node_count\n", progname);
+ exit(1);
+}
+
+// rm -rf
+static void
+delete_tree(char *rootpath)
+{
+ int retval;
+ struct stat statbuf;
+
+ retval = lstat(rootpath, &statbuf);
+ if (retval < 0) {
+ return;
+ }
+
+ if (S_ISDIR(statbuf.st_mode)) {
+ DIR *dir;
+ struct dirent *dent;
+ char pathbuf[PATH_MAX];
+
+ dir = opendir(rootpath);
+ while ((dent = readdir(dir)) != NULL) {
+ if (0 == strcmp(".", dent->d_name)) {
+ continue;
+ }
+ if (0 == strcmp("..", dent->d_name)) {
+ continue;
+ }
+ snprintf(pathbuf, sizeof(pathbuf),
+ "%s/%s", rootpath, dent->d_name);
+ delete_tree(pathbuf);
+ }
+ closedir(dir);
+
+ (void)rmdir(rootpath);
+ } else {
+ (void)unlink(rootpath);
+ }
+}
+
+static void
+create_subdir(char *dirpath)
+{
+ int i;
+
+ mkdir(dirpath, 0775);
+
+ for (i = 0; i < SUBDIR_FILES; i++) {
+ char pathbuf[PATH_MAX];
+ int fd;
+
+ snprintf(pathbuf, sizeof(pathbuf),
+ "%s/WA_RC_%d", dirpath, i);
+ fd = open(pathbuf, O_RDWR|O_CREAT, 0664);
+ write(fd, pathbuf, strlen(pathbuf));
+ close(fd);
+ }
+}
+
+static void
+create_tree(char *rootpath, int node_count)
+{
+ int n;
+
+ mkdir(rootpath, 0775);
+
+ for (n = 1; n <= node_count; n++) {
+ char pathbuf[PATH_MAX];
+ int fd;
+
+ snprintf(pathbuf, sizeof(pathbuf),
+ "%s/%d", rootpath, n);
+ mkdir(pathbuf, 0775);
+ create_subdir(pathbuf);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ char *arg_ptr;
+ long node_count;
+
+ if (argc != 2) {
+ usage(argv[0]);
+ }
+
+ node_count = strtol(argv[1], &arg_ptr, 10);
+ if (*arg_ptr != '\0') {
+ usage(argv[0]);
+ }
+
+ delete_tree(BASE_PATH);
+
+ create_tree(BASE_PATH, node_count);
+
+ exit(0);
+}
diff --git a/community-scripts/rename/atomic/bug1034/gt_read.c b/community-scripts/rename/atomic/bug1034/gt_read.c
new file mode 100644
index 0000000..7d07d59
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034/gt_read.c
@@ -0,0 +1,131 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "gt.h"
+
+static void
+usage(char *progname)
+{
+ fprintf(stderr, "usage: %s node_count\n", progname);
+ exit(1);
+}
+
+static void
+dump_data(char *buf, size_t buflen)
+{
+ int i;
+
+ fprintf(stderr, "raw data: ");
+ for (i = 0; i < buflen; i++) {
+ int c = buf[i];
+
+ if (isgraph(c)) {
+ fprintf(stderr, "%c", c);
+ } else if (isspace(c)) {
+ switch (c) {
+ case ' ':
+ fprintf(stderr, " ");
+ break;
+ case '\f':
+ fprintf(stderr, "\f");
+ break;
+ case '\n':
+ fprintf(stderr, "\n");
+ break;
+ case '\r':
+ fprintf(stderr, "\r");
+ break;
+ case '\t':
+ fprintf(stderr, "\t");
+ break;
+ case '\v':
+ fprintf(stderr, "\v");
+ break;
+ default:
+ fprintf(stderr, "\%03o", c);
+ break;
+ }
+ } else {
+ fprintf(stderr, "\%03o", c);
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+static void
+touch_tree(char *rootpath, int node_count)
+{
+ char pathbuf[PATH_MAX];
+ char databuf[PATH_MAX];
+ int fd;
+ int node;
+ int i;
+ int retval;
+
+ for (node = 1; node <= node_count; node++) {
+ for (i = 0; i < SUBDIR_FILES; i++) {
+ snprintf(pathbuf, sizeof(pathbuf),
+ "%s/%d/WA_RC_%d", rootpath, node, i);
+ fd = open(pathbuf, O_RDONLY);
+ if (0 > fd) {
+ fprintf(stderr, "gt_read: %s: open %s\n",
+ strerror(errno), pathbuf);
+ continue;
+ }
+ retval = read(fd, databuf, sizeof(databuf));
+ close(fd);
+ if (0 > retval) {
+ fprintf(stderr, "gt_read: %s: read %s\n",
+ strerror(errno), pathbuf);
+ } else if (retval != strlen(pathbuf)) {
+ fprintf(stderr,
+ "gt_read: incomplete read: read %s\n",
+ pathbuf);
+ } else {
+ databuf[retval] = '\0';
+ if (0 != strcmp(pathbuf, databuf)) {
+ fprintf(stderr,
+ "gt_read: bad data: read %s\n",
+ pathbuf);
+ dump_data(databuf, strlen(pathbuf));
+ }
+ }
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ char *arg_ptr;
+ long node_count;
+
+ if (argc != 2) {
+ usage(argv[0]);
+ }
+
+ node_count = strtol(argv[1], &arg_ptr, 10);
+ if (*arg_ptr != '\0') {
+ usage(argv[0]);
+ }
+
+ while (1) {
+ int snooze;
+
+ touch_tree(BASE_PATH, node_count);
+
+ snooze = CYCLE_TIME + random()%CYCLE_JITTER;
+ usleep(1000*snooze);
+ }
+
+ exit(0);
+}
diff --git a/community-scripts/rename/atomic/bug1034/gt_rename.c b/community-scripts/rename/atomic/bug1034/gt_rename.c
new file mode 100644
index 0000000..96ecce0
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034/gt_rename.c
@@ -0,0 +1,86 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gt.h"
+
+static void
+usage(char *progname)
+{
+ fprintf(stderr, "usage: %s node\n", progname);
+ exit(1);
+}
+
+static void
+touch_tree(char *rootpath, int node)
+{
+ char pathbuf[PATH_MAX];
+ char databuf[PATH_MAX];
+ int fd;
+ int i;
+ int retval;
+
+ for (i = 0; i < SUBDIR_FILES; i++) {
+ char tempbuf[PATH_MAX];
+
+ snprintf(pathbuf, sizeof(pathbuf),
+ "%s/%d/WA_RC_%d", rootpath, node, i);
+ snprintf(tempbuf, sizeof(tempbuf),
+ "%s/%d/WA_RC_%d.temp", rootpath, node, i);
+ fd = open(tempbuf, O_RDWR|O_CREAT, 0644);
+ if (0 > fd) {
+ fprintf(stderr, "gt_rename: %s: open %s\n",
+ strerror(errno), tempbuf);
+ continue;
+ }
+ retval = write(fd, pathbuf, strlen(pathbuf));
+ if (0 > retval) {
+ fprintf(stderr, "gt_rename: %s: write %s\n",
+ strerror(errno), pathbuf);
+ } else if (retval != strlen(pathbuf)) {
+ fprintf(stderr, "gt_rename: incomplete write: write %s\n",
+ pathbuf);
+ }
+ close(fd);
+
+ retval = rename(tempbuf, pathbuf);
+ if (0 > retval) {
+ fprintf(stderr, "gt_rename: %s rename %s\n",
+ strerror(errno), pathbuf);
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ char *arg_ptr;
+ long node;
+
+ if (argc != 2) {
+ usage(argv[0]);
+ }
+
+ node = strtol(argv[1], &arg_ptr, 10);
+ if (*arg_ptr != '\0') {
+ usage(argv[0]);
+ }
+
+ while (1) {
+ int snooze;
+
+ touch_tree(BASE_PATH, node);
+
+ snooze = CYCLE_TIME + random()%CYCLE_JITTER;
+ usleep(1000*snooze);
+ }
+
+ exit(0);
+}
diff --git a/community-scripts/rename/atomic/bug1034/volume.info b/community-scripts/rename/atomic/bug1034/volume.info
new file mode 100644
index 0000000..68d654e
--- /dev/null
+++ b/community-scripts/rename/atomic/bug1034/volume.info
@@ -0,0 +1,10 @@
+type=2
+count=2
+status=1
+sub_count=2
+version=1
+transport-type=0
+volume-id=01234567-89ab-cdef-0123-456789abcdef
+brick-0=host0:-our-brick-location
+brick-1=host1:-our-brick-location
+
diff --git a/community-scripts/rename/atomic/reader.c b/community-scripts/rename/atomic/reader.c
new file mode 100644
index 0000000..d25d9d8
--- /dev/null
+++ b/community-scripts/rename/atomic/reader.c
@@ -0,0 +1,23 @@
+/*
+ gcc reader.c -o reader -Wall
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main(void)
+{
+ int fd;
+
+ for (;;) {
+ usleep(rand() % 1000);
+ fd = open("dovecot.index", O_RDONLY);
+ if (fd == -1) {
+ perror("open(dovecot.index)");
+ break;
+ }
+ close(fd);
+ }
+ return 0;
+}
diff --git a/community-scripts/rename/atomic/writer.c b/community-scripts/rename/atomic/writer.c
new file mode 100644
index 0000000..16d07e1
--- /dev/null
+++ b/community-scripts/rename/atomic/writer.c
@@ -0,0 +1,48 @@
+/*
+ gcc writer.c -o writer -Wall
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main(void)
+{
+ int fd_old, fd_new, ret;
+
+ for (;;) {
+ fd_old = open("dovecot.index", O_RDWR);
+ if (fd_old == -1) {
+ perror("open(dovecot.index");
+ break;
+ }
+
+ usleep(rand() % 1000);
+ fd_new = creat("dovecot.index.tmp", 0600);
+ if (fd_new == -1) {
+ perror("creat(dovecot.index.tmp)");
+ break;
+ }
+ write(fd_new, "foo", 3);
+ close(fd_new);
+
+ ret = link("dovecot.index", "dovecot.index.backup.tmp");
+ if (ret < 0) {
+ perror("link(dovecot.index, dovecot.index.backup.tmp)");
+ break;
+ }
+ if (rename("dovecot.index.backup.tmp", "dovecot.index.backup") < 0) {
+ perror("rename(dovecot.index.backup.tmp, dovecot.index.backup)");
+ break;
+ }
+
+ usleep(rand() % 1000);
+ if (rename("dovecot.index.tmp", "dovecot.index") < 0) {
+ perror("rename(dovecot.index.tmp, dovecot.index)");
+ break;
+ }
+ usleep(rand() % 1000);
+ close(fd_old);
+ }
+ return 0;
+}