| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Minio Cloud Storage, (C) 2016 Minio, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 05:50:50 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-12-09 12:35:07 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2016-08-12 06:55:36 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2016-09-01 17:49:06 +08:00
										 |  |  | 	"net" | 
					
						
							|  |  |  | 	"net/rpc" | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 	"path" | 
					
						
							| 
									
										
										
										
											2017-02-15 19:47:47 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2016-08-26 08:16:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/minio/minio/pkg/disk" | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 03:51:56 +08:00
										 |  |  | type networkStorage struct { | 
					
						
							| 
									
										
										
										
											2017-06-03 05:05:51 +08:00
										 |  |  | 	rpcClient *AuthRPCClient | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2017-02-18 18:52:11 +08:00
										 |  |  | 	storageRPCPath = "/storage" | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | // Converts rpc.ServerError to underlying error. This function is
 | 
					
						
							|  |  |  | // written so that the storageAPI errors are consistent across network
 | 
					
						
							|  |  |  | // disks as well.
 | 
					
						
							|  |  |  | func toStorageErr(err error) error { | 
					
						
							| 
									
										
										
										
											2016-08-12 10:32:04 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-01 17:49:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch err.(type) { | 
					
						
							|  |  |  | 	case *net.OpError: | 
					
						
							| 
									
										
										
										
											2017-08-12 02:38:46 +08:00
										 |  |  | 		return errDiskNotFoundFromNetError | 
					
						
							| 
									
										
										
										
											2016-09-01 17:49:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-29 19:13:51 +08:00
										 |  |  | 	if err == rpc.ErrShutdown { | 
					
						
							| 
									
										
										
										
											2017-08-12 02:38:46 +08:00
										 |  |  | 		return errDiskNotFoundFromRPCShutdown | 
					
						
							| 
									
										
										
										
											2016-12-29 19:13:51 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 	switch err.Error() { | 
					
						
							| 
									
										
										
										
											2016-08-12 06:55:36 +08:00
										 |  |  | 	case io.EOF.Error(): | 
					
						
							|  |  |  | 		return io.EOF | 
					
						
							|  |  |  | 	case io.ErrUnexpectedEOF.Error(): | 
					
						
							|  |  |  | 		return io.ErrUnexpectedEOF | 
					
						
							|  |  |  | 	case errUnexpected.Error(): | 
					
						
							|  |  |  | 		return errUnexpected | 
					
						
							| 
									
										
										
										
											2016-04-19 17:42:10 +08:00
										 |  |  | 	case errDiskFull.Error(): | 
					
						
							|  |  |  | 		return errDiskFull | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 	case errVolumeNotFound.Error(): | 
					
						
							|  |  |  | 		return errVolumeNotFound | 
					
						
							|  |  |  | 	case errVolumeExists.Error(): | 
					
						
							|  |  |  | 		return errVolumeExists | 
					
						
							|  |  |  | 	case errFileNotFound.Error(): | 
					
						
							|  |  |  | 		return errFileNotFound | 
					
						
							| 
									
										
										
										
											2016-08-12 06:55:36 +08:00
										 |  |  | 	case errFileNameTooLong.Error(): | 
					
						
							|  |  |  | 		return errFileNameTooLong | 
					
						
							|  |  |  | 	case errFileAccessDenied.Error(): | 
					
						
							|  |  |  | 		return errFileAccessDenied | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 	case errIsNotRegular.Error(): | 
					
						
							|  |  |  | 		return errIsNotRegular | 
					
						
							|  |  |  | 	case errVolumeNotEmpty.Error(): | 
					
						
							|  |  |  | 		return errVolumeNotEmpty | 
					
						
							|  |  |  | 	case errVolumeAccessDenied.Error(): | 
					
						
							|  |  |  | 		return errVolumeAccessDenied | 
					
						
							| 
									
										
										
										
											2016-08-12 06:55:36 +08:00
										 |  |  | 	case errCorruptedFormat.Error(): | 
					
						
							|  |  |  | 		return errCorruptedFormat | 
					
						
							|  |  |  | 	case errUnformattedDisk.Error(): | 
					
						
							|  |  |  | 		return errUnformattedDisk | 
					
						
							| 
									
										
										
										
											2016-10-08 02:15:55 +08:00
										 |  |  | 	case errInvalidAccessKeyID.Error(): | 
					
						
							|  |  |  | 		return errInvalidAccessKeyID | 
					
						
							|  |  |  | 	case errAuthentication.Error(): | 
					
						
							|  |  |  | 		return errAuthentication | 
					
						
							|  |  |  | 	case errServerVersionMismatch.Error(): | 
					
						
							|  |  |  | 		return errServerVersionMismatch | 
					
						
							|  |  |  | 	case errServerTimeMismatch.Error(): | 
					
						
							|  |  |  | 		return errServerTimeMismatch | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 18:30:52 +08:00
										 |  |  | // Initialize new storage rpc client.
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | func newStorageRPC(endpoint Endpoint) StorageAPI { | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 	// Dial minio rpc storage http path.
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	rpcPath := path.Join(minioReservedBucketPath, storageRPCPath, endpoint.Path) | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	serverCred := serverConfig.GetCredential() | 
					
						
							| 
									
										
										
										
											2016-10-06 17:30:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 	return &networkStorage{ | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 		rpcClient: newAuthRPCClient(authConfig{ | 
					
						
							| 
									
										
										
										
											2017-04-12 06:44:27 +08:00
										 |  |  | 			accessKey:        serverCred.AccessKey, | 
					
						
							|  |  |  | 			secretKey:        serverCred.SecretKey, | 
					
						
							|  |  |  | 			serverAddr:       endpoint.Host, | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 			serviceEndpoint:  rpcPath, | 
					
						
							| 
									
										
										
										
											2017-01-12 05:59:51 +08:00
										 |  |  | 			secureConn:       globalIsSSL, | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 			serviceName:      "Storage", | 
					
						
							|  |  |  | 			disableReconnect: true, | 
					
						
							| 
									
										
										
										
											2016-12-30 11:42:02 +08:00
										 |  |  | 		}), | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-19 01:35:17 +08:00
										 |  |  | // Stringer provides a canonicalized representation of network device.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) String() string { | 
					
						
							| 
									
										
										
										
											2017-02-15 19:47:47 +08:00
										 |  |  | 	// Remove the storage RPC path prefix, internal paths are meaningless.
 | 
					
						
							| 
									
										
										
										
											2017-04-19 01:35:17 +08:00
										 |  |  | 	serviceEndpoint := strings.TrimPrefix(n.rpcClient.ServiceEndpoint(), | 
					
						
							|  |  |  | 		path.Join(minioReservedBucketPath, storageRPCPath)) | 
					
						
							|  |  |  | 	// Check for the transport layer being used.
 | 
					
						
							|  |  |  | 	scheme := "http" | 
					
						
							|  |  |  | 	if n.rpcClient.config.secureConn { | 
					
						
							|  |  |  | 		scheme = "https" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Finally construct the disk endpoint in http://<server>/<path> form.
 | 
					
						
							|  |  |  | 	return scheme + "://" + n.rpcClient.ServerAddr() + path.Join("/", serviceEndpoint) | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | // Init - attempts a login to reconnect.
 | 
					
						
							|  |  |  | func (n *networkStorage) Init() error { | 
					
						
							| 
									
										
										
										
											2017-02-15 19:47:47 +08:00
										 |  |  | 	return toStorageErr(n.rpcClient.Login()) | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Closes the underlying RPC connection.
 | 
					
						
							| 
									
										
										
										
											2017-02-15 19:47:47 +08:00
										 |  |  | func (n *networkStorage) Close() error { | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | 	// Close the underlying connection.
 | 
					
						
							| 
									
										
										
										
											2017-02-15 19:47:47 +08:00
										 |  |  | 	return toStorageErr(n.rpcClient.Close()) | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-26 08:16:34 +08:00
										 |  |  | // DiskInfo - fetch disk information for a remote disk.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) DiskInfo() (info disk.Info, err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	args := AuthRPCArgs{} | 
					
						
							| 
									
										
										
										
											2016-08-26 08:16:34 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.DiskInfoHandler", &args, &info); err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-20 09:37:57 +08:00
										 |  |  | 		return disk.Info{}, toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-08-26 08:16:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return info, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MakeVol - create a volume on a remote disk.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) MakeVol(volume string) (err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	reply := AuthRPCReply{} | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 	args := GenericVolArgs{Vol: volume} | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err := n.rpcClient.Call("Storage.MakeVolHandler", &args, &reply); err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 		return toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-26 08:16:34 +08:00
										 |  |  | // ListVols - List all volumes on a remote disk.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) ListVols() (vols []VolInfo, err error) { | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	ListVols := ListVolsReply{} | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	err = n.rpcClient.Call("Storage.ListVolsHandler", &AuthRPCArgs{}, &ListVols) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-20 09:37:57 +08:00
										 |  |  | 		return nil, toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return ListVols.Vols, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | // StatVol - get volume info over the network.
 | 
					
						
							|  |  |  | func (n *networkStorage) StatVol(volume string) (volInfo VolInfo, err error) { | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 	args := GenericVolArgs{Vol: volume} | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.StatVolHandler", &args, &volInfo); err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 		return VolInfo{}, toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return volInfo, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | // DeleteVol - Deletes a volume over the network.
 | 
					
						
							|  |  |  | func (n *networkStorage) DeleteVol(volume string) (err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	reply := AuthRPCReply{} | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 	args := GenericVolArgs{Vol: volume} | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err := n.rpcClient.Call("Storage.DeleteVolHandler", &args, &reply); err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 		return toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // File operations.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) PrepareFile(volume, path string, length int64) (err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	reply := AuthRPCReply{} | 
					
						
							| 
									
										
										
										
											2016-10-30 03:44:44 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.PrepareFileHandler", &PrepareFileArgs{ | 
					
						
							|  |  |  | 		Vol:  volume, | 
					
						
							|  |  |  | 		Path: path, | 
					
						
							|  |  |  | 		Size: length, | 
					
						
							|  |  |  | 	}, &reply); err != nil { | 
					
						
							|  |  |  | 		return toStorageErr(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | // AppendFile - append file writes buffer to a remote network path.
 | 
					
						
							|  |  |  | func (n *networkStorage) AppendFile(volume, path string, buffer []byte) (err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	reply := AuthRPCReply{} | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.AppendFileHandler", &AppendFileArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 		Vol:    volume, | 
					
						
							|  |  |  | 		Path:   path, | 
					
						
							|  |  |  | 		Buffer: buffer, | 
					
						
							| 
									
										
										
										
											2016-06-20 06:31:13 +08:00
										 |  |  | 	}, &reply); err != nil { | 
					
						
							|  |  |  | 		return toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-05-29 06:13:15 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-20 06:31:13 +08:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // StatFile - get latest Stat information for a file at path.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) StatFile(volume, path string) (fileInfo FileInfo, err error) { | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.StatFileHandler", &StatFileArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 		Vol:  volume, | 
					
						
							|  |  |  | 		Path: path, | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	}, &fileInfo); err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 		return FileInfo{}, toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return fileInfo, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 13:05:48 +08:00
										 |  |  | // ReadAll - reads entire contents of the file at path until EOF, returns the
 | 
					
						
							| 
									
										
										
										
											2016-06-26 05:51:06 +08:00
										 |  |  | // contents in a byte slice. Returns buf == nil if err != nil.
 | 
					
						
							|  |  |  | // This API is meant to be used on files which have small memory footprint, do
 | 
					
						
							|  |  |  | // not use this on large files as it would cause server to crash.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) ReadAll(volume, path string) (buf []byte, err error) { | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.ReadAllHandler", &ReadAllArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 		Vol:  volume, | 
					
						
							|  |  |  | 		Path: path, | 
					
						
							| 
									
										
										
										
											2016-06-26 05:51:06 +08:00
										 |  |  | 	}, &buf); err != nil { | 
					
						
							|  |  |  | 		return nil, toStorageErr(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return buf, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | // ReadFile - reads a file at remote path and fills the buffer.
 | 
					
						
							| 
									
										
										
										
											2017-09-26 02:32:56 +08:00
										 |  |  | func (n *networkStorage) ReadFile(volume string, path string, offset int64, buffer []byte, verifier *BitrotVerifier) (m int64, err error) { | 
					
						
							| 
									
										
										
										
											2016-12-09 12:35:07 +08:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if r := recover(); r != nil { | 
					
						
							|  |  |  | 			// Recover any panic from allocation, and return error.
 | 
					
						
							|  |  |  | 			err = bytes.ErrTooLarge | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() // Do not crash the server.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-26 02:32:56 +08:00
										 |  |  | 	args := ReadFileArgs{ | 
					
						
							|  |  |  | 		Vol:      volume, | 
					
						
							|  |  |  | 		Path:     path, | 
					
						
							|  |  |  | 		Offset:   offset, | 
					
						
							|  |  |  | 		Buffer:   buffer, | 
					
						
							|  |  |  | 		Verified: true, // mark read as verified by default
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if verifier != nil { | 
					
						
							|  |  |  | 		args.Algo = verifier.algorithm | 
					
						
							|  |  |  | 		args.ExpectedHash = verifier.sum | 
					
						
							|  |  |  | 		args.Verified = verifier.IsVerified() | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-17 05:21:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var result []byte | 
					
						
							| 
									
										
										
										
											2017-09-26 02:32:56 +08:00
										 |  |  | 	err = n.rpcClient.Call("Storage.ReadFileHandler", &args, &result) | 
					
						
							| 
									
										
										
										
											2017-05-17 05:21:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Copy results to buffer.
 | 
					
						
							|  |  |  | 	copy(buffer, result) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Return length of result, err if any.
 | 
					
						
							|  |  |  | 	return int64(len(result)), toStorageErr(err) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 03:51:56 +08:00
										 |  |  | // ListDir - list all entries at prefix.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) ListDir(volume, path string) (entries []string, err error) { | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.ListDirHandler", &ListDirArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 		Vol:  volume, | 
					
						
							|  |  |  | 		Path: path, | 
					
						
							| 
									
										
										
										
											2016-05-06 03:51:56 +08:00
										 |  |  | 	}, &entries); err != nil { | 
					
						
							|  |  |  | 		return nil, toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 	// Return successfully unmarshalled results.
 | 
					
						
							| 
									
										
										
										
											2016-05-06 03:51:56 +08:00
										 |  |  | 	return entries, nil | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // DeleteFile - Delete a file at path.
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | func (n *networkStorage) DeleteFile(volume, path string) (err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	reply := AuthRPCReply{} | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.DeleteFileHandler", &DeleteFileArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 		Vol:  volume, | 
					
						
							|  |  |  | 		Path: path, | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	}, &reply); err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 03:48:41 +08:00
										 |  |  | 		return toStorageErr(err) | 
					
						
							| 
									
										
										
										
											2016-04-13 03:45:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-30 03:17:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-24 07:48:10 +08:00
										 |  |  | // RenameFile - rename a remote file from source to destination.
 | 
					
						
							|  |  |  | func (n *networkStorage) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err error) { | 
					
						
							| 
									
										
										
										
											2016-12-23 23:12:19 +08:00
										 |  |  | 	reply := AuthRPCReply{} | 
					
						
							| 
									
										
										
										
											2016-08-23 02:01:21 +08:00
										 |  |  | 	if err = n.rpcClient.Call("Storage.RenameFileHandler", &RenameFileArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-24 10:19:24 +08:00
										 |  |  | 		SrcVol:  srcVolume, | 
					
						
							|  |  |  | 		SrcPath: srcPath, | 
					
						
							|  |  |  | 		DstVol:  dstVolume, | 
					
						
							|  |  |  | 		DstPath: dstPath, | 
					
						
							| 
									
										
										
										
											2016-05-02 18:12:18 +08:00
										 |  |  | 	}, &reply); err != nil { | 
					
						
							|  |  |  | 		return toStorageErr(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-04-30 03:17:48 +08:00
										 |  |  | } |