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.

292 lines
8.3 KiB

3 years ago
6 years ago
6 years ago
6 years ago
6 years ago
3 years ago
3 years ago
3 years ago
  1. package weed_server
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/chrislusf/seaweedfs/weed/cluster"
  6. "github.com/chrislusf/seaweedfs/weed/pb"
  7. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  8. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  9. "path/filepath"
  10. "time"
  11. "github.com/chrislusf/seaweedfs/weed/glog"
  12. "github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
  13. "github.com/chrislusf/seaweedfs/weed/stats"
  14. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  15. "github.com/chrislusf/seaweedfs/weed/storage/super_block"
  16. "github.com/chrislusf/seaweedfs/weed/storage/types"
  17. )
  18. func (vs *VolumeServer) DeleteCollection(ctx context.Context, req *volume_server_pb.DeleteCollectionRequest) (*volume_server_pb.DeleteCollectionResponse, error) {
  19. resp := &volume_server_pb.DeleteCollectionResponse{}
  20. err := vs.store.DeleteCollection(req.Collection)
  21. if err != nil {
  22. glog.Errorf("delete collection %s: %v", req.Collection, err)
  23. } else {
  24. glog.V(2).Infof("delete collection %v", req)
  25. }
  26. return resp, err
  27. }
  28. func (vs *VolumeServer) AllocateVolume(ctx context.Context, req *volume_server_pb.AllocateVolumeRequest) (*volume_server_pb.AllocateVolumeResponse, error) {
  29. resp := &volume_server_pb.AllocateVolumeResponse{}
  30. err := vs.store.AddVolume(
  31. needle.VolumeId(req.VolumeId),
  32. req.Collection,
  33. vs.needleMapKind,
  34. req.Replication,
  35. req.Ttl,
  36. req.Preallocate,
  37. req.MemoryMapMaxSizeMb,
  38. types.ToDiskType(req.DiskType),
  39. )
  40. if err != nil {
  41. glog.Errorf("assign volume %v: %v", req, err)
  42. } else {
  43. glog.V(2).Infof("assign volume %v", req)
  44. }
  45. return resp, err
  46. }
  47. func (vs *VolumeServer) VolumeMount(ctx context.Context, req *volume_server_pb.VolumeMountRequest) (*volume_server_pb.VolumeMountResponse, error) {
  48. resp := &volume_server_pb.VolumeMountResponse{}
  49. err := vs.store.MountVolume(needle.VolumeId(req.VolumeId))
  50. if err != nil {
  51. glog.Errorf("volume mount %v: %v", req, err)
  52. } else {
  53. glog.V(2).Infof("volume mount %v", req)
  54. }
  55. return resp, err
  56. }
  57. func (vs *VolumeServer) VolumeUnmount(ctx context.Context, req *volume_server_pb.VolumeUnmountRequest) (*volume_server_pb.VolumeUnmountResponse, error) {
  58. resp := &volume_server_pb.VolumeUnmountResponse{}
  59. err := vs.store.UnmountVolume(needle.VolumeId(req.VolumeId))
  60. if err != nil {
  61. glog.Errorf("volume unmount %v: %v", req, err)
  62. } else {
  63. glog.V(2).Infof("volume unmount %v", req)
  64. }
  65. return resp, err
  66. }
  67. func (vs *VolumeServer) VolumeDelete(ctx context.Context, req *volume_server_pb.VolumeDeleteRequest) (*volume_server_pb.VolumeDeleteResponse, error) {
  68. resp := &volume_server_pb.VolumeDeleteResponse{}
  69. err := vs.store.DeleteVolume(needle.VolumeId(req.VolumeId))
  70. if err != nil {
  71. glog.Errorf("volume delete %v: %v", req, err)
  72. } else {
  73. glog.V(2).Infof("volume delete %v", req)
  74. }
  75. return resp, err
  76. }
  77. func (vs *VolumeServer) VolumeConfigure(ctx context.Context, req *volume_server_pb.VolumeConfigureRequest) (*volume_server_pb.VolumeConfigureResponse, error) {
  78. resp := &volume_server_pb.VolumeConfigureResponse{}
  79. // check replication format
  80. if _, err := super_block.NewReplicaPlacementFromString(req.Replication); err != nil {
  81. resp.Error = fmt.Sprintf("volume configure replication %v: %v", req, err)
  82. return resp, nil
  83. }
  84. // unmount
  85. if err := vs.store.UnmountVolume(needle.VolumeId(req.VolumeId)); err != nil {
  86. glog.Errorf("volume configure unmount %v: %v", req, err)
  87. resp.Error = fmt.Sprintf("volume configure unmount %v: %v", req, err)
  88. return resp, nil
  89. }
  90. // modify the volume info file
  91. if err := vs.store.ConfigureVolume(needle.VolumeId(req.VolumeId), req.Replication); err != nil {
  92. glog.Errorf("volume configure %v: %v", req, err)
  93. resp.Error = fmt.Sprintf("volume configure %v: %v", req, err)
  94. return resp, nil
  95. }
  96. // mount
  97. if err := vs.store.MountVolume(needle.VolumeId(req.VolumeId)); err != nil {
  98. glog.Errorf("volume configure mount %v: %v", req, err)
  99. resp.Error = fmt.Sprintf("volume configure mount %v: %v", req, err)
  100. return resp, nil
  101. }
  102. return resp, nil
  103. }
  104. func (vs *VolumeServer) VolumeMarkReadonly(ctx context.Context, req *volume_server_pb.VolumeMarkReadonlyRequest) (*volume_server_pb.VolumeMarkReadonlyResponse, error) {
  105. resp := &volume_server_pb.VolumeMarkReadonlyResponse{}
  106. err := vs.store.MarkVolumeReadonly(needle.VolumeId(req.VolumeId))
  107. if err != nil {
  108. glog.Errorf("volume mark readonly %v: %v", req, err)
  109. } else {
  110. glog.V(2).Infof("volume mark readonly %v", req)
  111. }
  112. return resp, err
  113. }
  114. func (vs *VolumeServer) VolumeMarkWritable(ctx context.Context, req *volume_server_pb.VolumeMarkWritableRequest) (*volume_server_pb.VolumeMarkWritableResponse, error) {
  115. resp := &volume_server_pb.VolumeMarkWritableResponse{}
  116. err := vs.store.MarkVolumeWritable(needle.VolumeId(req.VolumeId))
  117. if err != nil {
  118. glog.Errorf("volume mark writable %v: %v", req, err)
  119. } else {
  120. glog.V(2).Infof("volume mark writable %v", req)
  121. }
  122. return resp, err
  123. }
  124. func (vs *VolumeServer) VolumeStatus(ctx context.Context, req *volume_server_pb.VolumeStatusRequest) (*volume_server_pb.VolumeStatusResponse, error) {
  125. resp := &volume_server_pb.VolumeStatusResponse{}
  126. v := vs.store.GetVolume(needle.VolumeId(req.VolumeId))
  127. if v == nil {
  128. return nil, fmt.Errorf("not found volume id %d", req.VolumeId)
  129. }
  130. resp.IsReadOnly = v.IsReadOnly()
  131. return resp, nil
  132. }
  133. func (vs *VolumeServer) VolumeServerStatus(ctx context.Context, req *volume_server_pb.VolumeServerStatusRequest) (*volume_server_pb.VolumeServerStatusResponse, error) {
  134. resp := &volume_server_pb.VolumeServerStatusResponse{}
  135. for _, loc := range vs.store.Locations {
  136. if dir, e := filepath.Abs(loc.Directory); e == nil {
  137. resp.DiskStatuses = append(resp.DiskStatuses, stats.NewDiskStatus(dir))
  138. }
  139. }
  140. resp.MemoryStatus = stats.MemStat()
  141. return resp, nil
  142. }
  143. func (vs *VolumeServer) VolumeServerLeave(ctx context.Context, req *volume_server_pb.VolumeServerLeaveRequest) (*volume_server_pb.VolumeServerLeaveResponse, error) {
  144. resp := &volume_server_pb.VolumeServerLeaveResponse{}
  145. vs.StopHeartbeat()
  146. return resp, nil
  147. }
  148. func (vs *VolumeServer) VolumeNeedleStatus(ctx context.Context, req *volume_server_pb.VolumeNeedleStatusRequest) (*volume_server_pb.VolumeNeedleStatusResponse, error) {
  149. resp := &volume_server_pb.VolumeNeedleStatusResponse{}
  150. volumeId := needle.VolumeId(req.VolumeId)
  151. n := &needle.Needle{
  152. Id: types.NeedleId(req.NeedleId),
  153. }
  154. var count int
  155. var err error
  156. hasVolume := vs.store.HasVolume(volumeId)
  157. if !hasVolume {
  158. _, hasEcVolume := vs.store.FindEcVolume(volumeId)
  159. if !hasEcVolume {
  160. return nil, fmt.Errorf("volume not found %d", req.VolumeId)
  161. }
  162. count, err = vs.store.ReadEcShardNeedle(volumeId, n, nil)
  163. } else {
  164. count, err = vs.store.ReadVolumeNeedle(volumeId, n, nil, nil)
  165. }
  166. if err != nil {
  167. return nil, err
  168. }
  169. if count < 0 {
  170. return nil, fmt.Errorf("needle not found %d", n.Id)
  171. }
  172. resp.NeedleId = uint64(n.Id)
  173. resp.Cookie = uint32(n.Cookie)
  174. resp.Size = uint32(n.Size)
  175. resp.LastModified = n.LastModified
  176. resp.Crc = n.Checksum.Value()
  177. if n.HasTtl() {
  178. resp.Ttl = n.Ttl.String()
  179. }
  180. return resp, nil
  181. }
  182. func (vs *VolumeServer) Ping(ctx context.Context, req *volume_server_pb.PingRequest) (resp *volume_server_pb.PingResponse, pingErr error) {
  183. resp = &volume_server_pb.PingResponse{
  184. StartTimeNs: time.Now().UnixNano(),
  185. }
  186. if req.TargetType == cluster.FilerType {
  187. pingErr = pb.WithFilerClient(false, pb.ServerAddress(req.Target), vs.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
  188. pingResp, err := client.Ping(ctx, &filer_pb.PingRequest{})
  189. if pingResp != nil {
  190. resp.RemoteTimeNs = pingResp.StartTimeNs
  191. }
  192. return err
  193. })
  194. }
  195. if req.TargetType == cluster.VolumeServerType {
  196. pingErr = pb.WithVolumeServerClient(false, pb.ServerAddress(req.Target), vs.grpcDialOption, func(client volume_server_pb.VolumeServerClient) error {
  197. pingResp, err := client.Ping(ctx, &volume_server_pb.PingRequest{})
  198. if pingResp != nil {
  199. resp.RemoteTimeNs = pingResp.StartTimeNs
  200. }
  201. return err
  202. })
  203. }
  204. if req.TargetType == cluster.MasterType {
  205. pingErr = pb.WithMasterClient(false, pb.ServerAddress(req.Target), vs.grpcDialOption, func(client master_pb.SeaweedClient) error {
  206. pingResp, err := client.Ping(ctx, &master_pb.PingRequest{})
  207. if pingResp != nil {
  208. resp.RemoteTimeNs = pingResp.StartTimeNs
  209. }
  210. return err
  211. })
  212. }
  213. if pingErr != nil {
  214. pingErr = fmt.Errorf("ping %s %s: %v", req.TargetType, req.Target, pingErr)
  215. }
  216. resp.StopTimeNs = time.Now().UnixNano()
  217. return
  218. }