summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/graph-print.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/graph-print.c')
-rw-r--r--libglusterfs/src/graph-print.c135
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);
+}