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.

120 lines
3.6 KiB

9 years ago
9 years ago
9 years ago
9 years ago
  1. package storage
  2. import (
  3. "fmt"
  4. "os"
  5. "time"
  6. "github.com/chrislusf/seaweedfs/weed/glog"
  7. )
  8. func loadVolumeWithoutIndex(dirname string, collection string, id VolumeId, needleMapKind NeedleMapType) (v *Volume, e error) {
  9. v = &Volume{dir: dirname, Collection: collection, Id: id}
  10. v.SuperBlock = SuperBlock{}
  11. v.needleMapKind = needleMapKind
  12. e = v.load(false, false, needleMapKind, 0)
  13. return
  14. }
  15. func (v *Volume) load(alsoLoadIndex bool, createDatIfMissing bool, needleMapKind NeedleMapType, preallocate int64) error {
  16. var e error
  17. fileName := v.FileName()
  18. alreadyHasSuperBlock := false
  19. if exists, canRead, canWrite, modifiedTime, fileSize := checkFile(fileName + ".dat"); exists {
  20. if !canRead {
  21. return fmt.Errorf("cannot read Volume Data file %s.dat", fileName)
  22. }
  23. if canWrite {
  24. v.dataFile, e = os.OpenFile(fileName+".dat", os.O_RDWR|os.O_CREATE, 0644)
  25. v.lastModifiedTime = uint64(modifiedTime.Unix())
  26. } else {
  27. glog.V(0).Infoln("opening " + fileName + ".dat in READONLY mode")
  28. v.dataFile, e = os.Open(fileName + ".dat")
  29. v.readOnly = true
  30. }
  31. if fileSize >= _SuperBlockSize {
  32. alreadyHasSuperBlock = true
  33. }
  34. } else {
  35. if createDatIfMissing {
  36. v.dataFile, e = createVolumeFile(fileName+".dat", preallocate)
  37. } else {
  38. return fmt.Errorf("Volume Data file %s.dat does not exist.", fileName)
  39. }
  40. }
  41. if e != nil {
  42. if !os.IsPermission(e) {
  43. return fmt.Errorf("cannot load Volume Data %s.dat: %v", fileName, e)
  44. } else {
  45. return fmt.Errorf("load data file %s.dat: %v", fileName, e)
  46. }
  47. }
  48. if alreadyHasSuperBlock {
  49. e = v.readSuperBlock()
  50. } else {
  51. e = v.maybeWriteSuperBlock()
  52. }
  53. if e == nil && alsoLoadIndex {
  54. var indexFile *os.File
  55. if v.readOnly {
  56. glog.V(1).Infoln("open to read file", fileName+".idx")
  57. if indexFile, e = os.OpenFile(fileName+".idx", os.O_RDONLY, 0644); e != nil {
  58. return fmt.Errorf("cannot read Volume Index %s.idx: %v", fileName, e)
  59. }
  60. } else {
  61. glog.V(1).Infoln("open to write file", fileName+".idx")
  62. if indexFile, e = os.OpenFile(fileName+".idx", os.O_RDWR|os.O_CREATE, 0644); e != nil {
  63. return fmt.Errorf("cannot write Volume Index %s.idx: %v", fileName, e)
  64. }
  65. }
  66. if e = CheckVolumeDataIntegrity(v, indexFile); e != nil {
  67. v.readOnly = true
  68. glog.V(0).Infof("volumeDataIntegrityChecking failed %v", e)
  69. }
  70. switch needleMapKind {
  71. case NeedleMapInMemory:
  72. glog.V(0).Infoln("loading index", fileName+".idx", "to memory readonly", v.readOnly)
  73. if v.nm, e = LoadCompactNeedleMap(indexFile); e != nil {
  74. glog.V(0).Infof("loading index %s to memory error: %v", fileName+".idx", e)
  75. }
  76. case NeedleMapLevelDb:
  77. glog.V(0).Infoln("loading leveldb", fileName+".ldb")
  78. if v.nm, e = NewLevelDbNeedleMap(fileName+".ldb", indexFile); e != nil {
  79. glog.V(0).Infof("loading leveldb %s error: %v", fileName+".ldb", e)
  80. }
  81. case NeedleMapBoltDb:
  82. glog.V(0).Infoln("loading boltdb", fileName+".bdb")
  83. if v.nm, e = NewBoltDbNeedleMap(fileName+".bdb", indexFile); e != nil {
  84. glog.V(0).Infof("loading boltdb %s error: %v", fileName+".bdb", e)
  85. }
  86. case NeedleMapBtree:
  87. glog.V(0).Infoln("loading index", fileName+".idx", "to btree readonly", v.readOnly)
  88. if v.nm, e = LoadBtreeNeedleMap(indexFile); e != nil {
  89. glog.V(0).Infof("loading index %s to btree error: %v", fileName+".idx", e)
  90. }
  91. }
  92. }
  93. return e
  94. }
  95. func checkFile(filename string) (exists, canRead, canWrite bool, modTime time.Time, fileSize int64) {
  96. exists = true
  97. fi, err := os.Stat(filename)
  98. if os.IsNotExist(err) {
  99. exists = false
  100. return
  101. }
  102. if fi.Mode()&0400 != 0 {
  103. canRead = true
  104. }
  105. if fi.Mode()&0200 != 0 {
  106. canWrite = true
  107. }
  108. modTime = fi.ModTime()
  109. fileSize = fi.Size()
  110. return
  111. }