diff options
Diffstat (limited to 'community-scripts/rename/atomic')
-rw-r--r-- | community-scripts/rename/atomic/bug1034.tar | bin | 0 -> 20480 bytes | |||
-rw-r--r-- | community-scripts/rename/atomic/bug1034/README | 88 | ||||
-rw-r--r-- | community-scripts/rename/atomic/bug1034/gt.h | 12 | ||||
-rw-r--r-- | community-scripts/rename/atomic/bug1034/gt_init.c | 114 | ||||
-rw-r--r-- | community-scripts/rename/atomic/bug1034/gt_read.c | 131 | ||||
-rw-r--r-- | community-scripts/rename/atomic/bug1034/gt_rename.c | 86 | ||||
-rw-r--r-- | community-scripts/rename/atomic/bug1034/volume.info | 10 | ||||
-rw-r--r-- | community-scripts/rename/atomic/reader.c | 23 | ||||
-rw-r--r-- | community-scripts/rename/atomic/writer.c | 48 |
9 files changed, 512 insertions, 0 deletions
diff --git a/community-scripts/rename/atomic/bug1034.tar b/community-scripts/rename/atomic/bug1034.tar Binary files differnew file mode 100644 index 0000000..88b5eb5 --- /dev/null +++ b/community-scripts/rename/atomic/bug1034.tar 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;
+}
|