[prev in list] [next in list] [prev in thread] [next in thread]
List: lxc-devel
Subject: [lxc-devel] [lxd/master] Add `shift` property on disk devices
From: stgraber on Github <lxc-bot () linuxcontainers ! org>
Date: 2019-07-24 20:38:07
Message-ID: 5d38c1af.1c69fb81.4fad9.82a7SMTPIN_ADDED_MISSING () mx ! google ! com
[Download RAW message or body]
[Attachment #2 (text/x-mailbox)]
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6010
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) ===
Closes #2860
There's going to be one step on top of that which should be for LXD to automatically \
use this feature for custom storage volumes so that they can be shared between \
idmap.isolated=true containers.
[Attachment #3 (text/plain)]
From a2016b362a2058d50f0d58fbdd067d0ec4e7950d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stéphane Graber?= <stgraber@ubuntu.com>
Date: Wed, 17 Jul 2019 23:35:06 -0400
Subject: [PATCH 1/6] api: Add container_disk_shift extension
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
---
doc/api-extensions.md | 3 +++
shared/version/api.go | 1 +
2 files changed, 4 insertions(+)
diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 3bf3d1adad..3202ad3e1b 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -803,3 +803,6 @@ Adds support for specifying User, Group and Cwd during `POST \
/1.0/containers/NAM Adds the `security.syscalls.intercept.\*` configuration keys to \
control what system calls will be interecepted by LXD and processed with
elevated permissions.
+
+## container\_disk\_shift
+Adds the `shift` property on `disk` devices which controls the use of the shiftfs \
overlay.
diff --git a/shared/version/api.go b/shared/version/api.go
index 99fef0b913..fdf8a5921f 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -160,6 +160,7 @@ var APIExtensions = []string{
"resources_v2",
"container_exec_user_group_cwd",
"container_syscall_intercept",
+ "container_disk_shift",
}
// APIExtensionsCount returns the number of available API extensions.
From 1df04cfd26b3d975788bba99c59af6da2222da3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stéphane Graber?= <stgraber@ubuntu.com>
Date: Wed, 17 Jul 2019 23:35:44 -0400
Subject: [PATCH 2/6] doc: Add shift option to disk device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
---
doc/containers.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/containers.md b/doc/containers.md
index 4c33c2c254..c3741f416b 100644
--- a/doc/containers.md
+++ b/doc/containers.md
@@ -493,6 +493,7 @@ size | string | - | no | \
Disk size in bytes recursive | boolean | false | no | \
Whether or not to recursively mount the source path pool | string | - \
| no | The storage pool the disk device belongs to. This is only applicable \
for storage volumes managed by LXD. propagation | string | - \
| no | Controls how a bind-mount is shared between the container and the host. \
(Can be one of `private`, the default, or `shared`, `slave`, `unbindable`, \
`rshared`, `rslave`, `runbindable`, `rprivate`. Please see the Linux Kernel [shared \
subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) \
documentation for a full explanation) +shift | boolean | false \
| no | Setup a shifting overlay to translate the source uid/gid to match the \
container
If multiple disks, backed by the same block device, have I/O limits set,
the average of the limits will be used.
From 3f04a1e092074fdd5a62d68fa55b2612d910f438 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stéphane Graber?= <stgraber@ubuntu.com>
Date: Wed, 17 Jul 2019 23:40:42 -0400
Subject: [PATCH 3/6] lxd/container: Don't validate liblxc version during
config parsing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
---
lxd/container.go | 5 -----
lxd/container_lxc.go | 4 ++++
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/lxd/container.go b/lxd/container.go
index a690fff70c..d6e1cb8a5e 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -22,7 +22,6 @@ import (
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/lxd/sys"
"github.com/lxc/lxd/lxd/task"
- "github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
"github.com/lxc/lxd/shared/idmap"
@@ -515,10 +514,6 @@ func containerValidDevices(cluster *db.Cluster, devices \
config.Devices, profile }
if m["propagation"] != "" {
- if !util.RuntimeLiblxcVersionAtLeast(3, 0, 0) {
- return fmt.Errorf("liblxc 3.0 is required for mount propagation configuration")
- }
-
if !shared.StringInSlice(m["propagation"], []string{"private", "shared", \
"slave", "unbindable", "rprivate", "rshared", "rslave", "runbindable"}) { return \
fmt.Errorf("Invalid propagation mode '%s'", m["propagation"]) }
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 1b5ca2ccd0..31354ce189 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1843,6 +1843,10 @@ func (c *containerLXC) initLXC(config bool) error {
}
if m["propagation"] != "" {
+ if !util.RuntimeLiblxcVersionAtLeast(3, 0, 0) {
+ return fmt.Errorf("liblxc 3.0 is required for mount propagation \
configuration") + }
+
options = append(options, m["propagation"])
}
From ef59832e811f83d2771764e5dc8cc037ea8c889b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stéphane Graber?= <stgraber@ubuntu.com>
Date: Wed, 17 Jul 2019 23:59:28 -0400
Subject: [PATCH 4/6] lxd: Add shift disk option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
---
lxd/container.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lxd/container.go b/lxd/container.go
index d6e1cb8a5e..4d4df4b91d 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -185,6 +185,8 @@ func containerValidDeviceConfigKey(t, k string) bool {
return true
case "propagation":
return true
+ case "shift":
+ return true
default:
return false
}
@@ -518,6 +520,12 @@ func containerValidDevices(cluster *db.Cluster, devices \
config.Devices, profile return fmt.Errorf("Invalid propagation mode '%s'", \
m["propagation"]) }
}
+
+ if m["shift"] != "" {
+ if m["pool"] != "" {
+ return fmt.Errorf("The \"shift\" property cannot be used with custom storage \
volumes") + }
+ }
} else if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
if m["source"] == "" && m["path"] == "" {
return fmt.Errorf("Unix device entry is missing the required \"source\" or \
\"path\" property")
From 12f16a412240f03222860bf31be7a38ca211a473 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stéphane Graber?= <stgraber@ubuntu.com>
Date: Thu, 18 Jul 2019 01:23:03 -0400
Subject: [PATCH 5/6] lxd/containers: Add shiftfs for disk devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
---
lxd/container_lxc.go | 44 ++++++++++++++++++++++++++++++++++---------
lxd/main_forkmount.go | 24 ++++++++++++++++++++++-
2 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 31354ce189..003b453e9c 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1828,6 +1828,23 @@ func (c *containerLXC) initLXC(config bool) error {
}
}
} else {
+ if shared.IsTrue(m["shift"]) {
+ err = lxcSetConfigItem(cc, "lxc.hook.pre-start", fmt.Sprintf("/bin/mount -t \
shiftfs -o mark,passthrough=3 %s %s", sourceDevPath, sourceDevPath)) + if err != \
nil { + return err
+ }
+
+ err = lxcSetConfigItem(cc, "lxc.hook.pre-mount", fmt.Sprintf("/bin/mount -t \
shiftfs -o passthrough=3 %s %s", sourceDevPath, sourceDevPath)) + if err != nil {
+ return err
+ }
+
+ err = lxcSetConfigItem(cc, "lxc.hook.start-host", fmt.Sprintf("/bin/umount -l \
%s", sourceDevPath)) + if err != nil {
+ return err
+ }
+ }
+
rbind := ""
options := []string{}
if isReadOnly {
@@ -5130,7 +5147,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, \
userRequested bool) error { }
} else if key == "security.devlxd" {
if value == "" || shared.IsTrue(value) {
- err = c.insertMount(shared.VarPath("devlxd"), "/dev/lxd", "none", unix.MS_BIND)
+ err = c.insertMount(shared.VarPath("devlxd"), "/dev/lxd", "none", unix.MS_BIND, \
false) if err != nil {
return err
}
@@ -7274,7 +7291,7 @@ func (c *containerLXC) StorageStop() (bool, error) {
}
// Mount handling
-func (c *containerLXC) insertMountLXD(source, target, fstype string, flags int, \
mntnsPID int) error { +func (c *containerLXC) insertMountLXD(source, target, fstype \
string, flags int, mntnsPID int, shiftfs bool) error { pid := mntnsPID
if pid <= 0 {
// Get the init PID
@@ -7311,11 +7328,20 @@ func (c *containerLXC) insertMountLXD(source, target, fstype \
string, flags int, }
defer unix.Unmount(tmpMount, unix.MNT_DETACH)
+ // Setup host side shiftfs as needed
+ if shiftfs {
+ err = unix.Mount(tmpMount, tmpMount, "shiftfs", 0, "mark,passthrough=3")
+ if err != nil {
+ return fmt.Errorf("Failed to setup host side shiftfs mount: %s", err)
+ }
+ defer unix.Unmount(tmpMount, unix.MNT_DETACH)
+ }
+
// Move the mount inside the container
mntsrc := filepath.Join("/dev/.lxd-mounts", filepath.Base(tmpMount))
pidStr := fmt.Sprintf("%d", pid)
- _, err = shared.RunCommand(c.state.OS.ExecPath, "forkmount", "lxd-mount", pidStr, \
mntsrc, target) + _, err = shared.RunCommand(c.state.OS.ExecPath, "forkmount", \
"lxd-mount", pidStr, mntsrc, target, fmt.Sprintf("%v", shiftfs)) if err != nil {
return err
}
@@ -7342,12 +7368,12 @@ func (c *containerLXC) insertMountLXC(source, target, fstype \
string, flags int) return nil
}
-func (c *containerLXC) insertMount(source, target, fstype string, flags int) error {
- if c.state.OS.LXCFeatures["mount_injection_file"] {
+func (c *containerLXC) insertMount(source, target, fstype string, flags int, shiftfs \
bool) error { + if c.state.OS.LXCFeatures["mount_injection_file"] && !shiftfs {
return c.insertMountLXC(source, target, fstype, flags)
}
- return c.insertMountLXD(source, target, fstype, flags, -1)
+ return c.insertMountLXD(source, target, fstype, flags, -1, shiftfs)
}
func (c *containerLXC) removeMount(mount string) error {
@@ -7549,7 +7575,7 @@ func (c *containerLXC) insertUnixDevice(prefix string, m \
config.Device, defaultM tgtPath := paths[1]
// Bind-mount it into the container
- err = c.insertMount(devPath, tgtPath, "none", unix.MS_BIND)
+ err = c.insertMount(devPath, tgtPath, "none", unix.MS_BIND, false)
if err != nil {
return fmt.Errorf("Failed to add mount for device: %s", err)
}
@@ -7642,7 +7668,7 @@ func (c *containerLXC) InsertSeccompUnixDevice(prefix string, m \
config.Device, p
// Bind-mount it into the container
defer os.Remove(devPath)
- return c.insertMountLXD(devPath, tgtPath, "none", unix.MS_BIND, pid)
+ return c.insertMountLXD(devPath, tgtPath, "none", unix.MS_BIND, pid, false)
}
func (c *containerLXC) insertUnixDeviceNum(name string, m config.Device, major int, \
minor int, path string, defaultMode bool) error { @@ -9334,7 +9360,7 @@ func (c \
*containerLXC) insertDiskDevice(name string, m config.Device) error {
// Bind-mount it into the container
destPath := strings.TrimSuffix(m["path"], "/")
- err = c.insertMount(devPath, destPath, "none", flags)
+ err = c.insertMount(devPath, destPath, "none", flags, shared.IsTrue(m["shift"]))
if err != nil {
return fmt.Errorf("Failed to add mount for device: %s", err)
}
diff --git a/lxd/main_forkmount.go b/lxd/main_forkmount.go
index 5b0209895b..c42bfa1f2d 100644
--- a/lxd/main_forkmount.go
+++ b/lxd/main_forkmount.go
@@ -128,7 +128,7 @@ void create(char *src, char *dest)
}
void do_lxd_forkmount(pid_t pid) {
- char *src, *dest, *opts;
+ char *src, *dest, *opts, *shiftfs;
attach_userns(pid);
@@ -139,6 +139,7 @@ void do_lxd_forkmount(pid_t pid) {
src = advance_arg(true);
dest = advance_arg(true);
+ shiftfs = advance_arg(true);
create(src, dest);
@@ -152,14 +153,35 @@ void do_lxd_forkmount(pid_t pid) {
_exit(1);
}
+ if (strcmp(shiftfs, "true") == 0) {
+ // Setup shiftfs inside the container
+ if (mount(src, src, "shiftfs", 0, "passthrough=3") < 0) {
+ fprintf(stderr, "Failed shiftfs setup for %s: %s\n", src, strerror(errno));
+ _exit(1);
+ }
+ }
+
// Here, we always move recursively, because we sometimes allow
// recursive mounts. If the mount has no kids then it doesn't matter,
// but if it does, we want to move those too.
if (mount(src, dest, "none", MS_MOVE | MS_REC, NULL) < 0) {
+ // If using shiftfs, undo the shiftfs mount
+ if (strcmp(shiftfs, "true") == 0) {
+ umount2(src, MNT_DETACH);
+ }
+
fprintf(stderr, "Failed mounting %s onto %s: %s\n", src, dest, strerror(errno));
_exit(1);
}
+ if (strcmp(shiftfs, "true") == 0) {
+ // Clear source mount as target is now in place
+ if (umount2(src, MNT_DETACH) < 0) {
+ fprintf(stderr, "Failed shiftfs source unmount for %s: %s\n", src, \
strerror(errno)); + _exit(1);
+ }
+ }
+
_exit(0);
}
From 6ff7c7c1d0f94e8293116d70c35c6ce5286ee843 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stéphane Graber?= <stgraber@ubuntu.com>
Date: Wed, 24 Jul 2019 16:29:06 -0400
Subject: [PATCH 6/6] tests: Test the shift disk property
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
---
test/main.sh | 1 +
test/suites/container_devices_disk.sh | 32 +++++++++++++++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 test/suites/container_devices_disk.sh
diff --git a/test/main.sh b/test/main.sh
index 1e1e1b0578..6e0b6369f9 100755
--- a/test/main.sh
+++ b/test/main.sh
@@ -188,6 +188,7 @@ run_test test_projects_images "images inside projects"
run_test test_projects_images_default "images from the global default project"
run_test test_projects_storage "projects and storage pools"
run_test test_projects_network "projects and networks"
+run_test test_container_devices_disk "container devices - disk"
run_test test_container_devices_nic_p2p "container devices - nic - p2p"
run_test test_container_devices_nic_bridged "container devices - nic - bridged"
run_test test_container_devices_nic_bridged_filtering "container devices - nic - \
bridged - filtering"
diff --git a/test/suites/container_devices_disk.sh \
b/test/suites/container_devices_disk.sh new file mode 100644
index 0000000000..e0368b25eb
--- /dev/null
+++ b/test/suites/container_devices_disk.sh
@@ -0,0 +1,32 @@
+test_container_devices_disk() {
+ ensure_import_testimage
+ ensure_has_localhost_remote "${LXD_ADDR}"
+
+ lxc launch testimage foo
+
+ test_container_devices_disk_shift
+
+ lxc delete -f foo
+}
+
+test_container_devices_disk_shift() {
+ if ! grep -q shiftfs /proc/filesystems; then
+ return
+ fi
+
+ mkdir -p "${TEST_DIR}/shift-source"
+ touch "${TEST_DIR}/shift-source/a"
+ chown 123:456 "${TEST_DIR}/shift-source/a"
+
+ lxc config device add foo shiftfs disk source="${TEST_DIR}/shift-source" path=/mnt
+ [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "65534:65534" ] || false
+ lxc config device remove foo shiftfs
+
+ lxc config device add foo shiftfs disk source="${TEST_DIR}/shift-source" path=/mnt \
shift=true + [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
+
+ lxc stop foo -f
+ lxc start foo
+ [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
+ lxc stop foo -f
+}
[Attachment #4 (text/plain)]
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic