How is read-write layer mounting done on the host with computestorage?
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 694
- Forks
- 304
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 28
Description
I was trying to implement a version of cmd/wclayer using the computestorage APIs, and I'm missing some important step for mount.
The flow with the RS1 APIs is:
ActivateLayer(rwLayerPath)PrepareLayer(rwLayerPath, parents)volumePath := GetLayerMountPath(rwLayerPath)SetVolumeMountPoint(targetPath, volumePath)
With computestorage, it seems we need:
- (I'm guessing this!)
vhd.AttachVhd(rwLayerPath+"\sandbox.vhdx") AttachLayerStorageFilter(rwLayerPath, parentLayerData)volumePath := GetLayerVhdMountPath(someVHDHandle)SetVolumeMountPoint(targetPath, volumePath)
The equivalence guess is based on the in-source description of ActivateLayer as mounting filesystems, and PrepareLayer as enabling the filesystem filter.
But I haven't been able to get this to actually work yet.
The current source code I'm trying to use, in case my flow is right but the flags are wrong
// containerSandboxVHDXName is "sandbox.vhdx".
// I have pushed this to https://github.com/TBBle/hcsshim/commit/90725df9c13487cd976604220c5d36742097fc75 if you want to see `getLayerData` for example.
var mountCommand = cli.Command{
Name: "mount",
Usage: "activates a scratch, optionally mounted to provided target",
ArgsUsage: "<scratch path> [target path]",
Before: appargs.Validate(appargs.NonEmptyString, appargs.Optional(appargs.String)),
Flags: []cli.Flag{
cli.StringSliceFlag{
Name: "layer, l",
Usage: "paths to the parent layers for this layer",
},
},
Action: func(cliContext *cli.Context) (err error) {
path, err := filepath.Abs(cliContext.Args().Get(0))
if err != nil {
return err
}
sandboxVHDXPath := filepath.Join(path, containerSandboxVHDXName)
if _, err := os.Stat(sandboxVHDXPath); err != nil {
return fmt.Errorf("failed to Stat %q: %w", sandboxVHDXPath, err)
}
if err := vhd.AttachVhd(sandboxVHDXPath); err != nil {
return fmt.Errorf("failed to Attach %q: %w", sandboxVHDXPath, err)
}
defer func() {
if err != nil {
_ = vhd.DetachVhd(sandboxVHDXPath)
}
}()
ctx := context.Background()
layerData, err := getLayerData(ctx, cliContext.StringSlice("layer"), true)
if err != nil {
return err
}
err = computestorage.AttachLayerStorageFilter(ctx, path, *layerData)
if err != nil {
return err
}
defer func() {
if err != nil {
_ = computestorage.DetachLayerStorageFilter(ctx, path)
}
}()
// Copied out of vhd.AttachVhd
vhdHandle, err := vhd.OpenVirtualDisk(
sandboxVHDXPath,
vhd.VirtualDiskAccessNone,
vhd.OpenVirtualDiskFlagCachedIO|vhd.OpenVirtualDiskFlagIgnoreRelativeParentLocator,
)
defer windows.CloseHandle(windows.Handle(vhdHandle))
mountPath, err := computestorage.GetLayerVhdMountPath(ctx, windows.Handle(vhdHandle))
if err != nil {
return err
}
_, err = fmt.Println(mountPath)
return err
},
}
When I try the above source code, the first call for a given newly-created read-write layer fails with:
failed to get vhd mount path: The specified network resource or device is no longer available.
and then recalling it on the same layer path gives:
failed to attach layer storage filter: The parameter is incorrect.
The latter failure indicates that I managed to get some state created, that the deferred DetachLayerStorageFilter + vhd.DetachVhd isn't cleaning up.
Without the computestorage.GetLayerVhdMountPath call, the code passes, but I don't see a new volume in mountvol the way I do with the existing wclayer code, suggesting that something is not right in the VHD-management step. In that case, repeating the call for the same path gives the same "The parameter is incorrect" error, so the state I'm creating that is not being cleaned up must come from computestorage.AttachLayerStorageFilter.
I can't find any existing use-cases for AttachLayerStorageFilter to model off, so I'm just throwing code at the wall to see what sticks, and my current guess is that vhd.AttachVhd is either the wrong thing to use, or I need to call the lower-level APIs in vhd with different flags to get the VHD attached correctly.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the cmd/wclayer mount flow and compare it with internal/wclayer/activatelayer.go and preparelayer.go. Reproduce the first and repeated calls using computestorage.AttachLayerStorageFilter and GetLayerVhdMountPath, then verify VHD and volume state with mountvol; done means the read-write layer mounts successfully and cleanup permits another mount.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100