The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6557
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) === Adds `MountInstanceReadOnly` functionality to backendLXD as a forthcoming requirement for the storage publish functionality. Also added support for disabling shiftfs at runtime using `LXD_SHIFTFS_DISABLE` environment variable, which will be useful when testing publish shifting,
From 7476f9ddb7fbd744ebd6f3c8ac97266be835470e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:35:52 +0000 Subject: [PATCH 1/9] lxd/backup: Comment consistency Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/backup.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lxd/backup.go b/lxd/backup.go index 15189bffd7..a01a9eb23f 100644 --- a/lxd/backup.go +++ b/lxd/backup.go @@ -63,6 +63,7 @@ func backupCreate(s *state.State, args db.InstanceBackupArgs, sourceInst instanc } defer os.RemoveAll(tmpPath) + // Check if we can load new storage layer for pool driver type. pool, err := storagePools.GetPoolByInstance(s, sourceInst) if err != storageDrivers.ErrUnknownDriver && err != storageDrivers.ErrNotImplemented { if err != nil { From c8794c30567b9b5a5ac78971b7ee189b7b72ddfa Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:36:49 +0000 Subject: [PATCH 2/9] lxd/daemon: Adds LXD_SHIFTFS_DISABLE env var to disable shiftfs Useful when testing traditional UID shifting. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/daemon.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lxd/daemon.go b/lxd/daemon.go index c5416d7dfc..98beb7a1ac 100644 --- a/lxd/daemon.go +++ b/lxd/daemon.go @@ -620,11 +620,17 @@ func (d *Daemon) init() error { logger.Infof(" - unprivileged file capabilities: no") } - if util.HasFilesystem("shiftfs") || util.LoadModule("shiftfs") == nil { - d.os.Shiftfs = true - logger.Infof(" - shiftfs support: yes") + // Detect shiftfs support. + if shared.IsTrue(os.Getenv("LXD_SHIFTFS_DISABLE")) { + logger.Infof(" - shiftfs support: disabled") } else { - logger.Infof(" - shiftfs support: no") + if util.HasFilesystem("shiftfs") || util.LoadModule("shiftfs") == nil { + d.os.Shiftfs = true + logger.Infof(" - shiftfs support: yes") + d.os.Shiftfs = false + } else { + logger.Infof(" - shiftfs support: no") + } } // Detect LXC features From 3fbc284a8a8ebf139b60727d3fd61cc1fc9abd8e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:38:48 +0000 Subject: [PATCH 3/9] doc/environment: Documents LXD_SHIFTFS_DISABLE env var Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- doc/environment.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/environment.md b/doc/environment.md index 2925711467..88246c1890 100644 --- a/doc/environment.md +++ b/doc/environment.md @@ -28,3 +28,4 @@ Name | Description `LXD_SECURITY_APPARMOR` | If set to `false`, forces AppArmor off `LXD_UNPRIVILEGED_ONLY` | If set to `true`, enforces that only unprivileged containers can be created. Note that any privileged containers that have been created before setting LXD_UNPRIVILEGED_ONLY will continue to be privileged. To use this option effectively it should be set when the LXD daemon is first setup. `LXD_OVMF_PATH` | Path to an OVMF build including `OVMF_CODE.fd` and `OVMF_VARS.ms.fd` +`LXD_SHIFTFS_DISABLE` | Disable shiftfs support (useful when testing traditional UID shifting) From 784e9eb94b01ac0704996ff982028138edcfe031 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:39:07 +0000 Subject: [PATCH 4/9] lxd/storage/pool/interface: Adds MountInstanceReadOnly Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/pool_interface.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lxd/storage/pool_interface.go b/lxd/storage/pool_interface.go index 802e4858bc..ca9487e701 100644 --- a/lxd/storage/pool_interface.go +++ b/lxd/storage/pool_interface.go @@ -41,6 +41,7 @@ type Pool interface { SetInstanceQuota(inst instance.Instance, size string, op *operations.Operation) error MountInstance(inst instance.Instance, op *operations.Operation) (bool, error) + MountInstanceReadOnly(inst instance.Instance, op *operations.Operation) (bool, error) UnmountInstance(inst instance.Instance, op *operations.Operation) (bool, error) GetInstanceDisk(inst instance.Instance) (string, error) From e7bc0f30965112f278af5a4f51a5f9f8f1931561 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:39:26 +0000 Subject: [PATCH 5/9] lxd/storage/backend/lxd: Implements MountInstanceReadOnly Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 8173a7a450..53278f7a3b 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1178,6 +1178,24 @@ func (b *lxdBackend) MountInstance(inst instance.Instance, op *operations.Operat return b.driver.MountVolume(volType, volStorageName, op) } +// MountInstanceReadOnly mounts the instance's root volume read-only. +func (b *lxdBackend) MountInstanceReadOnly(inst instance.Instance, op *operations.Operation) (bool, error) { + logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name()}) + logger.Debug("MountInstanceReadOnly started") + defer logger.Debug("MountInstanceReadOnly finished") + + // Check we can convert the instance to the volume type needed. + volType, err := InstanceTypeToVolumeType(inst.Type()) + if err != nil { + return false, err + } + + // Get the volume name on storage. + volStorageName := project.Prefix(inst.Project(), inst.Name()) + + return b.driver.MountVolumeReadOnly(volType, volStorageName, op) +} + // UnmountInstance unmounts the instance's root volume. func (b *lxdBackend) UnmountInstance(inst instance.Instance, op *operations.Operation) (bool, error) { logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name()}) From 6ed5d5998e73d690409cf713cd934b922c5beb50 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:39:59 +0000 Subject: [PATCH 6/9] lxd/storage/backend/mock: MountInstanceReadOnly placeholder Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_mock.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lxd/storage/backend_mock.go b/lxd/storage/backend_mock.go index b40cf40f20..122d7541b8 100644 --- a/lxd/storage/backend_mock.go +++ b/lxd/storage/backend_mock.go @@ -108,6 +108,10 @@ func (b *mockBackend) MountInstance(inst instance.Instance, op *operations.Opera return true, nil } +func (b *mockBackend) MountInstanceReadOnly(inst instance.Instance, op *operations.Operation) (bool, error) { + return true, nil +} + func (b *mockBackend) UnmountInstance(inst instance.Instance, op *operations.Operation) (bool, error) { return true, nil } From 0b5ab9474896795d1dc72b6f5bb086b266116ab7 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:40:16 +0000 Subject: [PATCH 7/9] lxd/storage/drivers/interface: Adds MountVolumeReadOnly Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/interface.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lxd/storage/drivers/interface.go b/lxd/storage/drivers/interface.go index 8297b2d7b9..34c4683aff 100644 --- a/lxd/storage/drivers/interface.go +++ b/lxd/storage/drivers/interface.go @@ -45,8 +45,9 @@ type Driver interface { GetVolumeDiskPath(volType VolumeType, volName string) (string, error) // MountVolume mounts a storage volume, returns true if we caused a new mount, false if - // already mounted. + // already mounted or doesn't need to be unmounted. MountVolume(volType VolumeType, volName string, op *operations.Operation) (bool, error) + MountVolumeReadOnly(volType VolumeType, volName string, op *operations.Operation) (bool, error) // MountVolumeSnapshot mounts a storage volume snapshot as readonly, returns true if we // caused a new mount, false if already mounted. From fbfd55947393be707d603538494bdb546da2ab46 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:40:40 +0000 Subject: [PATCH 8/9] lxd/storage/drivers/driver/cephfs: MountVolumeReadOnly placeholder Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/driver_cephfs.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lxd/storage/drivers/driver_cephfs.go b/lxd/storage/drivers/driver_cephfs.go index 75e589ea68..f9c292357d 100644 --- a/lxd/storage/drivers/driver_cephfs.go +++ b/lxd/storage/drivers/driver_cephfs.go @@ -621,6 +621,10 @@ func (d *cephfs) MountVolume(volType VolumeType, volName string, op *operations. return false, nil } +func (d *cephfs) MountVolumeReadOnly(volType VolumeType, volName string, op *operations.Operation) (bool, error) { + return false, ErrNotImplemented +} + func (d *cephfs) MountVolumeSnapshot(volType VolumeType, VolName, snapshotName string, op *operations.Operation) (bool, error) { if volType != VolumeTypeCustom { return false, fmt.Errorf("Volume type not supported") From 135a0836363774fc1552fc7a2288a42da0ac4e8e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 5 Dec 2019 11:40:59 +0000 Subject: [PATCH 9/9] lxd/storage/drivers/driver/dir: Implements MountVolumeReadOnly Also updated UnmountVolume to truly unmount the bind-mount created with MountVolumeReadOnly. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/driver_dir.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go index 7d8a0563bd..36e0bfe7e5 100644 --- a/lxd/storage/drivers/driver_dir.go +++ b/lxd/storage/drivers/driver_dir.go @@ -768,16 +768,24 @@ func (d *dir) MountVolume(volType VolumeType, volName string, op *operations.Ope return false, nil } +// MountVolumeReadOnly bind-mounts the volume as read-only. It may return true meaning that this +// volume will need to be unmounted later. +func (d *dir) MountVolumeReadOnly(volType VolumeType, volName string, op *operations.Operation) (bool, error) { + volPath := GetVolumeMountPath(d.name, volType, volName) + return mountReadOnly(volPath, volPath) +} + // MountVolumeSnapshot sets up a read-only mount on top of the snapshot to avoid accidental modifications. func (d *dir) MountVolumeSnapshot(volType VolumeType, volName, snapshotName string, op *operations.Operation) (bool, error) { snapPath := GetVolumeMountPath(d.name, volType, GetSnapshotVolumeName(volName, snapshotName)) return mountReadOnly(snapPath, snapPath) } -// UnmountVolume simulates unmounting a volume. As dir driver doesn't have volumes to unmount it -// returns false indicating the volume was already unmounted. +// UnmountVolume simulates unmounting a volume. Although we don't normally mount dir volumes, if it +// was mounted in read-only mode we will need to unmount the bind-mount that was created. func (d *dir) UnmountVolume(volType VolumeType, volName string, op *operations.Operation) (bool, error) { - return false, nil + volPath := GetVolumeMountPath(d.name, volType, volName) + return forceUnmount(volPath) // This is safe to call even if dir volume isn't bind-mounted. } // UnmountVolumeSnapshot removes the read-only mount placed on top of a snapshot.
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel