New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mount: support checking multiple kinds of block device driver #4743
Conversation
Please tell me the porting labels to be applied. |
Can one of the admins verify this patch? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more general question: the DM device check is a workaround for the device mapper snapshotter. Please explain a bit why we need to check for the extra block device types and how they are supposed to work with Kata Containers. Thanks!
src/runtime/virtcontainers/mount.go
Outdated
@@ -208,7 +208,7 @@ func getDeviceForPath(path string) (device, error) { | |||
|
|||
var blockFormatTemplate = "/sys/dev/block/%d:%d/dm" | |||
|
|||
var checkStorageDriver = isDeviceMapper | |||
var checkStorageDriver = checkBlockDevice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isDeviceMapper
is left over but it's a piece of dead code now? And the new code is not unit-tested as the code pieces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for adding unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for removing the isDeviceMapper code if not used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the change, very useful to extend block device support outside of device mapper!
src/runtime/virtcontainers/mount.go
Outdated
@@ -208,7 +208,7 @@ func getDeviceForPath(path string) (device, error) { | |||
|
|||
var blockFormatTemplate = "/sys/dev/block/%d:%d/dm" | |||
|
|||
var checkStorageDriver = isDeviceMapper | |||
var checkStorageDriver = checkBlockDevice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for adding unit tests.
src/runtime/virtcontainers/mount.go
Outdated
@@ -226,6 +226,40 @@ func isDeviceMapper(major, minor int) (bool, error) { | |||
return false, err | |||
} | |||
|
|||
var blockFormatTemplates = map[string]string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: blockFormatTemplates -> blockFormatFmts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blockFormatTemplates is consist with old code.
src/runtime/virtcontainers/mount.go
Outdated
} | ||
|
||
func checkBlockDevice(major, minor int) (bool, error) { | ||
var lastErr error = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
= nil
seems to be unnecessary
src/runtime/virtcontainers/mount.go
Outdated
for dev, template := range blockFormatTemplates { | ||
isBD, err := isBlockDevice(major, minor, template) | ||
if isBD { | ||
mountLogger().Infof("Found storage driver for %s", dev) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This log seems to be a little off from the context, can we log "device % is identified as a block device"?
_, err := os.Stat(sysPath) | ||
if err == nil { | ||
return true, nil | ||
} else if os.IsNotExist(err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove the else if
, or to add the last return into an else
block for consistency
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/runtime/virtcontainers/mount.go
Outdated
@@ -208,7 +208,7 @@ func getDeviceForPath(path string) (device, error) { | |||
|
|||
var blockFormatTemplate = "/sys/dev/block/%d:%d/dm" | |||
|
|||
var checkStorageDriver = isDeviceMapper | |||
var checkStorageDriver = checkBlockDevice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for removing the isDeviceMapper code if not used
src/runtime/virtcontainers/mount.go
Outdated
mountLogger().Infof("Found storage driver for %s", dev) | ||
return isBD, err | ||
} else if err != nil { | ||
lastErr = err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this logic easier to understand like the following? I think if any error occurred while checking can just throw the error without continuing.
isBD, err := isBlockDevice(major, minor, template)
if err != nil {
return
}
@bergwolf Thanks for commenting! I will add unit test and remove unused code. |
What does "add-pr-size-label" failed mean ? |
|
||
// fake the block device format | ||
blockFormatTemplate = "/sys/dev/char/%d:%d" | ||
isDM, err = isDeviceMapper(major, minor) | ||
blockFormatTemplates = map[string]string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to reset blockFormatTemplates
so in case other case will not be impacted, I think the old code probably missed this part
blockFormatTemplatesOld := blockFormatTemplates
defer func() {
blockFormatTemplates = blockFormatTemplatesOld
}()
blockFormatTemplates = map[string]string{
"/dev/tty": "/sys/dev/char/%d:%d",
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good way, I have done so.
src/runtime/virtcontainers/mount.go
Outdated
for dev, template := range blockFormatTemplates { | ||
isBD, err := isBlockDevice(major, minor, template) | ||
if err != nil { | ||
return false, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add UTs to cover all the branches for the newly added code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unchecked branch is err != nil
which only happens when isBlockDevice
return error. That happens when os.Stat
fails and not because of os.IsNotExist
.
I really don't know when it happens. Do you have any idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the easiest way to accomplish this here is to use a path with an invalid character (the null character \000
will work for both unix and window systems):
fmt.Println("Example: Invalid character")
_, err := os.Stat("\000path")
fmt.Println(err)
You can override the blockFormatTemplates
like you did the tests below to get a path with \000
in it
(Permissions errors should also work, but might be a little hard to setup tests for)
Also, if you need help getting this PR to the finish line, please let me know
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sazzy4o I have supplemented the test as you suggested.
It's really grateful that you can help finishing this PR.
@shuaichang Could you please have another look at reviewing this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@yuchen0cc Could you please merge |
OK, I've rebase it by mainstream. |
@bergwolf Could you please review this PR? |
@yuchen0cc It looks like one of the checks is failing because a749dd1 does not have a commit message body I think updating it to something like this should work:
See here for more info on expected commit message format I hope this is the last change. If you want me to take over changes to this PR, please let me know (I just need permission to push to your fork) |
@sazzy4o sorry to forget this checking, I've fixed it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks useful to enable overlaybd for Kata. Could you add a howto document in the docs/how-to/
directory?
After discussing with @sazzy4o, it is completely transparent, we do not need a specific overlaybd howto in kata.
src/runtime/virtcontainers/mount.go
Outdated
//Check if /sys/dev/block/${major}-${minor}/dm exists | ||
sysPath := fmt.Sprintf(blockFormatTemplate, major, minor) | ||
func isBlockDevice(major, minor int, formatTemplate string) (bool, error) { | ||
sysPath := fmt.Sprintf(formatTemplate, major, minor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not seem to work for nvme devices. Why not just check for /sys/dev/block/<major:minor>/
and forget about the specific block device types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have actually tested the above 3 block types with kata, and I'm not sure kata is compatible with all block types.
Just to be cautious, I make a minimal supportation, and allow for extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All block devices are equal in terms of virtio-block backend. So it doesn't matter where it comes from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, it seems reasonable.
As suggested by @bergwolf , I think there is no longer need to check multiple templates (using map and loop). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
TestIsDeviceMapper has been moved from mount_test.go to mount_linux_test |
Please test the code locally before sending it for review.
|
Device mapper is the only supported block device driver so far, which seems limiting. Kata Containers can work well with other block devices. It is necessary to enhance supporting of multiple kinds of host block device. Fixes kata-containers#4714 Signed-off-by: yuchen.cc <yuchen.cc@alibaba-inc.com>
I think that code looks good, but I'll try running locally (I think I should have some time to test locally tomorrow) |
Tested locally with
Notes:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good and works when testing locally
/test-arm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks reasonable
Device mapper is the only supported block device driver so far, which seems limiting. Kata Containers can work well with other block devices. It is necessary to enhance supporting of multiple kinds of host block device.
Fixes #4714
Signed-off-by: yuchen.cc yuchen.cc@alibaba-inc.com