@@ -12,12 +12,14 @@ import (
1212
1313 "github.com/pkg/errors"
1414 "github.com/sirupsen/logrus"
15+ "go.opencensus.io/trace"
1516 "golang.org/x/sys/windows"
1617
1718 "github.com/Microsoft/hcsshim/computestorage"
1819 hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
1920 "github.com/Microsoft/hcsshim/internal/hcserror"
2021 "github.com/Microsoft/hcsshim/internal/log"
22+ "github.com/Microsoft/hcsshim/internal/oc"
2123 "github.com/Microsoft/hcsshim/internal/resources"
2224 "github.com/Microsoft/hcsshim/internal/uvm"
2325 "github.com/Microsoft/hcsshim/internal/uvm/scsi"
@@ -37,6 +39,11 @@ func MountWCOWLayers(ctx context.Context, containerID string, vm *uvm.UtilityVM,
3739 return mountProcessIsolatedForkedCimLayers (ctx , containerID , l )
3840 }
3941 return nil , nil , fmt .Errorf ("hyperv isolated containers aren't supported with forked cim layers" )
42+ case * wcowBlockCIMLayers :
43+ if vm == nil {
44+ return mountProcessIsolatedBlockCIMLayers (ctx , containerID , l )
45+ }
46+ return nil , nil , fmt .Errorf ("hyperv isolated containers aren't supported with block cim layers" )
4047 default :
4148 return nil , nil , fmt .Errorf ("invalid layer type %T" , wl )
4249 }
@@ -171,53 +178,43 @@ func mountProcessIsolatedWCIFSLayers(ctx context.Context, l *wcowWCIFSLayers) (_
171178 }, nil
172179}
173180
174- // wcowHostForkedCIMLayerCloser is used to cleanup forked CIM layers mounted on the host for process isolated
175- // containers
176- type wcowHostForkedCIMLayerCloser struct {
177- scratchLayerData
178- containerID string
179- }
180-
181- func (l * wcowHostForkedCIMLayerCloser ) Release (ctx context.Context ) error {
182- mountPath , err := wclayer .GetLayerMountPath (ctx , l .scratchLayerPath )
183- if err != nil {
184- return err
185- }
186-
187- if err = computestorage .DetachOverlayFilter (ctx , mountPath , hcsschema .UnionFS ); err != nil {
188- return err
189- }
190-
191- if err = cimlayer .CleanupContainerMounts (l .containerID ); err != nil {
192- return err
193- }
194- return wclayer .DeactivateLayer (ctx , l .scratchLayerPath )
195- }
181+ // Handles the common processing for mounting all 3 types of cimfs layers. This involves
182+ // mounting the scratch, attaching the filter and preparing the return values.
183+ // `volume` is the path to the volume at which read only layer CIMs are mounted.
184+ func mountProcessIsolatedCimLayersCommon (ctx context.Context , containerID string , volume string , s * scratchLayerData ) (_ * MountedWCOWLayers , _ resources.ResourceCloser , err error ) {
185+ ctx , span := oc .StartSpan (ctx , "mountProcessIsolatedCimLayersCommon" )
186+ defer func () {
187+ oc .SetSpanStatus (span , err )
188+ span .End ()
189+ }()
190+ span .AddAttributes (
191+ trace .StringAttribute ("scratch path" , s .scratchLayerPath ),
192+ trace .StringAttribute ("mounted CIM volume" , volume ))
196193
197- func mountProcessIsolatedForkedCimLayers (ctx context.Context , containerID string , l * wcowForkedCIMLayers ) (_ * MountedWCOWLayers , _ resources.ResourceCloser , err error ) {
198- if err = wclayer .ActivateLayer (ctx , l .scratchLayerPath ); err != nil {
199- return nil , nil , err
200- }
194+ rcl := & resources.ResourceCloserList {}
201195 defer func () {
202196 if err != nil {
203- _ = wclayer .DeactivateLayer (ctx , l .scratchLayerPath )
197+ if rErr := rcl .Release (ctx ); rErr != nil {
198+ log .G (ctx ).WithError (err ).Warnf ("mount process isolated cim layers common, undo failed with: %s" , rErr )
199+ }
204200 }
205201 }()
206202
207- mountPath , err := wclayer .GetLayerMountPath (ctx , l .scratchLayerPath )
208- if err != nil {
203+ if err = wclayer .ActivateLayer (ctx , s .scratchLayerPath ); err != nil {
209204 return nil , nil , err
210205 }
206+ rcl .AddFunc (func (uCtx context.Context ) error {
207+ return wclayer .DeactivateLayer (uCtx , s .scratchLayerPath )
208+ })
211209
212- volume , err := cimlayer . MountForkedCimLayer (ctx , l . layers [ 0 ]. cimPath , containerID )
210+ mountPath , err := wclayer . GetLayerMountPath (ctx , s . scratchLayerPath )
213211 if err != nil {
214- return nil , nil , fmt . Errorf ( "mount layer cim: %w" , err )
212+ return nil , nil , err
215213 }
216- defer func () {
217- if err != nil {
218- _ = cimlayer .UnmountCimLayer (ctx , volume )
219- }
220- }()
214+ log .G (ctx ).WithFields (logrus.Fields {
215+ "scratch" : s .scratchLayerPath ,
216+ "mounted path" : mountPath ,
217+ }).Debug ("scratch activated" )
221218
222219 layerID , err := cimlayer .LayerID (volume )
223220 if err != nil {
@@ -239,22 +236,97 @@ func mountProcessIsolatedForkedCimLayers(ctx context.Context, containerID string
239236 if err = computestorage .AttachOverlayFilter (ctx , mountPath , layerData ); err != nil {
240237 return nil , nil , err
241238 }
239+ rcl .AddFunc (func (uCtx context.Context ) error {
240+ return computestorage .DetachOverlayFilter (uCtx , mountPath , hcsschema .UnionFS )
241+ })
242+
243+ log .G (ctx ).WithField ("layer data" , layerData ).Debug ("unionFS filter attached" )
244+
245+ return & MountedWCOWLayers {
246+ RootFS : mountPath ,
247+ MountedLayerPaths : []MountedWCOWLayer {{
248+ LayerID : layerID ,
249+ MountedPath : volume ,
250+ }},
251+ }, rcl , nil
252+ }
253+
254+ func mountProcessIsolatedForkedCimLayers (ctx context.Context , containerID string , l * wcowForkedCIMLayers ) (_ * MountedWCOWLayers , _ resources.ResourceCloser , err error ) {
255+ ctx , span := oc .StartSpan (ctx , "mountProcessIsolatedForkedCimLayers" )
256+ defer func () {
257+ oc .SetSpanStatus (span , err )
258+ span .End ()
259+ }()
260+
261+ rcl := & resources.ResourceCloserList {}
262+ defer func () {
263+ if err != nil {
264+ if rErr := rcl .Release (ctx ); rErr != nil {
265+ log .G (ctx ).WithError (err ).Warnf ("mount process isolated forked CIM layers, undo failed with: %s" , rErr )
266+ }
267+ }
268+ }()
269+
270+ volume , err := cimlayer .MountForkedCimLayer (ctx , l .layers [0 ].cimPath , containerID )
271+ if err != nil {
272+ return nil , nil , fmt .Errorf ("mount forked layer cim: %w" , err )
273+ }
274+ rcl .AddFunc (func (uCtx context.Context ) error {
275+ return cimlayer .UnmountCimLayer (uCtx , volume )
276+ })
277+
278+ mountedLayers , closer , err := mountProcessIsolatedCimLayersCommon (ctx , containerID , volume , & l .scratchLayerData )
279+ if err != nil {
280+ return nil , nil , err
281+ }
282+ return mountedLayers , rcl .Add (closer ), nil
283+ }
284+
285+ func mountProcessIsolatedBlockCIMLayers (ctx context.Context , containerID string , l * wcowBlockCIMLayers ) (_ * MountedWCOWLayers , _ resources.ResourceCloser , err error ) {
286+ ctx , span := oc .StartSpan (ctx , "mountProcessIsolatedBlockCIMLayers" )
287+ defer func () {
288+ oc .SetSpanStatus (span , err )
289+ span .End ()
290+ }()
291+
292+ var volume string
293+
294+ rcl := & resources.ResourceCloserList {}
242295 defer func () {
243296 if err != nil {
244- _ = computestorage .DetachOverlayFilter (ctx , mountPath , hcsschema .UnionFS )
297+ if rErr := rcl .Release (ctx ); rErr != nil {
298+ log .G (ctx ).WithError (err ).Warnf ("mount process isolated forked CIM layers, undo failed with: %s" , rErr )
299+ }
245300 }
246301 }()
247302
248- return & MountedWCOWLayers {
249- RootFS : mountPath ,
250- MountedLayerPaths : []MountedWCOWLayer {{
251- LayerID : layerID ,
252- MountedPath : volume ,
253- }},
254- }, & wcowHostForkedCIMLayerCloser {
255- containerID : containerID ,
256- scratchLayerData : l .scratchLayerData ,
257- }, nil
303+ log .G (ctx ).WithFields (logrus.Fields {
304+ "scratch" : l .scratchLayerPath ,
305+ "merged layer" : l .mergedLayer ,
306+ "parent layers" : l .parentLayers ,
307+ }).Debug ("mounting process isolated block CIM layers" )
308+
309+ if len (l .parentLayers ) > 1 {
310+ volume , err = cimlayer .MergeMountBlockCIMLayer (ctx , l .mergedLayer , l .parentLayers , containerID )
311+ } else {
312+ volume , err = cimlayer .MountBlockCIMLayer (ctx , l .parentLayers [0 ], containerID )
313+ }
314+ if err != nil {
315+ return nil , nil , fmt .Errorf ("mount block CIM layers: %w" , err )
316+ }
317+ rcl .AddFunc (func (uCtx context.Context ) error {
318+ return cimlayer .UnmountCimLayer (uCtx , volume )
319+ })
320+
321+ log .G (ctx ).WithField ("volume" , volume ).Debug ("mounted blockCIM layers for process isolated container" )
322+
323+ mountedLayers , layerCloser , err := mountProcessIsolatedCimLayersCommon (ctx , containerID , volume , & l .scratchLayerData )
324+ if err != nil {
325+ return nil , nil , fmt .Errorf ("failed mount CIM layers common: %w" , err )
326+ }
327+ rcl .Add (layerCloser )
328+
329+ return mountedLayers , rcl , nil
258330}
259331
260332type wcowIsolatedWCIFSLayerCloser struct {
0 commit comments