Change:
From here we see that the method takes 512 bytes sector size as a default option for verifying block read. This makes the test fail for the block devices that uses 4k sector size because the read is using . However, with modern kernels the area being operated on, must be aligned to and its size must be a multiple of the disk's block size. So using dd iflag=direct with size 512B on a 4k sector size device will fail. This is introduced in this PR: There should be proper handling of different block sector size for the test. Either a customizable parameter or something. Kubernetes version (use ): Cloud provider or hardware configuration: OS (e.g: ): Kernel (e.g. ): Install tools: Network plugin and version (if this is a network-related bug): Others: /cc /sig storage
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
cc
Since we are using Debian image for this test. I am wondering does it make sense to use instead of for the dd read? I guess my question is if we use , while it read after the cache is dropped or before?
Or I am wondering can we just change the size to 4096. A read/write to the multiply of the sector size should be okay I guess?
I am not sure that option is available now, notes from September last year () indicate I tried that as well. I think you still need to write blocks of 512 or 4096 bytes, not sure if (or the kernel) is smart enough to split larger requests into smaller blocks. has a pointer to detect the blocksize dynamically, which would be a cleaner way and more future proof.
I am not sure when you mention the "option is not available" you mean for busybox or debian. I think for this specific test we are using Debian image which has this option. Yes, this is what we use in the test and we found the test fail because in our case shows 4096 instead of 512
The option () used to be only applicable for (in Debian and CentOS) with , not with . I do not know if the Debian image was updated, and if it contains a new that supports the option.
+1 for using 4096 bytes. Or even more, 1MiB? Kernel/dd is smart and it will handle sequence of well.
I think that it's OK to just use large block size if there's no issue by doing so. However, I've made a PoC implementation of auto detect logic of sector size to compare alternative ideas. One issue is that current debian-iptables image that is used for this test doesn't contain blockdev command. In the PoC code, it is installed on execution time, however it should be included in the image, by either (1) adding it to debian-iptables image or (2) creating a new image that include it. If the issue can be resolved easily, this alternative approach will also be good.
I found that image contains both command and command and can be used for this test. I think that this additional detection logic is simple enough, so I made a PR above. Could you review it?

Discussion:
SeLinuxLabel:  e2epod.GetLinuxLabel(), NodeSelection: node, PVCsReadOnly:  readOnly, <del> ImageID:       e2epod.GetTestImageID(imageutils.DebianIptables), </del> <ins> ImageID:       e2epod.GetTestImageID(imageutils.JessieDnsutils), </ins> } pod, err := e2epod.CreateSecPodWithNodeSelection(cs, &podConfig, f.Timeouts.PodStart) defer func() {

} } <ins> path := "/mnt/volume1" </ins> var seed int64 byteLen := 64 directIO := false // direct IO is needed for Block-mode PVs if *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock { <ins> if len(pods) < 1 { framework.Failf("Number of pods shouldn't be less than 1, but got %d", len(pods)) } </ins> // byteLen should be the size of a sector to enable direct I/O <del> byteLen = 512 </del> <ins> byteLen = utils.GetSectorSize(f, pods[0], path) </ins> directIO = true } <del> path := "/mnt/volume1" </del> // Check if volume can be accessed from each pod for i, pod := range pods { index := i + 1

"math" "math/rand" "path/filepath" <ins> "strconv" </ins> "strings" "time"

e2evolume.VerifyExecInPodSucceed(f, pod, fmt.Sprintf("echo %s | base64 -d | dd of=%s %s bs=%d count=1", encoded, pathForVolMode, oflag, len)) } <ins> // GetSectorSize returns the sector size of the device. func GetSectorSize(f *framework.Framework, pod *v1.Pod, device string) int { stdout, _, err := e2evolume.PodExec(f, pod, fmt.Sprintf("blockdev --getss %s", device)) framework.ExpectNoError(err, "Failed to get sector size of %s", device) ss, err := strconv.Atoi(stdout) framework.ExpectNoError(err, "Sector size returned by blockdev command isn't integer value.") return ss } </ins> // findMountPoints returns all mount points on given node under specified directory. func findMountPoints(hostExec HostExec, node *v1.Node, dir string) []string { result, err := hostExec.IssueCommandWithResult(fmt.Sprintf(`find %s -type d -exec mountpoint {} ; | grep 'is a mountpoint$' || true`, dir), node)