summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@gluster.com>2010-10-02 07:30:38 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-10-02 06:30:18 -0700
commit067d0e476abe42f1e290039cb903928080e90d8d (patch)
tree2dfa9c04911ddedf283c5e4fac9ff9c41fb28ee6
parent1cc15f9b0057cd6c8843c8b9cbb36c02d334ec6f (diff)
implemented graph printing
Signed-off-by: Csaba Henk <csaba@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 1750 (clean up volgen) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1750
-rw-r--r--libglusterfs/src/Makefile.am4
-rw-r--r--libglusterfs/src/graph-mem-types.h32
-rw-r--r--libglusterfs/src/graph-print.c200
-rw-r--r--libglusterfs/src/graph-utils.h29
-rw-r--r--libglusterfs/src/mem-pool.c25
-rw-r--r--libglusterfs/src/mem-pool.h4
6 files changed, 285 insertions, 9 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index 3513419eb..71a088d98 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -6,9 +6,9 @@ libglusterfs_la_LIBADD = @LEXLIB@
lib_LTLIBRARIES = libglusterfs.la
-libglusterfs_la_SOURCES = dict.c graph.lex.c y.tab.c xlator.c logging.c hashfn.c defaults.c common-utils.c timer.c inode.c call-stub.c compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c globals.c statedump.c stack.c checksum.c $(CONTRIBDIR)/md5/md5.c $(CONTRIBDIR)/rbtree/rb.c rbthash.c latency.c graph.c $(CONTRIBDIR)/uuid/clear.c $(CONTRIBDIR)/uuid/copy.c $(CONTRIBDIR)/uuid/gen_uuid.c $(CONTRIBDIR)/uuid/pack.c $(CONTRIBDIR)/uuid/tst_uuid.c $(CONTRIBDIR)/uuid/parse.c $(CONTRIBDIR)/uuid/unparse.c $(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c $(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c
+libglusterfs_la_SOURCES = dict.c graph.lex.c y.tab.c xlator.c logging.c hashfn.c defaults.c common-utils.c timer.c inode.c call-stub.c compat.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c globals.c statedump.c stack.c checksum.c $(CONTRIBDIR)/md5/md5.c $(CONTRIBDIR)/rbtree/rb.c rbthash.c latency.c graph.c $(CONTRIBDIR)/uuid/clear.c $(CONTRIBDIR)/uuid/copy.c $(CONTRIBDIR)/uuid/gen_uuid.c $(CONTRIBDIR)/uuid/pack.c $(CONTRIBDIR)/uuid/tst_uuid.c $(CONTRIBDIR)/uuid/parse.c $(CONTRIBDIR)/uuid/unparse.c $(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c $(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c graph-print.c
-noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h xlator.h stack.h timer.h list.h inode.h call-stub.h compat.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h globals.h statedump.h checksum.h $(CONTRIBDIR)/md5/md5.h $(CONTRIBDIR)/rbtree/rb.h rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h $(CONTRIBDIR)/uuid/uuid_types.h syncop.h
+noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h xlator.h stack.h timer.h list.h inode.h call-stub.h compat.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h globals.h statedump.h checksum.h $(CONTRIBDIR)/md5/md5.h $(CONTRIBDIR)/rbtree/rb.h rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h $(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h $(CONTRIBDIR)/uuid/uuid_types.h syncop.h graph-utils.h graph-mem-types.h
EXTRA_DIST = graph.l graph.y
diff --git a/libglusterfs/src/graph-mem-types.h b/libglusterfs/src/graph-mem-types.h
new file mode 100644
index 000000000..49feb76c4
--- /dev/null
+++ b/libglusterfs/src/graph-mem-types.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS 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.
+
+ GlusterFS 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 __GRAPH_MEM_TYPES_H__
+#define __GRAPH_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
+
+enum gfd_mem_types_ {
+ gf_graph_mt_buf = GF_MEM_TYPE_START,
+ gfd_mt_end
+};
+#endif
+
diff --git a/libglusterfs/src/graph-print.c b/libglusterfs/src/graph-print.c
new file mode 100644
index 000000000..a6c20c735
--- /dev/null
+++ b/libglusterfs/src/graph-print.c
@@ -0,0 +1,200 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS 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.
+
+ GlusterFS 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/uio.h>
+
+#include "common-utils.h"
+#include "xlator.h"
+#include "graph-mem-types.h"
+#include "graph-utils.h"
+
+
+
+struct gf_printer {
+ ssize_t (*write) (struct gf_printer *gp, char *buf, size_t len);
+ void *priv;
+};
+
+static ssize_t
+gp_write_file (struct gf_printer *gp, char *buf, size_t len)
+{
+ FILE *f = gp->priv;
+
+ if (fwrite (buf, len, 1, f) != 1) {
+ gf_log ("graph-print", GF_LOG_ERROR, "fwrite failed (%s)",
+ strerror (errno));
+
+ return -1;
+ }
+
+ return len;
+}
+
+static ssize_t
+gp_write_buf (struct gf_printer *gp, char *buf, size_t len)
+{
+ struct iovec *iov = gp->priv;
+
+ if (iov->iov_len < len) {
+ gf_log ("graph-print", GF_LOG_ERROR, "buffer full");
+
+ return -1;
+ }
+
+ memcpy (iov->iov_base, buf, len);
+ iov->iov_base += len;
+ iov->iov_len -= len;
+
+ return len;
+}
+
+static int
+gpprintf (struct gf_printer *gp, const char *format, ...)
+{
+ va_list arg;
+ char *str = NULL;
+ int ret = 0;
+
+ va_start (arg, format);
+ ret = gf_vasprintf (&str, format, arg);
+ va_end (arg);
+
+ if (ret < 0)
+ return ret;
+
+ ret = gp->write (gp, str, ret);
+
+ GF_FREE (str);
+
+ return ret;
+}
+
+static int
+glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
+{
+#define GPPRINTF(gp, fmt, ...) do { \
+ ret = gpprintf (gp, fmt, ## __VA_ARGS__); \
+ if (ret == -1) \
+ goto out; \
+ else \
+ len += ret; \
+} while (0)
+
+ xlator_t *trav = NULL;
+ data_pair_t *pair = NULL;
+ xlator_list_t *xch = NULL;
+ int ret = 0;
+ ssize_t len = 0;
+
+ if (!graph->first)
+ return 0;
+
+ for (trav = graph->first; trav->next; trav = trav->next);
+ for (; trav; trav = trav->prev) {
+ GPPRINTF (gp, "volume %s\n type %s\n", trav->name,
+ trav->type);
+
+ for (pair = trav->options->members_list; pair && pair->next;
+ pair = pair->next);
+ for (; pair; pair = pair->prev)
+ GPPRINTF (gp, " option %s %s\n", pair->key,
+ pair->value->data);
+
+ if (trav->children) {
+ GPPRINTF (gp, " subvolumes");
+
+ for (xch = trav->children; xch; xch = xch->next)
+ GPPRINTF (gp, " %s", xch->xlator->name);
+
+ GPPRINTF (gp, "\n");
+ }
+
+ GPPRINTF (gp, "end-volume\n");
+ if (trav != graph->first)
+ GPPRINTF (gp, "\n");
+ }
+
+ out:
+ if (ret == -1) {
+ gf_log ("graph-print", GF_LOG_ERROR, "printing failed");
+
+ return -1;
+ }
+
+ return len;
+
+#undef GPPRINTF
+}
+
+int
+glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph)
+{
+ struct gf_printer gp = { .write = gp_write_file,
+ .priv = file
+ };
+
+ return glusterfs_graph_print (&gp, graph);
+}
+
+char *
+glusterfs_graph_print_buf (glusterfs_graph_t *graph)
+{
+ FILE *f = NULL;
+ struct iovec iov = {0,};
+ int len = 0;
+ char *buf = NULL;
+ struct gf_printer gp = { .write = gp_write_buf,
+ .priv = &iov
+ };
+
+ f = fopen ("/dev/null", "a");
+ if (!f) {
+ gf_log ("graph-print", GF_LOG_ERROR,
+ "cannot open /dev/null (%s)", strerror (errno));
+
+ return NULL;
+ }
+ len = glusterfs_graph_print_file (f, graph);
+ fclose (f);
+ if (len == -1)
+ return NULL;
+
+ buf = GF_CALLOC (1, len + 1, gf_graph_mt_buf);
+ if (!buf) {
+ gf_log ("graph-print", GF_LOG_ERROR, "Out of memory");
+
+ return NULL;
+ }
+ iov.iov_base = buf;
+ iov.iov_len = len;
+
+ len = glusterfs_graph_print (&gp, graph);
+ if (len == -1) {
+ GF_FREE (buf);
+
+ return NULL;
+ }
+
+ return buf;
+}
diff --git a/libglusterfs/src/graph-utils.h b/libglusterfs/src/graph-utils.h
new file mode 100644
index 000000000..359cdcc7a
--- /dev/null
+++ b/libglusterfs/src/graph-utils.h
@@ -0,0 +1,29 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS 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.
+
+ GlusterFS 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 _GRAPH_H_
+#define _GRAPH_H_
+
+int
+glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph);
+
+char *
+glusterfs_graph_print_buf (glusterfs_graph_t *graph);
+
+#endif
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index f266ce61f..1223b3711 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -197,9 +197,9 @@ __gf_realloc (void *ptr, size_t size)
}
int
-gf_asprintf (char **string_ptr, const char *format, ...)
+gf_vasprintf (char **string_ptr, const char *format, va_list arg)
{
- va_list arg;
+ va_list arg_save;
char *str = NULL;
int size = 0;
int rv = 0;
@@ -207,13 +207,12 @@ gf_asprintf (char **string_ptr, const char *format, ...)
if (!string_ptr || !format)
return -1;
- va_start (arg, format);
+ va_copy (arg_save, arg);
+
size = vsnprintf (NULL, 0, format, arg);
size++;
- va_start (arg, format);
str = GF_MALLOC (size, gf_common_mt_asprintf);
if (str == NULL) {
- va_end (arg);
/*
* Strictly speaking, GNU asprintf doesn't do this,
* but the caller isn't checking the return value.
@@ -222,13 +221,25 @@ gf_asprintf (char **string_ptr, const char *format, ...)
"failed to allocate memory");
return -1;
}
- rv = vsnprintf( str, size, format, arg);
- va_end (arg);
+ rv = vsnprintf (str, size, format, arg_save);
*string_ptr = str;
return (rv);
}
+int
+gf_asprintf (char **string_ptr, const char *format, ...)
+{
+ va_list arg;
+ int rv = 0;
+
+ va_start (arg, format);
+ rv = gf_vasprintf (string_ptr, format, arg);
+ va_end (arg);
+
+ return rv;
+}
+
void
__gf_free (void *free_ptr)
{
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index 0b467bb2c..21ff4c801 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
+#include <stdarg.h>
#define MALLOC(size) malloc(size)
@@ -61,6 +62,9 @@ void *
__gf_realloc (void *ptr, size_t size);
int
+gf_vasprintf (char **string_ptr, const char *format, va_list arg);
+
+int
gf_asprintf (char **string_ptr, const char *format, ...);
#define GF_CALLOC(nmemb, size, type) __gf_calloc (nmemb, size, type)