diff options
Diffstat (limited to 'libglusterfs/src/graph-print.c')
-rw-r--r-- | libglusterfs/src/graph-print.c | 200 |
1 files changed, 200 insertions, 0 deletions
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. <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; +} |