diff --git a/pkg/dmlegacy/cleanup/deactivate.go b/pkg/dmlegacy/cleanup/deactivate.go index 54fd828ae..2598e5d12 100644 --- a/pkg/dmlegacy/cleanup/deactivate.go +++ b/pkg/dmlegacy/cleanup/deactivate.go @@ -9,7 +9,8 @@ import ( func DeactivateSnapshot(vm *api.VM) error { dmArgs := []string{ "remove", - vm.SnapshotDev(), + "--verifyudev", // if udevd is not running, dmsetup will manage the device node in /dev/mapper + util.NewPrefixer().Prefix(vm.GetUID()), } // If the base device is visible in "dmsetup", we should remove it diff --git a/pkg/dmlegacy/loopdev.go b/pkg/dmlegacy/loopdev.go index 59f80e458..2c5e3872d 100644 --- a/pkg/dmlegacy/loopdev.go +++ b/pkg/dmlegacy/loopdev.go @@ -36,7 +36,11 @@ func (ld *loopDevice) Size512K() (uint64, error) { // dmsetup uses stdin to read multiline tables, this is a helper function for that func runDMSetup(name string, table []byte) error { - cmd := exec.Command("dmsetup", "create", name) + cmd := exec.Command( + "dmsetup", "create", + "--verifyudev", // if udevd is not running, dmsetup will manage the device node in /dev/mapper + name, + ) stdin, err := cmd.StdinPipe() if err != nil { return err @@ -52,7 +56,7 @@ func runDMSetup(name string, table []byte) error { out, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("command %q exited with %q: %v", cmd.Args, out, err) + return fmt.Errorf("command %q exited with %q: %w", cmd.Args, out, err) } return nil diff --git a/pkg/dmlegacy/snapshot.go b/pkg/dmlegacy/snapshot.go index 86c39fa52..24b9e57f9 100644 --- a/pkg/dmlegacy/snapshot.go +++ b/pkg/dmlegacy/snapshot.go @@ -17,10 +17,11 @@ import ( const snapshotLockFileName = "ignite-snapshot.lock" -// ActivateSnapshot sets up the snapshot with devicemapper so that it is active and can be used -func ActivateSnapshot(vm *api.VM) (err error) { +// ActivateSnapshot sets up the snapshot with devicemapper so that it is active and can be used. +// It returns the path of the bootable snapshot device. +func ActivateSnapshot(vm *api.VM) (devicePath string, err error) { device := util.NewPrefixer().Prefix(vm.GetUID()) - devicePath := vm.SnapshotDev() + devicePath = vm.SnapshotDev() // Return if the snapshot is already setup if util.FileExists(devicePath) { @@ -47,7 +48,8 @@ func ActivateSnapshot(vm *api.VM) (err error) { // Create a lockfile and obtain a lock. lock, err := lockfile.New(glpath) if err != nil { - return fmt.Errorf("failed to create lock: %v", err) + err = fmt.Errorf("failed to create lockfile: %w", err) + return } if err = obtainLock(lock); err != nil { return @@ -105,6 +107,7 @@ func ActivateSnapshot(vm *api.VM) (err error) { // "0 8388608 snapshot /dev/{loop0,mapper/ignite--base} /dev/loop1 P 8" dmTable := []byte(fmt.Sprintf("0 %d snapshot %s %s P 8", overlayLoopSize, basePath, overlayLoop.Path())) + // setup the main boot device if err = runDMSetup(device, dmTable); err != nil { return } diff --git a/pkg/dmlegacy/vm.go b/pkg/dmlegacy/vm.go index b4eb368cb..737835ef3 100644 --- a/pkg/dmlegacy/vm.go +++ b/pkg/dmlegacy/vm.go @@ -83,7 +83,7 @@ func AllocateAndPopulateOverlay(vm *api.VM) error { } func copyToOverlay(vm *api.VM) (err error) { - err = ActivateSnapshot(vm) + _, err = ActivateSnapshot(vm) if err != nil { return } diff --git a/pkg/operations/remove.go b/pkg/operations/remove.go index ba0d94abe..d67f0205f 100644 --- a/pkg/operations/remove.go +++ b/pkg/operations/remove.go @@ -48,7 +48,7 @@ func CleanupVM(vm *api.VM) error { // TODO should this function return a proper error? RemoveVMContainer(inspectResult) - // After remove the VM container, and the SnapshotDev still there + // After removing the VM container, if the Snapshot Device is still there, clean up if _, err := os.Stat(vm.SnapshotDev()); err == nil { // try remove it again with DeactivateSnapshot if err := cleanup.DeactivateSnapshot(vm); err != nil { diff --git a/pkg/operations/start.go b/pkg/operations/start.go index 21edde5af..12cce4ccb 100644 --- a/pkg/operations/start.go +++ b/pkg/operations/start.go @@ -25,7 +25,8 @@ func StartVM(vm *api.VM, debug bool) error { RemoveVMContainer(inspectResult) // Setup the snapshot overlay filesystem - if err := dmlegacy.ActivateSnapshot(vm); err != nil { + snapshotDevPath, err := dmlegacy.ActivateSnapshot(vm) + if err != nil { return err } @@ -70,7 +71,7 @@ func StartVM(vm *api.VM, debug bool) error { runtime.BindBoth("/dev/mapper/control"), // This enables containerized Ignite to remove its own dm snapshot runtime.BindBoth("/dev/net/tun"), // Needed for creating TAP adapters runtime.BindBoth("/dev/kvm"), // Pass through virtualization support - runtime.BindBoth(vm.SnapshotDev()), // The block device to boot from + runtime.BindBoth(snapshotDevPath), // The block device to boot from }, StopTimeout: constants.STOP_TIMEOUT + constants.IGNITE_TIMEOUT, PortBindings: vm.Spec.Network.Ports, // Add the port mappings to Docker