[lxc-devel] [lxd/master] Fix Ceph storage issues

stgraber on Github lxc-bot at linuxcontainers.org
Sat Feb 22 06:20:29 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200221/41f1ddaf/attachment.bin>
-------------- next part --------------
From 835bd66260e8447e4c421faaac06ed46d8af5cac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 22 Feb 2020 01:17:00 -0500
Subject: [PATCH 1/3] lxd/vm: Fix snapshots
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/instance/drivers/driver_qemu.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 010e56f111..0ceba5bca9 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -239,7 +239,7 @@ func qemuCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error)
 	}
 
 	// Create a new database entry for the instance's storage volume.
-	_, err = s.Cluster.StoragePoolVolumeCreate(args.Project, args.Name, "", db.StoragePoolVolumeTypeVM, false, poolID, volumeConfig)
+	_, err = s.Cluster.StoragePoolVolumeCreate(args.Project, args.Name, "", db.StoragePoolVolumeTypeVM, vm.IsSnapshot(), poolID, volumeConfig)
 	if err != nil {
 		return nil, err
 	}

From 41bda77336dda1f3956a81af032fa9a96e43424a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 22 Feb 2020 01:17:38 -0500
Subject: [PATCH 2/3] lxd/storage/ceph: Fix leftover rbd
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_ceph_volumes.go | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/lxd/storage/drivers/driver_ceph_volumes.go b/lxd/storage/drivers/driver_ceph_volumes.go
index 5e36a24fce..93bd1cd7e7 100644
--- a/lxd/storage/drivers/driver_ceph_volumes.go
+++ b/lxd/storage/drivers/driver_ceph_volumes.go
@@ -240,15 +240,6 @@ func (d *ceph) CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots boo
 			}
 		}
 
-		ourMount, err := d.MountVolume(vol, op)
-		if err != nil {
-			return err
-		}
-
-		if ourMount {
-			defer d.UnmountVolume(vol, op)
-		}
-
 		// For VMs, also copy the filesystem volume.
 		if vol.IsVMBlock() {
 			srcFSVol := srcVol.NewVMBlockFilesystemVolume()

From fe9545f438c923b34e6d0f73f3d00dcfce93646c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 22 Feb 2020 01:18:10 -0500
Subject: [PATCH 3/3] lxd/storage/ceph: Fix zombie handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_ceph_utils.go   | 21 +++++-----
 lxd/storage/drivers/driver_ceph_volumes.go | 46 ++++++++++++++--------
 2 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/lxd/storage/drivers/driver_ceph_utils.go b/lxd/storage/drivers/driver_ceph_utils.go
index 19039b211b..d3ecf1dd69 100644
--- a/lxd/storage/drivers/driver_ceph_utils.go
+++ b/lxd/storage/drivers/driver_ceph_utils.go
@@ -201,6 +201,7 @@ again:
 				}
 			}
 		}
+
 		return err
 	}
 
@@ -345,12 +346,9 @@ func (d *ceph) rbdListSnapshotClones(vol Volume, snapshotName string) ([]string,
 // RBD storage volume has protected snapshots; a scenario most common when
 // creating a sparse copy of a container or when LXD updated an image and the
 // image still has dependent container clones.
-func (d *ceph) rbdMarkVolumeDeleted(vol Volume, newVolumeName string, suffix string) error {
+func (d *ceph) rbdMarkVolumeDeleted(vol Volume, newVolumeName string) error {
 	newVol := NewVolume(d, d.name, vol.volType, vol.contentType, newVolumeName, nil, nil)
 	deletedName := d.getRBDVolumeName(newVol, "", true, true)
-	if suffix != "" {
-		deletedName = fmt.Sprintf("%s_%s", deletedName, suffix)
-	}
 	_, err := shared.RunCommand(
 		"rbd",
 		"--id", d.config["ceph.user.name"],
@@ -659,9 +657,8 @@ func (d *ceph) deleteVolume(vol Volume) (int, error) {
 				return 1, nil
 			}
 
-			newVolumeName := fmt.Sprintf("%s_%s", vol.name,
-				uuid.NewRandom().String())
-			err := d.rbdMarkVolumeDeleted(vol, newVolumeName, "")
+			newVolumeName := fmt.Sprintf("%s_%s", vol.name, uuid.NewRandom().String())
+			err := d.rbdMarkVolumeDeleted(vol, newVolumeName)
 			if err != nil {
 				return -1, err
 			}
@@ -837,14 +834,12 @@ func (d *ceph) deleteVolumeSnapshot(vol Volume, snapshotName string) (int, error
 			return 1, nil
 		}
 
-		err := d.rbdUnmapVolumeSnapshot(vol, snapshotName,
-			true)
+		err := d.rbdUnmapVolumeSnapshot(vol, snapshotName, true)
 		if err != nil {
 			return -1, err
 		}
 
-		newSnapshotName := fmt.Sprintf("zombie_%s", snapshotName)
-
+		newSnapshotName := fmt.Sprintf("zombie_snapshot_%s", uuid.NewRandom().String())
 		err = d.rbdRenameVolumeSnapshot(vol, snapshotName, newSnapshotName)
 		if err != nil {
 			return -1, err
@@ -1073,6 +1068,10 @@ func (d *ceph) getRBDVolumeName(vol Volume, snapName string, zombie bool, withPo
 	volumeType := string(vol.volType)
 	parentName, snapshotName, isSnapshot := shared.InstanceGetParentAndSnapshotName(vol.name)
 
+	if vol.volType == VolumeTypeImage {
+		parentName = fmt.Sprintf("%s_%s", parentName, d.getRBDFilesystem(vol))
+	}
+
 	if (vol.volType == VolumeTypeVM || vol.volType == VolumeTypeImage) && vol.contentType == ContentTypeBlock {
 		parentName = fmt.Sprintf("%s.block", parentName)
 	}
diff --git a/lxd/storage/drivers/driver_ceph_volumes.go b/lxd/storage/drivers/driver_ceph_volumes.go
index 93bd1cd7e7..645491fe9d 100644
--- a/lxd/storage/drivers/driver_ceph_volumes.go
+++ b/lxd/storage/drivers/driver_ceph_volumes.go
@@ -36,16 +36,22 @@ func (d *ceph) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Ope
 		revert.Add(func() { os.Remove(vol.MountPath()) })
 	}
 
+	// Figure out the potential zombie volume.
 	zombieImageVol := NewVolume(d, d.name, VolumeType("zombie_image"), vol.contentType,
 		fmt.Sprintf("%s_%s", vol.name, d.getRBDFilesystem(vol)), nil, nil)
+	if (vol.volType == VolumeTypeVM || vol.volType == VolumeTypeImage) && vol.contentType == ContentTypeBlock {
+		zombieImageVol = NewVolume(d, d.name, VolumeType("zombie_image"), vol.contentType,
+			fmt.Sprintf("%s_%s.block", vol.name, d.getRBDFilesystem(vol)), nil, nil)
+	}
 
 	// Check if we have a zombie image. If so, restore it otherwise
 	// create a new image volume.
 	if vol.volType == VolumeTypeImage && d.HasVolume(zombieImageVol) {
-		// Unmark deleted.
+		// Figure out the names.
 		oldName := d.getRBDVolumeName(zombieImageVol, "", false, true)
 		newName := d.getRBDVolumeName(vol, "", false, true)
 
+		// Rename back to active.
 		_, err := shared.RunCommand(
 			"rbd",
 			"--id", d.config["ceph.user.name"],
@@ -57,6 +63,18 @@ func (d *ceph) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Ope
 			return err
 		}
 
+		// For VMs, also create the filesystem volume.
+		if vol.IsVMBlock() {
+			fsVol := vol.NewVMBlockFilesystemVolume()
+
+			err := d.CreateVolume(fsVol, nil, op)
+			if err != nil {
+				return err
+			}
+
+			revert.Add(func() { d.DeleteVolume(fsVol, op) })
+		}
+
 		revert.Success()
 		return nil
 	}
@@ -485,7 +503,7 @@ func (d *ceph) DeleteVolume(vol Volume, op *operations.Operation) error {
 				return err
 			}
 
-			err = d.rbdMarkVolumeDeleted(vol, vol.name, vol.config["block.filesystem"])
+			err = d.rbdMarkVolumeDeleted(vol, vol.name)
 		}
 		if err != nil {
 			return err
@@ -694,7 +712,7 @@ func (d *ceph) MountVolume(vol Volume, op *operations.Operation) (bool, error) {
 
 // UnmountVolume simulates unmounting a volume.
 func (d *ceph) UnmountVolume(vol Volume, op *operations.Operation) (bool, error) {
-	// For VMs, also mount the filesystem dataset.
+	// For VMs, also unmount the filesystem dataset.
 	if vol.IsVMBlock() {
 		fsVol := vol.NewVMBlockFilesystemVolume()
 
@@ -704,23 +722,19 @@ func (d *ceph) UnmountVolume(vol Volume, op *operations.Operation) (bool, error)
 		}
 	}
 
+	// Attempt to unmount the volume.
 	mountPath := vol.MountPath()
-
-	if !shared.IsMountPoint(mountPath) {
-		return false, nil
-	}
-
-	err := TryUnmount(mountPath, unix.MNT_DETACH)
-	if err != nil {
-		return false, err
+	if shared.IsMountPoint(mountPath) {
+		err := TryUnmount(mountPath, unix.MNT_DETACH)
+		if err != nil {
+			return false, err
+		}
 	}
 
 	// Attempt to unmap.
-	if vol.volType == VolumeTypeCustom {
-		err = d.rbdUnmapVolume(vol, true)
-		if err != nil {
-			return true, err
-		}
+	err := d.rbdUnmapVolume(vol, true)
+	if err != nil {
+		return true, err
 	}
 
 	return true, nil


More information about the lxc-devel mailing list