glusterfs
135 строк · 3.3 Кб
1/*
2Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3This file is part of GlusterFS.
4
5This file is licensed to you under your choice of the GNU Lesser
6General Public License, version 3 or any later version (LGPLv3 or
7later), or the GNU General Public License, version 2 (GPLv2), in all
8cases as published by the Free Software Foundation.
9*/
10
11#include <sys/uio.h>
12
13#include "glusterfs/common-utils.h"
14#include "glusterfs/xlator.h"
15#include "glusterfs/graph-utils.h"
16#include "glusterfs/libglusterfs-messages.h"
17
18struct gf_printer {
19ssize_t (*write)(struct gf_printer *gp, char *buf, size_t len);
20void *priv;
21int len;
22};
23
24static ssize_t
25gp_write_file(struct gf_printer *gp, char *buf, size_t len)
26{
27FILE *f = gp->priv;
28
29if (fwrite(buf, len, 1, f) != 1) {
30gf_msg("graph-print", GF_LOG_ERROR, errno, LG_MSG_FWRITE_FAILED,
31"fwrite failed");
32
33return -1;
34}
35
36return len;
37}
38
39static int
40gpprintf(struct gf_printer *gp, const char *format, ...)
41{
42va_list arg;
43char *str = NULL;
44int ret = 0;
45
46va_start(arg, format);
47ret = gf_vasprintf(&str, format, arg);
48va_end(arg);
49
50if (ret < 0)
51return ret;
52
53ret = gp->write(gp, str, ret);
54
55GF_FREE(str);
56
57return ret;
58}
59
60#define GPPRINTF(gp, fmt, ...) \
61do { \
62ret = gpprintf(gp, fmt, ##__VA_ARGS__); \
63if (ret == -1) \
64goto out; \
65else \
66gp->len += ret; \
67} while (0)
68
69static int
70_print_volume_options(dict_t *d, char *k, data_t *v, void *tmp)
71{
72struct gf_printer *gp = tmp;
73int ret = 0;
74GPPRINTF(gp, " option %s %s\n", k, v->data);
75return 0;
76out:
77/* means, it is a failure */
78return -1;
79}
80
81static int
82glusterfs_graph_print(struct gf_printer *gp, glusterfs_graph_t *graph)
83{
84xlator_t *trav = NULL;
85xlator_list_t *xch = NULL;
86int ret = 0;
87ssize_t len = 0;
88
89if (!graph->first)
90return 0;
91
92for (trav = graph->first; trav->next; trav = trav->next)
93;
94for (; trav; trav = trav->prev) {
95GPPRINTF(gp, "volume %s\n type %s\n", trav->name, trav->type);
96
97ret = dict_foreach(trav->options, _print_volume_options, gp);
98if (ret)
99goto out;
100
101if (trav->children) {
102GPPRINTF(gp, " subvolumes");
103
104for (xch = trav->children; xch; xch = xch->next)
105GPPRINTF(gp, " %s", xch->xlator->name);
106
107GPPRINTF(gp, "\n");
108}
109
110GPPRINTF(gp, "end-volume\n");
111if (trav != graph->first)
112GPPRINTF(gp, "\n");
113}
114
115out:
116len = gp->len;
117if (ret == -1) {
118gf_msg("graph-print", GF_LOG_ERROR, 0, LG_MSG_PRINT_FAILED,
119"printing failed");
120
121return -1;
122}
123
124return len;
125
126#undef GPPRINTF
127}
128
129int
130glusterfs_graph_print_file(FILE *file, glusterfs_graph_t *graph)
131{
132struct gf_printer gp = {.write = gp_write_file, .priv = file};
133
134return glusterfs_graph_print(&gp, graph);
135}
136