routers: Fix a crash while initializing network fs. (#1382)

Crash happens when 'minio server filename' a file name is
provided instead of a directory on command line argument.

```
panic: runtime error: slice bounds out of range

goroutine 1 [running]:
panic(0x5eb460, 0xc82000e0b0)
	/usr/local/opt/go/libexec/src/runtime/panic.go:464 +0x3e6
main.splitNetPath(0x7fff5fbff9bd, 0x7, 0x0, 0x0, 0x0, 0x0)
	/Users/harsha/mygo/src/github.com/minio/minio/network-fs.go:49 +0xb7
main.newNetworkFS(0x7fff5fbff9bd, 0x7, 0x0, 0x0, 0x0, 0x0)
	/Users/harsha/mygo/src/github.com/minio/minio/network-fs.go:90 +0x20a
main.configureServerHandler(0xc82024e1c8, 0x5, 0xc8200640e0, 0x1, 0x1, 0x0, 0x0)
	/Users/harsha/mygo/src/github.com/minio/minio/routers.go:43 +0x6ce
main.configureServer(0xc82024e1c8, 0x5, 0xc8200640e0, 0x1, 0x1, 0x5)
	/Users/harsha/mygo/src/github.com/minio/minio/server-main.go:86 +0x67
```
This commit is contained in:
Harshavardhana 2016-04-25 18:10:40 -07:00 committed by Anand Babu (AB) Periasamy
parent 42254b5c4d
commit 5f80edf232
4 changed files with 24 additions and 30 deletions

View File

@ -79,7 +79,7 @@ func toStorageErr(err error) error {
// Initialize new network file system. // Initialize new network file system.
func newNetworkFS(networkPath string) (StorageAPI, error) { func newNetworkFS(networkPath string) (StorageAPI, error) {
// Input validation. // Input validation.
if networkPath == "" && strings.LastIndex(networkPath, ":") != -1 { if networkPath == "" || strings.LastIndex(networkPath, ":") == -1 {
log.WithFields(logrus.Fields{ log.WithFields(logrus.Fields{
"networkPath": networkPath, "networkPath": networkPath,
}).Debugf("Network path is malformed, should be of form <ip>:<port>:<export_dir>") }).Debugf("Network path is malformed, should be of form <ip>:<port>:<export_dir>")

View File

@ -32,7 +32,8 @@ func (s *MySuite) TestFSAPISuite(c *C) {
create := func() objectAPI { create := func() objectAPI {
path, err := ioutil.TempDir(os.TempDir(), "minio-") path, err := ioutil.TempDir(os.TempDir(), "minio-")
c.Check(err, IsNil) c.Check(err, IsNil)
storageAPI, err := newFS(path) storageAPI, err := newStorageAPI(path)
c.Check(err, IsNil)
objAPI := newObjectLayer(storageAPI) objAPI := newObjectLayer(storageAPI)
storageList = append(storageList, path) storageList = append(storageList, path)
return objAPI return objAPI
@ -52,7 +53,7 @@ func (s *MySuite) TestXLAPISuite(c *C) {
erasureDisks = append(erasureDisks, path) erasureDisks = append(erasureDisks, path)
} }
storageList = append(storageList, erasureDisks...) storageList = append(storageList, erasureDisks...)
storageAPI, err := newXL(erasureDisks...) storageAPI, err := newStorageAPI(erasureDisks...)
c.Check(err, IsNil) c.Check(err, IsNil)
objAPI := newObjectLayer(storageAPI) objAPI := newObjectLayer(storageAPI)
return objAPI return objAPI

View File

@ -17,40 +17,33 @@
package main package main
import ( import (
"errors"
"net/http" "net/http"
"os" "path/filepath"
"runtime" "strings"
router "github.com/gorilla/mux" router "github.com/gorilla/mux"
"github.com/minio/minio/pkg/probe" "github.com/minio/minio/pkg/probe"
) )
// newStorageAPI - initialize any storage API depending on the export path style.
func newStorageAPI(exportPaths ...string) (StorageAPI, error) {
if len(exportPaths) == 1 {
exportPath := exportPaths[0]
if !strings.ContainsRune(exportPath, ':') || filepath.VolumeName(exportPath) != "" {
// Initialize filesystem storage API.
return newFS(exportPath)
}
// Initialize network storage API.
return newNetworkFS(exportPath)
}
// Initialize XL storage API.
return newXL(exportPaths...)
}
// configureServer handler returns final handler for the http server. // configureServer handler returns final handler for the http server.
func configureServerHandler(srvCmdConfig serverCmdConfig) http.Handler { func configureServerHandler(srvCmdConfig serverCmdConfig) http.Handler {
var storageAPI StorageAPI storageAPI, e := newStorageAPI(srvCmdConfig.exportPaths...)
var e error fatalIf(probe.NewError(e), "Initializing storage API failed.", nil)
if len(srvCmdConfig.exportPaths) == 1 {
// Verify if export path is a local file system path.
var st os.FileInfo
st, e = os.Stat(srvCmdConfig.exportPaths[0])
if e == nil && st.Mode().IsDir() {
// Initialize storage API.
storageAPI, e = newFS(srvCmdConfig.exportPaths[0])
fatalIf(probe.NewError(e), "Initializing fs failed.", nil)
} else {
// Initialize network storage API.
storageAPI, e = newNetworkFS(srvCmdConfig.exportPaths[0])
fatalIf(probe.NewError(e), "Initializing network fs failed.", nil)
}
} else {
if runtime.GOOS == "windows" {
fatalIf(probe.NewError(errors.New("")), "Initializing XL failed, not supported on windows yet.", nil)
}
// Initialize XL storage API.
storageAPI, e = newXL(srvCmdConfig.exportPaths...)
fatalIf(probe.NewError(e), "Initializing XL failed.", nil)
}
// Initialize object layer. // Initialize object layer.
objAPI := newObjectLayer(storageAPI) objAPI := newObjectLayer(storageAPI)

View File

@ -162,7 +162,7 @@ func initServerConfig(c *cli.Context) {
// Check server arguments. // Check server arguments.
func checkServerSyntax(c *cli.Context) { func checkServerSyntax(c *cli.Context) {
if !c.Args().Present() && c.Args().First() == "help" { if !c.Args().Present() || c.Args().First() == "help" {
cli.ShowCommandHelpAndExit(c, "server", 1) cli.ShowCommandHelpAndExit(c, "server", 1)
} }
} }