From ed3de0e40caeb004ab960468339ca81f54bf3309 Mon Sep 17 00:00:00 2001 From: Amit Barve Date: Mon, 20 Nov 2023 09:40:14 -0800 Subject: [PATCH] Don't create container scratch per base layer For WCIFS based layers, a container scratch base VHD (and a differencing VHD) both are created per unique base layer. This is because we add reparse points for the base layer files inside the VHD. However, with UnionFS we don't add any reparse points and the VHD is empty, so we don't need to create a VHD per unique base layer. Now the CimFS snapshotter will handle container scratch VHD creation and the LayerWriter will only created a VHD for the UtilityVM. (The UtilityVM VHD still needs to be created per unique base layer since the BCD of that layer is configured to boot from the UtilityVM VHD and the BCD is unique per image) Signed-off-by: Amit Barve --- internal/wclayer/cim/process.go | 97 +++------------------------------ 1 file changed, 8 insertions(+), 89 deletions(-) diff --git a/internal/wclayer/cim/process.go b/internal/wclayer/cim/process.go index efce1251f0..efd65d2aee 100644 --- a/internal/wclayer/cim/process.go +++ b/internal/wclayer/cim/process.go @@ -22,77 +22,14 @@ import ( const defaultVHDXBlockSizeInMB = 1 -func createContainerBaseLayerVHDs(ctx context.Context, layerPath string) (err error) { - baseVhdPath := filepath.Join(layerPath, wclayer.ContainerBaseVhd) - diffVhdPath := filepath.Join(layerPath, wclayer.ContainerScratchVhd) - defaultVhdSize := uint64(20) - - if _, err := os.Stat(baseVhdPath); err == nil { - if err := os.RemoveAll(baseVhdPath); err != nil { - return fmt.Errorf("failed to remove base vhdx path: %w", err) - } - } - if _, err := os.Stat(diffVhdPath); err == nil { - if err := os.RemoveAll(diffVhdPath); err != nil { - return fmt.Errorf("failed to remove differencing vhdx: %w", err) - } - } - - createParams := &vhd.CreateVirtualDiskParameters{ - Version: 2, - Version2: vhd.CreateVersion2{ - MaximumSize: defaultVhdSize * memory.GiB, - BlockSizeInBytes: defaultVHDXBlockSizeInMB * memory.MiB, - }, - } - handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams) - if err != nil { - return fmt.Errorf("failed to create vhdx: %w", err) - } - - defer func() { - if err != nil { - os.RemoveAll(baseVhdPath) - os.RemoveAll(diffVhdPath) - } - }() - - err = computestorage.FormatWritableLayerVhd(ctx, windows.Handle(handle)) - // we always wanna close the handle whether format succeeds for not. - closeErr := syscall.CloseHandle(handle) - if err != nil { - return err - } else if closeErr != nil { - return fmt.Errorf("failed to close vhdx handle: %w", closeErr) - } - - // Create the differencing disk that will be what's copied for the final rw layer - // for a container. - if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil { - return fmt.Errorf("failed to create differencing disk: %w", err) - } - - if err = security.GrantVmGroupAccess(baseVhdPath); err != nil { - return fmt.Errorf("failed to grant vm group access to %s: %w", baseVhdPath, err) - } - if err = security.GrantVmGroupAccess(diffVhdPath); err != nil { - return fmt.Errorf("failed to grant vm group access to %s: %w", diffVhdPath, err) - } - return nil -} - -// processUtilityVMLayer is similar to createContainerBaseLayerVHDs but along with the scratch creation it -// also does some BCD modifications to allow the UVM to boot from the CIM. It expects that the UVM BCD file is -// present at layerPath/`wclayer.BcdFilePath` and a UVM SYSTEM hive is present at -// layerPath/UtilityVM/`wclayer.RegFilesPath`/SYSTEM. The scratch VHDs are created under the `layerPath` -// directory. +// processUtilityVMLayer creates a base VHD for the UtilityVM's scratch. Configures the BCD file at path +// "layerPath/`wclayer.BcdFilePath`" to make the UVM boot from this base VHD. Also, configures the UVM's +// SYSTEM hive at path "layerPath/UtilityVM/`wclayer.RegFilesPath`/SYSTEM" to specify that the UVM is booting +// from a CIM. func processUtilityVMLayer(ctx context.Context, layerPath string) error { - // func createUtilityVMLayerVHDs(ctx context.Context, layerPath string) error { baseVhdPath := filepath.Join(layerPath, wclayer.UtilityVMPath, wclayer.UtilityVMBaseVhd) - diffVhdPath := filepath.Join(layerPath, wclayer.UtilityVMPath, wclayer.UtilityVMScratchVhd) defaultVhdSize := uint64(10) - // Just create the vhdx for utilityVM layer, no need to format it. createParams := &vhd.CreateVirtualDiskParameters{ Version: 2, Version2: vhd.CreateVersion2{ @@ -109,7 +46,6 @@ func processUtilityVMLayer(ctx context.Context, layerPath string) error { defer func() { if err != nil { os.RemoveAll(baseVhdPath) - os.RemoveAll(diffVhdPath) } }() @@ -121,6 +57,10 @@ func processUtilityVMLayer(ctx context.Context, layerPath string) error { return fmt.Errorf("failed to close vhdx handle: %w", closeErr) } + if err := security.GrantVmGroupAccess(baseVhdPath); err != nil { + return fmt.Errorf("failed to grant vm group access to %s: %w", baseVhdPath, err) + } + partitionInfo, err := vhdx.GetScratchVhdPartitionInfo(ctx, baseVhdPath) if err != nil { return fmt.Errorf("failed to get base vhd layout info: %w", err) @@ -138,23 +78,6 @@ func processUtilityVMLayer(ctx context.Context, layerPath string) error { return fmt.Errorf("failed to setup cim image for uvm boot: %w", err) } - // Note: diff vhd creation and granting of vm group access must be done AFTER - // getting the partition info of the base VHD. Otherwise it causes the vhd parent - // chain to get corrupted. - // TODO(ambarve): figure out why this happens so that bcd update can be moved to a separate function - - // Create the differencing disk that will be what's copied for the final rw layer - // for a container. - if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil { - return fmt.Errorf("failed to create differencing disk: %w", err) - } - - if err := security.GrantVmGroupAccess(baseVhdPath); err != nil { - return fmt.Errorf("failed to grant vm group access to %s: %w", baseVhdPath, err) - } - if err := security.GrantVmGroupAccess(diffVhdPath); err != nil { - return fmt.Errorf("failed to grant vm group access to %s: %w", diffVhdPath, err) - } return nil } @@ -228,10 +151,6 @@ func processLayoutFile(layerPath string) ([]pendingCimOp, error) { // inside the cim, some registry file links must be updated. This function takes care of all those // steps. This function opens the cim file for writing and updates it. func (cw *CimLayerWriter) processBaseLayer(ctx context.Context, processUtilityVM bool) (err error) { - if err = createContainerBaseLayerVHDs(ctx, cw.path); err != nil { - return fmt.Errorf("failed to create container base VHDs: %w", err) - } - if processUtilityVM { if err = processUtilityVMLayer(ctx, cw.path); err != nil { return fmt.Errorf("process utilityVM layer: %w", err)