Skip to content
This repository has been archived by the owner on Oct 21, 2020. It is now read-only.

Detect local volume capacity #135

Merged
merged 1 commit into from
Jun 12, 2017

Conversation

ddysher
Copy link
Contributor

@ddysher ddysher commented May 24, 2017

Detect local volume capacity, a couple of implementation notes:

  • to correctly detect host devices, daemonset is changed to run in privileged mode
  • after investigating cadvisor, i think we can just detect capacity using statfs, instead of collecting all information from device name, device number, mountpoint, etc; we don't need that much data
  • statfs returns 'total, free, available'. We use 'total - free + available' as pv capacity
  • if user just create regular directory, then the available space for the mount device is returned, in which case the behavior is similar to hostpath

Future work

@msau42 @jsafrane @humblec @wongma7

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label May 24, 2017
Copy link
Contributor

@msau42 msau42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add/extend a unit test to check that the created PV object has the correct capacity specified?

// TODO: detect capacity
d.createPV(file, relativePath, class)

avail, err := d.VolUtil.GetFsAvailable(filePath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you call this GetFsAvailable<Unit> to be more explicit? Where unit is bytes, mb, gb, etc.

@@ -85,11 +90,12 @@ func generatePVName(file, node, class string) string {
return fmt.Sprintf("%v-%v-%v", class, node, file)
}

func (d *Discoverer) createPV(file, relativePath, class string) {
func (d *Discoverer) createPV(file, relativePath, class string, avail uint64) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add the unit to the variable name

// TODO: detect capacity
v1.ResourceName(v1.ResourceStorage): resource.MustParse("10Gi"),
v1.ResourceName(v1.ResourceStorage): *resource.NewQuantity(int64(avail), resource.BinarySI),
// v1.ResourceName(v1.ResourceStorage): resource.MustParse("10Gi"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line can be removed

@@ -20,6 +20,7 @@ import (
"fmt"
"os"
"path/filepath"
"syscall"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this pkg is deprecated, and we're supposed to use https://godoc.org/golang.org/x/sys/unix instead.

if err := syscall.Statfs(fullPath, &s); err != nil {
return 0, err
}
return uint64(s.Frsize) * s.Bavail, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between frsize and bsize?

Do we want to use total blocks instead of available? I'm thinking of a situation where they might want pre-populated data in the volume.

Also in the shared directory case, we could get inconsistent capacities depending on the order that pods fill them up (although the capacity is already going to be inaccurate in that case).

Copy link
Contributor Author

@ddysher ddysher May 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this and this which explain the concept pretty well (the concept applies to most fs).

What is not quite clear is how this was handled in all sorts of filesystem; but it looks like the values are usually the same (the option to create different fragment size is actually removes the option from mke2fs, though man page still has the option).

Using Frsize here is mainly based on cadvisor https://github.com/google/cadvisor/blob/aee77359083ccef523d0299316e831f1aed712bd/fs/fs.go#L530

Also, df uses frsize as welll (fall back to bsize if it is not available): https://github.com/coreutils/gnulib/blob/2a0c08e48834ae056964922ee6d21ccd223d1d80/lib/fsusage.c#L131

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@msau42 I'm ok with using total blocks for reasons listed in ur comment (pre-populated data and consistent capacity). My concern is that the total block is generally not the capacity user can actually use, e.g. for ext4, there's 5% system reserved space.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm is there a field that can distinguish between system reserved, and user used?

Copy link
Contributor Author

@ddysher ddysher Jun 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such a field that i know of. Looking further into df, I think what we can do is to use 'used + available'.

related logic from df:

  bv->total = fsu->fsu_blocks;
  bv->available_to_root = fsu->fsu_bfree;

  bv->used = bv->total - fsu->fsu_bfree;

  uintmax_t nonroot_total = v->used + v->available;

so simply put, we can return s.Blocks - s.Bfree + s.Bavail. This will return total capacity for non root user, with system reserved removed altogether.

WDYT

@ddysher ddysher force-pushed the detect-capacity branch 2 times, most recently from f4e9811 to c7fedb2 Compare June 2, 2017 07:25
@ddysher
Copy link
Contributor Author

ddysher commented Jun 2, 2017

@msau42 comment addressed

@ddysher
Copy link
Contributor Author

ddysher commented Jun 2, 2017

Also, to correctly detect capacity for mountpoint after provisioner has already started, we need mount propagation for hostpath
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/propagation.md

@ddysher ddysher changed the title WIP: detect local volume capacity Detect local volume capacity Jun 2, 2017
Copy link
Contributor

@msau42 msau42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just one minor comment, lgtm!

var s syscall.Statfs_t
if err := syscall.Statfs(fullPath, &s); err != nil {
// GetFsAvailableByte returns available capacity in byte about a mounted filesystem.
// fullPath is the pathname of any file within the mounted filesystem.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add in this comment that this does not include fs reserved space?

@msau42
Copy link
Contributor

msau42 commented Jun 6, 2017

Remind me to add the limitation about mount propagation in the docs.

@msau42
Copy link
Contributor

msau42 commented Jun 6, 2017

@jsafrane do you know the status for the mount propagation?

@ddysher
Copy link
Contributor Author

ddysher commented Jun 7, 2017

@msau42

talked to @jsafrane in another issue, this missed 1.7

kubernetes/community#659

@ddysher ddysher force-pushed the detect-capacity branch 3 times, most recently from 1b922ca to dfadbd1 Compare June 10, 2017 02:25
@ddysher
Copy link
Contributor Author

ddysher commented Jun 10, 2017

@msau42 rebase to HEAD, PTAL

@msau42
Copy link
Contributor

msau42 commented Jun 12, 2017

/lgtm

@wongma7 wongma7 merged commit a3a14e5 into kubernetes-retired:master Jun 12, 2017
cofyc pushed a commit to cofyc/external-storage that referenced this pull request Dec 17, 2018
yangruiray pushed a commit to yangruiray/external-storage that referenced this pull request Jul 19, 2019
Add Block volume support for CSI provisioner
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants