[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