mirror of
https://github.com/gluster/glusterd2.git
synced 2026-02-05 12:45:38 +01:00
Fix Option names in group profile and add db profile
- Group profile for transactional DB workload added - Fixed the option names used in other group profiles - Fixed the validation issues related to setting the options glusterfs PR to support enable/disable of xlators https://review.gluster.org/21813 Fixes: #1250 Signed-off-by: Aravinda VK <avishwan@redhat.com>
This commit is contained in:
committed by
Madhu Rajanna
parent
b73370c553
commit
8de2a9ee49
@@ -63,10 +63,7 @@ func validateOptions(opts map[string]string, flags api.VolOptionFlags) error {
|
||||
|
||||
func validateXlatorOptions(opts map[string]string, volinfo *volume.Volinfo) error {
|
||||
for k, v := range opts {
|
||||
_, xl, key, err := options.SplitKey(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, xl, key := options.SplitKey(k)
|
||||
xltr, err := xlator.Find(xl)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -339,10 +336,7 @@ func isActionStepRequired(opt map[string]string, volinfo *volume.Volinfo) bool {
|
||||
return false
|
||||
}
|
||||
for k := range opt {
|
||||
_, xl, _, err := options.SplitKey(k)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
_, xl, _ := options.SplitKey(k)
|
||||
if xltr, err := xlator.Find(xl); err == nil && xltr.Actor != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -7,136 +7,161 @@ import (
|
||||
// defaultGroupOptions maps from a profile name to a set of options
|
||||
var defaultGroupOptions = map[string]*api.OptionGroup{
|
||||
"profile.gluster-block": {"profile.gluster-block",
|
||||
[]api.VolumeOption{{Name: "performance.quick-read", OnValue: "off"},
|
||||
{Name: "performance.read-ahead", OnValue: "off"},
|
||||
{Name: "performance.io-cache", OnValue: "off"},
|
||||
{Name: "performance.stat-prefetch", OnValue: "off"},
|
||||
{Name: "performance.open-behind", OnValue: "off"},
|
||||
{Name: "performance.readdir-ahead", OnValue: "off"},
|
||||
{Name: "performance.strict-o-direct", OnValue: "on"},
|
||||
{Name: "network.remote-dio", OnValue: "disable"},
|
||||
{Name: "cluster.eager-lock", OnValue: "disable"},
|
||||
{Name: "cluster.quorum-type", OnValue: "auto"},
|
||||
{Name: "cluster.data-self-heal-algorithm", OnValue: "full"},
|
||||
{Name: "cluster.locking-scheme", OnValue: "granular"},
|
||||
{Name: "cluster.shd-max-threads", OnValue: "8"},
|
||||
{Name: "cluster.shd-wait-qlength", OnValue: "10000"},
|
||||
{Name: "features.shard", OnValue: "on"},
|
||||
{Name: "features.shard-block-size", OnValue: "64MB"},
|
||||
[]api.VolumeOption{{Name: "performance/quick-read", OnValue: "off"},
|
||||
{Name: "performance/read-ahead", OnValue: "off"},
|
||||
{Name: "performance/io-cache", OnValue: "off"},
|
||||
{Name: "performance/md-cache", OnValue: "off"},
|
||||
{Name: "performance/open-behind", OnValue: "off"},
|
||||
{Name: "performance/readdir-ahead", OnValue: "off"},
|
||||
{Name: "performance/write-behind.strict-O_DIRECT", OnValue: "on"},
|
||||
{Name: "protocol/client.filter-O_DIRECT", OnValue: "disable"},
|
||||
{Name: "cluster/replicate.eager-lock", OnValue: "disable"},
|
||||
{Name: "cluster/replicate.quorum-type", OnValue: "auto"},
|
||||
{Name: "cluster/replicate.data-self-heal-algorithm", OnValue: "full"},
|
||||
{Name: "cluster/replicate.locking-scheme", OnValue: "granular"},
|
||||
{Name: "cluster/replicate.shd-max-threads", OnValue: "8"},
|
||||
{Name: "cluster/replicate.shd-wait-qlength", OnValue: "10000"},
|
||||
{Name: "features/shard", OnValue: "on"},
|
||||
{Name: "features/shard.shard-block-size", OnValue: "64MB"},
|
||||
{Name: "user.cifs", OnValue: "off"},
|
||||
{Name: "server.allow-insecure", OnValue: "on"}},
|
||||
{Name: "protocol/server.rpc-auth-allow-insecure", OnValue: "on"}},
|
||||
"Enable this profile for optimal results, in block use case"},
|
||||
"profile.SMB-small-file": {"profile.SMB-small-file",
|
||||
[]api.VolumeOption{{Name: "features.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "network.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance.stat-prefetch", OnValue: "on"},
|
||||
{Name: "performance.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.cache-samba-metadata", OnValue: "on"},
|
||||
{Name: "performance.nl-cache", OnValue: "on"},
|
||||
{Name: "performance.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.qr-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance.parallel-readdir", OnValue: "on"},
|
||||
{Name: "client.event-threads", OnValue: "4"},
|
||||
{Name: "server.event-threads", OnValue: "4"},
|
||||
{Name: "cluster.lookup-optimize", OnValue: "on"},
|
||||
{Name: "cluster.readdir-optimize", OnValue: "on"}},
|
||||
[]api.VolumeOption{{Name: "features/upcall.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features/upcall.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "protocol/server.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance/md-cache", OnValue: "on"},
|
||||
{Name: "performance/quick-read.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/md-cache.cache-samba-metadata", OnValue: "on"},
|
||||
{Name: "performance/nl-cache", OnValue: "on"},
|
||||
{Name: "performance/nl-cache.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/quick-read.qr-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance/readdir-ahead.parallel-readdir", OnValue: "on"},
|
||||
{Name: "protocol/client.event-threads", OnValue: "4"},
|
||||
{Name: "protocol/server.event-threads", OnValue: "4"},
|
||||
{Name: "cluster/distribute.lookup-optimize", OnValue: "on"},
|
||||
{Name: "cluster/distribute.readdir-optimize", OnValue: "on"}},
|
||||
"For use cases with dominant small file workload in SMB access, enable this profile"},
|
||||
"profile.FUSE-small-file": {"profile.FUSE-small-file",
|
||||
[]api.VolumeOption{{Name: "features.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "network.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance.stat-prefetch", OnValue: "on"},
|
||||
{Name: "performance.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.nl-cache", OnValue: "on"},
|
||||
{Name: "performance.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.qr-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance.parallel-readdir", OnValue: "on"},
|
||||
{Name: "client.event-threads", OnValue: "4"},
|
||||
{Name: "server.event-threads", OnValue: "4"},
|
||||
{Name: "cluster.lookup-optimize", OnValue: "on"},
|
||||
{Name: "cluster.readdir-optimize", OnValue: "on"}},
|
||||
[]api.VolumeOption{{Name: "features/upcall.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features/upcall.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "protocol/server.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance/md-cache", OnValue: "on"},
|
||||
{Name: "performance/quick-read.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/nl-cache", OnValue: "on"},
|
||||
{Name: "performance/nl-cache.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/quick-read.qr-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance/readdir-ahead.parallel-readdir", OnValue: "on"},
|
||||
{Name: "protocol/client.event-threads", OnValue: "4"},
|
||||
{Name: "protocol/server.event-threads", OnValue: "4"},
|
||||
{Name: "cluster/distribute.lookup-optimize", OnValue: "on"},
|
||||
{Name: "cluster/distribute.readdir-optimize", OnValue: "on"}},
|
||||
"For use cases with dominant small file workload in native FUSE mount access, enable this profile"},
|
||||
"profile.SMB-large-file-EC": {"profile.SMB-large-file-EC",
|
||||
[]api.VolumeOption{{Name: "features.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "network.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance.stat-prefetch", OnValue: "on"},
|
||||
{Name: "performance.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.cache-samba-metadata", OnValue: "on"},
|
||||
{Name: "performance.nl-cache", OnValue: "on"},
|
||||
{Name: "performance.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance.parallel-readdir", OnValue: "on"},
|
||||
{Name: "performance.quick-read", OnValue: "off"},
|
||||
{Name: "performance.open-behind", OnValue: "off"},
|
||||
{Name: "performance.write-behind-trickling-writes", OnValue: "off"},
|
||||
{Name: "performance.aggregate-size", OnValue: "1MB"},
|
||||
{Name: "client.event-threads", OnValue: "4"},
|
||||
{Name: "server.event-threads", OnValue: "4"}},
|
||||
[]api.VolumeOption{{Name: "features/upcall.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features/upcall.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "protocol/server.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance/md-cache", OnValue: "on"},
|
||||
{Name: "performance/quick-read.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/md-cache.cache-samba-metadata", OnValue: "on"},
|
||||
{Name: "performance/nl-cache", OnValue: "on"},
|
||||
{Name: "performance/nl-cache.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance/readdir-ahead.parallel-readdir", OnValue: "on"},
|
||||
{Name: "performance/quick-read", OnValue: "off"},
|
||||
{Name: "performance/open-behind", OnValue: "off"},
|
||||
{Name: "performance/write-behind.trickling-writes", OnValue: "off"},
|
||||
{Name: "performance/write-behind.aggregate-size", OnValue: "1MB"},
|
||||
{Name: "protocol/client.event-threads", OnValue: "4"},
|
||||
{Name: "protocol/server.event-threads", OnValue: "4"}},
|
||||
"Enable this profile for use cases consisting of mostly large files like video surveillance, backup, video streaming and others, with SMB access to an erasure coded volume"},
|
||||
"profile.FUSE-large-file-EC": {"profile.FUSE-large-file-EC",
|
||||
[]api.VolumeOption{{Name: "features.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "network.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance.stat-prefetch", OnValue: "on"},
|
||||
{Name: "performance.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.nl-cache", OnValue: "on"},
|
||||
{Name: "performance.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance.readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance.parallel-readdir", OnValue: "on"},
|
||||
{Name: "performance.quick-read", OnValue: "off"},
|
||||
{Name: "performance.open-behind", OnValue: "off"},
|
||||
{Name: "performance.write-behind-trickling-writes", OnValue: "off"},
|
||||
{Name: "performance.aggregate-size", OnValue: "1MB"},
|
||||
{Name: "client.event-threads", OnValue: "4"},
|
||||
{Name: "server.event-threads", OnValue: "4"}},
|
||||
[]api.VolumeOption{{Name: "features/upcall.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features/upcall.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "protocol/server.inode-lru-limit", OnValue: "200000"},
|
||||
{Name: "performance.md-cache", OnValue: "on"},
|
||||
{Name: "performance/quick-read.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/nl-cache", OnValue: "on"},
|
||||
{Name: "performance/nl-cache.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "performance/readdir-ahead", OnValue: "on"},
|
||||
{Name: "performance/readdir-ahead.parallel-readdir", OnValue: "on"},
|
||||
{Name: "performance/quick-read", OnValue: "off"},
|
||||
{Name: "performance/open-behind", OnValue: "off"},
|
||||
{Name: "performance/write-behind.trickling-writes", OnValue: "off"},
|
||||
{Name: "performance/write-behind.aggregate-size", OnValue: "1MB"},
|
||||
{Name: "protocol/client.event-threads", OnValue: "4"},
|
||||
{Name: "protocol/server.event-threads", OnValue: "4"}},
|
||||
"Enable this profile for use cases consisting of mostly large files like video surveillance, backup, video streaming and others, with native FUSE mount access to an erasure coded volume"},
|
||||
"profile.nl-cache": {"profile.nl-cache",
|
||||
[]api.VolumeOption{{Name: "features.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "performance.nl-cache", OnValue: "on"},
|
||||
{Name: "performance.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "network.inode-lru-limit", OnValue: "200000"}},
|
||||
[]api.VolumeOption{{Name: "features/upcall.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features/upcall.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "performance/nl-cache", OnValue: "on"},
|
||||
{Name: "performance/nl-cache.nl-cache-timeout", OnValue: "600"},
|
||||
{Name: "protocol/server.inode-lru-limit", OnValue: "200000"}},
|
||||
"Enable this for the workloads that generate lots of lookups before creating files, eg: SMB access, git tool and others"},
|
||||
"profile.metadata-cache": {"profile.metadata-cache",
|
||||
[]api.VolumeOption{{Name: "cache-invalidation", OnValue: "on"},
|
||||
{Name: "cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "performance.stat-prefetch", OnValue: "on"},
|
||||
{Name: "performance.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "inode-lru-limit", OnValue: "200000"}},
|
||||
[]api.VolumeOption{{Name: "features/upcall.cache-invalidation", OnValue: "on"},
|
||||
{Name: "features/upcall.cache-invalidation-timeout", OnValue: "600"},
|
||||
{Name: "performance/md-cache", OnValue: "on"},
|
||||
{Name: "performance/quick-read.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.cache-invalidation", OnValue: "on"},
|
||||
{Name: "performance/md-cache.md-cache-timeout", OnValue: "600"},
|
||||
{Name: "protocol/server.inode-lru-limit", OnValue: "200000"}},
|
||||
"This profile enables metadata(stat, xattr) caching on client side. Its recommended to enable this for most workloads other than the ones that require 100% consistency like databases"},
|
||||
"profile.virt": {"profile.virt",
|
||||
[]api.VolumeOption{{Name: "performance.quick-read", OnValue: "off"},
|
||||
{Name: "performance.read-ahead", OnValue: "off"},
|
||||
{Name: "performance.io-cache", OnValue: "off"},
|
||||
{Name: "performance.low-prio-threads", OnValue: "32"},
|
||||
{Name: "network.remote-dio", OnValue: "enable"},
|
||||
{Name: "cluster.eager-lock", OnValue: "enable"},
|
||||
{Name: "cluster.quorum-type", OnValue: "auto"},
|
||||
[]api.VolumeOption{{Name: "performance/quick-read", OnValue: "off"},
|
||||
{Name: "performance/read-ahead", OnValue: "off"},
|
||||
{Name: "performance/io-cache", OnValue: "off"},
|
||||
{Name: "performance/io-threads.low-prio-threads", OnValue: "32"},
|
||||
{Name: "protocol/client.filter-O_DIRECT", OnValue: "enable"},
|
||||
{Name: "cluster/replicate.eager-lock", OnValue: "enable"},
|
||||
{Name: "cluster/replicate.quorum-type", OnValue: "auto"},
|
||||
{Name: "cluster.server-quorum-type", OnValue: "server"},
|
||||
{Name: "cluster.data-self-heal-algorithm", OnValue: "full"},
|
||||
{Name: "cluster.locking-scheme", OnValue: "granular"},
|
||||
{Name: "cluster.shd-max-threads", OnValue: "8"},
|
||||
{Name: "cluster.shd-wait-qlength", OnValue: "10000"},
|
||||
{Name: "features.shard", OnValue: "on"},
|
||||
{Name: "cluster/replicate.data-self-heal-algorithm", OnValue: "full"},
|
||||
{Name: "cluster/replicate.locking-scheme", OnValue: "granular"},
|
||||
{Name: "cluster/replicate.shd-max-threads", OnValue: "8"},
|
||||
{Name: "cluster/replicate.shd-wait-qlength", OnValue: "10000"},
|
||||
{Name: "features/shard", OnValue: "on"},
|
||||
{Name: "user.cifs", OnValue: "off"}},
|
||||
"Enable this profile, if the Gluster Volume is used to store virtual machines"},
|
||||
"profile.db": {"profile.db",
|
||||
[]api.VolumeOption{
|
||||
{Name: "performance/open-behind", OnValue: "on"},
|
||||
{Name: "performance/write-behind", OnValue: "off"},
|
||||
{Name: "performance/quick-read", OnValue: "off"},
|
||||
{Name: "performance/read-ahead", OnValue: "off"},
|
||||
{Name: "performance/io-cache", OnValue: "off"},
|
||||
{Name: "performance/readdir-ahead", OnValue: "off"},
|
||||
// as per new volgen, this has been named 'md-cache' instead of its
|
||||
// legacy name 'stat-prefetch'
|
||||
{Name: "performance/md-cache", OnValue: "off"},
|
||||
// https://github.com/gluster/glusterd2/issues/376#issuecomment-424970778
|
||||
{Name: "protocol/client.io-threads", OnValue: "on"},
|
||||
// xlator options
|
||||
{Name: "protocol/server.event-threads", OnValue: "4"},
|
||||
{Name: "protocol/client.event-threads", OnValue: "4"},
|
||||
{Name: "performance/open-behind.read-after-open", OnValue: "on"},
|
||||
{Name: "performance/write-behind.strict-O_DIRECT", OnValue: "on"},
|
||||
},
|
||||
"Enable profile that tunes volume for database workload"},
|
||||
"tls": {"tls",
|
||||
[]api.VolumeOption{
|
||||
{Name: "server.transport.socket.ssl-enabled", OnValue: "on"},
|
||||
{Name: "client.transport.socket.ssl-enabled", OnValue: "on"},
|
||||
{Name: "protocol/server.transport.socket.ssl-enabled", OnValue: "on"},
|
||||
{Name: "protocol/client.transport.socket.ssl-enabled", OnValue: "on"},
|
||||
},
|
||||
"Enable TLS for the volume for both bricks and clients"},
|
||||
"profile.test": {"profile.test",
|
||||
[]api.VolumeOption{{Name: "afr.eager-lock", OnValue: "on"},
|
||||
{Name: "gfproxy.afr.eager-lock", OnValue: "on"}},
|
||||
[]api.VolumeOption{{Name: "cluster/replicate.eager-lock", OnValue: "on"},
|
||||
{Name: "gfproxy.cluster/replicate.eager-lock", OnValue: "on"}},
|
||||
"Test purpose only"},
|
||||
}
|
||||
|
||||
@@ -153,10 +153,7 @@ func xlatorAction(c transaction.TxnCtx, txnOp txnOpType, volOp xlator.VolumeOpTy
|
||||
}
|
||||
//The code below applies only for xlator.VolumeSet and xlator.VolumeReset operations.
|
||||
for k, v := range reqOptions {
|
||||
_, xl, key, err := options.SplitKey(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, xl, key := options.SplitKey(k)
|
||||
xltr, err := xlator.Find(xl)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,46 +1,42 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/gluster/glusterd2/pkg/utils"
|
||||
)
|
||||
|
||||
// InvalidKeyError is returned by SplitKey if key is not of the correct form.
|
||||
type InvalidKeyError string
|
||||
|
||||
func (e InvalidKeyError) Error() string {
|
||||
return fmt.Sprintf("option key not in [<graph>.]<xlator>.<option-name> form: %s", string(e))
|
||||
}
|
||||
|
||||
var validGraphs = [...]string{
|
||||
"brick",
|
||||
"fuse",
|
||||
"gfproxy",
|
||||
"nfs",
|
||||
}
|
||||
|
||||
// SplitKey returns three strings by breaking key of the form
|
||||
// [<graph>].<xlator>.<option-name> into its constituents. <graph> is optional.
|
||||
// Returns an InvalidKeyError if key is not of correcf form.
|
||||
func SplitKey(k string) (string, string, string, error) {
|
||||
func SplitKey(k string) (string, string, string) {
|
||||
var graph, xlator, optName string
|
||||
|
||||
tmp := strings.Split(strings.TrimSpace(k), ".")
|
||||
if len(tmp) < 2 {
|
||||
// must at least be of the form <xlator>.<name>
|
||||
return graph, xlator, optName, InvalidKeyError(k)
|
||||
if len(tmp) == 1 {
|
||||
// If only xlator name is specified to enable/disable that xlator
|
||||
|
||||
// Remove category prefix for example "cluster/replicate"
|
||||
// will be converted to "replicate"
|
||||
optName = path.Base(tmp[0])
|
||||
|
||||
return graph, tmp[0], optName
|
||||
}
|
||||
|
||||
if utils.StringInSlice(tmp[0], validGraphs[:]) {
|
||||
if utils.StringInSlice(tmp[0], utils.ValidVolfiles[:]) {
|
||||
// valid graph present
|
||||
if len(tmp) < 3 {
|
||||
// must be of the form <graph>.<xlator>.<name>
|
||||
return graph, xlator, optName, InvalidKeyError(k)
|
||||
}
|
||||
graph = tmp[0]
|
||||
xlator = tmp[1]
|
||||
|
||||
if len(tmp) < 3 {
|
||||
// may be only <graph>.<xlator> specified
|
||||
|
||||
// Remove category prefix for example "cluster/replicate"
|
||||
// will be converted to "replicate"
|
||||
optName = path.Base(xlator)
|
||||
|
||||
return graph, xlator, optName
|
||||
}
|
||||
optName = strings.Join(tmp[2:], ".")
|
||||
} else {
|
||||
// key is of the format <xlator>.<name> where <name> itself
|
||||
@@ -49,5 +45,5 @@ func SplitKey(k string) (string, string, string, error) {
|
||||
optName = k[len(xlator)+1:]
|
||||
}
|
||||
|
||||
return graph, xlator, optName, nil
|
||||
return graph, xlator, optName
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/gluster/glusterd2/pkg/utils"
|
||||
|
||||
config "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@@ -45,8 +47,8 @@ func LoadDefaultTemplates() error {
|
||||
func init() {
|
||||
tmpls := make(map[string]Template)
|
||||
// default brick template
|
||||
tmpls["brick"] = Template{
|
||||
Name: "brick",
|
||||
tmpls[utils.BrickVolfile] = Template{
|
||||
Name: utils.BrickVolfile,
|
||||
Level: VolfileLevelBrick,
|
||||
Xlators: []Xlator{
|
||||
{
|
||||
@@ -96,8 +98,8 @@ func init() {
|
||||
}
|
||||
|
||||
// default client template
|
||||
tmpls["client"] = Template{
|
||||
Name: "fuse",
|
||||
tmpls[utils.ClientVolfile] = Template{
|
||||
Name: utils.ClientVolfile,
|
||||
Level: VolfileLevelVolume,
|
||||
Xlators: []Xlator{
|
||||
{
|
||||
@@ -131,8 +133,8 @@ func init() {
|
||||
}
|
||||
|
||||
// default rebalance template
|
||||
tmpls["rebalance"] = Template{
|
||||
Name: "rebalance",
|
||||
tmpls[utils.RebalanceVolfile] = Template{
|
||||
Name: utils.RebalanceVolfile,
|
||||
Level: VolfileLevelVolume,
|
||||
Xlators: []Xlator{
|
||||
{
|
||||
@@ -167,8 +169,8 @@ func init() {
|
||||
}
|
||||
|
||||
// default glustershd template
|
||||
tmpls["glustershd"] = Template{
|
||||
Name: "glustershd",
|
||||
tmpls[utils.SelfHealVolfile] = Template{
|
||||
Name: utils.SelfHealVolfile,
|
||||
Level: VolfileLevelCluster,
|
||||
Xlators: []Xlator{
|
||||
{
|
||||
@@ -192,8 +194,8 @@ func init() {
|
||||
},
|
||||
}
|
||||
|
||||
tmpls["bitd"] = Template{
|
||||
Name: "bitd",
|
||||
tmpls[utils.BitdVolfile] = Template{
|
||||
Name: utils.BitdVolfile,
|
||||
Level: VolfileLevelCluster,
|
||||
Xlators: []Xlator{
|
||||
{
|
||||
@@ -224,8 +226,8 @@ func init() {
|
||||
},
|
||||
}
|
||||
|
||||
tmpls["scrubd"] = Template{
|
||||
Name: "scrubd",
|
||||
tmpls[utils.ScrubdVolfile] = Template{
|
||||
Name: utils.ScrubdVolfile,
|
||||
Level: VolfileLevelCluster,
|
||||
Xlators: []Xlator{
|
||||
{
|
||||
|
||||
@@ -13,19 +13,33 @@ func (xl *Xlator) isEnabled(volinfo *volume.Volinfo, tmplName string) bool {
|
||||
// If Volinfo.Options can contains xlator, check for xlator
|
||||
// existence in the following order: FullName, Name and Suffix
|
||||
// For example changelog can be enabled using
|
||||
// `brick.features.changelog` or `features.changelog`
|
||||
// or `changelog`
|
||||
// `brick.features/changelog.changelog` or `features/changelog.changelog`
|
||||
// or `changelog.changelog`
|
||||
// volinfo can be nil in case of cluster level graphs
|
||||
if volinfo != nil {
|
||||
value, exists := volinfo.Options[xl.fullName(tmplName)]
|
||||
sfx := "." + xl.suffix()
|
||||
value, exists := volinfo.Options[xl.fullName(tmplName)+sfx]
|
||||
|
||||
if !exists {
|
||||
value, exists = volinfo.Options[xl.fullName(tmplName)]
|
||||
}
|
||||
|
||||
if !exists {
|
||||
value, exists = volinfo.Options[xl.name()+sfx]
|
||||
}
|
||||
|
||||
if !exists {
|
||||
value, exists = volinfo.Options[xl.name()]
|
||||
}
|
||||
|
||||
if !exists {
|
||||
value, exists = volinfo.Options[xl.suffix()]
|
||||
value, exists = volinfo.Options[xl.suffix()+sfx]
|
||||
}
|
||||
|
||||
if !exists {
|
||||
value, exists = volinfo.Options[xl.name()]
|
||||
}
|
||||
|
||||
if exists {
|
||||
return boolify(value)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package xlator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/gluster/glusterd2/glusterd2/options"
|
||||
)
|
||||
@@ -16,6 +17,10 @@ func (e NotFoundError) Error() string {
|
||||
// Find returns a Xlator with the give ID if found.
|
||||
// Returns a XlatorNotFoundError otherwise.
|
||||
func Find(id string) (*Xlator, error) {
|
||||
// Remove category prefix for example "cluster/replicate"
|
||||
// will be converted to "replicate"
|
||||
id = path.Base(id)
|
||||
|
||||
xl, ok := xlMap[id]
|
||||
if !ok {
|
||||
return nil, NotFoundError(id)
|
||||
@@ -37,10 +42,11 @@ func (e OptionNotFoundError) Error() string {
|
||||
func FindOption(k string) (*options.Option, error) {
|
||||
// Interested only in <xlator>.<name> part of the key as optMap is indexed
|
||||
// using them.
|
||||
_, xl, name, err := options.SplitKey(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, xl, name := options.SplitKey(k)
|
||||
|
||||
// Remove category prefix for example "cluster/replicate"
|
||||
// will be converted to "replicate"
|
||||
xl = path.Base(xl)
|
||||
|
||||
opt, ok := optMap[xl+"."+name]
|
||||
if !ok {
|
||||
|
||||
32
pkg/utils/volfiletypes.go
Normal file
32
pkg/utils/volfiletypes.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package utils
|
||||
|
||||
const (
|
||||
// BrickVolfile is name of brick volfile template
|
||||
BrickVolfile = "brick"
|
||||
// ClientVolfile is a name of client volfile template
|
||||
ClientVolfile = "client"
|
||||
// RebalanceVolfile is a name of rebalance volfile template
|
||||
RebalanceVolfile = "rebalance"
|
||||
// SelfHealVolfile is a name of selfheal volfile template
|
||||
SelfHealVolfile = "glustershd"
|
||||
// BitdVolfile is a name of bitd volfile template
|
||||
BitdVolfile = "bitd"
|
||||
// ScrubdVolfile is a name of scrubd volfile template
|
||||
ScrubdVolfile = "scrubd"
|
||||
// GfProxyVolfile is a name of gfproxy volfile template
|
||||
GfProxyVolfile = "gfproxy"
|
||||
// NFSVolfile is a name of nfs volfile template
|
||||
NFSVolfile = "nfs"
|
||||
)
|
||||
|
||||
// ValidVolfiles represents list of valid volfile names
|
||||
var ValidVolfiles = [...]string{
|
||||
BrickVolfile,
|
||||
ClientVolfile,
|
||||
RebalanceVolfile,
|
||||
SelfHealVolfile,
|
||||
BitdVolfile,
|
||||
ScrubdVolfile,
|
||||
GfProxyVolfile,
|
||||
NFSVolfile,
|
||||
}
|
||||
@@ -13,10 +13,13 @@ var names = [...]string{"distribute", "dht"}
|
||||
func validateOptions(v *volume.Volinfo, key, value string) error {
|
||||
if strings.Contains(key, "readdirplus-for-dir") {
|
||||
if value == "on" {
|
||||
if v, ok := v.Options["features.cache-invalidation"]; ok && v == "on" {
|
||||
if v, ok := v.Options["features/upcall.cache-invalidation"]; ok && v == "on" {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("enable \"features.cache-invalidation\" before enabling %s", key)
|
||||
if v, ok := v.Options["upcall.cache-invalidation"]; ok && v == "on" {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("enable \"features/upcall.cache-invalidation\" before enabling %s", key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user