Skip to content
This repository was archived by the owner on Oct 22, 2024. It is now read-only.

Commit 46e365d

Browse files
authored
Merge pull request #1059 from pohly/xfs-ioctl
XFS: fix creating volumes on OpenShift
2 parents db5801e + 4f1a2d8 commit 46e365d

File tree

4 files changed

+99
-13
lines changed

4 files changed

+99
-13
lines changed

pkg/pmem-csi-driver/nodeserver.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/intel/pmem-csi/pkg/pmem-csi-driver/parameters"
3131
pmdmanager "github.com/intel/pmem-csi/pkg/pmem-device-manager"
3232
"github.com/intel/pmem-csi/pkg/volumepathhandler"
33+
"github.com/intel/pmem-csi/pkg/xfs"
3334
)
3435

3536
const (
@@ -285,12 +286,7 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
285286
}
286287

287288
if ephemeral && fsType == "xfs" {
288-
// FS was created only in ephemeral case.
289-
// Only if created filesytem and it was XFS:
290-
// Tune XFS file system to serve huge pages:
291-
// Set file system extent size to 2 MiB sized and aligned block allocations.
292-
_, err := pmemexec.RunCommand(ctx, "xfs_io", "-c", "extsize 2m", hostMount)
293-
if err != nil {
289+
if err := xfs.ConfigureFS(hostMount); err != nil {
294290
return nil, status.Error(codes.Internal, err.Error())
295291
}
296292
}
@@ -587,11 +583,8 @@ func (ns *nodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
587583
return nil, status.Error(codes.Internal, err.Error())
588584
}
589585

590-
if existingFsType == "" && requestedFsType == "xfs" {
591-
// Only if created a new filesytem and it was XFS:
592-
// Align XFS file system for hugepages
593-
_, err := pmemexec.RunCommand(ctx, "xfs_io", "-c", "extsize 2m", stagingtargetPath)
594-
if err != nil {
586+
if requestedFsType == "xfs" {
587+
if err := xfs.ConfigureFS(stagingtargetPath); err != nil {
595588
return nil, status.Error(codes.Internal, err.Error())
596589
}
597590
}

pkg/xfs/xfs.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright 2022 Intel Corporation
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package xfs
8+
9+
// #include <linux/fs.h>
10+
// #include <sys/ioctl.h>
11+
// #include <errno.h>
12+
// #include <string.h>
13+
//
14+
// char *getxattr(int fd, struct fsxattr *arg) {
15+
// return ioctl(fd, FS_IOC_FSGETXATTR, arg) == 0 ? 0 : strerror(errno);
16+
// }
17+
//
18+
// char *setxattr(int fd, struct fsxattr *arg) {
19+
// return ioctl(fd, FS_IOC_FSSETXATTR, arg) == 0 ? 0 : strerror(errno);
20+
// }
21+
import "C"
22+
23+
import (
24+
"fmt"
25+
"os"
26+
)
27+
28+
// ConfigureFS must be called after mkfs.xfs for the mounted
29+
// XFS filesystem to prepare the volume for usage as fsdax.
30+
// It is idempotent.
31+
func ConfigureFS(path string) error {
32+
// Operate on root directory.
33+
file, err := os.Open(path)
34+
if err != nil {
35+
return fmt.Errorf("open %q: %v", path, err)
36+
}
37+
defer file.Close()
38+
fd := C.int(file.Fd())
39+
40+
// Get extended attributes.
41+
var attr C.struct_fsxattr
42+
if errnostr := C.getxattr(fd, &attr); errnostr != nil {
43+
return fmt.Errorf("FS_IOC_FSGETXATTR for %q: %v", path, C.GoString(errnostr))
44+
}
45+
46+
// Set extsize to 2m to enable hugepages in combination with
47+
// fsdax. This is equivalent to the "xfs_io -c 'extsize 2m'" invocation
48+
// mentioned in https://nvdimm.wiki.kernel.org/2mib_fs_dax
49+
attr.fsx_xflags |= C.FS_XFLAG_EXTSZINHERIT
50+
attr.fsx_extsize = 2 * 1024 * 1024
51+
if errnostr := C.setxattr(fd, &attr); errnostr != nil {
52+
return fmt.Errorf("FS_IOC_FSSETXATTR for %q: %v", path, C.GoString(errnostr))
53+
}
54+
55+
return nil
56+
}

pkg/xfs/xfs_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
Copyright 2022 Intel Corporation
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package xfs
8+
9+
import (
10+
"testing"
11+
)
12+
13+
func Test_ConfigureFS(t *testing.T) {
14+
// This is assumed to be backed by tmpfs and thus doesn't support xattr.
15+
tmp := t.TempDir()
16+
err := ConfigureFS(tmp)
17+
if err == nil {
18+
t.Fatal("did not get expected error")
19+
}
20+
t.Logf("got expected error: %v", err)
21+
}

test/e2e/storage/dax/dax.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func (p *daxTestSuite) DefineTests(driver storageframework.TestDriver, pattern s
123123
init()
124124
defer cleanup()
125125

126-
testDaxInPod(f, l.root, l.resource.Pattern.VolMode, l.resource.VolSource, l.config, withKataContainers, p.daxSupported)
126+
testDaxInPod(f, l.root, l.resource.Pattern.VolMode, l.resource.VolSource, l.config, withKataContainers, p.daxSupported, l.resource.Pattern.FsType)
127127
})
128128
}
129129

@@ -135,6 +135,7 @@ func testDaxInPod(
135135
config *storageframework.PerTestConfig,
136136
withKataContainers bool,
137137
daxSupported bool,
138+
fstype string,
138139
) {
139140
expectDax := daxSupported
140141
if withKataContainers {
@@ -151,11 +152,19 @@ func testDaxInPod(
151152
}
152153
}
153154

155+
// Workaround for https://github.com/kubernetes/kubernetes/issues/107286:
156+
// the storage framework should set FSType but doesn't.
157+
if source.CSI != nil &&
158+
source.CSI.FSType == nil &&
159+
fstype != "" {
160+
source.CSI.FSType = &fstype
161+
}
162+
154163
pod := CreatePod(f, "dax-volume-test", volumeMode, source, config, withKataContainers)
155164
defer func() {
156165
DeletePod(f, pod)
157166
}()
158-
checkWithNormalRuntime := testDax(f, pod, root, volumeMode, source, withKataContainers, expectDax)
167+
checkWithNormalRuntime := testDax(f, pod, root, volumeMode, source, withKataContainers, expectDax, fstype)
159168
DeletePod(f, pod)
160169
if checkWithNormalRuntime {
161170
testDaxOutside(f, pod, root)
@@ -336,6 +345,7 @@ func testDax(
336345
source *v1.VolumeSource,
337346
withKataContainers bool,
338347
expectDax bool,
348+
fstype string,
339349
) bool {
340350
ns := f.Namespace.Name
341351
containerName := pod.Spec.Containers[0].Name
@@ -351,6 +361,12 @@ func testDax(
351361
if expectDax {
352362
By("checking volume for DAX support")
353363
pmempod.RunInPod(f, root, nil, "lsblk; mount | grep /mnt; /usr/local/bin/pmem-dax-check /mnt/daxtest", ns, pod.Name, containerName)
364+
365+
if fstype == "xfs" {
366+
By("checking volume for extsize 2m")
367+
// "xfs_io -c extsize" prints "[2097152] /mnt".
368+
pmempod.RunInPod(f, root, nil, "xfs_io -c extsize /mnt | tee /dev/stderr | grep -q -w 2097152", ns, pod.Name, containerName)
369+
}
354370
} else {
355371
By("checking volume for missing DAX support")
356372
stdout, _ := pmempod.RunInPod(f, root, nil, "ndctl list -NR; lsblk; mount | grep /mnt; /usr/local/bin/pmem-dax-check /mnt/daxtest; if [ $? -ne 1 ]; then echo should have reported missing DAX >&2; exit 1; fi", ns, pod.Name, containerName)

0 commit comments

Comments
 (0)