#include #include #include #include #include #include #include #include #include #include #include #define LOG_ERR(msg) do { \ fprintf (stderr, "%s : Error (%s)\n", msg, strerror (errno)); \ } while (0) /*This test tests that shard xlator handles offset in appending writes * correctly. This test performs writes of 1025 bytes 1025 times, in 5 threads * with different threads. The buffer to be written is same character repeated * 1025 times in the buffer for a thread. At the end it reads the buffer till * end of file and tests that the read of 1025 bytes is always same character * and the content read is 5*1025*1025 size. 1025 bytes is chosen because it * will lead to write on more than one shard at some point when the size is * going over the initial shard*/ pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; int thread_data = '1'; glfs_t * init_glfs (const char *hostname, const char *volname, const char *logfile) { int ret = -1; glfs_t *fs = NULL; fs = glfs_new (volname); if (!fs) { LOG_ERR ("glfs_new failed"); return NULL; } ret = glfs_set_volfile_server (fs, "tcp", hostname, 24007); if (ret < 0) { LOG_ERR ("glfs_set_volfile_server failed"); goto out; } ret = glfs_set_logging (fs, logfile, 7); if (ret < 0) { LOG_ERR ("glfs_set_logging failed"); goto out; } ret = glfs_init (fs); if (ret < 0) { LOG_ERR ("glfs_init failed"); goto out; } ret = 0; out: if (ret) { glfs_fini (fs); fs = NULL; } return fs; } void* write_data (void *data) { char buf[1025] = {0}; glfs_fd_t *glfd = NULL; glfs_t *fs = data; int i = 0; pthread_mutex_lock (&lock); { memset(buf, thread_data, sizeof(buf)); thread_data++; } pthread_mutex_unlock (&lock); for (i = 0; i < 1025; i++) { glfd = glfs_creat(fs, "parallel-write.txt", O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR | O_SYNC); if (!glfd) { LOG_ERR ("Failed to create file"); exit(1); } if (glfs_write (glfd, buf, sizeof(buf), 0) < 0) { LOG_ERR ("Failed to write to file"); exit(1); } if (glfs_close(glfd) != 0) { LOG_ERR ("Failed to close file"); exit(1); } } return NULL; } int main (int argc, char *argv[]) { pthread_t tid[5] = {0}; char buf[1025] = {0}; char cmp_buf[1025] = {0}; int ret = 0; char *hostname = NULL; char *volname = NULL; char *logfile = NULL; glfs_t *fs = NULL; glfs_fd_t *glfd = NULL; ssize_t bytes_read = 0; ssize_t total_bytes_read = 0; int i = 0; if (argc != 4) { fprintf (stderr, "Invalid argument\n"); exit(1); } hostname = argv[1]; volname = argv[2]; logfile = argv[3]; fs = init_glfs (hostname, volname, logfile); if (fs == NULL) { LOG_ERR ("init_glfs failed"); return -1; } for (i = 0; i < 5; i++) { pthread_create(&tid[i], NULL, write_data, fs); } for (i = 0; i < 5; i++) { pthread_join(tid[i], NULL); } glfd = glfs_open(fs, "parallel-write.txt", O_RDONLY); if (!glfd) { LOG_ERR ("Failed to open file for reading"); exit(1); } while ((bytes_read = glfs_read (glfd, buf, sizeof(buf), 0)) > 0) { if (bytes_read != sizeof(buf)) { fprintf (stderr, "Didn't read complete data read: %zd " "expected: %lu", bytes_read, sizeof(buf)); exit(1); } total_bytes_read += bytes_read; if (buf[0] < '1' || buf[0] >= thread_data) { fprintf(stderr, "Invalid character found: %c", buf[0]); exit(1); } memset(cmp_buf, buf[0], sizeof(cmp_buf)); if (memcmp(cmp_buf, buf, sizeof(cmp_buf))) { LOG_ERR ("Data corrupted"); exit(1); } memset(cmp_buf, 0, sizeof(cmp_buf)); } if (total_bytes_read != 5*1025*1025) { fprintf(stderr, "Failed to read what is written, read; %zd, " "expected %zu", total_bytes_read, 5*1025*1025); exit(1); } if (glfs_close(glfd) != 0) { LOG_ERR ("Failed to close"); exit(1); } return 0; }