[lxc-devel] [lxd/master] Storage instance mount read-only and LXD_SHIFTFS_DISABLE

tomponline on Github lxc-bot at linuxcontainers.org
Thu Dec 5 11:44:34 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 582 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191205/aa036540/attachment.bin>
-------------- next part --------------
From 7476f9ddb7fbd744ebd6f3c8ac97266be835470e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.parrott at 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.


More information about the lxc-devel mailing list