Compare commits
3 Commits
90d0c2dc72
...
9f87624ed1
Author | SHA1 | Date |
---|---|---|
Vitaliy Filippov | 9f87624ed1 | |
Vitaliy Filippov | 3b0ab317cf | |
Vitaliy Filippov | 18eb99c494 |
|
@ -3,10 +3,10 @@ module vitastor.io/csi
|
|||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/container-storage-interface/spec v1.4.0
|
||||
github.com/container-storage-interface/spec v1.8.0
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
github.com/kubernetes-csi/csi-lib-utils v0.9.1
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
||||
golang.org/x/net v0.7.0
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/grpc v1.33.1
|
||||
google.golang.org/protobuf v1.24.0
|
||||
|
|
31
csi/go.sum
31
csi/go.sum
|
@ -41,8 +41,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
|||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
github.com/container-storage-interface/spec v1.4.0 h1:ozAshSKxpJnYUfmkpZCTYyF/4MYeYlhdXbAvPvfGmkg=
|
||||
github.com/container-storage-interface/spec v1.4.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
github.com/container-storage-interface/spec v1.8.0 h1:D0vhF3PLIZwlwZEf2eNbpujGCNwspwTYf2idJRJx4xI=
|
||||
github.com/container-storage-interface/spec v1.8.0/go.mod h1:ROLik+GhPslwwWRNFF1KasPzroNARibH2rfz1rkg4H0=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -182,6 +182,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
|
@ -195,6 +196,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -213,6 +215,7 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
|
|||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -228,8 +231,10 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -240,6 +245,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -259,13 +265,22 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -286,8 +301,10 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
|
@ -158,6 +158,12 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
|
|||
return nil, status.Error(codes.InvalidArgument, "volume capabilities is a required field")
|
||||
}
|
||||
|
||||
err := cs.checkCaps(volumeCapabilities)
|
||||
if (err != nil)
|
||||
{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
etcdVolumePrefix := req.Parameters["etcdVolumePrefix"]
|
||||
poolId, _ := strconv.ParseUint(req.Parameters["poolId"], 10, 64)
|
||||
if (poolId == 0)
|
||||
|
@ -301,13 +307,43 @@ func (cs *ControllerServer) ValidateVolumeCapabilities(ctx context.Context, req
|
|||
return nil, status.Error(codes.InvalidArgument, "volumeCapabilities is nil")
|
||||
}
|
||||
|
||||
err := cs.checkCaps(volumeCapabilities)
|
||||
if (err != nil)
|
||||
{
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &csi.ValidateVolumeCapabilitiesResponse{
|
||||
Confirmed: &csi.ValidateVolumeCapabilitiesResponse_Confirmed{
|
||||
VolumeCapabilities: req.VolumeCapabilities,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cs *ControllerServer) checkCaps(volumeCapabilities []*csi.VolumeCapability) error {
|
||||
var volumeCapabilityAccessModes []*csi.VolumeCapability_AccessMode
|
||||
for _, mode := range []csi.VolumeCapability_AccessMode_Mode{
|
||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
|
||||
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
|
||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_READER_ONLY,
|
||||
csi.VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY,
|
||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER,
|
||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER,
|
||||
} {
|
||||
volumeCapabilityAccessModes = append(volumeCapabilityAccessModes, &csi.VolumeCapability_AccessMode{Mode: mode})
|
||||
}
|
||||
for _, capability := range volumeCapabilities
|
||||
{
|
||||
if (capability.GetBlock() != nil)
|
||||
{
|
||||
for _, mode := range []csi.VolumeCapability_AccessMode_Mode{
|
||||
csi.VolumeCapability_AccessMode_MULTI_NODE_SINGLE_WRITER,
|
||||
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
|
||||
} {
|
||||
volumeCapabilityAccessModes = append(volumeCapabilityAccessModes, &csi.VolumeCapability_AccessMode{Mode: mode})
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
capabilitySupport := false
|
||||
for _, capability := range volumeCapabilities
|
||||
|
@ -323,14 +359,10 @@ func (cs *ControllerServer) ValidateVolumeCapabilities(ctx context.Context, req
|
|||
|
||||
if (!capabilitySupport)
|
||||
{
|
||||
return nil, status.Errorf(codes.NotFound, "%v not supported", req.GetVolumeCapabilities())
|
||||
return status.Errorf(codes.NotFound, "%v not supported", volumeCapabilities)
|
||||
}
|
||||
|
||||
return &csi.ValidateVolumeCapabilitiesResponse{
|
||||
Confirmed: &csi.ValidateVolumeCapabilitiesResponse_Confirmed{
|
||||
VolumeCapabilities: req.VolumeCapabilities,
|
||||
},
|
||||
}, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListVolumes returns a list of volumes
|
||||
|
|
|
@ -228,6 +228,26 @@ func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
|
|||
|
||||
// Check that it's not already mounted
|
||||
_, err = mount.IsNotMountPoint(ns.mounter, targetPath)
|
||||
if (err == nil)
|
||||
{
|
||||
var finfo os.FileInfo
|
||||
finfo, err = os.Stat(targetPath)
|
||||
if (err != nil)
|
||||
{
|
||||
klog.Errorf("failed to stat %s: %v", targetPath, err)
|
||||
return nil, err
|
||||
}
|
||||
if (finfo.IsDir() != (!isBlock))
|
||||
{
|
||||
err = os.Remove(targetPath)
|
||||
if (err != nil)
|
||||
{
|
||||
klog.Errorf("failed to remove %s (to recreate it with correct type): %v", targetPath, err)
|
||||
return nil, err
|
||||
}
|
||||
err = os.ErrNotExist
|
||||
}
|
||||
}
|
||||
if (err != nil)
|
||||
{
|
||||
if (os.IsNotExist(err))
|
||||
|
@ -385,7 +405,7 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
|||
defer ns.unlockVolume(ctxVars["configPath"]+":"+volName)
|
||||
|
||||
targetPath := req.GetStagingTargetPath()
|
||||
devicePath, refCount, err := mount.GetDeviceNameFromMount(ns.mounter, targetPath)
|
||||
devicePath, _, err := mount.GetDeviceNameFromMount(ns.mounter, targetPath)
|
||||
if (err != nil)
|
||||
{
|
||||
if (os.IsNotExist(err))
|
||||
|
@ -402,6 +422,16 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
|||
return &csi.NodeUnstageVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
refList, err := ns.mounter.GetMountRefs(targetPath)
|
||||
if (err != nil)
|
||||
{
|
||||
return nil, err
|
||||
}
|
||||
if (len(refList) > 0)
|
||||
{
|
||||
klog.Warningf("%s is still referenced: %v", targetPath, refList)
|
||||
}
|
||||
|
||||
// unmount
|
||||
err = mount.CleanupMountPoint(targetPath, ns.mounter, false)
|
||||
if (err != nil)
|
||||
|
@ -410,7 +440,7 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
|||
}
|
||||
|
||||
// unmap device
|
||||
if (refCount == 1)
|
||||
if (len(refList) == 0)
|
||||
{
|
||||
if (!ns.useVduse)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,8 @@ project(vitastor)
|
|||
# vitastor-disk
|
||||
add_executable(vitastor-disk
|
||||
disk_tool.cpp disk_simple_offsets.cpp
|
||||
disk_tool_journal.cpp disk_tool_meta.cpp disk_tool_prepare.cpp disk_tool_resize.cpp disk_tool_udev.cpp disk_tool_utils.cpp disk_tool_upgrade.cpp
|
||||
disk_tool_journal.cpp disk_tool_meta.cpp disk_tool_prepare.cpp disk_tool_resize.cpp
|
||||
disk_tool_resize_auto.cpp disk_tool_udev.cpp disk_tool_utils.cpp disk_tool_upgrade.cpp
|
||||
../util/crc32c.c ../util/str_util.cpp ../util/json_util.cpp ../../json11/json11.cpp ../util/rw_blocking.cpp ../util/allocator.cpp ../util/ringloop.cpp ../blockstore/blockstore_disk.cpp
|
||||
)
|
||||
target_link_libraries(vitastor-disk
|
||||
|
|
|
@ -92,8 +92,22 @@ static const char *help_text =
|
|||
" \n"
|
||||
" Requires the `sfdisk` utility.\n"
|
||||
"\n"
|
||||
"vitastor-disk resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]\n"
|
||||
" Resize data area and/or rewrite/move journal and metadata\n"
|
||||
"vitastor-disk resize <osd_num>|<osd_device> [OPTIONS]\n"
|
||||
" Resize data area and/or move journal and metadata:\n"
|
||||
" --move-journal TARGET move journal to TARGET\n"
|
||||
" --move-meta TARGET move metadata to TARGET\n"
|
||||
" --journal-size NEW_SIZE resize journal to NEW_SIZE\n"
|
||||
" --data-size NEW_SIZE resize data device to NEW_SIZE\n"
|
||||
" --dry-run only show new layout, do not apply it\n"
|
||||
" \n"
|
||||
" NEW_SIZE may include k/m/g/t suffixes.\n"
|
||||
" TARGET may be one of:\n"
|
||||
" <partition> move journal/metadata to an existing GPT partition\n"
|
||||
" <raw_device> create a GPT partition on <raw_device> and move journal/metadata to it\n"
|
||||
" \"\" (empty string) move journal/metadata back to the data device\n"
|
||||
"\n"
|
||||
"vitastor-disk raw-resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]\n"
|
||||
" Resize data area and/or rewrite/move journal and metadata (manual format).\n"
|
||||
" ALL_OSD_PARAMETERS must include all (at least all disk-related)\n"
|
||||
" parameters from OSD command line (i.e. from systemd unit or superblock).\n"
|
||||
" NEW_LAYOUT may include new disk layout parameters:\n"
|
||||
|
@ -236,6 +250,10 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
self.options["force"] = "1";
|
||||
}
|
||||
else if (!strcmp(argv[i], "--dry-run") || !strcmp(argv[i], "--dry_run"))
|
||||
{
|
||||
self.options["dry_run"] = "1";
|
||||
}
|
||||
else if (!strcmp(argv[i], "--allow-data-loss"))
|
||||
{
|
||||
self.options["allow_data_loss"] = "1";
|
||||
|
@ -243,7 +261,7 @@ int main(int argc, char *argv[])
|
|||
else if (argv[i][0] == '-' && argv[i][1] == '-' && i < argc-1)
|
||||
{
|
||||
char *key = argv[i]+2;
|
||||
self.options[key] = argv[++i];
|
||||
self.options[str_replace(key, "-", "_")] = argv[++i];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -375,7 +393,16 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
else if (!strcmp(cmd[0], "resize"))
|
||||
{
|
||||
return self.resize_data();
|
||||
if (cmd.size() != 2)
|
||||
{
|
||||
fprintf(stderr, "Exactly 1 OSD number or OSD device path argument is required\n");
|
||||
return 1;
|
||||
}
|
||||
return self.resize_data(cmd[1]);
|
||||
}
|
||||
else if (!strcmp(cmd[0], "raw-resize"))
|
||||
{
|
||||
return self.raw_resize();
|
||||
}
|
||||
else if (!strcmp(cmd[0], "simple-offsets"))
|
||||
{
|
||||
|
|
|
@ -98,7 +98,11 @@ struct disk_tool_t
|
|||
int write_json_journal(json11::Json entries);
|
||||
int write_json_meta(json11::Json meta);
|
||||
|
||||
int resize_data();
|
||||
int resize_data(std::string device);
|
||||
int resize_parse_move_journal(std::map<std::string, std::string> & move_options, bool dry_run);
|
||||
int resize_parse_move_meta(std::map<std::string, std::string> & move_options, bool dry_run);
|
||||
|
||||
int raw_resize();
|
||||
int resize_parse_params();
|
||||
void resize_init(blockstore_meta_header_v2_t *hdr);
|
||||
int resize_remap_blocks();
|
||||
|
|
|
@ -159,7 +159,7 @@ int disk_tool_t::dump_load_check_superblock(const std::string & device)
|
|||
{
|
||||
auto cfg = json_to_string_map(sb["params"].object_items());
|
||||
dsk.parse_config(cfg);
|
||||
dsk.data_io = dsk.meta_io = dsk.journal_io = "cached";
|
||||
dsk.data_io = dsk.meta_io = dsk.journal_io = "direct";
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
|
|
|
@ -18,7 +18,7 @@ struct resizer_data_moving_t
|
|||
uint64_t old_loc, new_loc;
|
||||
};
|
||||
|
||||
int disk_tool_t::resize_data()
|
||||
int disk_tool_t::raw_resize()
|
||||
{
|
||||
int r;
|
||||
// Parse parameters
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
// Copyright (c) Vitaliy Filippov, 2019+
|
||||
// License: VNPL-1.1 (see README.md for details)
|
||||
|
||||
#include "disk_tool.h"
|
||||
#include "rw_blocking.h"
|
||||
#include "str_util.h"
|
||||
#include "json_util.h"
|
||||
|
||||
int disk_tool_t::resize_data(std::string device)
|
||||
{
|
||||
if (options.find("move_journal") == options.end() &&
|
||||
options.find("move_data") == options.end() &&
|
||||
options.find("journal_size") == options.end() &&
|
||||
options.find("data_size") == options.end())
|
||||
{
|
||||
fprintf(stderr, "None of --move-journal, --move-data, --journal-size, --data-size options are specified - nothing to do!\n");
|
||||
return 1;
|
||||
}
|
||||
if (stoull_full(device))
|
||||
device = "/dev/vitastor/osd"+device+"-data";
|
||||
json11::Json sb = read_osd_superblock(device, true, false);
|
||||
if (sb.is_null())
|
||||
return 1;
|
||||
auto sb_params = json_to_string_map(sb["params"].object_items());
|
||||
try
|
||||
{
|
||||
dsk.parse_config(sb_params);
|
||||
dsk.data_io = dsk.meta_io = dsk.journal_io = "cached";
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
dsk.calc_lengths(true);
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
dsk.close_all();
|
||||
fprintf(stderr, "%s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
dsk.close_all();
|
||||
bool dry_run = options.find("dry_run") != options.end();
|
||||
auto old_journal_device = dsk.journal_device;
|
||||
auto old_meta_device = dsk.meta_device;
|
||||
new_journal_len = dsk.journal_len;
|
||||
if (options.find("journal_size") != options.end())
|
||||
{
|
||||
new_journal_len = parse_size(options["journal_size"]);
|
||||
if (options.find("move_journal") == options.end())
|
||||
options["move_journal"] = dsk.journal_device == dsk.data_device ? "" : dsk.journal_device;
|
||||
}
|
||||
std::map<std::string, std::string> move_options;
|
||||
if (options.find("move_journal") != options.end())
|
||||
{
|
||||
if (resize_parse_move_journal(move_options, dry_run) != 0)
|
||||
return 1;
|
||||
}
|
||||
if (options.find("move_meta") != options.end())
|
||||
{
|
||||
if (resize_parse_move_meta(move_options, dry_run) != 0)
|
||||
return 1;
|
||||
}
|
||||
auto new_journal_device = move_options.find("new_journal_device") != move_options.end()
|
||||
? move_options["new_journal_device"] : dsk.journal_device;
|
||||
auto new_meta_device = move_options.find("new_meta_device") != move_options.end()
|
||||
? move_options["new_meta_device"] : dsk.meta_device;
|
||||
// Calculate new data & meta offsets
|
||||
new_data_offset = 4096 + (new_journal_device == dsk.data_device ? new_journal_len : 0) +
|
||||
(new_meta_device == dsk.data_device ? dsk.meta_len : 0);
|
||||
new_data_offset += ((dsk.data_offset-new_data_offset) % dsk.data_block_size);
|
||||
if (new_data_offset != dsk.data_offset)
|
||||
move_options["new_data_offset"] = std::to_string(new_data_offset);
|
||||
if (options.find("data_size") != options.end())
|
||||
{
|
||||
auto new_data_dev_size = parse_size(options["data_size"]);
|
||||
new_data_dev_size = options["data_size"] == "max" || new_data_dev_size > dsk.data_device_size
|
||||
? dsk.data_device_size : new_data_dev_size;
|
||||
if (new_data_dev_size-dsk.data_offset != dsk.data_len)
|
||||
move_options["new_data_len"] = std::to_string(new_data_dev_size-new_data_offset);
|
||||
}
|
||||
new_meta_offset = 4096 + (new_meta_device == new_journal_device ? new_journal_len : 0);
|
||||
if (new_meta_offset != dsk.meta_offset)
|
||||
move_options["new_meta_offset"] = std::to_string(new_meta_offset);
|
||||
// Run resize
|
||||
auto orig_options = std::move(options);
|
||||
options = sb_params;
|
||||
for (auto & kv: move_options)
|
||||
options[kv.first] = kv.second;
|
||||
if (!json)
|
||||
{
|
||||
std::string cmd;
|
||||
for (auto & kv: move_options)
|
||||
cmd += " "+kv.first+" = "+kv.second+"\n";
|
||||
fprintf(stderr, "Running resize:\n%s", cmd.c_str());
|
||||
}
|
||||
if (!dry_run && raw_resize() != 0)
|
||||
return 1;
|
||||
// Write new superblocks
|
||||
json11::Json::object new_sb_params = sb["params"].object_items();
|
||||
if (move_options.find("new_journal_device") != move_options.end())
|
||||
new_sb_params["journal_device"] = move_options["new_journal_device"];
|
||||
if (move_options.find("new_meta_device") != move_options.end())
|
||||
new_sb_params["meta_device"] = move_options["new_meta_device"];
|
||||
new_sb_params["data_offset"] = new_data_offset;
|
||||
new_sb_params["meta_offset"] = new_meta_offset;
|
||||
if (move_options.find("new_data_len") != move_options.end())
|
||||
new_sb_params["data_size"] = stoull_full(move_options["new_data_len"]);
|
||||
std::set<std::string> clear_superblocks, write_superblocks;
|
||||
write_superblocks.insert(dsk.data_device);
|
||||
write_superblocks.insert(new_journal_device);
|
||||
write_superblocks.insert(new_meta_device);
|
||||
if (write_superblocks.find(old_journal_device) == write_superblocks.end())
|
||||
clear_superblocks.insert(old_journal_device);
|
||||
if (write_superblocks.find(old_meta_device) == write_superblocks.end())
|
||||
clear_superblocks.insert(old_meta_device);
|
||||
for (auto & dev: clear_superblocks)
|
||||
{
|
||||
if (!json)
|
||||
fprintf(stderr, "Clearing OSD superblock on %s\n", dev.c_str());
|
||||
if (!dry_run && clear_osd_superblock(dev) != 0)
|
||||
return 1;
|
||||
}
|
||||
for (auto & dev: write_superblocks)
|
||||
{
|
||||
if (!json)
|
||||
fprintf(stderr, "Writing new OSD superblock to %s\n", dev.c_str());
|
||||
if (!dry_run && !write_osd_superblock(dev, new_sb_params))
|
||||
return 1;
|
||||
}
|
||||
if (json)
|
||||
{
|
||||
printf("%s\n", json11::Json(json11::Json::object {
|
||||
{ "new_sb_params", new_sb_params },
|
||||
}).dump().c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disk_tool_t::resize_parse_move_journal(std::map<std::string, std::string> & move_options, bool dry_run)
|
||||
{
|
||||
if (options["move_journal"] == "")
|
||||
{
|
||||
// move back to the data device
|
||||
// but first check if not already there :)
|
||||
if (dsk.journal_device == dsk.data_device && new_journal_len == dsk.journal_len)
|
||||
{
|
||||
// already there
|
||||
fprintf(stderr, "journal is already on data device and has the same size\n");
|
||||
return 0;
|
||||
}
|
||||
move_options["new_journal_device"] = dsk.data_device;
|
||||
move_options["new_journal_offset"] = "4096";
|
||||
move_options["new_journal_len"] = std::to_string(new_journal_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string real_dev = realpath_str(options["move_journal"], false);
|
||||
if (real_dev == "")
|
||||
return 1;
|
||||
std::string parent_dev = get_parent_device(real_dev);
|
||||
if (parent_dev == "")
|
||||
return 1;
|
||||
if (parent_dev == real_dev)
|
||||
{
|
||||
// whole disk - create partition
|
||||
std::string old_real_dev = realpath_str(dsk.journal_device);
|
||||
if (old_real_dev == "")
|
||||
return 1;
|
||||
if (options.find("force") == options.end() &&
|
||||
get_parent_device(old_real_dev) == parent_dev)
|
||||
{
|
||||
// already there
|
||||
fprintf(stderr, "journal is already on a partition of %s, add --force to create a new partition\n", options["move_journal"].c_str());
|
||||
return 0;
|
||||
}
|
||||
new_journal_len = ((new_journal_len+1024*1024-1)/1024/1024)*1024*1024;
|
||||
if (!dry_run)
|
||||
{
|
||||
auto devinfos = collect_devices({ real_dev });
|
||||
if (devinfos.size() == 0)
|
||||
return 1;
|
||||
std::vector<std::string> sizes;
|
||||
sizes.push_back(std::to_string(new_journal_len/1024/1024)+"MiB");
|
||||
auto new_parts = add_partitions(devinfos[0], sizes);
|
||||
if (!new_parts.array_items().size())
|
||||
return 1;
|
||||
options["move_journal"] = "/dev/disk/by-partuuid/"+strtolower(new_parts[0]["uuid"].string_value());
|
||||
}
|
||||
else
|
||||
options["move_journal"] = "<new journal partition on "+parent_dev+">";
|
||||
}
|
||||
else if (options["move_journal"].substr(0, 22) != "/dev/disk/by-partuuid/")
|
||||
{
|
||||
// Partitions should be identified by GPT partition UUID
|
||||
fprintf(stderr, "%s does not start with /dev/disk/by-partuuid/. Partitions should be identified by GPT partition UUIDs\n", options["move_journal"].c_str());
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// already a partition - check that it's a GPT partition with correct type
|
||||
if (options.find("force") == options.end() &&
|
||||
check_existing_partition(real_dev) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
new_journal_len = get_device_size(options["move_journal"], true);
|
||||
if (new_journal_len == UINT64_MAX)
|
||||
return 1;
|
||||
}
|
||||
new_journal_len -= 4096;
|
||||
move_options["new_journal_device"] = options["move_journal"];
|
||||
move_options["new_journal_offset"] = "4096";
|
||||
move_options["new_journal_len"] = std::to_string(new_journal_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disk_tool_t::resize_parse_move_meta(std::map<std::string, std::string> & move_options, bool dry_run)
|
||||
{
|
||||
if (options["move_meta"] == "")
|
||||
{
|
||||
// move back to the data device
|
||||
// but first check if not already there :)
|
||||
if (dsk.meta_device == dsk.data_device)
|
||||
{
|
||||
// already there
|
||||
fprintf(stderr, "metadata is already on data device\n");
|
||||
return 0;
|
||||
}
|
||||
auto new_journal_device = move_options.find("new_journal_device") != move_options.end()
|
||||
? move_options["new_journal_device"] : dsk.journal_device;
|
||||
move_options["new_meta_device"] = dsk.data_device;
|
||||
move_options["new_meta_len"] = std::to_string(dsk.meta_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string real_dev = realpath_str(options["move_meta"], false);
|
||||
if (real_dev == "")
|
||||
return 1;
|
||||
std::string parent_dev = get_parent_device(real_dev);
|
||||
if (parent_dev == "")
|
||||
return 1;
|
||||
uint64_t new_meta_len = 0;
|
||||
if (parent_dev == real_dev)
|
||||
{
|
||||
// whole disk - create partition
|
||||
std::string old_real_dev = realpath_str(dsk.meta_device);
|
||||
if (old_real_dev == "")
|
||||
return 1;
|
||||
if (options.find("force") == options.end() &&
|
||||
get_parent_device(old_real_dev) == parent_dev)
|
||||
{
|
||||
// already there
|
||||
fprintf(stderr, "metadata is already on a partition of %s\n", options["move_meta"].c_str());
|
||||
return 0;
|
||||
}
|
||||
new_meta_len = ((dsk.meta_len+1024*1024-1)/1024/1024)*1024*1024;
|
||||
if (!dry_run)
|
||||
{
|
||||
auto devinfos = collect_devices({ real_dev });
|
||||
if (devinfos.size() == 0)
|
||||
return 1;
|
||||
std::vector<std::string> sizes;
|
||||
sizes.push_back(std::to_string(new_meta_len/1024/1024)+"MiB");
|
||||
auto new_parts = add_partitions(devinfos[0], sizes);
|
||||
if (!new_parts.array_items().size())
|
||||
return 1;
|
||||
options["move_meta"] = "/dev/disk/by-partuuid/"+strtolower(new_parts[0]["uuid"].string_value());
|
||||
}
|
||||
else
|
||||
options["move_meta"] = "<new metadata partition on "+parent_dev+">";
|
||||
}
|
||||
else if (options["move_meta"].substr(0, 22) != "/dev/disk/by-partuuid/")
|
||||
{
|
||||
// Partitions should be identified by GPT partition UUID
|
||||
fprintf(stderr, "%s does not start with /dev/disk/by-partuuid/. Partitions should be identified by GPT partition UUIDs\n", options["move_meta"].c_str());
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// already a partition - check that it's a GPT partition with correct type
|
||||
if (options.find("force") == options.end() &&
|
||||
check_existing_partition(real_dev) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
new_meta_len = get_device_size(options["move_meta"], true);
|
||||
if (new_meta_len == UINT64_MAX)
|
||||
return 1;
|
||||
}
|
||||
new_meta_len -= 4096;
|
||||
move_options["new_meta_len"] = std::to_string(new_meta_len);
|
||||
move_options["new_meta_device"] = options["move_meta"];
|
||||
move_options["new_meta_offset"] = "4096";
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -101,7 +101,7 @@ int disk_tool_t::upgrade_simple_unit(std::string unit)
|
|||
resizer.options = options;
|
||||
for (auto & kv: resize)
|
||||
resizer.options[kv.first] = std::to_string(kv.second);
|
||||
if (resizer.resize_data() != 0)
|
||||
if (resizer.raw_resize() != 0)
|
||||
{
|
||||
// FIXME: Resize with backup or journal
|
||||
fprintf(
|
||||
|
|
Loading…
Reference in New Issue