mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Support for hugetlbfs in empty dir volume plugin
This commit is contained in:
parent
38d5dee677
commit
2dba8f1715
@ -681,8 +681,9 @@ type EmptyDirVolumeSource struct {
|
||||
type StorageMedium string
|
||||
|
||||
const (
|
||||
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
|
||||
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
|
||||
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
|
||||
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
|
||||
StorageMediumHugepages StorageMedium = "Hugepages" // use hugepages
|
||||
)
|
||||
|
||||
// Protocol defines network protocols supported for things like container ports.
|
||||
|
@ -104,9 +104,11 @@ func (plugin *emptyDirPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, opts vo
|
||||
|
||||
func (plugin *emptyDirPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions) (volume.Mounter, error) {
|
||||
medium := v1.StorageMediumDefault
|
||||
|
||||
if spec.Volume.EmptyDir != nil { // Support a non-specified source as EmptyDir.
|
||||
medium = spec.Volume.EmptyDir.Medium
|
||||
}
|
||||
|
||||
return &emptyDir{
|
||||
pod: pod,
|
||||
volName: spec.Name(),
|
||||
@ -159,8 +161,9 @@ type mountDetector interface {
|
||||
type storageMedium int
|
||||
|
||||
const (
|
||||
mediumUnknown storageMedium = 0 // assume anything we don't explicitly handle is this
|
||||
mediumMemory storageMedium = 1 // memory (e.g. tmpfs on linux)
|
||||
mediumUnknown storageMedium = 0 // assume anything we don't explicitly handle is this
|
||||
mediumMemory storageMedium = 1 // memory (e.g. tmpfs on linux)
|
||||
mediumHugepages storageMedium = 2 // hugepages
|
||||
)
|
||||
|
||||
// EmptyDir volumes are temporary directories exposed to the pod.
|
||||
@ -221,6 +224,8 @@ func (ed *emptyDir) SetUpAt(dir string, fsGroup *int64) error {
|
||||
err = ed.setupDir(dir)
|
||||
case v1.StorageMediumMemory:
|
||||
err = ed.setupTmpfs(dir)
|
||||
case v1.StorageMediumHugepages:
|
||||
err = ed.setupHugepages(dir)
|
||||
default:
|
||||
err = fmt.Errorf("unknown storage medium %q", ed.medium)
|
||||
}
|
||||
@ -257,6 +262,29 @@ func (ed *emptyDir) setupTmpfs(dir string) error {
|
||||
return ed.mounter.Mount("tmpfs", dir, "tmpfs", nil /* options */)
|
||||
}
|
||||
|
||||
// setupHugepages creates a hugepage mount at the specified directory.
|
||||
func (ed *emptyDir) setupHugepages(dir string) error {
|
||||
if ed.mounter == nil {
|
||||
return fmt.Errorf("memory storage requested, but mounter is nil")
|
||||
}
|
||||
if err := ed.setupDir(dir); err != nil {
|
||||
return err
|
||||
}
|
||||
// Make SetUp idempotent.
|
||||
medium, isMnt, err := ed.mountDetector.GetMountMedium(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If the directory is a mountpoint with medium memory, there is no
|
||||
// work to do since we are already in the desired state.
|
||||
if isMnt && medium == mediumHugepages {
|
||||
return nil
|
||||
}
|
||||
|
||||
glog.V(3).Infof("pod %v: mounting hugepages for volume %v", ed.pod.UID, ed.volName)
|
||||
return ed.mounter.Mount("nodev", dir, "hugetlbfs", []string{})
|
||||
}
|
||||
|
||||
// setupDir creates the directory with the default permissions specified by the perm constant.
|
||||
func (ed *emptyDir) setupDir(dir string) error {
|
||||
// Create the directory if it doesn't already exist.
|
||||
@ -318,9 +346,14 @@ func (ed *emptyDir) TearDownAt(dir string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isMnt && medium == mediumMemory {
|
||||
ed.medium = v1.StorageMediumMemory
|
||||
return ed.teardownTmpfs(dir)
|
||||
if isMnt {
|
||||
if medium == mediumMemory {
|
||||
ed.medium = v1.StorageMediumMemory
|
||||
return ed.teardownTmpfsOrHugetlbfs(dir)
|
||||
} else if medium == mediumHugepages {
|
||||
ed.medium = v1.StorageMediumHugepages
|
||||
return ed.teardownTmpfsOrHugetlbfs(dir)
|
||||
}
|
||||
}
|
||||
// assume StorageMediumDefault
|
||||
return ed.teardownDefault(dir)
|
||||
@ -336,7 +369,7 @@ func (ed *emptyDir) teardownDefault(dir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ed *emptyDir) teardownTmpfs(dir string) error {
|
||||
func (ed *emptyDir) teardownTmpfsOrHugetlbfs(dir string) error {
|
||||
if ed.mounter == nil {
|
||||
return fmt.Errorf("memory storage requested, but mounter is nil")
|
||||
}
|
||||
|
@ -27,7 +27,10 @@ import (
|
||||
)
|
||||
|
||||
// Defined by Linux - the type number for tmpfs mounts.
|
||||
const linuxTmpfsMagic = 0x01021994
|
||||
const (
|
||||
linuxTmpfsMagic = 0x01021994
|
||||
linuxHugetlbfsMagic = 0x958458f6
|
||||
)
|
||||
|
||||
// realMountDetector implements mountDetector in terms of syscalls.
|
||||
type realMountDetector struct {
|
||||
@ -48,6 +51,8 @@ func (m *realMountDetector) GetMountMedium(path string) (storageMedium, bool, er
|
||||
glog.V(5).Infof("Statfs_t of %v: %+v", path, buf)
|
||||
if buf.Type == linuxTmpfsMagic {
|
||||
return mediumMemory, !notMnt, nil
|
||||
} else if buf.Type == linuxHugetlbfsMagic {
|
||||
return mediumHugepages, !notMnt, nil
|
||||
}
|
||||
return mediumUnknown, !notMnt, nil
|
||||
}
|
||||
|
@ -80,6 +80,15 @@ func TestPluginEmptyRootContext(t *testing.T) {
|
||||
expectedTeardownMounts: 0})
|
||||
}
|
||||
|
||||
func TestPluginHugetlbfs(t *testing.T) {
|
||||
doTestPlugin(t, pluginTestConfig{
|
||||
medium: v1.StorageMediumHugepages,
|
||||
expectedSetupMounts: 1,
|
||||
expectedTeardownMounts: 0,
|
||||
shouldBeMountedBeforeTeardown: true,
|
||||
})
|
||||
}
|
||||
|
||||
type pluginTestConfig struct {
|
||||
medium v1.StorageMedium
|
||||
idempotent bool
|
||||
@ -165,7 +174,7 @@ func doTestPlugin(t *testing.T, config pluginTestConfig) {
|
||||
if e, a := config.expectedSetupMounts, len(physicalMounter.Log); e != a {
|
||||
t.Errorf("Expected %v physicalMounter calls during setup, got %v", e, a)
|
||||
} else if config.expectedSetupMounts == 1 &&
|
||||
(physicalMounter.Log[0].Action != mount.FakeActionMount || physicalMounter.Log[0].FSType != "tmpfs") {
|
||||
(physicalMounter.Log[0].Action != mount.FakeActionMount || (physicalMounter.Log[0].FSType != "tmpfs" && physicalMounter.Log[0].FSType != "hugetlbfs")) {
|
||||
t.Errorf("Unexpected physicalMounter action during setup: %#v", physicalMounter.Log[0])
|
||||
}
|
||||
physicalMounter.ResetLog()
|
||||
|
@ -943,8 +943,9 @@ type FlockerVolumeSource struct {
|
||||
type StorageMedium string
|
||||
|
||||
const (
|
||||
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
|
||||
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
|
||||
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
|
||||
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
|
||||
StorageMediumHugepages StorageMedium = "HugePages" // use hugepages
|
||||
)
|
||||
|
||||
// Protocol defines network protocols supported for things like container ports.
|
||||
|
Loading…
Reference in New Issue
Block a user