The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2721
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) === In particular, if there are two paths to be mounted: /mnt /mnt/foo We should always mount /mnt before we mount /mnt/foo, otherwise, the /mnt mount will overmount /mnt/foo, which is almost certainly not what people want. Closes #2717 Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
From 7507fa1c2fe65ef50f487d26877ec5f5a1515b5d Mon Sep 17 00:00:00 2001 From: Tycho Andersen <tycho.ander...@canonical.com> Date: Wed, 14 Dec 2016 17:16:38 +0000 Subject: [PATCH] do mounts in the right order In particular, if there are two paths to be mounted: /mnt /mnt/foo We should always mount /mnt before we mount /mnt/foo, otherwise, the /mnt mount will overmount /mnt/foo, which is almost certainly not what people want. Closes #2717 Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com> --- lxd/container_lxc.go | 59 +++++++++++++++++++++++++++++++++++++++++++-------- test/suites/config.sh | 20 +++++++++++++++++ 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go index 5561571..cbbe8c2 100644 --- a/lxd/container_lxc.go +++ b/lxd/container_lxc.go @@ -1577,6 +1577,7 @@ func (c *containerLXC) startCommon() (string, error) { var usbs []usbDevice var gpus []gpuDevice var nvidiaDevices []nvidiaGpuDevices + diskDevices := map[string]shared.Device{} // Create the devices for _, k := range c.expandedDevices.DeviceNames() { @@ -1662,12 +1663,8 @@ func (c *containerLXC) startCommon() (string, error) { } } } else if m["type"] == "disk" { - // Disk device if m["path"] != "/" { - _, err := c.createDiskDevice(k, m) - if err != nil { - return "", err - } + diskDevices[k] = m } } else if m["type"] == "nic" { if m["nictype"] == "bridged" && shared.IsTrue(m["security.mac_filtering"]) { @@ -1710,6 +1707,14 @@ func (c *containerLXC) startCommon() (string, error) { } } + err = c.addDiskDevices(diskDevices, func(name string, d shared.Device) error { + _, err := c.createDiskDevice(name, d) + return err + }) + if err != nil { + return "", err + } + // Create any missing directory err = os.MkdirAll(c.LogPath(), 0700) if err != nil { @@ -3412,6 +3417,8 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error { } } + diskDevices := map[string]shared.Device{} + for k, m := range addDevices { if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) { err = c.insertUnixDevice(m) @@ -3419,10 +3426,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error { return err } } else if m["type"] == "disk" && m["path"] != "/" { - err = c.insertDiskDevice(k, m) - if err != nil { - return err - } + diskDevices[k] = m } else if m["type"] == "nic" { err = c.insertNetworkDevice(k, m) if err != nil { @@ -3497,6 +3501,11 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error { } } + err = c.addDiskDevices(diskDevices, c.insertDiskDevice) + if err != nil { + return err + } + updateDiskLimit := false for k, m := range updateDevices { if m["type"] == "disk" { @@ -5707,6 +5716,38 @@ func (c *containerLXC) insertDiskDevice(name string, m shared.Device) error { return nil } +type byPath []shared.Device + +func (a byPath) Len() int { + return len(a) +} + +func (a byPath) Swap(i, j int) { + a[i], a[j] = a[j], a[i] +} + +func (a byPath) Less(i, j int) bool { + return a[i]["path"] < a[j]["path"] +} + +func (c *containerLXC) addDiskDevices(devices map[string]shared.Device, handler func(string, shared.Device)error) error { + ordered := byPath{} + + for _, d := range devices { + ordered = append(ordered, d) + } + + sort.Sort(ordered) + for _, d := range ordered { + err := handler(d["path"], d) + if err != nil { + return err + } + } + + return nil +} + func (c *containerLXC) removeDiskDevice(name string, m shared.Device) error { // Check that the container is running pid := c.InitPID() diff --git a/test/suites/config.sh b/test/suites/config.sh index 74c6d78..3bfbaea 100644 --- a/test/suites/config.sh +++ b/test/suites/config.sh @@ -79,6 +79,24 @@ testloopmounts() { sed -i "\|^${lpath}|d" "${TEST_DIR}/loops" } +test_mount_order() { + mkdir -p "${TEST_DIR}/order/empty" + mkdir -p "${TEST_DIR}/order/full" + touch "${TEST_DIR}/order/full/filler" + + # The idea here is that sometimes (depending on how golang randomizes the + # config) the empty dir will have the contents of full in it, but sometimes + # it won't depending on whether the devices below are processed in order or + # not. This should not be racy, and they should *always* be processed in path + # order, so the filler file should always be there. + lxc config device add foo order disk source="${TEST_DIR}/order" path=/mnt + lxc config device add foo orderFull disk source="${TEST_DIR}/order/full" path=/mnt/empty + + lxc start foo + lxc exec foo -- cat /mnt/empty/filler + lxc stop foo --force +} + test_config_profiles() { ensure_import_testimage @@ -185,6 +203,8 @@ test_config_profiles() { testloopmounts + test_mount_order + lxc delete foo lxc init testimage foo
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel