Skip to content

Commit 5eab81e

Browse files
committed
Tighter checks on CreateVolume CapacityRange
The CSI spec is clear that when CapacityRange is supplied, neither RequiredBytes nor LimitBytes may be negative, and at least one of the two values must be non-zero. It is also impossible to create a volume that requires more bytes than a non-zero limit. However, before this patch, we were not taking the limit into account. Note that since we do not check whether hp.createVolume() rounds capacity up during the creation, we cannot detect the case where that rounding would violate limit. See also kubernetes-csi/csi-test#568 which will test these changes. Signed-off-by: Eric Blake <[email protected]>
1 parent 245a8ee commit 5eab81e

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

pkg/hostpath/controllerserver.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,23 @@ func (hp *hostPath) CreateVolume(ctx context.Context, req *csi.CreateVolumeReque
9797
requestedAccessType = state.MountAccess
9898
}
9999

100+
capacity := int64(req.GetCapacityRange().GetRequiredBytes())
101+
limit := int64(req.GetCapacityRange().GetLimitBytes())
102+
if capacity < 0 || limit < 0 {
103+
return nil, status.Error(codes.InvalidArgument, "cannot have negative capacity")
104+
}
105+
if limit > 0 && capacity > limit {
106+
return nil, status.Error(codes.InvalidArgument, "capacity cannot exceed limit")
107+
}
108+
if capacity == 0 && limit > 0 {
109+
capacity = limit
110+
}
111+
100112
// Lock before acting on global state. A production-quality
101113
// driver might use more fine-grained locking.
102114
hp.mutex.Lock()
103115
defer hp.mutex.Unlock()
104116

105-
capacity := int64(req.GetCapacityRange().GetRequiredBytes())
106117
topologies := []*csi.Topology{}
107118
if hp.config.EnableTopology {
108119
topologies = append(topologies, &csi.Topology{Segments: map[string]string{TopologyKeyNode: hp.config.NodeID}})
@@ -114,7 +125,7 @@ func (hp *hostPath) CreateVolume(ctx context.Context, req *csi.CreateVolumeReque
114125
// Since err is nil, it means the volume with the same name already exists
115126
// need to check if the size of existing volume is the same as in new
116127
// request
117-
if exVol.VolSize < capacity {
128+
if exVol.VolSize < capacity || (limit > 0 && exVol.VolSize > limit) {
118129
return nil, status.Errorf(codes.AlreadyExists, "Volume with the same name: %s but with different size already exist", req.GetName())
119130
}
120131
if req.GetVolumeContentSource() != nil {
@@ -146,6 +157,8 @@ func (hp *hostPath) CreateVolume(ctx context.Context, req *csi.CreateVolumeReque
146157

147158
volumeID := uuid.NewUUID().String()
148159
kind := req.GetParameters()[storageKind]
160+
// This code does not check whether hp.createVolume rounds capacity up;
161+
// a more robust driver would ensure any rounding does not exceed limit.
149162
vol, err := hp.createVolume(volumeID, req.GetName(), capacity, requestedAccessType, false /* ephemeral */, kind)
150163
if err != nil {
151164
return nil, err
@@ -182,7 +195,7 @@ func (hp *hostPath) CreateVolume(ctx context.Context, req *csi.CreateVolumeReque
182195
return &csi.CreateVolumeResponse{
183196
Volume: &csi.Volume{
184197
VolumeId: volumeID,
185-
CapacityBytes: req.GetCapacityRange().GetRequiredBytes(),
198+
CapacityBytes: capacity,
186199
VolumeContext: req.GetParameters(),
187200
ContentSource: req.GetVolumeContentSource(),
188201
AccessibleTopology: topologies,

0 commit comments

Comments
 (0)