forked from microsoft/hcsshim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cimfs: Add cim layer mount/unmount functionality. (microsoft#1955)
Signed-off-by: Amit Barve <ambarve@microsoft.com>
- Loading branch information
Showing
1 changed file
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package cim | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"sync" | ||
|
||
"github.com/Microsoft/go-winio/pkg/guid" | ||
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" | ||
cimfs "github.com/Microsoft/hcsshim/pkg/cimfs" | ||
) | ||
|
||
// a cache of cim layer to its mounted volume - The mount manager plugin currently doesn't have an option of | ||
// querying a mounted cim to get the volume at which it is mounted, so we maintain a cache of that here | ||
var ( | ||
cimMounts map[string]string = make(map[string]string) | ||
cimMountMapLock sync.Mutex | ||
// A random GUID used as a namespace for generating cim mount volume GUIDs: 6827367b-c388-4e9b-95ec-961c6d2c936c | ||
cimMountNamespace guid.GUID = guid.GUID{Data1: 0x6827367b, Data2: 0xc388, Data3: 0x4e9b, Data4: [8]byte{0x96, 0x1c, 0x6d, 0x2c, 0x93, 0x6c}} | ||
) | ||
|
||
// MountCimLayer mounts the cim at path `cimPath` and returns the mount location of that cim. This method | ||
// uses the `CimMountFlagCacheFiles` mount flag when mounting the cim. The containerID is used to generated | ||
// the volumeID for the volume at which this CIM is mounted. containerID is used so that if the shim process | ||
// crashes for any reason, the mounted cim can be correctly cleaned up during `shim delete` call. | ||
func MountCimLayer(ctx context.Context, cimPath, containerID string) (string, error) { | ||
volumeGUID, err := guid.NewV5(cimMountNamespace, []byte(containerID)) | ||
if err != nil { | ||
return "", fmt.Errorf("generated cim mount GUID: %w", err) | ||
} | ||
|
||
vol, err := cimfs.Mount(cimPath, volumeGUID, hcsschema.CimMountFlagCacheFiles) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
cimMountMapLock.Lock() | ||
defer cimMountMapLock.Unlock() | ||
cimMounts[fmt.Sprintf("%s_%s", containerID, cimPath)] = vol | ||
|
||
return vol, nil | ||
} | ||
|
||
// Unmount unmounts the cim at mounted for given container. | ||
func UnmountCimLayer(ctx context.Context, cimPath, containerID string) error { | ||
cimMountMapLock.Lock() | ||
defer cimMountMapLock.Unlock() | ||
if vol, ok := cimMounts[fmt.Sprintf("%s_%s", containerID, cimPath)]; !ok { | ||
return fmt.Errorf("cim %s not mounted", cimPath) | ||
} else { | ||
delete(cimMounts, fmt.Sprintf("%s_%s", containerID, cimPath)) | ||
err := cimfs.Unmount(vol) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// GetCimMountPath returns the volume at which a cim is mounted. If the cim is not mounted returns error | ||
func GetCimMountPath(cimPath, containerID string) (string, error) { | ||
cimMountMapLock.Lock() | ||
defer cimMountMapLock.Unlock() | ||
|
||
if vol, ok := cimMounts[fmt.Sprintf("%s_%s", containerID, cimPath)]; !ok { | ||
return "", fmt.Errorf("cim %s not mounted", cimPath) | ||
} else { | ||
return vol, nil | ||
} | ||
} | ||
|
||
func CleanupContainerMounts(containerID string) error { | ||
volumeGUID, err := guid.NewV5(cimMountNamespace, []byte(containerID)) | ||
if err != nil { | ||
return fmt.Errorf("generated cim mount GUID: %w", err) | ||
} | ||
|
||
volPath := fmt.Sprintf("\\\\?\\Volume{%s}\\", volumeGUID.String()) | ||
if _, err := os.Stat(volPath); err == nil { | ||
err = cimfs.Unmount(volPath) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |