From 067d0e476abe42f1e290039cb903928080e90d8d Mon Sep 17 00:00:00 2001 From: Csaba Henk Date: Sat, 2 Oct 2010 07:30:38 +0000 Subject: implemented graph printing Signed-off-by: Csaba Henk Signed-off-by: Vijay Bellur BUG: 1750 (clean up volgen) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1750 --- libglusterfs/src/Makefile.am | 4 +- libglusterfs/src/graph-mem-types.h | 32 ++++++ libglusterfs/src/graph-print.c | 200 +++++++++++++++++++++++++++++++++++++ libglusterfs/src/graph-utils.h | 29 ++++++ libglusterfs/src/mem-pool.c | 25 +++-- libglusterfs/src/mem-pool.h | 4 + 6 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 libglusterfs/src/graph-mem-types.h create mode 100644 libglusterfs/src/graph-print.c create mode 100644 libglusterfs/src/graph-utils.h (limited to 'libglusterfs') diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 3513419ebc9..71a088d98eb 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 00000000000..49feb76c4a2 --- /dev/null +++ b/libglusterfs/src/graph-mem-types.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2010 Gluster, Inc. + 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 + . +*/ + +#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 00000000000..a6c20c735ad --- /dev/null +++ b/libglusterfs/src/graph-print.c @@ -0,0 +1,200 @@ +/* + Copyright (c) 2010 Gluster, Inc. + 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 + . +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include + +#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 00000000000..359cdcc7a34 --- /dev/null +++ b/libglusterfs/src/graph-utils.h @@ -0,0 +1,29 @@ +/* + Copyright (c) 2010 Gluster, Inc. + 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 + . +*/ + +#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 f266ce61f3b..1223b3711a6 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 0b467bb2cdb..21ff4c801c3 100644 --- a/libglusterfs/src/mem-pool.h +++ b/libglusterfs/src/mem-pool.h @@ -26,6 +26,7 @@ #include #include #include +#include #define MALLOC(size) malloc(size) @@ -60,6 +61,9 @@ __gf_malloc (size_t size, uint32_t type); 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, ...); -- cgit