diff options
Diffstat (limited to 'libglusterfs/src/graph-print.c')
| -rw-r--r-- | libglusterfs/src/graph-print.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/libglusterfs/src/graph-print.c b/libglusterfs/src/graph-print.c new file mode 100644 index 00000000000..595d74330a1 --- /dev/null +++ b/libglusterfs/src/graph-print.c @@ -0,0 +1,135 @@ +/* + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <sys/uio.h> + +#include "glusterfs/common-utils.h" +#include "glusterfs/xlator.h" +#include "glusterfs/graph-utils.h" +#include "glusterfs/libglusterfs-messages.h" + +struct gf_printer { + ssize_t (*write)(struct gf_printer *gp, char *buf, size_t len); + void *priv; + int len; +}; + +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_msg("graph-print", GF_LOG_ERROR, errno, LG_MSG_FWRITE_FAILED, + "fwrite failed"); + + return -1; + } + + 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; +} + +#define GPPRINTF(gp, fmt, ...) \ + do { \ + ret = gpprintf(gp, fmt, ##__VA_ARGS__); \ + if (ret == -1) \ + goto out; \ + else \ + gp->len += ret; \ + } while (0) + +static int +_print_volume_options(dict_t *d, char *k, data_t *v, void *tmp) +{ + struct gf_printer *gp = tmp; + int ret = 0; + GPPRINTF(gp, " option %s %s\n", k, v->data); + return 0; +out: + /* means, it is a failure */ + return -1; +} + +static int +glusterfs_graph_print(struct gf_printer *gp, glusterfs_graph_t *graph) +{ + xlator_t *trav = 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); + + ret = dict_foreach(trav->options, _print_volume_options, gp); + if (ret) + goto out; + + 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: + len = gp->len; + if (ret == -1) { + gf_msg("graph-print", GF_LOG_ERROR, 0, LG_MSG_PRINT_FAILED, + "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); +} |
