You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.1 KiB

  1. package volume_info
  2. import (
  3. "fmt"
  4. jsonpb "google.golang.org/protobuf/encoding/protojson"
  5. "os"
  6. "github.com/seaweedfs/seaweedfs/weed/glog"
  7. "github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
  8. _ "github.com/seaweedfs/seaweedfs/weed/storage/backend/rclone_backend"
  9. _ "github.com/seaweedfs/seaweedfs/weed/storage/backend/s3_backend"
  10. "github.com/seaweedfs/seaweedfs/weed/util"
  11. )
  12. // MaybeLoadVolumeInfo load the file data as *volume_server_pb.VolumeInfo, the returned volumeInfo will not be nil
  13. func MaybeLoadVolumeInfo(fileName string) (volumeInfo *volume_server_pb.VolumeInfo, hasRemoteFile bool, hasVolumeInfoFile bool, err error) {
  14. volumeInfo = &volume_server_pb.VolumeInfo{}
  15. glog.V(1).Infof("maybeLoadVolumeInfo checks %s", fileName)
  16. if exists, canRead, _, _, _ := util.CheckFile(fileName); !exists || !canRead {
  17. if !exists {
  18. return
  19. }
  20. hasVolumeInfoFile = true
  21. if !canRead {
  22. glog.Warningf("can not read %s", fileName)
  23. err = fmt.Errorf("can not read %s", fileName)
  24. return
  25. }
  26. return
  27. }
  28. hasVolumeInfoFile = true
  29. glog.V(1).Infof("maybeLoadVolumeInfo reads %s", fileName)
  30. fileData, readErr := os.ReadFile(fileName)
  31. if readErr != nil {
  32. glog.Warningf("fail to read %s : %v", fileName, readErr)
  33. err = fmt.Errorf("fail to read %s : %v", fileName, readErr)
  34. return
  35. }
  36. glog.V(1).Infof("maybeLoadVolumeInfo Unmarshal volume info %v", fileName)
  37. if err = jsonpb.Unmarshal(fileData, volumeInfo); err != nil {
  38. if oldVersionErr := tryOldVersionVolumeInfo(fileData, volumeInfo); oldVersionErr != nil {
  39. glog.Warningf("unmarshal error: %v oldFormat: %v", err, oldVersionErr)
  40. err = fmt.Errorf("unmarshal error: %v oldFormat: %v", err, oldVersionErr)
  41. return
  42. } else {
  43. err = nil
  44. }
  45. }
  46. if len(volumeInfo.GetFiles()) == 0 {
  47. return
  48. }
  49. hasRemoteFile = true
  50. return
  51. }
  52. func SaveVolumeInfo(fileName string, volumeInfo *volume_server_pb.VolumeInfo) error {
  53. if exists, _, canWrite, _, _ := util.CheckFile(fileName); exists && !canWrite {
  54. return fmt.Errorf("failed to check %s not writable", fileName)
  55. }
  56. m := jsonpb.MarshalOptions{
  57. AllowPartial: true,
  58. EmitUnpopulated: true,
  59. Indent: " ",
  60. }
  61. text, marshalErr := m.Marshal(volumeInfo)
  62. if marshalErr != nil {
  63. return fmt.Errorf("failed to marshal %s: %v", fileName, marshalErr)
  64. }
  65. if err := util.WriteFile(fileName, text, 0644); err != nil {
  66. return fmt.Errorf("failed to write %s: %v", fileName, err)
  67. }
  68. return nil
  69. }
  70. func tryOldVersionVolumeInfo(data []byte, volumeInfo *volume_server_pb.VolumeInfo) error {
  71. oldVersionVolumeInfo := &volume_server_pb.OldVersionVolumeInfo{}
  72. if err := jsonpb.Unmarshal(data, oldVersionVolumeInfo); err != nil {
  73. return fmt.Errorf("failed to unmarshal old version volume info: %v", err)
  74. }
  75. volumeInfo.Files = oldVersionVolumeInfo.Files
  76. volumeInfo.Version = oldVersionVolumeInfo.Version
  77. volumeInfo.Replication = oldVersionVolumeInfo.Replication
  78. volumeInfo.BytesOffset = oldVersionVolumeInfo.BytesOffset
  79. volumeInfo.DatFileSize = oldVersionVolumeInfo.DatFileSize
  80. volumeInfo.ExpireAtSec = oldVersionVolumeInfo.DestroyTime
  81. volumeInfo.ReadOnly = oldVersionVolumeInfo.ReadOnly
  82. return nil
  83. }