[lxc-devel] [lxd/master] storage: upgrade improvements for dir and btrfs
brauner on Github
lxc-bot at linuxcontainers.org
Tue Feb 21 01:58:31 UTC 2017
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/20170221/95781a13/attachment.bin>
-------------- next part --------------
From 3ee10d6167e975ea9d262d46fa6bd517be4fe224 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 21 Feb 2017 02:49:41 +0100
Subject: [PATCH 1/2] patches: improve dir upgrade
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/patches.go | 123 +++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 89 insertions(+), 34 deletions(-)
diff --git a/lxd/patches.go b/lxd/patches.go
index 4bfd534..e6ae6cf 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -432,18 +432,35 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
poolConfig := map[string]string{}
poolConfig["source"] = shared.VarPath("storage-pools", defaultPoolName)
- poolID, err := dbStoragePoolCreate(d.db, defaultPoolName, defaultStorageTypeName, poolConfig)
- if err != nil {
- return err
- }
+ poolID := int64(-1)
+ _, err := dbStoragePools(d.db)
+ if err == nil { // Already exist valid storage pools.
+ // Get the pool ID as we need it for storage volume creation.
+ // (Use a tmp variable as Go's scoping is freaking me out.)
+ tmp, err := dbStoragePoolGetID(d.db, defaultPoolName)
+ if err != nil {
+ shared.LogErrorf("Failed to query database: %s.", err)
+ return err
+ }
+ poolID = tmp
+ } else if err == NoSuchObjectError { // Likely a pristine upgrade.
+ tmp, err := dbStoragePoolCreate(d.db, defaultPoolName, defaultStorageTypeName, poolConfig)
+ if err != nil {
+ return err
+ }
+ poolID = tmp
- s, err := storagePoolInit(d, defaultPoolName)
- if err != nil {
- return err
- }
+ s, err := storagePoolInit(d, defaultPoolName)
+ if err != nil {
+ return err
+ }
- err = s.StoragePoolCreate()
- if err != nil {
+ err = s.StoragePoolCreate()
+ if err != nil {
+ return err
+ }
+ } else { // Shouldn't happen.
+ shared.LogErrorf("Failed to query database: %s.", err)
return err
}
@@ -451,26 +468,39 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
volumeConfig := map[string]string{}
// Insert storage volumes for containers into the database.
for _, ct := range cRegular {
- _, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, volumeConfig)
- if err != nil {
- shared.LogWarnf("Could not insert a storage volume for container \"%s\".", ct)
- continue
+ _, err := dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
+ if err == nil {
+ shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+ } else if err == NoSuchObjectError {
+ // Insert storage volumes for containers into the database.
+ _, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, volumeConfig)
+ if err != nil {
+ shared.LogErrorf("Could not insert a storage volume for container \"%s\".", ct)
+ return err
+ }
+ } else {
+ shared.LogErrorf("Failed to query database: %s", err)
+ return err
}
// Create the new path where containers will be located on the
// new storage api.
containersMntPoint := getContainerMountPoint(defaultPoolName, "")
- err = os.MkdirAll(containersMntPoint, 0711)
- if err != nil {
- return err
+ if !shared.PathExists(containersMntPoint) {
+ err := os.MkdirAll(containersMntPoint, 0711)
+ if err != nil {
+ return err
+ }
}
// Simply rename the container when they are directories.
oldContainerMntPoint := shared.VarPath("containers", ct)
newContainerMntPoint := getContainerMountPoint(defaultPoolName, ct)
- err = os.Rename(oldContainerMntPoint, newContainerMntPoint)
- if err != nil {
- return err
+ if shared.PathExists(oldContainerMntPoint) {
+ err := os.Rename(oldContainerMntPoint, newContainerMntPoint)
+ if err != nil {
+ return err
+ }
}
doesntMatter := false
@@ -496,16 +526,20 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
// Create the new path where snapshots will be located on the
// new storage api.
snapshotsMntPoint := shared.VarPath("storage-pools", defaultPoolName, "snapshots")
- err = os.MkdirAll(snapshotsMntPoint, 0711)
- if err != nil {
- return err
+ if !shared.PathExists(snapshotsMntPoint) {
+ err := os.MkdirAll(snapshotsMntPoint, 0711)
+ if err != nil {
+ return err
+ }
}
// Now simply rename the snapshots directory as well.
newSnapshotMntPoint := getSnapshotMountPoint(defaultPoolName, ct)
- err = os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
- if err != nil {
- return err
+ if shared.PathExists(oldSnapshotMntPoint) {
+ err := os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
+ if err != nil {
+ return err
+ }
}
// Create a symlink for this container. snapshots.
@@ -519,10 +553,22 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
// snapshots have already been moved and symlinked above. So no need to
// do any work here.
for _, cs := range cSnapshots {
- _, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, volumeConfig)
- if err != nil {
- shared.LogWarnf("Could not insert a storage volume for snapshot \"%s\".", cs)
- continue
+ // Insert storage volumes for snapshots into the
+ // database. Note that snapshots have already been moved
+ // and symlinked above. So no need to do any work here.
+ _, err := dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
+ if err == nil {
+ shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+ } else if err == NoSuchObjectError {
+ // Insert storage volumes for containers into the database.
+ _, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, volumeConfig)
+ if err != nil {
+ shared.LogErrorf("Could not insert a storage volume for snapshot \"%s\".", cs)
+ return err
+ }
+ } else {
+ shared.LogErrorf("Failed to query database: %s", err)
+ return err
}
}
@@ -530,10 +576,19 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
// move. The tarballs remain in their original location.
images := append(imgPublic, imgPrivate...)
for _, img := range images {
- _, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, volumeConfig)
- if err != nil {
- shared.LogWarnf("Could not insert a storage volume for image \"%s\".", img)
- continue
+ _, err := dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
+ if err == nil {
+ shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+ } else if err == NoSuchObjectError {
+ // Insert storage volumes for containers into the database.
+ _, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, volumeConfig)
+ if err != nil {
+ shared.LogWarnf("Could not insert a storage volume for image \"%s\".", img)
+ return err
+ }
+ } else {
+ shared.LogErrorf("Failed to query database: %s", err)
+ return err
}
}
From f6845f00052a1549d94f94bbc0ce6c4274b83341 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 21 Feb 2017 02:56:28 +0100
Subject: [PATCH 2/2] patches: improve btrfs upgrade
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/patches.go | 138 +++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 96 insertions(+), 42 deletions(-)
diff --git a/lxd/patches.go b/lxd/patches.go
index e6ae6cf..3ae5672 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -271,18 +271,35 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
poolSubvolumePath := getStoragePoolMountPoint(defaultPoolName)
poolConfig["source"] = poolSubvolumePath
- poolID, err := dbStoragePoolCreate(d.db, defaultPoolName, defaultStorageTypeName, poolConfig)
- if err != nil {
- return err
- }
+ poolID := int64(-1)
+ _, err := dbStoragePools(d.db)
+ if err == nil { // Already exist valid storage pools.
+ // Get the pool ID as we need it for storage volume creation.
+ // (Use a tmp variable as Go's scoping is freaking me out.)
+ tmp, err := dbStoragePoolGetID(d.db, defaultPoolName)
+ if err != nil {
+ shared.LogErrorf("Failed to query database: %s.", err)
+ return err
+ }
+ poolID = tmp
+ } else if err == NoSuchObjectError { // Likely a pristine upgrade.
+ tmp, err := dbStoragePoolCreate(d.db, defaultPoolName, defaultStorageTypeName, poolConfig)
+ if err != nil {
+ return err
+ }
+ poolID = tmp
- s, err := storagePoolInit(d, defaultPoolName)
- if err != nil {
- return err
- }
+ s, err := storagePoolInit(d, defaultPoolName)
+ if err != nil {
+ return err
+ }
- err = s.StoragePoolCreate()
- if err != nil {
+ err = s.StoragePoolCreate()
+ if err != nil {
+ return err
+ }
+ } else { // Shouldn't happen.
+ shared.LogErrorf("Failed to query database: %s.", err)
return err
}
@@ -292,19 +309,30 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
if len(cRegular) > 0 {
// ${LXD_DIR}/storage-pools/<name>
containersSubvolumePath := getContainerMountPoint(defaultPoolName, "")
- err := os.MkdirAll(containersSubvolumePath, 0711)
- if err != nil {
- return err
+ if !shared.PathExists(containersSubvolumePath) {
+ err := os.MkdirAll(containersSubvolumePath, 0711)
+ if err != nil {
+ return err
+ }
}
}
for _, ct := range cRegular {
// Create new db entry in the storage volumes table for the
// container.
- _, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, volumeConfig)
- if err != nil {
- shared.LogWarnf("Could not insert a storage volume for container \"%s\".", ct)
- continue
+ _, err := dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
+ if err == nil {
+ shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+ } else if err == NoSuchObjectError {
+ // Insert storage volumes for containers into the database.
+ _, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, volumeConfig)
+ if err != nil {
+ shared.LogErrorf("Could not insert a storage volume for container \"%s\".", ct)
+ return err
+ }
+ } else {
+ shared.LogErrorf("Failed to query database: %s", err)
+ return err
}
// Rename the btrfs subvolume and making it a
@@ -312,9 +340,11 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
// mv ${LXD_DIR}/containers/<container_name> ${LXD_DIR}/storage-pools/<pool>/<container_name>
oldContainerMntPoint := shared.VarPath("containers", ct)
newContainerMntPoint := getContainerMountPoint(defaultPoolName, ct)
- err = os.Rename(oldContainerMntPoint, newContainerMntPoint)
- if err != nil {
- return err
+ if shared.PathExists(oldContainerMntPoint) {
+ err = os.Rename(oldContainerMntPoint, newContainerMntPoint)
+ if err != nil {
+ return err
+ }
}
// Create a symlink to the mountpoint of the container:
@@ -337,9 +367,11 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
// the new storage pool:
// ${LXD_DIR}/storage-pools/<pool>/snapshots
newSnapshotsMntPoint := getSnapshotMountPoint(defaultPoolName, ct)
- err = os.MkdirAll(newSnapshotsMntPoint, 0700)
- if err != nil {
- return err
+ if !shared.PathExists(newSnapshotsMntPoint) {
+ err := os.MkdirAll(newSnapshotsMntPoint, 0700)
+ if err != nil {
+ return err
+ }
}
}
@@ -347,10 +379,22 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
// Insert storage volumes for snapshots into the
// database. Note that snapshots have already been moved
// and symlinked above. So no need to do any work here.
- _, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, volumeConfig)
- if err != nil {
- shared.LogWarnf("Could not insert a storage volume for snapshot \"%s\".", cs)
+ _, err := dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
+ if err == nil {
+ shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+ // For btrfs we need to assume that the btrfs
+ // execs below succeeded.
continue
+ } else if err == NoSuchObjectError {
+ // Insert storage volumes for containers into the database.
+ _, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, volumeConfig)
+ if err != nil {
+ shared.LogErrorf("Could not insert a storage volume for snapshot \"%s\".", cs)
+ return err
+ }
+ } else {
+ shared.LogErrorf("Failed to query database: %s", err)
+ return err
}
// We need to create a new snapshot since we can't move
@@ -387,16 +431,13 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
// ${LXD_DIR}/snapshots/<container_name> -> ${LXD_DIR}/storage-pools/<pool>/snapshots/<container_name>
snapshotsPath := shared.VarPath("snapshots", ct)
newSnapshotMntPoint := getSnapshotMountPoint(defaultPoolName, ct)
- if shared.PathExists(snapshotsPath) {
- err := os.Remove(snapshotsPath)
+ os.Remove(snapshotsPath)
+ if !shared.PathExists(snapshotsPath) {
+ err := os.Symlink(newSnapshotMntPoint, snapshotsPath)
if err != nil {
return err
}
}
- err = os.Symlink(newSnapshotMntPoint, snapshotsPath)
- if err != nil {
- return err
- }
}
}
@@ -405,23 +446,36 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
// move. The tarballs remain in their original location.
images := append(imgPublic, imgPrivate...)
for _, img := range images {
- _, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, volumeConfig)
- if err != nil {
- shared.LogWarnf("Could not insert a storage volume for image \"%s\".", img)
- continue
+ _, err := dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
+ if err == nil {
+ shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+ } else if err == NoSuchObjectError {
+ // Insert storage volumes for containers into the database.
+ _, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, volumeConfig)
+ if err != nil {
+ shared.LogWarnf("Could not insert a storage volume for image \"%s\".", img)
+ return err
+ }
+ } else {
+ shared.LogErrorf("Failed to query database: %s", err)
+ return err
}
imagesMntPoint := getImageMountPoint(defaultPoolName, "")
- err = os.MkdirAll(imagesMntPoint, 0700)
- if err != nil {
- return err
+ if !shared.PathExists(imagesMntPoint) {
+ err := os.MkdirAll(imagesMntPoint, 0700)
+ if err != nil {
+ return err
+ }
}
oldImageMntPoint := shared.VarPath("images", img+".btrfs")
newImageMntPoint := getImageMountPoint(defaultPoolName, img)
- err = os.Rename(oldImageMntPoint, newImageMntPoint)
- if err != nil {
- return err
+ if shared.PathExists(oldImageMntPoint) {
+ err := os.Rename(oldImageMntPoint, newImageMntPoint)
+ if err != nil {
+ return err
+ }
}
}
More information about the lxc-devel
mailing list