[lxc-devel] [lxd/master] Better handle UUID regeneration on CEPH

stgraber on Github lxc-bot at linuxcontainers.org
Fri Apr 26 16:58:54 UTC 2019


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/20190426/affe22fa/attachment.bin>
-------------- next part --------------
From 3f437dae6b8e8645cb986e559bd8d72127b8a18d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 26 Apr 2019 12:51:18 -0400
Subject: [PATCH 1/2] lxd/storage: Handle XFS with leftover journal entries

---
 lxd/storage_utils.go | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/lxd/storage_utils.go b/lxd/storage_utils.go
index d798a4d170..10bcbfc6c7 100644
--- a/lxd/storage_utils.go
+++ b/lxd/storage_utils.go
@@ -230,16 +230,28 @@ func fsGenerateNewUUID(fstype string, lvpath string) (string, error) {
 	return "", nil
 }
 
-func xfsGenerateNewUUID(lvpath string) (string, error) {
-	msg, err := shared.RunCommand(
-		"xfs_admin",
-		"-U", "generate",
-		lvpath)
+func xfsGenerateNewUUID(devPath string) (string, error) {
+	// Attempt to generate a new UUID
+	msg, err := shared.RunCommand("xfs_admin", "-U", "generate", devPath)
 	if err != nil {
 		return msg, err
 	}
 
-	return "", nil
+	if msg != "" {
+		// Exit 0 with a msg usually means some log entry getting in the way
+		msg, err = shared.RunCommand("xfs_repair", "-L", devPath)
+		if err != nil {
+			return msg, err
+		}
+
+		// Attempt to generate a new UUID again
+		msg, err = shared.RunCommand("xfs_admin", "-U", "generate", devPath)
+		if err != nil {
+			return msg, err
+		}
+	}
+
+	return msg, nil
 }
 
 func btrfsGenerateNewUUID(lvpath string) (string, error) {
@@ -252,7 +264,7 @@ func btrfsGenerateNewUUID(lvpath string) (string, error) {
 		return msg, err
 	}
 
-	return "", nil
+	return msg, nil
 }
 
 func growFileSystem(fsType string, devPath string, mntpoint string) error {

From 72a102dc6f3c9d119178d6e4db171de9fa0411d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 26 Apr 2019 12:51:32 -0400
Subject: [PATCH 2/2] lxd/storage/ceph: Fix UUID re-generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #5701

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_ceph.go           | 55 +++++++++------------------
 lxd/storage_ceph_migration.go |  6 +++
 lxd/storage_ceph_utils.go     | 70 ++++++++++++-----------------------
 3 files changed, 47 insertions(+), 84 deletions(-)

diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 976867f7a2..af574e0529 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -903,37 +903,13 @@ func (s *storageCeph) ContainerCreateFromImage(container container, fingerprint
 		}
 	}()
 
-	RBDDevPath, err := cephRBDVolumeMap(s.ClusterName, s.OSDPoolName,
-		volumeName, storagePoolVolumeTypeNameContainer, s.UserName)
-	if err != nil {
-		logger.Errorf(`Failed to map RBD storage volume for container "%s"`, containerName)
-		return err
-	}
-	logger.Debugf(`Mapped RBD storage volume for container "%s"`,
-		containerName)
-
-	defer func() {
-		if !revert {
-			return
-		}
-
-		err := cephRBDVolumeUnmap(s.ClusterName, s.OSDPoolName,
-			volumeName, storagePoolVolumeTypeNameContainer,
-			s.UserName, true)
-		if err != nil {
-			logger.Warnf(`Failed to unmap RBD storage volume for container "%s": %s`, containerName, err)
-		}
-	}()
-
-	// Generate a new xfs's UUID
-	RBDFilesystem := s.getRBDFilesystem()
-
-	msg, err := fsGenerateNewUUID(RBDFilesystem, RBDDevPath)
+	// Re-generate the UUID
+	err = s.cephRBDGenerateUUID(volumeName, storagePoolVolumeTypeNameContainer)
 	if err != nil {
-		logger.Errorf("Failed to create new \"%s\" UUID for container \"%s\" on storage pool \"%s\": %s", RBDFilesystem, containerName, s.pool.Name, msg)
 		return err
 	}
 
+	// Create the mountpoint
 	privileged := container.IsPrivileged()
 	err = createContainerMountpoint(containerPoolVolumeMntPoint,
 		containerPath, privileged)
@@ -1193,6 +1169,12 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 			return err
 		}
 
+		// Re-generate the UUID
+		err := s.cephRBDGenerateUUID(projectPrefix(target.Project(), target.Name()), storagePoolVolumeTypeNameContainer)
+		if err != nil {
+			return err
+		}
+
 		logger.Debugf(`Copied RBD container storage %s to %s`,
 			sourceContainerName, target.Name())
 		return nil
@@ -1359,24 +1341,17 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 		}
 		logger.Debugf(`Copied RBD container storage %s to %s`, sourceVolumeName, targetVolumeName)
 
-		// Note, we don't need to register another cleanup function for
-		// the actual container's storage volume since we already
-		// registered one above for the dummy volume we created.
-
-		// map the container's volume
-		_, err = cephRBDVolumeMap(s.ClusterName, s.OSDPoolName,
-			projectPrefix(target.Project(), targetContainerName), storagePoolVolumeTypeNameContainer,
-			s.UserName)
+		// Re-generate the UUID
+		err := s.cephRBDGenerateUUID(projectPrefix(target.Project(), targetContainerName), storagePoolVolumeTypeNameContainer)
 		if err != nil {
-			logger.Errorf(`Failed to map RBD storage volume for container "%s" on storage pool "%s": %s`, targetContainerName, s.pool.Name, err)
 			return err
 		}
-		logger.Debugf(`Mapped RBD storage volume for container "%s" on storage pool "%s"`, targetContainerName, s.pool.Name)
 
 		logger.Debugf(`Created non-sparse copy of RBD storage volume for container "%s" to "%s" including snapshots`,
 			sourceContainerName, targetContainerName)
 	}
 
+	// Mount the container
 	ourMount, err := s.ContainerMount(target)
 	if err != nil {
 		return err
@@ -1658,6 +1633,12 @@ func (s *storageCeph) ContainerRestore(target container, source container) error
 		return err
 	}
 
+	// Re-generate the UUID
+	err = s.cephRBDGenerateUUID(projectPrefix(target.Project(), target.Name()), storagePoolVolumeTypeNameContainer)
+	if err != nil {
+		return err
+	}
+
 	logger.Debugf(`Restored RBD storage volume for container "%s" from %s to %s`, targetName, sourceName, targetName)
 	return nil
 }
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index 1411f76e19..899a356aed 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -344,6 +344,12 @@ func (s *storageCeph) MigrationSink(conn *websocket.Conn, op *operation, args Mi
 		logger.Debugf(`Received RBD storage volume "%s"`, recvName)
 	}
 
+	// Re-generate the UUID
+	err = s.cephRBDGenerateUUID(projectPrefix(args.Container.Project(), args.Container.Name()), storagePoolVolumeTypeNameContainer)
+	if err != nil {
+		return err
+	}
+
 	containerMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
 	err = createContainerMountpoint(
 		containerMntPoint,
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index b283b0af26..abe9bdc4af 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -814,23 +814,13 @@ func (s *storageCeph) copyWithoutSnapshotsSparse(target container,
 		return err
 	}
 
-	RBDDevPath, err := cephRBDVolumeMap(s.ClusterName, s.OSDPoolName,
-		targetContainerName, storagePoolVolumeTypeNameContainer,
-		s.UserName)
-	if err != nil {
-		logger.Errorf(`Failed to map RBD storage volume for image "%s" on storage pool "%s": %s`, targetContainerName,
-			s.pool.Name, err)
-		return err
-	}
-
-	// Generate a new xfs's UUID
-	RBDFilesystem := s.getRBDFilesystem()
-	msg, err := fsGenerateNewUUID(RBDFilesystem, RBDDevPath)
+	// Re-generate the UUID
+	err = s.cephRBDGenerateUUID(projectPrefix(target.Project(), target.Name()), storagePoolVolumeTypeNameContainer)
 	if err != nil {
-		logger.Errorf("Failed to create new \"%s\" UUID for container \"%s\" on storage pool \"%s\": %s", RBDFilesystem, targetContainerName, s.pool.Name, msg)
 		return err
 	}
 
+	// Create mountpoint
 	targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, target.Name())
 	err = createContainerMountpoint(targetContainerMountPoint, target.Path(), target.IsPrivileged())
 	if err != nil {
@@ -1969,30 +1959,14 @@ func (s *storageCeph) copyVolumeWithoutSnapshotsFull(source *api.StorageVolumeSo
 		return err
 	}
 
-	// Map the rbd
-	RBDDevPath, err := cephRBDVolumeMap(s.ClusterName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName)
-	if err != nil {
-		logger.Errorf("Failed to map RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
-		return err
-	}
-
-	// Generate a new UUID
-	RBDFilesystem := s.getRBDFilesystem()
-	msg, err := fsGenerateNewUUID(RBDFilesystem, RBDDevPath)
+	// Re-generate the UUID
+	err = s.cephRBDGenerateUUID(s.volume.Name, storagePoolVolumeTypeNameCustom)
 	if err != nil {
-		logger.Errorf("Failed to create new UUID for filesystem \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s: %s", RBDFilesystem, s.volume.Name, s.pool.Name, msg, err)
-		return err
-	}
-
-	// Unmap the rbd
-	err = cephRBDVolumeUnmap(s.ClusterName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName, true)
-	if err != nil {
-		logger.Errorf("Failed to unmap RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
 		return err
 	}
 
+	// Create the mountpoint
 	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-
 	err = os.MkdirAll(volumeMntPoint, 0711)
 	if err != nil {
 		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)
@@ -2033,34 +2007,36 @@ func (s *storageCeph) copyVolumeWithoutSnapshotsSparse(source *api.StorageVolume
 		return err
 	}
 
-	// Map the rbd
-	RBDDevPath, err := cephRBDVolumeMap(s.ClusterName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName)
+	// Re-generate the UUID
+	err = s.cephRBDGenerateUUID(s.volume.Name, storagePoolVolumeTypeNameCustom)
 	if err != nil {
-		logger.Errorf("Failed to map RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
 		return err
 	}
 
-	// Generate a new UUID
-	RBDFilesystem := s.getRBDFilesystem()
-	msg, err := fsGenerateNewUUID(RBDFilesystem, RBDDevPath)
+	// Create the mountpoint
+	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	err = os.MkdirAll(volumeMntPoint, 0711)
 	if err != nil {
-		logger.Errorf("Failed to create new UUID for filesystem \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s: %s", RBDFilesystem, s.volume.Name, s.pool.Name, msg, err)
+		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)
 		return err
 	}
 
-	// Unmap the rbd
-	err = cephRBDVolumeUnmap(s.ClusterName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName, true)
+	return nil
+}
+
+// cephRBDGenerateUUID regenerates the XFS/btrfs UUID as needed
+func (s *storageCeph) cephRBDGenerateUUID(volumeName string, volumeType string) error {
+	// Map the RBD volume
+	RBDDevPath, err := cephRBDVolumeMap(s.ClusterName, s.OSDPoolName, volumeName, volumeType, s.UserName)
 	if err != nil {
-		logger.Errorf("Failed to unmap RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
 		return err
 	}
+	defer cephRBDVolumeUnmap(s.ClusterName, s.OSDPoolName, volumeName, volumeType, s.UserName, true)
 
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-
-	err = os.MkdirAll(volumeMntPoint, 0711)
+	// Update the UUID
+	msg, err := fsGenerateNewUUID(s.getRBDFilesystem(), RBDDevPath)
 	if err != nil {
-		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)
-		return err
+		return fmt.Errorf("Failed to regenerate UUID for '%v': %v: %v", volumeName, err, msg)
 	}
 
 	return nil


More information about the lxc-devel mailing list