The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6675
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Assorted collection of small changes I've made as part of doing the LVM driver.
From 071fc4e56dcf9b2ad5d3a983467bcbe19f1d3f6f Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 6 Jan 2020 16:20:26 +0000 Subject: [PATCH 1/6] lxd/storage/drivers/driver/dir/volumes: Use SetVolumeQuota from UpdateVolume Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/driver_dir_volumes.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go index ffa3acf227..068dd60297 100644 --- a/lxd/storage/drivers/driver_dir_volumes.go +++ b/lxd/storage/drivers/driver_dir_volumes.go @@ -197,13 +197,7 @@ func (d *dir) UpdateVolume(vol Volume, changedConfig map[string]string) error { } if _, changed := changedConfig["size"]; changed { - volID, err := d.getVolID(vol.volType, vol.name) - if err != nil { - return err - } - - // Set the quota if specified in volConfig or pool config. - err = d.setQuota(vol.MountPath(), volID, changedConfig["size"]) + err := d.SetVolumeQuota(vol, changedConfig["size"], nil) if err != nil { return err } From be98f228c684475cfcbd40b92f650076d088c6d7 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 7 Jan 2020 09:20:51 +0000 Subject: [PATCH 2/6] lxd/storage/backend/lxd: Makes specific lock name for volume EnsureImage action Avoids deadlock with MountTask lock during same process. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index e4219293da..82c102be5c 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1784,9 +1784,10 @@ func (b *lxdBackend) EnsureImage(fingerprint string, op *operations.Operation) e return nil // Nothing to do for drivers that don't support optimized images volumes. } - // We need to lock this operation to ensure that the image is not being - // created multiple times. - unlock := locking.Lock(b.name, string(drivers.VolumeTypeImage), fingerprint) + // We need to lock this operation to ensure that the image is not being created multiple times. + // Uses a lock name of "EnsureImage_<fingerprint>" to avoid deadlocking with CreateVolume below that also + // establishes a lock on the volume type & name if it needs to mount the volume before filling. + unlock := locking.Lock(b.name, string(drivers.VolumeTypeImage), fmt.Sprintf("EnsureImage_%v", fingerprint)) defer unlock() // There's no need to pass the content type or config. Both are not needed From 2f0be1f87fb867f9804045508dd3dffcb9c7b755 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 7 Jan 2020 09:21:41 +0000 Subject: [PATCH 3/6] lxd/storage/drivers/volume: Adds UnmountTask function Allows a volume to be temporarily unmounted (if mounted) and a function be run before volume then being re-mounted (if previously mounted). Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/volume.go | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lxd/storage/drivers/volume.go b/lxd/storage/drivers/volume.go index b7ec773dff..fcba388445 100644 --- a/lxd/storage/drivers/volume.go +++ b/lxd/storage/drivers/volume.go @@ -183,6 +183,54 @@ func (v Volume) MountTask(task func(mountPath string, op *operations.Operation) return task(v.MountPath(), op) } +// UnmountTask runs the supplied task after unmounting the volume if needed. If the volume was unmounted +// for this then it is mounted when the task finishes. +func (v Volume) UnmountTask(task func(op *operations.Operation) error, op *operations.Operation) error { + isSnap := v.IsSnapshot() + + // If the volume is a snapshot then call the snapshot specific mount/unmount functions as + // these will mount the snapshot read only. + if isSnap { + unlock := locking.Lock(v.pool, string(v.volType), v.name) + + ourUnmount, err := v.driver.UnmountVolumeSnapshot(v, op) + if err != nil { + unlock() + return err + } + + unlock() + + if ourUnmount { + defer func() { + unlock := locking.Lock(v.pool, string(v.volType), v.name) + v.driver.MountVolumeSnapshot(v, op) + unlock() + }() + } + } else { + unlock := locking.Lock(v.pool, string(v.volType), v.name) + + ourUnmount, err := v.driver.UnmountVolume(v, op) + if err != nil { + unlock() + return err + } + + unlock() + + if ourUnmount { + defer func() { + unlock := locking.Lock(v.pool, string(v.volType), v.name) + v.driver.MountVolume(v, op) + unlock() + }() + } + } + + return task(op) +} + // Snapshots returns a list of snapshots for the volume. func (v Volume) Snapshots(op *operations.Operation) ([]Volume, error) { if v.IsSnapshot() { From 5c187fdace34557857fd83f45ce822ca39e09263 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 7 Jan 2020 09:22:32 +0000 Subject: [PATCH 4/6] lxd/storage/drivers/utils: Adds volume filesystem shrink and grow functions Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/utils.go | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index 768aab8b69..07a8b32268 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -10,6 +10,7 @@ import ( "golang.org/x/sys/unix" + "github.com/lxc/lxd/lxd/operations" "github.com/lxc/lxd/shared" "github.com/lxc/lxd/shared/units" ) @@ -401,3 +402,65 @@ func resolveMountOptions(options string) (uintptr, string) { return mountFlags, strings.Join(tmp, ",") } + +// shrinkFileSystem shrinks a filesystem if it is supported. Ext4 volumes will be unmounted temporarily if needed. +func shrinkFileSystem(fsType string, devPath string, vol Volume, byteSize int64) error { + strSize := fmt.Sprintf("%dK", byteSize/1024) + + switch fsType { + case "": // if not specified, default to ext4. + fallthrough + case "xfs": + return fmt.Errorf(`Shrinking not supported for filesystem type "%s". A dump, mkfs, and restore are required`, fsType) + case "ext4": + return vol.UnmountTask(func(op *operations.Operation) error { + _, err := shared.TryRunCommand("e2fsck", "-f", "-y", devPath) + if err != nil { + return err + } + + _, err = shared.TryRunCommand("resize2fs", devPath, strSize) + if err != nil { + return err + } + + return nil + }, nil) + case "btrfs": + _, err := shared.TryRunCommand("btrfs", "filesystem", "resize", strSize, vol.MountPath()) + if err != nil { + return err + } + default: + return fmt.Errorf(`Shrinking not supported for filesystem type "%s"`, fsType) + } + + return nil +} + +// growFileSystem grows a filesystem if it is supported. The volume will be mounted temporarily if needed. +func growFileSystem(fsType string, devPath string, vol Volume) error { + return vol.MountTask(func(mountPath string, op *operations.Operation) error { + var msg string + var err error + switch fsType { + case "": // if not specified, default to ext4 + fallthrough + case "ext4": + msg, err = shared.TryRunCommand("resize2fs", devPath) + case "xfs": + msg, err = shared.TryRunCommand("xfs_growfs", devPath) + case "btrfs": + msg, err = shared.TryRunCommand("btrfs", "filesystem", "resize", "max", mountPath) + default: + return fmt.Errorf(`Growing not supported for filesystem type "%s"`, fsType) + } + + if err != nil { + errorMsg := fmt.Sprintf(`Could not extend underlying %s filesystem for "%s": %s`, fsType, devPath, msg) + return fmt.Errorf(errorMsg) + } + + return nil + }, nil) +} From 7e5736f85b50381277dbb01d67f4ab50bdc8b069 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 7 Jan 2020 15:56:27 +0000 Subject: [PATCH 5/6] lxd/storage/drivers/errors: Adds "not supported" error type Can be used when a driver doesn't support a specific feature. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/errors.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lxd/storage/drivers/errors.go b/lxd/storage/drivers/errors.go index 56d1bdab3c..e9fb157bc6 100644 --- a/lxd/storage/drivers/errors.go +++ b/lxd/storage/drivers/errors.go @@ -9,3 +9,6 @@ var ErrNotImplemented = fmt.Errorf("Not implemented") // ErrUnknownDriver is the "Unknown driver" error var ErrUnknownDriver = fmt.Errorf("Unknown driver") + +// ErrNotSupported is the "Not supported" error +var ErrNotSupported = fmt.Errorf("Not supported") From b2eca17175e3218e4c6d33889c15c4135618aaa2 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 7 Jan 2020 15:55:52 +0000 Subject: [PATCH 6/6] lxd/container/lxc: Detects storage drivers that dont support volume usage stats Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/container_lxc.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go index 7eede32fcd..e1058c6595 100644 --- a/lxd/container_lxc.go +++ b/lxd/container_lxc.go @@ -5811,7 +5811,9 @@ func (c *containerLXC) diskState() map[string]api.InstanceStateDisk { usage, err = pool.GetInstanceUsage(c) if err != nil { - logger.Error("Error getting disk usage", log.Ctx{"project": c.Project(), "instance": c.Name(), "err": err}) + if err != storageDrivers.ErrNotSupported { + logger.Error("Error getting disk usage", log.Ctx{"project": c.Project(), "instance": c.Name(), "err": err}) + } continue } } else {
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel