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.

323 lines
9.5 KiB

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