summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/cli-rpc-ops.c12
-rwxr-xr-xtests/bugs/bug-765230.t61
-rwxr-xr-xtests/bugs/bug-770655.t168
-rwxr-xr-xtests/bugs/bug-782095.t48
-rwxr-xr-xtests/bugs/bug-896431.t124
-rw-r--r--xlators/cluster/dht/src/dht.c2
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c17
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c7
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c9
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h3
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c270
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.h14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c8
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c1082
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h2
17 files changed, 1575 insertions, 266 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index 69496492217..62b949b1673 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -1557,10 +1557,12 @@ gf_cli_set_volume_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_err ("volume set: failed: %s", rsp.op_errstr);
-
- if (!rsp.op_ret) {
+ if (rsp.op_ret) {
+ if (strcmp (rsp.op_errstr, ""))
+ cli_err ("volume set: failed: %s", rsp.op_errstr);
+ else
+ cli_err ("volume set: failed");
+ } else {
if (help_str == NULL) {
if (debug_xlator == NULL)
cli_out ("volume set: success");
@@ -1569,8 +1571,6 @@ gf_cli_set_volume_cbk (struct rpc_req *req, struct iovec *iov,
}else {
cli_out ("%s", help_str);
}
- } else {
- cli_err ("volume set: failed");
}
ret = rsp.op_ret;
diff --git a/tests/bugs/bug-765230.t b/tests/bugs/bug-765230.t
new file mode 100755
index 00000000000..3f6074741f6
--- /dev/null
+++ b/tests/bugs/bug-765230.t
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+## Start and create a volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting quota-timeout as 20
+TEST ! $CLI volume set $V0 features.quota-timeout 20
+EXPECT '' volinfo_field $V0 'features.quota-timeout';
+
+#### quota-deem-statfs is not available in v3.4, disabling tests involving that for now.
+## Enabling features.quota-deem-statfs
+#TEST ! $CLI volume set $V0 features.quota-deem-statfs on
+#EXPECT '' volinfo_field $V0 'features.quota-deem-statfs'
+
+## Enabling quota
+TEST $CLI volume quota $V0 enable
+EXPECT 'on' volinfo_field $V0 'features.quota'
+
+## Setting quota-timeout as 20
+TEST $CLI volume set $V0 features.quota-timeout 20
+EXPECT '20' volinfo_field $V0 'features.quota-timeout';
+
+## Enabling features.quota-deem-statfs
+#TEST $CLI volume set $V0 features.quota-deem-statfs on
+#EXPECT 'on' volinfo_field $V0 'features.quota-deem-statfs'
+
+## Disabling quota
+TEST $CLI volume quota $V0 disable
+EXPECT 'off' volinfo_field $V0 'features.quota'
+
+## Setting quota-timeout as 30
+TEST ! $CLI volume set $V0 features.quota-timeout 30
+EXPECT '20' volinfo_field $V0 'features.quota-timeout';
+
+## Disabling features.quota-deem-statfs
+#TEST ! $CLI volume set $V0 features.quota-deem-statfs off
+#EXPECT 'on' volinfo_field $V0 'features.quota-deem-statfs'
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
diff --git a/tests/bugs/bug-770655.t b/tests/bugs/bug-770655.t
new file mode 100755
index 00000000000..945e323bbc8
--- /dev/null
+++ b/tests/bugs/bug-770655.t
@@ -0,0 +1,168 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+## Start and create a distribute-replicate volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Distributed-Replicate' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting stripe-block-size as 10MB
+TEST ! $CLI volume set $V0 stripe-block-size 10MB
+EXPECT '' volinfo_field $V0 'cluster.stripe-block-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a replicate volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 8 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Replicate' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting stripe-block-size as 10MB
+TEST ! $CLI volume set $V0 stripe-block-size 10MB
+EXPECT '' volinfo_field $V0 'cluster.stripe-block-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a distribute volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Distribute' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting stripe-block-size as 10MB
+TEST ! $CLI volume set $V0 stripe-block-size 10MB
+EXPECT '' volinfo_field $V0 'cluster.stripe-block-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a stripe volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 stripe 8 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Stripe' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting stripe-block-size as 10MB
+TEST $CLI volume set $V0 stripe-block-size 10MB
+EXPECT '10MB' volinfo_field $V0 'cluster.stripe-block-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a distributed stripe volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 stripe 4 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Distributed-Stripe' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting stripe-block-size as 10MB
+TEST $CLI volume set $V0 stripe-block-size 10MB
+EXPECT '10MB' volinfo_field $V0 'cluster.stripe-block-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a distributed stripe replicate volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 stripe 2 replica 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Distributed-Striped-Replicate' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting stripe-block-size as 10MB
+TEST $CLI volume set $V0 stripe-block-size 10MB
+EXPECT '10MB' volinfo_field $V0 'cluster.stripe-block-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
diff --git a/tests/bugs/bug-782095.t b/tests/bugs/bug-782095.t
new file mode 100755
index 00000000000..a0cea14ee86
--- /dev/null
+++ b/tests/bugs/bug-782095.t
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+## Start and create a volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting performance cache min size as 2MB
+TEST $CLI volume set $V0 performance.cache-min-file-size 2MB
+EXPECT '2MB' volinfo_field $V0 'performance.cache-min-file-size';
+
+## Setting performance cache max size as 20MB
+TEST $CLI volume set $V0 performance.cache-max-file-size 20MB
+EXPECT '20MB' volinfo_field $V0 'performance.cache-max-file-size';
+
+## Trying to set performance cache min size as 25MB
+TEST ! $CLI volume set $V0 performance.cache-min-file-size 25MB
+EXPECT '2MB' volinfo_field $V0 'performance.cache-min-file-size';
+
+## Able to set performance cache min size as long as its lesser than max size
+TEST $CLI volume set $V0 performance.cache-min-file-size 15MB
+EXPECT '15MB' volinfo_field $V0 'performance.cache-min-file-size';
+
+## Trying it out with only cache-max-file-size in CLI as 10MB
+TEST ! $CLI volume set $V0 cache-max-file-size 10MB
+EXPECT '20MB' volinfo_field $V0 'performance.cache-max-file-size';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
diff --git a/tests/bugs/bug-896431.t b/tests/bugs/bug-896431.t
new file mode 100755
index 00000000000..f968e59c1b3
--- /dev/null
+++ b/tests/bugs/bug-896431.t
@@ -0,0 +1,124 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+## Start and create a volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting cluster.subvols-per-directory as -5
+TEST ! $CLI volume set $V0 cluster.subvols-per-directory -5
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST ! $CLI volume set $V0 subvols-per-directory -5
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Setting cluster.subvols-per-directory as 0
+TEST ! $CLI volume set $V0 cluster.subvols-per-directory 0
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST ! $CLI volume set $V0 subvols-per-directory 0
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Setting cluster.subvols-per-directory as 4 (the total number of bricks)
+TEST ! $CLI volume set $V0 cluster.subvols-per-directory 4
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST ! $CLI volume set $V0 subvols-per-directory 4
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Setting cluster.subvols-per-directory as 2 (the total number of subvolumes)
+TEST $CLI volume set $V0 cluster.subvols-per-directory 2
+EXPECT '2' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Setting cluster.subvols-per-directory as 1
+TEST $CLI volume set $V0 subvols-per-directory 1
+EXPECT '1' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a pure replicate volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 8 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Replicate' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting cluster.subvols-per-directory as 8 for a replicate volume
+TEST ! $CLI volume set $V0 cluster.subvols-per-directory 8
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST ! $CLI volume set $V0 subvols-per-directory 8
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Setting cluster.subvols-per-directory as 1 for a replicate volume
+TEST $CLI volume set $V0 cluster.subvols-per-directory 1
+EXPECT '1' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST $CLI volume set $V0 subvols-per-directory 1
+EXPECT '1' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
+
+## Start and create a pure stripe volume
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 stripe 8 $H0:$B0/${V0}{1,2,3,4,5,6,7,8};
+
+## Verify volume is created
+EXPECT "$V0" volinfo_field $V0 'Volume Name';
+EXPECT 'Created' volinfo_field $V0 'Status';
+EXPECT 'Stripe' volinfo_field $V0 'Type';
+
+## Start volume and verify
+TEST $CLI volume start $V0;
+EXPECT 'Started' volinfo_field $V0 'Status';
+
+## Setting cluster.subvols-per-directory as 8 for a stripe volume
+TEST ! $CLI volume set $V0 cluster.subvols-per-directory 8
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST ! $CLI volume set $V0 subvols-per-directory 8
+EXPECT '' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Setting cluster.subvols-per-directory as 1 for a stripe volume
+TEST $CLI volume set $V0 cluster.subvols-per-directory 1
+EXPECT '1' volinfo_field $V0 'cluster.subvols-per-directory';
+TEST $CLI volume set $V0 subvols-per-directory 1
+EXPECT '1' volinfo_field $V0 'cluster.subvols-per-directory';
+
+## Finish up
+TEST $CLI volume stop $V0;
+EXPECT 'Stopped' volinfo_field $V0 'Status';
+
+TEST $CLI volume delete $V0;
+TEST ! $CLI volume info $V0;
+
+cleanup;
diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c
index bb4d70ec8a3..9d396434ed3 100644
--- a/xlators/cluster/dht/src/dht.c
+++ b/xlators/cluster/dht/src/dht.c
@@ -614,6 +614,8 @@ struct volume_options options[] = {
},
{ .key = {"directory-layout-spread"},
.type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .validate = GF_OPT_VALIDATE_MIN,
.description = "Specifies the directory layout spread."
},
{ .key = {"decommissioned-bricks"},
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
index e43d57e2833..df15453dc90 100644
--- a/xlators/mgmt/glusterd/src/Makefile.am
+++ b/xlators/mgmt/glusterd/src/Makefile.am
@@ -11,7 +11,7 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \
glusterd-volgen.c glusterd-rebalance.c glusterd-quota.c \
glusterd-geo-rep.c glusterd-replace-brick.c glusterd-log-ops.c \
glusterd-volume-ops.c glusterd-brick-ops.c glusterd-mountbroker.c \
- glusterd-syncop.c glusterd-hooks.c
+ glusterd-syncop.c glusterd-hooks.c glusterd-volume-set.c
glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la \
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
index 1d927044ef5..e26d65ff1cb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
@@ -928,13 +928,15 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count,
if (stripe_count) {
volinfo->stripe_count = stripe_count;
}
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- volinfo->replica_count);
+ volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
/* backward compatibility */
volinfo->sub_count = ((volinfo->dist_leaf_count == 1) ? 0:
volinfo->dist_leaf_count);
+ volinfo->subvol_count = (volinfo->brick_count /
+ volinfo->dist_leaf_count);
+
ret = glusterd_create_volfiles_and_notify_services (volinfo);
if (ret)
goto out;
@@ -1625,8 +1627,10 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)
volinfo->replica_count, replica_count,
volinfo->volname);
volinfo->replica_count = replica_count;
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- replica_count);
+ volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
+ volinfo->subvol_count = (volinfo->brick_count /
+ volinfo->dist_leaf_count);
+
if (replica_count == 1) {
if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {
volinfo->type = GF_CLUSTER_TYPE_NONE;
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index da1e8f83ffb..19f0934cd41 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -105,6 +105,8 @@ static char *glusterd_op_sm_event_names[] = {
"GD_OP_EVENT_INVALID"
};
+extern struct volopt_map_entry glusterd_volopt_map[];
+
char*
glusterd_op_sm_state_name_get (int state)
{
@@ -401,7 +403,8 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
uint32_t local_key_op_version = 0;
gf_boolean_t origin_glusterd = _gf_true;
gf_boolean_t check_op_version = _gf_true;
- gf_boolean_t all_vol = _gf_false;
+ gf_boolean_t all_vol = _gf_false;
+ struct volopt_map_entry *vme = NULL;
GF_ASSERT (dict);
this = THIS;
@@ -559,6 +562,18 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
if (is_key_glusterd_hooks_friendly (key))
continue;
+ for (vme = &glusterd_volopt_map[0]; vme->key; vme++) {
+ if ((vme->validate_fn) &&
+ ((!strcmp (key, vme->key)) ||
+ (!strcmp (key, strchr (vme->key, '.') + 1)))) {
+ ret = vme->validate_fn (dict, key, value,
+ op_errstr);
+ if (ret)
+ goto out;
+ break;
+ }
+ }
+
exists = glusterd_check_option_exists (key, &key_fixed);
if (exists == -1) {
ret = -1;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 863b70c7ccb..085e3e85dc4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -2530,8 +2530,11 @@ glusterd_store_retrieve_volume (char *volname)
break;
}
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- volinfo->replica_count);
+ volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
+
+ volinfo->subvol_count = (volinfo->brick_count /
+ volinfo->dist_leaf_count);
+
}
if (op_errno != GD_STORE_EOF)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 29dec5669d5..16dcc832ab8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -4131,6 +4131,15 @@ glusterd_restart_gsyncds (glusterd_conf_t *conf)
return ret;
}
+inline int
+glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo)
+{
+ int rcount = volinfo->replica_count;
+ int scount = volinfo->stripe_count;
+
+ return (rcount ? rcount : 1) * (scount ? scount : 1);
+}
+
int
glusterd_get_brickinfo (xlator_t *this, const char *brickname, int port,
gf_boolean_t localhost, glusterd_brickinfo_t **brickinfo)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index ac920a655ce..d58a45d51e4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -426,6 +426,9 @@ glusterd_add_node_to_dict (char *server, dict_t *dict, int count,
char *
glusterd_uuid_to_hostname (uuid_t uuid);
+int
+glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo);
+
glusterd_brickinfo_t*
glusterd_get_brickinfo_by_position (glusterd_volinfo_t *volinfo, uint32_t pos);
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 3d5d109e29d..4a03ee4c5ad 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -35,241 +35,7 @@
#include "glusterd-utils.h"
#include "run.h"
-#define AUTH_ALLOW_MAP_KEY "auth.allow"
-#define AUTH_REJECT_MAP_KEY "auth.reject"
-#define NFS_DISABLE_MAP_KEY "nfs.disable"
-#define AUTH_ALLOW_OPT_KEY "auth.addr.*.allow"
-#define AUTH_REJECT_OPT_KEY "auth.addr.*.reject"
-#define NFS_DISABLE_OPT_KEY "nfs.*.disable"
-
-
-/* dispatch table for VOLUME SET
- * -----------------------------
- *
- * Format of entries:
- *
- * First field is the <key>, for the purpose of looking it up
- * in volume dictionary. Each <key> is of the format "<domain>.<specifier>".
- *
- * Second field is <voltype>.
- *
- * Third field is <option>, if its unset, it's assumed to be
- * the same as <specifier>.
- *
- * Fourth field is <value>. In this context they are used to specify
- * a default. That is, even the volume dict doesn't have a value,
- * we procced as if the default value were set for it.
- *
- * Fifth field is <doctype>, which decides if the option is public and available
- * in "set help" or not. "NODOC" entries are not part of the public interface
- * and are subject to change at any time. This also decides if an option is
- * global (apllies to all volumes) or normal (applies to only specified volume).
- *
- * Sixth field is <flags>.
- *
- * Seventh field is <op-version>.
- *
- * There are two type of entries: basic and special.
- *
- * - Basic entries are the ones where the <option> does _not_ start with
- * the bang! character ('!').
- *
- * In their case, <option> is understood as an option for an xlator of
- * type <voltype>. Their effect is to copy over the volinfo->dict[<key>]
- * value to all graph nodes of type <voltype> (if such a value is set).
- *
- * You are free to add entries of this type, they will become functional
- * just by being present in the table.
- *
- * - Special entries where the <option> starts with the bang!.
- *
- * They are not applied to all graphs during generation, and you cannot
- * extend them in a trivial way which could be just picked up. Better
- * not touch them unless you know what you do.
- *
- *
- * Another kind of grouping for options, according to visibility:
- *
- * - Exported: one which is used in the code. These are characterized by
- * being used a macro as <key> (of the format VKEY_..., defined in
- * glusterd-volgen.h
- *
- * - Non-exported: the rest; these have string literal <keys>.
- *
- * Adhering to this policy, option name changes shall be one-liners.
- *
- */
-
-static struct volopt_map_entry glusterd_volopt_map[] = {
- /* DHT xlator options */
- {"cluster.lookup-unhashed", "cluster/distribute", NULL, NULL, DOC, 0, 1},
- {"cluster.min-free-disk", "cluster/distribute", NULL, NULL, DOC, 0, 1},
- {"cluster.min-free-inodes", "cluster/distribute", NULL, NULL, DOC, 0, 1},
- {"cluster.rebalance-stats", "cluster/distribute", NULL, NULL, DOC, 0, 2},
- {"cluster.subvols-per-directory", "cluster/distribute", "directory-layout-spread", NULL, DOC, 0, 2},
- {"cluster.readdir-optimize", "cluster/distribute", NULL, NULL, DOC, 0, 2},
- {"cluster.nufa", "cluster/distribute", "!nufa", NULL, NO_DOC, 0, 2},
-
- /* AFR xlator options */
- {"cluster.entry-change-log", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.read-subvolume", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.read-subvolume-index", "cluster/replicate", NULL, NULL, DOC, 0, 2},
- {"cluster.read-hash-mode", "cluster/replicate", NULL, NULL, DOC, 0, 2},
- {"cluster.background-self-heal-count", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.metadata-self-heal", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.data-self-heal", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.entry-self-heal", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.self-heal-daemon", "cluster/replicate", "!self-heal-daemon" , NULL, DOC, 0, 1},
- {"cluster.heal-timeout", "cluster/replicate", "!heal-timeout" , NULL, DOC, 0, 2},
- {"cluster.strict-readdir", "cluster/replicate", NULL, NULL, NO_DOC, 0, 1},
- {"cluster.self-heal-window-size", "cluster/replicate", "data-self-heal-window-size", NULL, DOC, 0, 1},
- {"cluster.data-change-log", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.metadata-change-log", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.data-self-heal-algorithm", "cluster/replicate", "data-self-heal-algorithm", NULL, DOC, 0, 1},
- {"cluster.eager-lock", "cluster/replicate", NULL, NULL, DOC, 0, 1},
- {"cluster.quorum-type", "cluster/replicate", "quorum-type", NULL, DOC, 0, 1},
- {"cluster.quorum-count", "cluster/replicate", "quorum-count", NULL, DOC, 0, 1},
- {"cluster.choose-local", "cluster/replicate", NULL, NULL, DOC, 0, 2},
- {"cluster.self-heal-readdir-size", "cluster/replicate", NULL, NULL, DOC, 0, 2},
- {"cluster.post-op-delay-secs", "cluster/replicate", NULL, NULL, NO_DOC, 0, 2},
- {"cluster.readdir-failover", "cluster/replicate", NULL, NULL, DOC, 0, 2},
-
- /* Stripe xlator options */
- {"cluster.stripe-block-size", "cluster/stripe", "block-size", NULL, DOC, 0, 1},
- {"cluster.stripe-coalesce", "cluster/stripe", "coalesce", NULL, DOC, 0, 2},
-
- /* IO-stats xlator options */
- {VKEY_DIAG_LAT_MEASUREMENT, "debug/io-stats", "latency-measurement", "off", DOC, 0, 1},
- {"diagnostics.dump-fd-stats", "debug/io-stats", NULL, NULL, DOC, 0, 1},
- {VKEY_DIAG_CNT_FOP_HITS, "debug/io-stats", "count-fop-hits", "off", NO_DOC, 0, 1},
- {"diagnostics.brick-log-level", "debug/io-stats", "!brick-log-level", NULL, DOC, 0, 1},
- {"diagnostics.client-log-level", "debug/io-stats", "!client-log-level", NULL, DOC, 0, 1},
- {"diagnostics.brick-sys-log-level", "debug/io-stats", "!sys-log-level", NULL, DOC, 0, 1},
- {"diagnostics.client-sys-log-level", "debug/io-stats", "!sys-log-level", NULL, DOC, 0, 1},
-
- /* IO-cache xlator options */
- {"performance.cache-max-file-size", "performance/io-cache", "max-file-size", NULL, DOC, 0, 1},
- {"performance.cache-min-file-size", "performance/io-cache", "min-file-size", NULL, DOC, 0, 1},
- {"performance.cache-refresh-timeout", "performance/io-cache", "cache-timeout", NULL, DOC, 0, 1},
- {"performance.cache-priority", "performance/io-cache", "priority", NULL, DOC, 0, 1},
- {"performance.cache-size", "performance/io-cache", NULL, NULL, DOC, 0, 1},
-
- /* IO-threads xlator options */
- {"performance.io-thread-count", "performance/io-threads", "thread-count", NULL, DOC, 0, 1},
- {"performance.high-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0, 1},
- {"performance.normal-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0, 1},
- {"performance.low-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0, 1},
- {"performance.least-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0, 1},
- {"performance.enable-least-priority", "performance/io-threads", NULL, NULL, DOC, 0, 2},
- {"performance.least-rate-limit", "performance/io-threads", NULL, NULL, DOC, 0, 1},
-
- /* Other perf xlators' options */
- {"performance.cache-size", "performance/quick-read", NULL, NULL, DOC, 0, 1},
-
- {"performance.flush-behind", "performance/write-behind", "flush-behind", NULL, DOC, 0, 1},
- {"performance.write-behind-window-size", "performance/write-behind", "cache-size", NULL, DOC, 1},
- {"performance.strict-o-direct", "performance/write-behind", "strict-O_DIRECT", NULL, DOC, 2},
- {"performance.strict-write-ordering", "performance/write-behind", "strict-write-ordering", NULL, DOC, 2},
-
- {"performance.read-ahead-page-count", "performance/read-ahead", "page-count", NULL, DOC, 1},
- {"performance.md-cache-timeout", "performance/md-cache", "md-cache-timeout", NULL, DOC, 0, 2},
-
- /* Client xlator options */
- {"network.frame-timeout", "protocol/client", NULL, NULL, DOC, 0, 1},
- {"network.ping-timeout", "protocol/client", NULL, NULL, DOC, 0, 1},
- {"network.tcp-window-size", "protocol/client", NULL, NULL, DOC, 0, 1},
- {"features.lock-heal", "protocol/client", "lk-heal", NULL, DOC, 0, 1},
- {"features.grace-timeout", "protocol/client", "grace-timeout", NULL, DOC, 0, 1},
- {"client.ssl", "protocol/client", "transport.socket.ssl-enabled", NULL, NO_DOC, 0, 2},
- {"network.remote-dio", "protocol/client", "filter-O_DIRECT", NULL, DOC, 0, 1},
-
- /* Server xlator options */
- {"network.tcp-window-size", "protocol/server", NULL, NULL, DOC, 0, 1},
- {"network.inode-lru-limit", "protocol/server", NULL, NULL, DOC, 0, 1},
- {AUTH_ALLOW_MAP_KEY, "protocol/server", "!server-auth", "*", DOC, 0, 1},
- {AUTH_REJECT_MAP_KEY, "protocol/server", "!server-auth", NULL, DOC, 0},
-
- {"transport.keepalive", "protocol/server", "transport.socket.keepalive", NULL, NO_DOC, 0, 1},
- {"server.allow-insecure", "protocol/server", "rpc-auth-allow-insecure", NULL, NO_DOC, 0, 1},
- {"server.root-squash", "protocol/server", "root-squash", NULL, DOC, 0, 2},
- {"server.statedump-path", "protocol/server", "statedump-path", NULL, DOC, 0, 1},
- {"features.lock-heal", "protocol/server", "lk-heal", NULL, NO_DOC, 0, 1},
- {"features.grace-timeout", "protocol/server", "grace-timeout", NULL, NO_DOC, 0, 1},
- {"server.ssl", "protocol/server", "transport.socket.ssl-enabled", NULL, NO_DOC, 0, 2},
-
- /* Performance xlators enable/disbable options */
- {"performance.write-behind", "performance/write-behind", "!perf", "on", NO_DOC, 0, 1},
- {"performance.read-ahead", "performance/read-ahead", "!perf", "on", NO_DOC, 0, 1},
- {"performance.io-cache", "performance/io-cache", "!perf", "on", NO_DOC, 0, 1},
- {"performance.quick-read", "performance/quick-read", "!perf", "on", NO_DOC, 0, 1},
- {"performance.open-behind", "performance/open-behind", "!perf", "on", NO_DOC, 0, 2},
- {"performance.stat-prefetch", "performance/md-cache", "!perf", "on", NO_DOC, 0, 1},
- {"performance.client-io-threads", "performance/io-threads", "!perf", "off", NO_DOC, 0, 1},
-
- {"performance.nfs.write-behind", "performance/write-behind", "!nfsperf", "on", NO_DOC, 0, 1},
- {"performance.nfs.read-ahead", "performance/read-ahead", "!nfsperf", "off", NO_DOC, 0, 1},
- {"performance.nfs.io-cache", "performance/io-cache", "!nfsperf", "off", NO_DOC, 0, 1},
- {"performance.nfs.quick-read", "performance/quick-read", "!nfsperf", "off", NO_DOC, 0, 1},
- {"performance.nfs.stat-prefetch", "performance/md-cache", "!nfsperf", "off", NO_DOC, 0, 1},
- {"performance.nfs.io-threads", "performance/io-threads", "!nfsperf", "off", NO_DOC, 0, 1},
- {"performance.force-readdirp", "performance/md-cache", "force-readdirp", NULL, DOC, 0, 2},
-
- /* Quota xlator options */
- {VKEY_FEATURES_LIMIT_USAGE, "features/quota", "limit-set", NULL, NO_DOC, 0, 1},
- {"features.quota-timeout", "features/quota", "timeout", "0", DOC, 0, 1},
-
- /* Marker xlator options */
- {VKEY_MARKER_XTIME, "features/marker", "xtime", "off", NO_DOC, OPT_FLAG_FORCE, 1},
- {VKEY_MARKER_XTIME, "features/marker", "!xtime", "off", NO_DOC, OPT_FLAG_FORCE, 1},
- {VKEY_FEATURES_QUOTA, "features/marker", "quota", "off", NO_DOC, OPT_FLAG_FORCE, 1},
-
- /* Debug xlators options */
- {"debug.trace", "debug/trace", "!debug","off", NO_DOC, 0, 1},
- {"debug.log-history", "debug/trace", "log-history", NULL, NO_DOC, 0, 2},
- {"debug.log-file", "debug/trace", "log-file", NULL, NO_DOC, 0, 2},
- {"debug.exclude-ops", "debug/trace", "exclude-ops", NULL, NO_DOC, 0, 2},
- {"debug.include-ops", "debug/trace", "include-ops", NULL, NO_DOC, 0, 2},
- {"debug.error-gen", "debug/error-gen", "!debug","off", NO_DOC, 0, 1},
-
- /* NFS xlator options */
- {"nfs.enable-ino32", "nfs/server", "nfs.enable-ino32", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.mem-factor", "nfs/server", "nfs.mem-factor", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.export-dirs", "nfs/server", "nfs3.export-dirs", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.export-volumes", "nfs/server", "nfs3.export-volumes", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.addr-namelookup", "nfs/server", "rpc-auth.addr.namelookup", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.dynamic-volumes", "nfs/server", "nfs.dynamic-volumes", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.register-with-portmap", "nfs/server", "rpc.register-with-portmap", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.port", "nfs/server", "nfs.port", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.rpc-auth-unix", "nfs/server", "!rpc-auth.auth-unix.*", NULL, DOC, 0, 1},
- {"nfs.rpc-auth-null", "nfs/server", "!rpc-auth.auth-null.*", NULL, DOC, 0, 1},
- {"nfs.rpc-auth-allow", "nfs/server", "!rpc-auth.addr.*.allow", NULL, DOC, 0, 1},
- {"nfs.rpc-auth-reject", "nfs/server", "!rpc-auth.addr.*.reject", NULL, DOC, 0, 1},
- {"nfs.ports-insecure", "nfs/server", "!rpc-auth.ports.*.insecure", NULL, DOC, 0, 1},
- {"nfs.transport-type", "nfs/server", "!nfs.transport-type", NULL, DOC, 0, 1},
- {"nfs.trusted-sync", "nfs/server", "!nfs3.*.trusted-sync", NULL, DOC, 0, 1},
- {"nfs.trusted-write", "nfs/server", "!nfs3.*.trusted-write", NULL, DOC, 0, 1},
- {"nfs.volume-access", "nfs/server", "!nfs3.*.volume-access", NULL, DOC, 0, 1},
- {"nfs.export-dir", "nfs/server", "!nfs3.*.export-dir", NULL, DOC, 0, 1},
- {NFS_DISABLE_MAP_KEY, "nfs/server", "!nfs-disable", NULL, DOC, 0, 1},
- {"nfs.nlm", "nfs/server", "nfs.nlm", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.mount-udp", "nfs/server", "nfs.mount-udp", NULL, GLOBAL_DOC, 0, 1},
- {"nfs.server-aux-gids", "nfs/server", "nfs.server-aux-gids", NULL, NO_DOC, 0, 2},
-
- /* Other options which don't fit any place above */
- {"features.read-only", "features/read-only", "!read-only", "off", DOC, 0, 2},
- {"features.worm", "features/worm", "!worm", "off", DOC, 0, 2},
-
- {"storage.linux-aio", "storage/posix", NULL, NULL, DOC, 0, 2},
- {"storage.owner-uid", "storage/posix", "brick-uid", NULL, DOC, 0, 2},
- {"storage.owner-gid", "storage/posix", "brick-gid", NULL, DOC, 0, 2},
- {"config.memory-accounting", "configuration", "!config", NULL, DOC, 0, 2},
- {"config.transport", "configuration", "!config", NULL, DOC, 0, 2},
- {GLUSTERD_QUORUM_TYPE_KEY, "mgmt/glusterd", NULL, "off", DOC, 0, 2},
- {GLUSTERD_QUORUM_RATIO_KEY, "mgmt/glusterd", NULL, "0", DOC, 0, 2},
- {NULL, }
-};
-
-
+extern struct volopt_map_entry glusterd_volopt_map[];
/*********************************************
*
@@ -2162,33 +1928,37 @@ glusterd_get_volopt_content (dict_t * ctx, gf_boolean_t xml_out)
if (get_key_from_volopt (vme, &key))
goto out; /*Some error while getin key*/
- if (!xlator_type || strcmp (vme->voltype, xlator_type)){
- ret = xlator_volopt_dynload (vme->voltype,
- &dl_handle,
- &vol_opt_handle);
- if (ret) {
- dl_handle = NULL;
- continue;
+ if (vme->description) {
+ descr = vme->description;
+ def_val = vme->value;
+ } else {
+ if (!xlator_type || strcmp (vme->voltype, xlator_type)){
+ ret = xlator_volopt_dynload (vme->voltype,
+ &dl_handle,
+ &vol_opt_handle);
+ if (ret) {
+ dl_handle = NULL;
+ continue;
+ }
}
+ ret = xlator_option_info_list (&vol_opt_handle, key,
+ &def_val, &descr);
+ if (ret) /*Swallow Error i.e if option not found*/
+ continue;
}
- ret = xlator_option_info_list (&vol_opt_handle, key,
- &def_val, &descr);
- if (ret) /*Swallow Error i.e if option not found*/
- continue;
-
if (xml_out) {
#if (HAVE_LIB_XML)
if (xml_add_volset_element (writer,vme->key,
- def_val, descr))
+ def_val, descr))
goto out;
#else
gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present");
#endif
} else {
snprintf (tmp_str, 2048, "Option: %s\nDefault "
- "Value: %s\nDescription: %s\n\n",
- vme->key, def_val, descr);
+ "Value: %s\nDescription: %s\n\n",
+ vme->key, def_val, descr);
strcat (output_string, tmp_str);
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h
index 6df88f75f67..0a9647bdf93 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.h
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h
@@ -25,6 +25,14 @@
#define VKEY_MARKER_XTIME GEOREP".indexing"
#define VKEY_FEATURES_QUOTA "features.quota"
+#define AUTH_ALLOW_MAP_KEY "auth.allow"
+#define AUTH_REJECT_MAP_KEY "auth.reject"
+#define NFS_DISABLE_MAP_KEY "nfs.disable"
+#define AUTH_ALLOW_OPT_KEY "auth.addr.*.allow"
+#define AUTH_REJECT_OPT_KEY "auth.addr.*.reject"
+#define NFS_DISABLE_OPT_KEY "nfs.*.disable"
+
+
typedef enum {
GF_CLIENT_TRUSTED,
GF_CLIENT_OTHER
@@ -78,6 +86,9 @@ typedef enum {
typedef enum { DOC, NO_DOC, GLOBAL_DOC, GLOBAL_NO_DOC } option_type_t;
+typedef int (*vme_option_validation) (dict_t *dict, char *key, char *value,
+ char **op_errstr);
+
struct volopt_map_entry {
char *key;
char *voltype;
@@ -86,7 +97,10 @@ struct volopt_map_entry {
option_type_t type;
uint32_t flags;
uint32_t op_version;
+ char *description;
+ vme_option_validation validate_fn;
};
+
int glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo);
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index bc656a091b2..29be76aa9b8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1549,8 +1549,12 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr)
/* dist-leaf-count is the count of brick nodes for a given
subvolume of distribute */
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- volinfo->replica_count);
+ volinfo->dist_leaf_count = glusterd_get_dist_leaf_count (volinfo);
+
+ /* subvol_count is the count of number of subvolumes present
+ for a given distribute volume */
+ volinfo->subvol_count = (volinfo->brick_count /
+ volinfo->dist_leaf_count);
/* Keep sub-count same as earlier, for the sake of backward
compatibility */
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
new file mode 100644
index 00000000000..73b06fb9a07
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -0,0 +1,1082 @@
+/*
+ Copyright (c) 2013 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.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterd-volgen.h"
+#include "glusterd-utils.h"
+
+static int
+check_dict_key_value (dict_t *dict, char *key, char *value)
+{
+ glusterd_conf_t *priv = NULL;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR, "Received Empty Dict.");
+ ret = -1;
+ goto out;
+ }
+
+ if (!key) {
+ gf_log (this->name, GF_LOG_ERROR, "Received Empty Key.");
+ ret = -1;
+ goto out;
+ }
+
+ if (!value) {
+ gf_log (this->name, GF_LOG_ERROR, "Received Empty Value.");
+ ret = -1;
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+get_volname_volinfo (dict_t *dict, char **volname, glusterd_volinfo_t **volinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "volname", volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (*volname, volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+validate_cache_max_min_size (dict_t *dict, char *key, char *value,
+ char **op_errstr)
+{
+ char *current_max_value = NULL;
+ char *current_min_value = NULL;
+ char errstr[2048] = "";
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+ uint64_t max_value = 0;
+ uint64_t min_value = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = check_dict_key_value (dict, key, value);
+ if (ret)
+ goto out;
+
+ ret = get_volname_volinfo (dict, &volname, &volinfo);
+ if (ret)
+ goto out;
+
+ if ((!strcmp (key, "performance.cache-min-file-size")) ||
+ (!strcmp (key, "cache-min-file-size"))) {
+ glusterd_volinfo_get (volinfo,
+ "performance.cache-max-file-size",
+ &current_max_value);
+ if (current_max_value) {
+ gf_string2bytesize (current_max_value, &max_value);
+ gf_string2bytesize (value, &min_value);
+ current_min_value = value;
+ }
+ } else if ((!strcmp (key, "performance.cache-max-file-size")) ||
+ (!strcmp (key, "cache-max-file-size"))) {
+ glusterd_volinfo_get (volinfo,
+ "performance.cache-min-file-size",
+ &current_min_value);
+ if (current_min_value) {
+ gf_string2bytesize (current_min_value, &min_value);
+ gf_string2bytesize (value, &max_value);
+ current_max_value = value;
+ }
+ }
+
+ if (min_value > max_value) {
+ snprintf (errstr, sizeof (errstr),
+ "cache-min-file-size (%s) is greater than "
+ "cache-max-file-size (%s)",
+ current_min_value, current_max_value);
+ gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
+ *op_errstr = gf_strdup (errstr);
+ ret = -1;
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+validate_quota (dict_t *dict, char *key, char *value,
+ char **op_errstr)
+{
+ char errstr[2048] = "";
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = check_dict_key_value (dict, key, value);
+ if (ret)
+ goto out;
+
+ ret = get_volname_volinfo (dict, &volname, &volinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get the quota status");
+ goto out;
+ }
+
+ if (ret == _gf_false) {
+ snprintf (errstr, sizeof (errstr),
+ "Cannot set %s. Enable quota first.", key);
+ gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
+ *op_errstr = gf_strdup (errstr);
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+validate_stripe (dict_t *dict, char *key, char *value, char **op_errstr)
+{
+ char errstr[2048] = "";
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = check_dict_key_value (dict, key, value);
+ if (ret)
+ goto out;
+
+ ret = get_volname_volinfo (dict, &volname, &volinfo);
+ if (ret)
+ goto out;
+
+ if (volinfo->stripe_count == 1) {
+ snprintf (errstr, sizeof (errstr),
+ "Cannot set %s for a non-stripe volume.", key);
+ gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
+ *op_errstr = gf_strdup (errstr);
+ ret = -1;
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+validate_subvols_per_directory (dict_t *dict, char *key, char *value,
+ char **op_errstr)
+{
+ char errstr[2048] = "";
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+ int subvols = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = check_dict_key_value (dict, key, value);
+ if (ret)
+ goto out;
+
+ ret = get_volname_volinfo (dict, &volname, &volinfo);
+ if (ret)
+ goto out;
+
+ subvols = atoi(value);
+
+ /* Checking if the subvols-per-directory exceed the total
+ number of subvolumes. */
+ if (subvols > volinfo->subvol_count) {
+ snprintf (errstr, sizeof(errstr),
+ "subvols-per-directory(%d) is greater "
+ "than the number of subvolumes(%d).",
+ subvols, volinfo->subvol_count);
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s.", errstr);
+ *op_errstr = gf_strdup (errstr);
+ ret = -1;
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+
+/* dispatch table for VOLUME SET
+ * -----------------------------
+ *
+ * Format of entries:
+ *
+ * First field is the <key>, for the purpose of looking it up
+ * in volume dictionary. Each <key> is of the format "<domain>.<specifier>".
+ *
+ * Second field is <voltype>.
+ *
+ * Third field is <option>, if its unset, it's assumed to be
+ * the same as <specifier>.
+ *
+ * Fourth field is <value>. In this context they are used to specify
+ * a default. That is, even the volume dict doesn't have a value,
+ * we procced as if the default value were set for it.
+ *
+ * Fifth field is <doctype>, which decides if the option is public and available
+ * in "set help" or not. "NO_DOC" entries are not part of the public interface
+ * and are subject to change at any time. This also decides if an option is
+ * global (apllies to all volumes) or normal (applies to only specified volume).
+ *
+ * Sixth field is <flags>.
+ *
+ * Seventh field is <op-version>.
+ *
+ * Eight field is description of option: If NULL, tried to fetch from
+ * translator code's xlator_options table.
+ *
+ * Nineth field is validation function: If NULL, xlator's option specific
+ * validation will be tried, otherwise tried at glusterd code itself.
+ *
+ * There are two type of entries: basic and special.
+ *
+ * - Basic entries are the ones where the <option> does _not_ start with
+ * the bang! character ('!').
+ *
+ * In their case, <option> is understood as an option for an xlator of
+ * type <voltype>. Their effect is to copy over the volinfo->dict[<key>]
+ * value to all graph nodes of type <voltype> (if such a value is set).
+ *
+ * You are free to add entries of this type, they will become functional
+ * just by being present in the table.
+ *
+ * - Special entries where the <option> starts with the bang!.
+ *
+ * They are not applied to all graphs during generation, and you cannot
+ * extend them in a trivial way which could be just picked up. Better
+ * not touch them unless you know what you do.
+ *
+ *
+ * Another kind of grouping for options, according to visibility:
+ *
+ * - Exported: one which is used in the code. These are characterized by
+ * being used a macro as <key> (of the format VKEY_..., defined in
+ * glusterd-volgen.h
+ *
+ * - Non-exported: the rest; these have string literal <keys>.
+ *
+ * Adhering to this policy, option name changes shall be one-liners.
+ *
+ */
+
+struct volopt_map_entry glusterd_volopt_map[] = {
+ /* DHT xlator options */
+ { .key = "cluster.lookup-unhashed",
+ .voltype = "cluster/distribute",
+ .op_version = 1
+ },
+ { .key = "cluster.min-free-disk",
+ .voltype = "cluster/distribute",
+ .op_version = 1
+ },
+ { .key = "cluster.min-free-inodes",
+ .voltype = "cluster/distribute",
+ .op_version = 1
+ },
+ { .key = "cluster.rebalance-stats",
+ .voltype = "cluster/distribute",
+ .op_version = 2
+ },
+ { .key = "cluster.subvols-per-directory",
+ .voltype = "cluster/distribute",
+ .option = "directory-layout-spread",
+ .op_version = 2,
+ .validate_fn = validate_subvols_per_directory
+ },
+ { .key = "cluster.readdir-optimize",
+ .voltype = "cluster/distribute",
+ .op_version = 2
+ },
+ { .key = "cluster.nufa",
+ .voltype = "cluster/distribute",
+ .option = "!nufa",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+
+
+ /* AFR xlator options */
+ { .key = "cluster.entry-change-log",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.read-subvolume",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.read-subvolume-index",
+ .voltype = "cluster/replicate",
+ .op_version = 2
+ },
+ { .key = "cluster.read-hash-mode",
+ .voltype = "cluster/replicate",
+ .op_version = 2
+ },
+ { .key = "cluster.background-self-heal-count",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.metadata-self-heal",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.data-self-heal",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.entry-self-heal",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.self-heal-daemon",
+ .voltype = "cluster/replicate",
+ .option = "!self-heal-daemon",
+ .op_version = 1
+ },
+ { .key = "cluster.heal-timeout",
+ .voltype = "cluster/replicate",
+ .option = "!heal-timeout",
+ .op_version = 2
+ },
+ { .key = "cluster.strict-readdir",
+ .voltype = "cluster/replicate",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "cluster.self-heal-window-size",
+ .voltype = "cluster/replicate",
+ .option = "data-self-heal-window-size",
+ .op_version = 1
+ },
+ { .key = "cluster.data-change-log",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.metadata-change-log",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.data-self-heal-algorithm",
+ .voltype = "cluster/replicate",
+ .option = "data-self-heal-algorithm",
+ .op_version = 1
+ },
+ { .key = "cluster.eager-lock",
+ .voltype = "cluster/replicate",
+ .op_version = 1
+ },
+ { .key = "cluster.quorum-type",
+ .voltype = "cluster/replicate",
+ .option = "quorum-type",
+ .op_version = 1
+ },
+ { .key = "cluster.quorum-count",
+ .voltype = "cluster/replicate",
+ .option = "quorum-count",
+ .op_version = 1
+ },
+ { .key = "cluster.choose-local",
+ .voltype = "cluster/replicate",
+ .op_version = 2
+ },
+ { .key = "cluster.self-heal-readdir-size",
+ .voltype = "cluster/replicate",
+ .op_version = 2
+ },
+ { .key = "cluster.post-op-delay-secs",
+ .voltype = "cluster/replicate",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+ { .key = "cluster.readdir-failover",
+ .voltype = "cluster/replicate",
+ .op_version = 2
+ },
+
+ /* Stripe xlator options */
+ { .key = "cluster.stripe-block-size",
+ .voltype = "cluster/stripe",
+ .option = "block-size",
+ .op_version = 1,
+ .validate_fn = validate_stripe
+ },
+ { .key = "cluster.stripe-coalesce",
+ .voltype = "cluster/stripe",
+ .option = "coalesce",
+ .op_version = 2
+ },
+
+ /* IO-stats xlator options */
+ { .key = VKEY_DIAG_LAT_MEASUREMENT,
+ .voltype = "debug/io-stats",
+ .option = "latency-measurement",
+ .value = "off",
+ .op_version = 1
+ },
+ { .key = "diagnostics.dump-fd-stats",
+ .voltype = "debug/io-stats",
+ .op_version = 1
+ },
+ { .key = VKEY_DIAG_CNT_FOP_HITS,
+ .voltype = "debug/io-stats",
+ .option = "count-fop-hits",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "diagnostics.brick-log-level",
+ .voltype = "debug/io-stats",
+ .option = "!brick-log-level",
+ .op_version = 1
+ },
+ { .key = "diagnostics.client-log-level",
+ .voltype = "debug/io-stats",
+ .option = "!client-log-level",
+ .op_version = 1
+ },
+ { .key = "diagnostics.brick-sys-log-level",
+ .voltype = "debug/io-stats",
+ .option = "!sys-log-level",
+ .op_version = 1
+ },
+ { .key = "diagnostics.client-sys-log-level",
+ .voltype = "debug/io-stats",
+ .option = "!sys-log-level",
+ .op_version = 1
+ },
+
+ /* IO-cache xlator options */
+ { .key = "performance.cache-max-file-size",
+ .voltype = "performance/io-cache",
+ .option = "max-file-size",
+ .op_version = 1,
+ .validate_fn = validate_cache_max_min_size
+ },
+ { .key = "performance.cache-min-file-size",
+ .voltype = "performance/io-cache",
+ .option = "min-file-size",
+ .op_version = 1,
+ .validate_fn = validate_cache_max_min_size
+ },
+ { .key = "performance.cache-refresh-timeout",
+ .voltype = "performance/io-cache",
+ .option = "cache-timeout",
+ .op_version = 1
+ },
+ { .key = "performance.cache-priority",
+ .voltype = "performance/io-cache",
+ .option = "priority",
+ .op_version = 1
+ },
+ { .key = "performance.cache-size",
+ .voltype = "performance/io-cache",
+ .op_version = 1
+ },
+
+ /* IO-threads xlator options */
+ { .key = "performance.io-thread-count",
+ .voltype = "performance/io-threads",
+ .option = "thread-count",
+ .op_version = 1
+ },
+ { .key = "performance.high-prio-threads",
+ .voltype = "performance/io-threads",
+ .op_version = 1
+ },
+ { .key = "performance.normal-prio-threads",
+ .voltype = "performance/io-threads",
+ .op_version = 1
+ },
+ { .key = "performance.low-prio-threads",
+ .voltype = "performance/io-threads",
+ .op_version = 1
+ },
+ { .key = "performance.least-prio-threads",
+ .voltype = "performance/io-threads",
+ .op_version = 1
+ },
+ { .key = "performance.enable-least-priority",
+ .voltype = "performance/io-threads",
+ .op_version = 2
+ },
+ { .key = "performance.least-rate-limit",
+ .voltype = "performance/io-threads",
+ .op_version = 1
+ },
+
+ /* Other perf xlators' options */
+ { .key = "performance.cache-size",
+ .voltype = "performance/quick-read",
+ .op_version = 1
+ },
+ { .key = "performance.flush-behind",
+ .voltype = "performance/write-behind",
+ .option = "flush-behind",
+ .op_version = 1
+ },
+ { .key = "performance.write-behind-window-size",
+ .voltype = "performance/write-behind",
+ .option = "cache-size",
+ .op_version = 1
+ },
+ { .key = "performance.strict-o-direct",
+ .voltype = "performance/write-behind",
+ .option = "strict-O_DIRECT",
+ .op_version = 2
+ },
+ { .key = "performance.strict-write-ordering",
+ .voltype = "performance/write-behind",
+ .option = "strict-write-ordering",
+ .op_version = 2
+ },
+ { .key = "performance.read-ahead-page-count",
+ .voltype = "performance/read-ahead",
+ .option = "page-count",
+ .op_version = 1
+ },
+ { .key = "performance.md-cache-timeout",
+ .voltype = "performance/md-cache",
+ .option = "md-cache-timeout",
+ .op_version = 2
+ },
+
+ /* Client xlator options */
+ { .key = "network.frame-timeout",
+ .voltype = "protocol/client",
+ .op_version = 1
+ },
+ { .key = "network.ping-timeout",
+ .voltype = "protocol/client",
+ .op_version = 1
+ },
+ { .key = "network.tcp-window-size",
+ .voltype = "protocol/client",
+ .op_version = 1
+ },
+ { .key = "features.lock-heal",
+ .voltype = "protocol/client",
+ .option = "lk-heal",
+ .op_version = 1
+ },
+ { .key = "features.grace-timeout",
+ .voltype = "protocol/client",
+ .option = "grace-timeout",
+ .op_version = 1
+ },
+ { .key = "client.ssl",
+ .voltype = "protocol/client",
+ .option = "transport.socket.ssl-enabled",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+ { .key = "network.remote-dio",
+ .voltype = "protocol/client",
+ .option = "filter-O_DIRECT",
+ .op_version = 1
+ },
+
+ /* Server xlator options */
+ { .key = "network.tcp-window-size",
+ .voltype = "protocol/server",
+ .op_version = 1
+ },
+ { .key = "network.inode-lru-limit",
+ .voltype = "protocol/server",
+ .op_version = 1
+ },
+ { .key = AUTH_ALLOW_MAP_KEY,
+ .voltype = "protocol/server",
+ .option = "!server-auth",
+ .value = "*",
+ .op_version = 1
+ },
+ { .key = AUTH_REJECT_MAP_KEY,
+ .voltype = "protocol/server",
+ .option = "!server-auth",
+ .op_version = 1
+ },
+ { .key = "transport.keepalive",
+ .voltype = "protocol/server",
+ .option = "transport.socket.keepalive",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "server.allow-insecure",
+ .voltype = "protocol/server",
+ .option = "rpc-auth-allow-insecure",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "server.root-squash",
+ .voltype = "protocol/server",
+ .option = "root-squash",
+ .op_version = 2
+ },
+ { .key = "server.statedump-path",
+ .voltype = "protocol/server",
+ .option = "statedump-path",
+ .op_version = 1
+ },
+ { .key = "features.lock-heal",
+ .voltype = "protocol/server",
+ .option = "lk-heal",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "features.grace-timeout",
+ .voltype = "protocol/server",
+ .option = "grace-timeout",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "server.ssl",
+ .voltype = "protocol/server",
+ .option = "transport.socket.ssl-enabled",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+
+ /* Performance xlators enable/disbable options */
+ { .key = "performance.write-behind",
+ .voltype = "performance/write-behind",
+ .option = "!perf",
+ .value = "on",
+ .op_version = 1,
+ .description = "enable/disable write-behind translator in the volume."
+ },
+ { .key = "performance.read-ahead",
+ .voltype = "performance/read-ahead",
+ .option = "!perf",
+ .value = "on",
+ .op_version = 1,
+ .description = "enable/disable read-ahead translator in the volume."
+ },
+ { .key = "performance.io-cache",
+ .voltype = "performance/io-cache",
+ .option = "!perf",
+ .value = "on",
+ .op_version = 1,
+ .description = "enable/disable io-cache translator in the volume."
+ },
+ { .key = "performance.quick-read",
+ .voltype = "performance/quick-read",
+ .option = "!perf",
+ .value = "on",
+ .op_version = 1,
+ .description = "enable/disable quick-read translator in the volume."
+ },
+ { .key = "performance.open-behind",
+ .voltype = "performance/open-behind",
+ .option = "!perf",
+ .value = "on",
+ .op_version = 2,
+ .description = "enable/disable open-behind translator in the volume."
+ },
+ { .key = "performance.stat-prefetch",
+ .voltype = "performance/md-cache",
+ .option = "!perf",
+ .value = "on",
+ .op_version = 1,
+ .description = "enable/disable meta-data caching translator in the "
+ "volume."
+ },
+ { .key = "performance.client-io-threads",
+ .voltype = "performance/io-threads",
+ .option = "!perf",
+ .value = "off",
+ .op_version = 1,
+ .description = "enable/disable io-threads translator in the client "
+ "graph of volume."
+ },
+ { .key = "performance.nfs.write-behind",
+ .voltype = "performance/write-behind",
+ .option = "!nfsperf",
+ .value = "on",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "performance.nfs.read-ahead",
+ .voltype = "performance/read-ahead",
+ .option = "!nfsperf",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "performance.nfs.io-cache",
+ .voltype = "performance/io-cache",
+ .option = "!nfsperf",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "performance.nfs.quick-read",
+ .voltype = "performance/quick-read",
+ .option = "!nfsperf",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "performance.nfs.stat-prefetch",
+ .voltype = "performance/md-cache",
+ .option = "!nfsperf",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "performance.nfs.io-threads",
+ .voltype = "performance/io-threads",
+ .option = "!nfsperf",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "performance.force-readdirp",
+ .voltype = "performance/md-cache",
+ .option = "force-readdirp",
+ .op_version = 2
+ },
+
+ /* Quota xlator options */
+ { .key = VKEY_FEATURES_LIMIT_USAGE,
+ .voltype = "features/quota",
+ .option = "limit-set",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "features.quota-timeout",
+ .voltype = "features/quota",
+ .option = "timeout",
+ .value = "0",
+ .op_version = 1,
+ .validate_fn = validate_quota
+ },
+
+ /* Marker xlator options */
+ { .key = VKEY_MARKER_XTIME,
+ .voltype = "features/marker",
+ .option = "xtime",
+ .value = "off",
+ .type = NO_DOC,
+ .flags = OPT_FLAG_FORCE,
+ .op_version = 1
+ },
+ { .key = VKEY_MARKER_XTIME,
+ .voltype = "features/marker",
+ .option = "!xtime",
+ .value = "off",
+ .type = NO_DOC,
+ .flags = OPT_FLAG_FORCE,
+ .op_version = 1
+ },
+ { .key = VKEY_FEATURES_QUOTA,
+ .voltype = "features/marker",
+ .option = "quota",
+ .value = "off",
+ .type = NO_DOC,
+ .flags = OPT_FLAG_FORCE,
+ .op_version = 1
+ },
+
+ /* Debug xlators options */
+ { .key = "debug.trace",
+ .voltype = "debug/trace",
+ .option = "!debug",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+ { .key = "debug.log-history",
+ .voltype = "debug/trace",
+ .option = "log-history",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+ { .key = "debug.log-file",
+ .voltype = "debug/trace",
+ .option = "log-file",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+ { .key = "debug.exclude-ops",
+ .voltype = "debug/trace",
+ .option = "exclude-ops",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+ { .key = "debug.include-ops",
+ .voltype = "debug/trace",
+ .option = "include-ops",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+ { .key = "debug.error-gen",
+ .voltype = "debug/error-gen",
+ .option = "!debug",
+ .value = "off",
+ .type = NO_DOC,
+ .op_version = 1
+ },
+
+
+ /* NFS xlator options */
+ { .key = "nfs.enable-ino32",
+ .voltype = "nfs/server",
+ .option = "nfs.enable-ino32",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.mem-factor",
+ .voltype = "nfs/server",
+ .option = "nfs.mem-factor",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.export-dirs",
+ .voltype = "nfs/server",
+ .option = "nfs3.export-dirs",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.export-volumes",
+ .voltype = "nfs/server",
+ .option = "nfs3.export-volumes",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.addr-namelookup",
+ .voltype = "nfs/server",
+ .option = "rpc-auth.addr.namelookup",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.dynamic-volumes",
+ .voltype = "nfs/server",
+ .option = "nfs.dynamic-volumes",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.register-with-portmap",
+ .voltype = "nfs/server",
+ .option = "rpc.register-with-portmap",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.port",
+ .voltype = "nfs/server",
+ .option = "nfs.port",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.rpc-auth-unix",
+ .voltype = "nfs/server",
+ .option = "!rpc-auth.auth-unix.*",
+ .op_version = 1
+ },
+ { .key = "nfs.rpc-auth-null",
+ .voltype = "nfs/server",
+ .option = "!rpc-auth.auth-null.*",
+ .op_version = 1
+ },
+ { .key = "nfs.rpc-auth-allow",
+ .voltype = "nfs/server",
+ .option = "!rpc-auth.addr.*.allow",
+ .op_version = 1
+ },
+ { .key = "nfs.rpc-auth-reject",
+ .voltype = "nfs/server",
+ .option = "!rpc-auth.addr.*.reject",
+ .op_version = 1
+ },
+ { .key = "nfs.ports-insecure",
+ .voltype = "nfs/server",
+ .option = "!rpc-auth.ports.*.insecure",
+ .op_version = 1
+ },
+ { .key = "nfs.transport-type",
+ .voltype = "nfs/server",
+ .option = "!nfs.transport-type",
+ .value = "tcp",
+ .op_version = 1,
+ .description = "Specifies the nfs transport type. Valid "
+ "transport types are 'tcp' and 'rdma'."
+ },
+ { .key = "nfs.trusted-sync",
+ .voltype = "nfs/server",
+ .option = "!nfs3.*.trusted-sync",
+ .op_version = 1
+ },
+ { .key = "nfs.trusted-write",
+ .voltype = "nfs/server",
+ .option = "!nfs3.*.trusted-write",
+ .op_version = 1
+ },
+ { .key = "nfs.volume-access",
+ .voltype = "nfs/server",
+ .option = "!nfs3.*.volume-access",
+ .op_version = 1
+ },
+ { .key = "nfs.export-dir",
+ .voltype = "nfs/server",
+ .option = "!nfs3.*.export-dir",
+ .op_version = 1
+ },
+ { .key = NFS_DISABLE_MAP_KEY,
+ .voltype = "nfs/server",
+ .option = "!nfs-disable",
+ .op_version = 1
+ },
+ { .key = "nfs.nlm",
+ .voltype = "nfs/server",
+ .option = "nfs.nlm",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.mount-udp",
+ .voltype = "nfs/server",
+ .option = "nfs.mount-udp",
+ .type = GLOBAL_DOC,
+ .op_version = 1
+ },
+ { .key = "nfs.server-aux-gids",
+ .voltype = "nfs/server",
+ .option = "nfs.server-aux-gids",
+ .type = NO_DOC,
+ .op_version = 2
+ },
+
+ /* Other options which don't fit any place above */
+ { .key = "features.read-only",
+ .voltype = "features/read-only",
+ .option = "!read-only",
+ .value = "off",
+ .op_version = 2
+ },
+ { .key = "features.worm",
+ .voltype = "features/worm",
+ .option = "!worm",
+ .value = "off",
+ .op_version = 2
+ },
+ { .key = "storage.linux-aio",
+ .voltype = "storage/posix",
+ .op_version = 2
+ },
+ { .key = "storage.owner-uid",
+ .voltype = "storage/posix",
+ .option = "brick-uid",
+ .op_version = 2
+ },
+ { .key = "storage.owner-gid",
+ .voltype = "storage/posix",
+ .option = "brick-gid",
+ .op_version = 2
+ },
+ { .key = "config.memory-accounting",
+ .voltype = "configuration",
+ .option = "!config",
+ .op_version = 2
+ },
+ { .key = "config.transport",
+ .voltype = "configuration",
+ .option = "!config",
+ .op_version = 2
+ },
+ { .key = GLUSTERD_QUORUM_TYPE_KEY,
+ .voltype = "mgmt/glusterd",
+ .value = "off",
+ .op_version = 2
+ },
+ { .key = GLUSTERD_QUORUM_RATIO_KEY,
+ .voltype = "mgmt/glusterd",
+ .value = "0",
+ .op_version = 2
+ },
+ { .key = NULL
+ }
+};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 5198ff41d5f..b03986a8a90 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -269,6 +269,8 @@ struct glusterd_volinfo_ {
int sub_count; /* backward compatibility */
int stripe_count;
int replica_count;
+ int subvol_count; /* Number of subvolumes in a
+ distribute volume */
int dist_leaf_count; /* Number of bricks in one
distribute subvolume */
int port;