summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendrabhat@gluster.com>2012-01-04 19:08:45 +0530
committerRaghavendra Bhat <raghavendrabhat@gluster.com>2012-01-23 00:20:52 +0530
commit80ed64e2245d6604b0052d4fe3c8e537e7975e76 (patch)
tree153ff7394d41f3b1272c1e3337f509466fd7f721
parent050acf41d8ece168016184f3e2ae5be9023cb4b4 (diff)
c_pgms/threaded_io: changes to take arguments from user
Changes to take the working directory and the time duration for which the test has to run from the user. Change-Id: I2d56b0b0b640675dd52f4f3a6f17229e3cdf5d1a Signed-off-by: Raghavendra Bhat <raghavendrabhat@gluster.com>
-rw-r--r--c_pgms/threaded_io/thread_fops.c220
-rw-r--r--c_pgms/threaded_io/thread_fops.h52
2 files changed, 211 insertions, 61 deletions
diff --git a/c_pgms/threaded_io/thread_fops.c b/c_pgms/threaded_io/thread_fops.c
index 8f1267a..f8d874b 100644
--- a/c_pgms/threaded_io/thread_fops.c
+++ b/c_pgms/threaded_io/thread_fops.c
@@ -1,6 +1,140 @@
#include "thread_fops.h"
+static error_t
+thread_parse_opts (int key, char *arg,
+ struct argp_state *_state);
+static void
+thread_default_config (void);
+
+static thread_config_t thread_config;
+
+static struct argp_option thread_options[] = {
+ { "dir", 'd', "DIRECTORY", 0, "absolute or relative path of the tests"},
+ { "time", 't', "TIME", 0, "time duration for which test should run"
+ " (defaults to 600 seconds)"},
+ {0, 0, 0, 0, 0}
+};
+
+static error_t
+thread_parse_opts (int key, char *arg,
+ struct argp_state *_state)
+{
+ switch (key) {
+ case 'd':
+ {
+ int len = 0;
+ int pathlen = 0;
+ int ret = -1;
+ int old_errno = 0;
+ struct stat stbuf = {0,};
+
+ len = strlen (arg) + strlen ("playground");
+ if (len > UNIX_PATH_MAX) {
+ fprintf (stderr, "pathname is too long (%s)\n",
+ arg);
+ return -1;
+ }
+
+ strcpy (thread_config.directory, arg);
+ pathlen = strlen (thread_config.directory);
+ if (thread_config.directory[pathlen - 1] != '/')
+ thread_config.directory[pathlen] = '/';
+ thread_config.directory[pathlen+1] = '\0';
+
+ old_errno = errno;
+ errno = 0;
+ ret = stat (thread_config.directory, &stbuf);
+ if ((ret == -1) || !S_ISDIR (stbuf.st_mode)) {
+ if (errno == ENOENT) {
+ fprintf (stderr, "the directory %s does not "
+ "exist\n", thread_config.directory);
+ return -1;
+ } else {
+ fprintf (stderr, "given path %s is not a "
+ "directory\n",
+ thread_config.directory);
+ return -1;
+ }
+ }
+ strcat (thread_config.directory, "playground");
+ errno = old_errno;
+ }
+ break;
+
+ case 't':
+ {
+ long long time = 0;
+ char *tail = NULL;
+
+ errno = 0;
+ time = strtoll (arg, &tail, 10);
+ if (errno == ERANGE || errno == EINVAL) {
+ fprintf (stderr, "invalid time (%s)\n", arg);
+ return -1;
+ }
+
+ if (tail[0] != '\0') {
+ fprintf (stderr, "invalid time (%s)\n", arg);
+ return -1;
+ }
+
+ if (time < 0) {
+ fprintf (stderr, "time (%s) cannot be -ve\n", arg);
+ return -1;
+ }
+
+ thread_config.time = time;
+ }
+ break;
+
+ case ARGP_KEY_NO_ARGS:
+ break;
+ case ARGP_KEY_ARG:
+ break;
+ case ARGP_KEY_END:
+ if (_state->argc == 1) {
+ //argp_usage (_state);
+ thread_default_config ();
+ }
+
+ }
+
+ return 0;
+}
+
+static struct argp argp = {
+ thread_options,
+ thread_parse_opts,
+ "",
+ "threaded-io - tool which spawns multiple threads, with each thread "
+ "opening the same file and doing different fops on their respective "
+ "fds"
+};
+
+static void
+thread_default_config (void)
+{
+ int ret = -1;
+ char playground[UNIX_PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+
+ getcwd (playground, sizeof (playground));
+
+ ret = stat (playground, &stbuf);
+ if (ret == -1) {
+ fprintf (stderr, "Error: %s: The playground directory %s "
+ "seems to have an error (%s)", __FUNCTION__,
+ playground, strerror (errno));
+ return;
+ }
+
+ strcat (playground, "/playground");
+ strcpy (thread_config.directory, playground);
+
+ thread_config.time = 600;
+}
+
int
main(int argc, char *argv[])
{
@@ -25,6 +159,15 @@ main(int argc, char *argv[])
opendir_and_readdir,
};
+ thread_default_config ();
+
+ ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
+ if (ret != 0) {
+ ret = -1;
+ fprintf (stderr, "%s: argp_parse() failed\n", argv[0]);
+ goto err;
+ }
+
open_t *file = NULL;
file = (open_t *)calloc(1,sizeof(*file));
if (!file) {
@@ -38,7 +181,7 @@ main(int argc, char *argv[])
file->flags = O_CREAT | O_RDWR;
file->mode = 0755;
- fstat_t *inode;
+ fstat_t *inode = NULL;
inode = (fstat_t *)calloc(1,sizeof(*inode));
if (!inode) {
fprintf (stderr, "%s:out of memory\n",
@@ -46,6 +189,7 @@ main(int argc, char *argv[])
goto out;
}
+ inode->buf = NULL;
inode->buf = (struct stat *)calloc(1,sizeof(struct stat));
if (!inode->buf) {
fprintf (stderr, "%s:Out of memory\n",
@@ -55,7 +199,7 @@ main(int argc, char *argv[])
int fd_main = -1;
- oft *both;
+ oft *both = NULL;
both = (oft *)calloc(1,sizeof(*both));
if (!both) {
fprintf (stderr, "%s:out of memory\n",
@@ -63,20 +207,8 @@ main(int argc, char *argv[])
goto out;
}
- if (argc > 1)
- strncpy (playground, argv[1], strlen (argv[1]));
- else
- getcwd (playground, sizeof (playground));
-
- ret = stat (playground, &stbuf);
- if (ret == -1) {
- fprintf (stderr, "Error: %s: The playground directory %s "
- "seems to have an error (%s)", __FUNCTION__,
- playground, strerror (errno));
- goto out;
- }
+ strcpy (playground, thread_config.directory);
- strcat (playground, "/playground");
ret = mkdir (playground, 0755);
if (ret == -1 && (errno != EEXIST) ) {
fprintf (stderr, "Error: Error creating the playground ",
@@ -85,7 +217,8 @@ main(int argc, char *argv[])
goto out;
}
- printf ("Switching over to the working directory %s\n", playground);
+ printf ("Switching over to the working directory %s time %llu\n",
+ playground, thread_config.time);
ret = chdir (playground);
if (ret == -1) {
fprintf (stderr, "Error changing directory to the playground %s",
@@ -111,33 +244,45 @@ main(int argc, char *argv[])
i++;
}
- sleep (600);
+ sleep (thread_config.time);
printf ("Total Statistics ======>\n");
- printf ("Opens : %d/%d\n", info.num_open_success,info.num_open);
- printf ("Reads : %d/%d\n", info.read_success, info.read);
- printf ("Writes : %d/%d\n", info.write_success, info.write);
- printf ("Flocks : %d/%d\n", info.flocks_success, info.flocks);
- printf ("fcntl locks : %d/%d\n", info.fcntl_locks_success,
+ printf ("Opens : %llu/%llu\n", info.num_open_success,info.num_open);
+ printf ("Reads : %llu/%llu\n", info.read_success, info.read);
+ printf ("Writes : %llu/%llu\n", info.write_success, info.write);
+ printf ("Flocks : %llu/%llu\n", info.flocks_success, info.flocks);
+ printf ("fcntl locks : %llu/%llu\n", info.fcntl_locks_success,
info.fcntl_locks);
- printf ("Truncates : %d/%d\n", info.truncate_success, info.truncate);
- printf ("Fstat : %d/%d\n", info.fstat_success, info.fstat);
- printf ("Chown : %d/%d\n", info.chown_success, info.chown);
- printf ("Opendir : %d/%d\n", info.opendir_success, info.opendir);
- printf ("Readdir : %d/%d\n", info.readdir_success, info.readdir);
+ printf ("Truncates : %llu/%llu\n", info.truncate_success, info.truncate);
+ printf ("Fstat : %llu/%llu\n", info.fstat_success, info.fstat);
+ printf ("Chown : %llu/%llu\n", info.chown_success, info.chown);
+ printf ("Opendir : %llu/%llu\n", info.opendir_success, info.opendir);
+ printf ("Readdir : %llu/%llu\n", info.readdir_success, info.readdir);
ret = 0;
out:
- if (both)
- free(both);
- if (inode->buf)
- free (inode->buf);
- if (inode)
- free (inode);
- if (file)
+ if (file) {
free (file);
+ file = NULL;
+ }
+ if (inode) {
+ if (inode->buf) {
+ free (inode->buf);
+ inode->buf = NULL;
+ }
+ free (inode);
+ inode = NULL;
+ }
+ if (both) {
+ both->open = NULL;
+ both->fstat = NULL;
+ free(both);
+ both = NULL;
+ }
pthread_mutex_destroy (&info.mutex);
+
+err:
return ret;
}
@@ -260,8 +405,6 @@ open_thread(void *tmp)
close (fd);
}
out:
- if (file)
- free(file);
return NULL;
}
@@ -315,12 +458,7 @@ fstat_thread(void *ptr)
}
out:
-
close (fd);
- if (inode->buf)
- free (inode->buf);
- if (inode)
- free(inode);
return NULL;
}
diff --git a/c_pgms/threaded_io/thread_fops.h b/c_pgms/threaded_io/thread_fops.h
index 44479e6..545145d 100644
--- a/c_pgms/threaded_io/thread_fops.h
+++ b/c_pgms/threaded_io/thread_fops.h
@@ -9,6 +9,8 @@
#include <string.h>
#include <pthread.h>
#include <dirent.h>
+#include <argp.h>
+#include <libgen.h>
void * open_thread (void *);
void * fstat_thread (void *);
@@ -68,28 +70,38 @@ typedef struct open_fstat oft;
} \
} while (0);
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 4096
+#endif
+
typedef struct info {
pthread_mutex_t mutex;
- unsigned int num_open;
- unsigned int num_open_success;
- unsigned int flocks;
- unsigned int flocks_success;
- unsigned int fcntl_locks;
- unsigned int fcntl_locks_success;
- unsigned int read;
- unsigned int read_success;
- unsigned int write;
- unsigned int write_success;
- unsigned int fstat;
- unsigned int fstat_success;
- unsigned int truncate;
- unsigned int truncate_success;
- unsigned int chown;
- unsigned int chown_success;
- unsigned int opendir;
- unsigned int opendir_success;
- unsigned int readdir;
- unsigned int readdir_success;
+ unsigned long long num_open;
+ unsigned long long num_open_success;
+ unsigned long long flocks;
+ unsigned long long flocks_success;
+ unsigned long long fcntl_locks;
+ unsigned long long fcntl_locks_success;
+ unsigned long long read;
+ unsigned long long read_success;
+ unsigned long long write;
+ unsigned long long write_success;
+ unsigned long long fstat;
+ unsigned long long fstat_success;
+ unsigned long long truncate;
+ unsigned long long truncate_success;
+ unsigned long long chown;
+ unsigned long long chown_success;
+ unsigned long long opendir;
+ unsigned long long opendir_success;
+ unsigned long long readdir;
+ unsigned long long readdir_success;
} info_t;
+typedef struct
+{
+ char directory[UNIX_PATH_MAX];
+ unsigned long long time;
+} thread_config_t;
+
info_t info = {0,};