backend.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package backend
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/util"
  4. "io"
  5. "os"
  6. "strings"
  7. "time"
  8. "github.com/chrislusf/seaweedfs/weed/glog"
  9. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  10. "github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
  11. )
  12. type BackendStorageFile interface {
  13. io.ReaderAt
  14. io.WriterAt
  15. Truncate(off int64) error
  16. io.Closer
  17. GetStat() (datSize int64, modTime time.Time, err error)
  18. Name() string
  19. Sync() error
  20. }
  21. type BackendStorage interface {
  22. ToProperties() map[string]string
  23. NewStorageFile(key string, tierInfo *volume_server_pb.VolumeInfo) BackendStorageFile
  24. CopyFile(f *os.File, attributes map[string]string, fn func(progressed int64, percentage float32) error) (key string, size int64, err error)
  25. DownloadFile(fileName string, key string, fn func(progressed int64, percentage float32) error) (size int64, err error)
  26. DeleteFile(key string) (err error)
  27. }
  28. type StringProperties interface {
  29. GetString(key string) string
  30. }
  31. type StorageType string
  32. type BackendStorageFactory interface {
  33. StorageType() StorageType
  34. BuildStorage(configuration StringProperties, configPrefix string, id string) (BackendStorage, error)
  35. }
  36. var (
  37. BackendStorageFactories = make(map[StorageType]BackendStorageFactory)
  38. BackendStorages = make(map[string]BackendStorage)
  39. )
  40. // used by master to load remote storage configurations
  41. func LoadConfiguration(config *util.ViperProxy) {
  42. StorageBackendPrefix := "storage.backend"
  43. for backendTypeName := range config.GetStringMap(StorageBackendPrefix) {
  44. backendStorageFactory, found := BackendStorageFactories[StorageType(backendTypeName)]
  45. if !found {
  46. glog.Fatalf("backend storage type %s not found", backendTypeName)
  47. }
  48. for backendStorageId := range config.GetStringMap(StorageBackendPrefix + "." + backendTypeName) {
  49. if !config.GetBool(StorageBackendPrefix + "." + backendTypeName + "." + backendStorageId + ".enabled") {
  50. continue
  51. }
  52. backendStorage, buildErr := backendStorageFactory.BuildStorage(config,
  53. StorageBackendPrefix+"."+backendTypeName+"."+backendStorageId+".", backendStorageId)
  54. if buildErr != nil {
  55. glog.Fatalf("fail to create backend storage %s.%s", backendTypeName, backendStorageId)
  56. }
  57. BackendStorages[backendTypeName+"."+backendStorageId] = backendStorage
  58. if backendStorageId == "default" {
  59. BackendStorages[backendTypeName] = backendStorage
  60. }
  61. }
  62. }
  63. }
  64. // used by volume server to receive remote storage configurations from master
  65. func LoadFromPbStorageBackends(storageBackends []*master_pb.StorageBackend) {
  66. for _, storageBackend := range storageBackends {
  67. backendStorageFactory, found := BackendStorageFactories[StorageType(storageBackend.Type)]
  68. if !found {
  69. glog.Warningf("storage type %s not found", storageBackend.Type)
  70. continue
  71. }
  72. backendStorage, buildErr := backendStorageFactory.BuildStorage(newProperties(storageBackend.Properties), "", storageBackend.Id)
  73. if buildErr != nil {
  74. glog.Fatalf("fail to create backend storage %s.%s", storageBackend.Type, storageBackend.Id)
  75. }
  76. BackendStorages[storageBackend.Type+"."+storageBackend.Id] = backendStorage
  77. if storageBackend.Id == "default" {
  78. BackendStorages[storageBackend.Type] = backendStorage
  79. }
  80. }
  81. }
  82. type Properties struct {
  83. m map[string]string
  84. }
  85. func newProperties(m map[string]string) *Properties {
  86. return &Properties{m: m}
  87. }
  88. func (p *Properties) GetString(key string) string {
  89. if v, found := p.m[key]; found {
  90. return v
  91. }
  92. return ""
  93. }
  94. func ToPbStorageBackends() (backends []*master_pb.StorageBackend) {
  95. for sName, s := range BackendStorages {
  96. sType, sId := BackendNameToTypeId(sName)
  97. if sType == "" {
  98. continue
  99. }
  100. backends = append(backends, &master_pb.StorageBackend{
  101. Type: sType,
  102. Id: sId,
  103. Properties: s.ToProperties(),
  104. })
  105. }
  106. return
  107. }
  108. func BackendNameToTypeId(backendName string) (backendType, backendId string) {
  109. parts := strings.Split(backendName, ".")
  110. if len(parts) == 1 {
  111. return backendName, "default"
  112. }
  113. if len(parts) != 2 {
  114. return
  115. }
  116. backendType, backendId = parts[0], parts[1]
  117. return
  118. }