summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-volgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-volgen.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c1654
1 files changed, 1654 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
new file mode 100644
index 000000000..6e3cc7440
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -0,0 +1,1654 @@
+/*
+ Copyright (c) 2006-2009 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is GF_FREE software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero 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 "xlator.h"
+#include "protocol-common.h"
+#include "glusterd.h"
+#include "defaults.h"
+#include "list.h"
+#include "dict.h"
+#include "compat.h"
+#include "compat-errno.h"
+#include "glusterd-sm.h"
+#include "glusterd-op-sm.h"
+#include "cli1.h"
+#include "glusterd-mem-types.h"
+#include "glusterd-volgen.h"
+
+static int
+set_xlator_option (dict_t *dict, char *key,
+ char *value)
+{
+ int ret = 0;
+ char *str = NULL;
+
+ str = GF_CALLOC (1, strlen (value) + 1,
+ gf_gld_mt_char);
+
+ if (!str)
+ return -1;
+
+ strncpy (str, value, strlen (value));
+
+ ret = dict_set_dynstr (dict, key, str);
+
+ return ret;
+}
+
+static int32_t
+set_default_options (dict_t *dict, char *volname)
+{
+ int ret = -1;
+
+ ret = dict_set_str (dict, "volname",
+ volname);
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_POSIX_OPTION_ODIRECT,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_POSIX_OPTION_STATFSSIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_POSIX_OPTION_MANDATTR,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_POSIX_OPTION_SPANDEVICES,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_POSIX_OPTION_BCKUNLINK,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_LOCKS_OPTION_TRACE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_LOCKS_OPTION_MAND,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_CLIENT_OPTION_TRANSTYPE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_CLIENT_OPTION_NODELAY,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOT_OPTION_THREADCOUNT,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOT_OPTION_AUTOSCALING,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOT_OPTION_MINTHREADS,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOT_OPTION_MAXTHREADS,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_SERVER_OPTION_TRANSTYPE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_SERVER_OPTION_NODELAY,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_READSUBVOL,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_FAVCHILD,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_BCKSHCOUNT,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_DATASH,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_DATASHALGO,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_SHWINDOWSIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_METASH,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_ENTRYSH,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_DATACHANGELOG,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_METADATACHANGELOG,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_ENTRYCHANGELOG,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_REPLICATE_OPTION_STRICTREADDIR,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_STRIPE_OPTION_BLOCKSIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_STRIPE_OPTION_USEXATTR,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_DHT_OPTION_LOOKUPUNHASH,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_DHT_OPTION_MINFREEDISK,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_DHT_OPTION_UNHASHSTICKY,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_WB_OPTION_FLUSHBEHIND,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_WB_OPTION_CACHESIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_WB_OPTION_DISABLENBYTES,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_WB_OPTION_OSYNC,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_WB_OPTION_TRICKLINGWRITES,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_RA_OPTION_ATIME,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_RA_OPTION_PAGECOUNT,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOCACHE_OPTION_PRIORITY,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOCACHE_OPTION_TIMEOUT,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOCACHE_OPTION_CACHESIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOCACHE_OPTION_MINFILESIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_IOCACHE_OPTION_MAXFILESIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_QR_OPTION_PRIORITY,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_QR_OPTION_TIMEOUT,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_QR_OPTION_CACHESIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = set_xlator_option (dict, VOLGEN_QR_OPTION_MAXFILESIZE,
+ "on");
+ if (ret)
+ goto out;
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int32_t
+glusterd_default_xlator_options (glusterd_volinfo_t *volinfo)
+{
+ int ret = -1;
+
+ volinfo->dict = dict_new ();
+ if (!volinfo->dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = set_default_options (volinfo->dict,
+ volinfo->volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+
+}
+
+static int
+__write_posix_xlator (FILE *file, dict_t *dict,
+ char *posix_directory)
+{
+ char *volname = NULL;
+ char *opt_odirect = NULL;
+ char *opt_statfssize = NULL;
+ char *opt_mandattr = NULL;
+ char *opt_spandevices = NULL;
+ char *opt_bckunlink = NULL;
+ int ret = -1;
+
+ const char *posix_str = "volume %s-%s\n"
+ "type storage/posix\n"
+ "option directory %s\n"
+ "option o-direct %s\n"
+ "option export-statfs-size %s\n"
+ "option mandate-attribute %s\n"
+ "option span-devices %s\n"
+ "option background-unlink %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_POSIX_OPTION_ODIRECT,
+ &opt_odirect);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_POSIX_OPTION_STATFSSIZE,
+ &opt_statfssize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_POSIX_OPTION_MANDATTR,
+ &opt_mandattr);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_POSIX_OPTION_SPANDEVICES,
+ &opt_spandevices);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_POSIX_OPTION_BCKUNLINK,
+ &opt_bckunlink);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, posix_str,
+ volname,
+ "posix",
+ posix_directory,
+ opt_odirect,
+ opt_statfssize,
+ opt_mandattr,
+ opt_spandevices,
+ opt_bckunlink);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_locks_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_trace = NULL;
+ char *opt_mand = NULL;
+ int ret = -1;
+
+ const char *locks_str = "volume %s-%s\n"
+ "type features/locks\n"
+ "option trace %s\n"
+ "option mandatory %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_LOCKS_OPTION_TRACE,
+ &opt_trace);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_LOCKS_OPTION_MAND,
+ &opt_mand);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, locks_str,
+ volname,
+ "locks",
+ opt_trace,
+ opt_mand,
+ subvolume);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_client_xlator (FILE *file, dict_t *dict,
+ char *remote_subvol,
+ char *remote_host,
+ int count,
+ int replace_brick_flag)
+{
+ char *volname = NULL;
+ char *opt_transtype = NULL;
+ char *opt_nodelay = NULL;
+ int ret = 0;
+
+
+ const char *client_str = "volume %s-%s-%d\n"
+ "type protocol/client\n"
+ "option transport-type %s\n"
+ "option remote-host %s\n"
+ "option remote-port %s\n"
+ "option transport.socket.nodelay %s\n"
+ "option remote-subvolume %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_CLIENT_OPTION_TRANSTYPE,
+ &opt_transtype);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_CLIENT_OPTION_NODELAY,
+ &opt_nodelay);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, client_str,
+ volname,
+ replace_brick_flag ?
+ "replace-brick" : "client",
+ count,
+ opt_transtype,
+ replace_brick_flag ? "" : remote_host,
+ replace_brick_flag ? "34034" : "",
+ opt_nodelay,
+ replace_brick_flag ? "" : remote_subvol);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_pump_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ int ret = -1;
+
+ const char *pump_str = "volume %s-%s\n"
+ "type cluster/pump\n"
+ "subvolumes %s %s-replace-brick-0\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, pump_str,
+ volname, "pump",
+ subvolume,
+ volname);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_iothreads_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_threadcount = NULL;
+ char *opt_autoscaling = NULL;
+ char *opt_minthreads = NULL;
+ char *opt_maxthreads = NULL;
+ int ret = -1;
+
+ const char *iot_str = "volume %s-%s\n"
+ "type performance/io-threads\n"
+ "option thread-count %s\n"
+ "option autoscaling %s\n"
+ "option min-threads %s\n"
+ "option max-threads %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOT_OPTION_THREADCOUNT,
+ &opt_threadcount);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOT_OPTION_AUTOSCALING,
+ &opt_autoscaling);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOT_OPTION_MINTHREADS,
+ &opt_minthreads);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOT_OPTION_MAXTHREADS,
+ &opt_maxthreads);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, iot_str,
+ volname, "io-threads",
+ opt_threadcount,
+ opt_autoscaling,
+ opt_minthreads,
+ opt_maxthreads,
+ subvolume);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_server_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_transtype = NULL;
+ char *opt_nodelay = NULL;
+ int ret = -1;
+
+ const char *server_str = "volume %s-%s\n"
+ "type protocol/server\n"
+ "option transport-type %s\n"
+ "option auth.addr.%s.allow\n"
+ "option transport.socket.nodelay %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_SERVER_OPTION_TRANSTYPE,
+ &opt_transtype);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_SERVER_OPTION_NODELAY,
+ &opt_nodelay);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, server_str,
+ volname, "server",
+ opt_transtype,
+ subvolume,
+ opt_nodelay,
+ subvolume);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_replicate_xlator (FILE *file, dict_t *dict,
+ char *subvolume,
+ int replicate_count,
+ int count)
+{
+ char *volname = NULL;
+ char *opt_readsubvol = NULL;
+ char *opt_favchild = NULL;
+ char *opt_bckshcount = NULL;
+ char *opt_datash = NULL;
+ char *opt_datashalgo = NULL;
+ char *opt_shwindowsize = NULL;
+ char *opt_metash = NULL;
+ char *opt_entrysh = NULL;
+ char *opt_datachangelog = NULL;
+ char *opt_metadatachangelog = NULL;
+ char *opt_entrychangelog = NULL;
+ char *opt_strictreaddir = NULL;
+ char subvol_str[8192] = {0,};
+ char tmp[4096] = {0,};
+ int ret = -1;
+ int i = 0;
+
+ const char *replicate_str = "volume %s-%s-%d\n"
+ "type cluster/replicate\n"
+ "option read-subvolume %s\n"
+ "option favorite-child %s\n"
+ "option background-self-heal-count %s\n"
+ "option data-self-heal %s\n"
+ "option data-self-heal-algorithm %s\n"
+ "option data-self-heal-window-size %s\n"
+ "option metadata-self-heal %s\n"
+ "option entry-self-heal %s\n"
+ "option data-change-log %s\n"
+ "option metadata-change-log %s\n"
+ "option entry-change-log %s\n"
+ "option strict-readdir %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_READSUBVOL,
+ &opt_readsubvol);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_FAVCHILD,
+ &opt_favchild);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_BCKSHCOUNT,
+ &opt_bckshcount);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_DATASH,
+ &opt_datash);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_DATASHALGO,
+ &opt_datashalgo);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_SHWINDOWSIZE,
+ &opt_shwindowsize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_METASH,
+ &opt_metash);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_ENTRYSH,
+ &opt_entrysh);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_DATACHANGELOG,
+ &opt_datachangelog);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_METADATACHANGELOG,
+ &opt_metadatachangelog);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_ENTRYCHANGELOG,
+ &opt_entrychangelog);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_REPLICATE_OPTION_STRICTREADDIR,
+ &opt_strictreaddir);
+ if (ret) {
+ goto out;
+ }
+
+ for (i = 0; i < replicate_count; i++) {
+ snprintf (tmp, 4096, "%s-%d ", subvolume, i);
+ strncat (subvol_str, tmp, strlen (tmp));
+ }
+
+ fprintf (file, replicate_str,
+ volname,
+ "replicate",
+ count,
+ opt_readsubvol,
+ opt_favchild,
+ opt_bckshcount,
+ opt_datash,
+ opt_datashalgo,
+ opt_shwindowsize,
+ opt_metash,
+ opt_entrysh,
+ opt_datachangelog,
+ opt_metadatachangelog,
+ opt_entrychangelog,
+ opt_strictreaddir,
+ subvol_str);
+
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_stripe_xlator (FILE *file, dict_t *dict,
+ char *subvolume,
+ int stripe_count,
+ int count)
+{
+ char *volname = NULL;
+ char *opt_blocksize = NULL;
+ char *opt_usexattr = NULL;
+ char subvol_str[8192] = {0,};
+ char tmp[4096] = {0,};
+ int ret = -1;
+ int i = 0;
+
+ const char *stripe_str = "volume %s-%s-%d\n"
+ "type cluster/stripe\n"
+ "option block-size %s\n"
+ "option use-xattr %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_STRIPE_OPTION_BLOCKSIZE,
+ &opt_blocksize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_STRIPE_OPTION_USEXATTR,
+ &opt_usexattr);
+ if (ret) {
+ goto out;
+ }
+
+
+ for (i = 0; i < stripe_count; i++) {
+ snprintf (tmp, 4096, "%s-%d ", subvolume, i);
+ strncat (subvol_str, tmp, strlen (tmp));
+ }
+
+ fprintf (file, stripe_str,
+ volname,
+ count,
+ "stripe",
+ opt_blocksize,
+ opt_usexattr,
+ subvol_str);
+
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_distribute_xlator (FILE *file, dict_t *dict,
+ char *subvolume,
+ int dist_count)
+{
+ char *volname = NULL;
+ char subvol_str[8192] = {0,};
+ char tmp[4096] = {0,};
+ char *opt_lookupunhash = NULL;
+ char *opt_minfreedisk = NULL;
+ char *opt_unhashsticky = NULL;
+ int ret = -1;
+ int i = 0;
+
+ const char *dht_str = "volume %s-%s\n"
+ "type cluster/distribute\n"
+ "option lookup-unhashed %s\n"
+ "option min-free-disk %s\n"
+ "option unhashed-sticky-bit %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_DHT_OPTION_LOOKUPUNHASH,
+ &opt_lookupunhash);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_DHT_OPTION_MINFREEDISK,
+ &opt_minfreedisk);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_DHT_OPTION_UNHASHSTICKY,
+ &opt_unhashsticky);
+ if (ret) {
+ goto out;
+ }
+
+ for (i = 0; i < dist_count; i++) {
+ snprintf (tmp, 4096, "%s-%d ", subvolume, i);
+ strncat (subvol_str, tmp, strlen (tmp));
+ }
+
+ fprintf (file, dht_str,
+ volname,
+ "dht",
+ opt_lookupunhash,
+ opt_minfreedisk,
+ opt_unhashsticky,
+ subvol_str);
+
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_wb_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_flushbehind = NULL;
+ char *opt_cachesize = NULL;
+ char *opt_disablenbytes = NULL;
+ char *opt_osync = NULL;
+ char *opt_tricklingwrites = NULL;
+ int ret = -1;
+
+ const char *dht_str = "volume %s-%s\n"
+ "type performance/write-behind\n"
+ "option flush-behind %s\n"
+ "option cache-size %s\n"
+ "option disable-for-first-nbytes %s\n"
+ "option enable-O_SYNC %s\n"
+ "option enable-trickling-writes %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_WB_OPTION_FLUSHBEHIND,
+ &opt_flushbehind);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_WB_OPTION_CACHESIZE,
+ &opt_cachesize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_WB_OPTION_DISABLENBYTES,
+ &opt_disablenbytes);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_WB_OPTION_OSYNC,
+ &opt_osync);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_WB_OPTION_TRICKLINGWRITES,
+ &opt_tricklingwrites);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, dht_str,
+ volname,
+ "write-behind",
+ opt_flushbehind,
+ opt_cachesize,
+ opt_disablenbytes,
+ opt_osync,
+ opt_tricklingwrites,
+ subvolume);
+
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_ra_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_atime = NULL;
+ char *opt_pagecount = NULL;
+ int ret = -1;
+
+ const char *ra_str = "volume %s-%s\n"
+ "type performance/read-ahead\n"
+ "option force-atime-update %s\n"
+ "option page-count %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_RA_OPTION_ATIME,
+ &opt_atime);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_RA_OPTION_PAGECOUNT,
+ &opt_pagecount);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, ra_str,
+ volname,
+ "read-ahead",
+ opt_atime,
+ opt_pagecount,
+ subvolume);
+
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_iocache_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_priority = NULL;
+ char *opt_timeout = NULL;
+ char *opt_cachesize = NULL;
+ char *opt_minfilesize = NULL;
+ char *opt_maxfilesize = NULL;
+ int ret = -1;
+
+ const char *iocache_str = "volume %s-%s\n"
+ "type performance/io-cache\n"
+ "option priority %s\n"
+ "option cache-timeout %s\n"
+ "option cache-size %s\n"
+ "option min-file-size %s\n"
+ "option max-file-size %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOCACHE_OPTION_PRIORITY,
+ &opt_priority);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOCACHE_OPTION_TIMEOUT,
+ &opt_timeout);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOCACHE_OPTION_CACHESIZE,
+ &opt_cachesize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOCACHE_OPTION_MINFILESIZE,
+ &opt_minfilesize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_IOCACHE_OPTION_MAXFILESIZE,
+ &opt_maxfilesize);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, iocache_str,
+ volname,
+ "io-cache",
+ opt_priority,
+ opt_timeout,
+ opt_cachesize,
+ opt_minfilesize,
+ opt_maxfilesize,
+ subvolume);
+
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_qr_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ char *opt_priority = NULL;
+ char *opt_timeout = NULL;
+ char *opt_cachesize = NULL;
+ char *opt_maxfilesize = NULL;
+ int ret = -1;
+
+ const char *qr_str = "volume %s-%s\n"
+ "type performance/quick-read\n"
+ "option priority %s\n"
+ "option cache-timeout %s\n"
+ "option cache-size %s\n"
+ "option max-file-size %s\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_QR_OPTION_PRIORITY,
+ &opt_priority);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_QR_OPTION_TIMEOUT,
+ &opt_timeout);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_QR_OPTION_CACHESIZE,
+ &opt_cachesize);
+ if (ret) {
+ goto out;
+ }
+
+ ret = dict_get_str (dict, VOLGEN_QR_OPTION_MAXFILESIZE,
+ &opt_maxfilesize);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, qr_str,
+ volname,
+ "quick-read",
+ opt_priority,
+ opt_timeout,
+ opt_cachesize,
+ opt_maxfilesize,
+ subvolume);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+__write_statprefetch_xlator (FILE *file, dict_t *dict,
+ char *subvolume)
+{
+ char *volname = NULL;
+ int ret = -1;
+
+ const char *statprefetch_str = "volume %s-%s\n"
+ "type performance/statprefetch\n"
+ "subvolumes %s\n"
+ "end-volume\n\n";
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ fprintf (file, statprefetch_str,
+ volname,
+ "stat-prefetch",
+ subvolume);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+generate_server_volfile (glusterd_brickinfo_t *brickinfo,
+ dict_t *dict,
+ const char *filename)
+{
+ FILE *file = NULL;
+ char subvol[2048] = {0,};
+ char *volname = NULL;
+ int ret = -1;
+
+ GF_ASSERT (filename);
+
+ file = fopen (filename, "w+");
+ if (!file) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not open file %s", filename);
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ goto out;
+ }
+
+ /* Call functions in the same order
+ as you'd call if you were manually
+ writing a volfile top-down
+ */
+
+ ret = __write_posix_xlator (file, dict, brickinfo->path);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "posix");
+
+ ret = __write_locks_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "locks");
+
+ ret = __write_iothreads_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ ret = __write_client_xlator (file, dict,
+ "", "",
+ 0, 1);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "io-threads");
+
+ ret = __write_pump_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "pump");
+
+ ret = __write_server_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ fclose (file);
+ file = NULL;
+
+out:
+ return ret;
+}
+
+static int
+generate_client_volfile (glusterd_volinfo_t *volinfo, char *filename)
+{
+ FILE *file = NULL;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ glusterd_brickinfo_t *brick = NULL;
+ char subvol[2048] = {0,};
+ int32_t replicate_count = 0;
+ int32_t stripe_count = 0;
+ int32_t dist_count = 0;
+ int32_t num_bricks = 0;
+ int count = 0;
+ int i = 0;
+ int ret = -1;
+
+ GF_ASSERT (filename);
+
+ volname = volinfo->volname;
+ dict = volinfo->dict;
+
+ list_for_each_entry (brick, &volinfo->bricks, brick_list)
+ num_bricks++;
+
+ if (GF_CLUSTER_TYPE_REPLICATE == volinfo->type) {
+ ret = dict_get_int32 (dict, "replica-count",
+ &replicate_count);
+ if (ret)
+ goto out;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Volfile is distributed-replicated");
+ dist_count = num_bricks / replicate_count;
+
+ } else if (GF_CLUSTER_TYPE_STRIPE == volinfo->type) {
+ ret = dict_get_int32 (dict, "stripe-count",
+ &stripe_count);
+ if (ret)
+ goto out;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Volfile is distributed-striped");
+ dist_count = num_bricks / stripe_count;
+ } else {
+ gf_log ("", GF_LOG_DEBUG,
+ "Volfile is plain distributed");
+ dist_count = num_bricks;
+ }
+
+
+ file = fopen (filename, "w+");
+ if (!file) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not open file %s", filename);
+ ret = -1;
+ goto out;
+ }
+
+ /* Call functions in the same order
+ as you'd call if you were manually
+ writing a volfile top-down
+ */
+
+ count = 0;
+
+ list_for_each_entry (brick, &volinfo->bricks, brick_list) {
+
+ ret = __write_client_xlator (file, dict, brick->path,
+ brick->hostname, count, 0);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ count++;
+ }
+
+ if (stripe_count && replicate_count) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Striped Replicate config not allowed");
+ ret = -1;
+ goto out;
+ }
+
+ if (replicate_count > 1) {
+ for (i = 0; i < dist_count; i++) {
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "client");
+
+ ret = __write_replicate_xlator (file, dict, subvol,
+ replicate_count, i);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Count not write xlator");
+ goto out;
+ }
+ }
+ }
+
+ if (stripe_count > 1) {
+ for (i = 0; i < dist_count; i++) {
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "client");
+
+ ret = __write_stripe_xlator (file, dict, subvol,
+ stripe_count, i);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Count not write xlator");
+ goto out;
+ }
+ }
+
+ }
+
+ if (dist_count > 1) {
+ if (replicate_count) {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname,
+ "replicate");
+ } else if (stripe_count) {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname,
+ "stripe");
+ } else {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname,
+ "client");
+ }
+
+
+ ret = __write_distribute_xlator (file,
+ dict,
+ subvol,
+ dist_count);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Count not write xlator");
+ goto out;
+ }
+ }
+
+
+ if (dist_count > 1) {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "dht");
+ ret = __write_wb_xlator (file, dict, subvol);
+ }
+ else if (replicate_count > 1) {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "replicate-0");
+ ret = __write_wb_xlator (file, dict, subvol);
+ }
+ else if (stripe_count > 1) {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "stripe-0");
+ ret = __write_wb_xlator (file, dict, subvol);
+ }
+ else {
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "client-0");
+ ret = __write_wb_xlator (file, dict, subvol);
+ }
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "write-behind");
+ ret = __write_ra_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "read-ahead");
+ ret = __write_iocache_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "io-cache");
+ ret = __write_qr_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ VOLGEN_GENERATE_VOLNAME (subvol, volname, "quick-read");
+ ret = __write_statprefetch_xlator (file, dict, subvol);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not write xlator");
+ goto out;
+ }
+
+ fclose (file);
+ file = NULL;
+
+out:
+ return ret;
+}
+
+static char *
+get_brick_filename (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo)
+{
+ char path[PATH_MAX] = {0,};
+ char *ret = NULL;
+ char brick[PATH_MAX] = {0,};
+ char *tmp = NULL;
+ char *dir = NULL;
+ char *junk = NULL;
+ char *filename = NULL;
+
+ filename = GF_CALLOC (1, PATH_MAX, gf_gld_mt_char);
+ if (!filename)
+ goto out;
+
+ tmp = gf_strdup (brickinfo->path);
+ if (!tmp)
+ goto out;
+
+ dir = strtok_r (tmp, "/", &junk);
+ while (dir != NULL) {
+ strcat (brick, dir);
+ strcat (brick, "-");
+ dir = strtok_r (NULL, "/", &junk);
+ }
+
+ VOLGEN_GET_VOLUME_DIR (path, volinfo);
+
+ snprintf (filename, PATH_MAX, "%s/%s.%s.%s.vol",
+ path, volinfo->volname,
+ brickinfo->hostname,
+ brick);
+
+ GF_FREE (tmp);
+
+ ret = filename;
+out:
+ return ret;
+}
+
+static char *
+get_client_filename (glusterd_volinfo_t *volinfo)
+{
+ char path[PATH_MAX] = {0,};
+ char *ret = NULL;
+ char *filename = NULL;
+
+ filename = GF_CALLOC (1, PATH_MAX, gf_gld_mt_char);
+ if (!filename)
+ goto out;
+
+ VOLGEN_GET_VOLUME_DIR (path, volinfo);
+
+ snprintf (filename, PATH_MAX, "%s/%s-fuse.vol",
+ path, volinfo->volname);
+
+ ret = filename;
+out:
+ return ret;
+}
+
+static int
+generate_brick_volfiles (glusterd_volinfo_t *volinfo)
+{
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char *filename = NULL;
+ int ret = -1;
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Found a brick - %s:%s", brickinfo->hostname,
+ brickinfo->path);
+
+ filename = get_brick_filename (volinfo, brickinfo);
+ if (!filename) {
+ gf_log ("", GF_LOG_ERROR,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ }
+
+ ret = generate_server_volfile (brickinfo, volinfo->dict,
+ filename);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not generate volfile for brick %s:%s",
+ brickinfo->hostname, brickinfo->path);
+ goto out;
+ }
+
+ if (filename)
+ GF_FREE (filename);
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static int
+generate_client_volfiles (glusterd_volinfo_t *volinfo)
+{
+ char *filename = NULL;
+ int ret = -1;
+
+ filename = get_client_filename (volinfo);
+ if (!filename) {
+ gf_log ("", GF_LOG_ERROR,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ }
+
+ ret = generate_client_volfile (volinfo, filename);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not generate volfile for client");
+ goto out;
+ }
+
+out:
+ if (filename)
+ GF_FREE (filename);
+
+ return ret;
+}
+
+int
+glusterd_create_volfiles (glusterd_volinfo_t *volinfo)
+{
+ int ret = -1;
+
+
+ ret = generate_brick_volfiles (volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not generate volfiles for bricks");
+ goto out;
+ }
+
+ ret = generate_client_volfiles (volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not generate volfile for client");
+ goto out;
+ }
+
+out:
+ return ret;
+}