[lxc-devel] [lxd/master] devices: switch to improved device naming scheme
brauner on Github
lxc-bot at linuxcontainers.org
Fri Nov 24 21:13:38 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 416 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171124/7ac3975e/attachment.bin>
-------------- next part --------------
From 8d0dc2b85950522e784831fa9c38ab358fe8eae3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Nov 2017 15:30:33 +0100
Subject: [PATCH 1/3] devices: pass the name of the device
This is done in preparation for our new device handling whereby each device
gets a new subfolder named after the name of the device.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/container_lxc.go | 84 +++++++++++++++++++++++++++-------------------------
lxd/devices.go | 4 +--
2 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index ea1201cd2..a47a6f84c 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1634,7 +1634,7 @@ func (c *containerLXC) expandDevices() error {
// setupUnixDevice() creates the unix device and sets up the necessary low-level
// liblxc configuration items.
-func (c *containerLXC) setupUnixDevice(devType string, dev types.Device, major int, minor int, path string, createMustSucceed bool) error {
+func (c *containerLXC) setupUnixDevice(name string, dev types.Device, major int, minor int, path string, createMustSucceed bool) error {
if c.IsPrivileged() && !c.state.OS.RunningInUserNS && c.state.OS.CGroupDevicesController {
err := lxcSetConfigItem(c.c, "lxc.cgroup.devices.allow", fmt.Sprintf("c %d:%d rwm", major, minor))
if err != nil {
@@ -1651,9 +1651,9 @@ func (c *containerLXC) setupUnixDevice(devType string, dev types.Device, major i
temp["minor"] = fmt.Sprintf("%d", minor)
temp["path"] = path
- paths, err := c.createUnixDevice(temp)
+ paths, err := c.createUnixDevice(name, temp)
if err != nil {
- logger.Debug("failed to create device", log.Ctx{"err": err, "device": devType})
+ logger.Debug("failed to create device", log.Ctx{"err": err, "device": name})
if createMustSucceed {
return err
}
@@ -1855,7 +1855,7 @@ func (c *containerLXC) startCommon() (string, error) {
m := c.expandedDevices[k]
if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
// Unix device
- paths, err := c.createUnixDevice(m)
+ paths, err := c.createUnixDevice(k, m)
if err != nil {
return "", err
}
@@ -3862,7 +3862,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
// Live update the devices
for k, m := range removeDevices {
if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
- err = c.removeUnixDevice(m)
+ err = c.removeUnixDevice(k, m)
if err != nil {
return err
}
@@ -3890,7 +3890,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
continue
}
- err := c.removeUnixDeviceNum(m, usb.major, usb.minor, usb.path)
+ err := c.removeUnixDeviceNum(k, m, usb.major, usb.minor, usb.path)
if err != nil {
return err
}
@@ -3911,7 +3911,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
continue
}
- err := c.removeUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
+ err := c.removeUnixDeviceNum(k, m, gpu.major, gpu.minor, gpu.path)
if err != nil {
logger.Error("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
return err
@@ -3921,7 +3921,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
continue
}
- err = c.removeUnixDeviceNum(m, gpu.nvidia.major, gpu.nvidia.minor, gpu.nvidia.path)
+ err = c.removeUnixDeviceNum(k, m, gpu.nvidia.major, gpu.nvidia.minor, gpu.nvidia.path)
if err != nil {
logger.Error("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
return err
@@ -3931,7 +3931,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
nvidiaExists := false
for _, gpu := range gpus {
if gpu.nvidia.path != "" {
- if c.deviceExists(gpu.path) {
+ if c.deviceExists(k, gpu.path) {
nvidiaExists = true
break
}
@@ -3940,10 +3940,10 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
if !nvidiaExists {
for _, gpu := range nvidiaDevices {
- if !c.deviceExists(gpu.path) {
+ if !c.deviceExists(k, gpu.path) {
continue
}
- err = c.removeUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
+ err = c.removeUnixDeviceNum(k, m, gpu.major, gpu.minor, gpu.path)
if err != nil {
logger.Error("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
return err
@@ -3957,7 +3957,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
for k, m := range addDevices {
if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
- err = c.insertUnixDevice(m)
+ err = c.insertUnixDevice(k, m)
if err != nil {
return err
}
@@ -3981,7 +3981,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
continue
}
- err = c.insertUnixDeviceNum(m, usb.major, usb.minor, usb.path)
+ err = c.insertUnixDeviceNum(k, m, usb.major, usb.minor, usb.path)
if err != nil {
logger.Error("failed to insert usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
}
@@ -4006,7 +4006,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
found = true
- err = c.insertUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
+ err = c.insertUnixDeviceNum(k, m, gpu.major, gpu.minor, gpu.path)
if err != nil {
logger.Error("Failed to insert GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
return err
@@ -4016,7 +4016,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
continue
}
- err = c.insertUnixDeviceNum(m, gpu.nvidia.major, gpu.nvidia.minor, gpu.nvidia.path)
+ err = c.insertUnixDeviceNum(k, m, gpu.nvidia.major, gpu.nvidia.minor, gpu.nvidia.path)
if err != nil {
logger.Error("Failed to insert GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
return err
@@ -4027,10 +4027,10 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
if sawNvidia {
for _, gpu := range nvidiaDevices {
- if c.deviceExists(gpu.path) {
+ if c.deviceExists(k, gpu.path) {
continue
}
- err = c.insertUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
+ err = c.insertUnixDeviceNum(k, m, gpu.major, gpu.minor, gpu.path)
if err != nil {
logger.Error("failed to insert GPU device", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
return err
@@ -5602,7 +5602,7 @@ func (c *containerLXC) removeMount(mount string) error {
}
// Check if the unix device already exists.
-func (c *containerLXC) deviceExists(path string) bool {
+func (c *containerLXC) deviceExists(name string, path string) bool {
tgtPath := strings.TrimPrefix(path, "/")
devName := fmt.Sprintf("unix.%s", strings.Replace(tgtPath, "/", "-", -1))
devPath := filepath.Join(c.DevicesPath(), devName)
@@ -5610,7 +5610,7 @@ func (c *containerLXC) deviceExists(path string) bool {
}
// Unix devices handling
-func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
+func (c *containerLXC) createUnixDevice(name string, m types.Device) ([]string, error) {
var err error
var major, minor int
@@ -5619,9 +5619,11 @@ func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
if !exist {
srcPath = m["path"]
}
+
relativeSrcPath := strings.TrimPrefix(srcPath, "/")
- devName := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
- devPath := filepath.Join(c.DevicesPath(), devName)
+
+ devNameLegacy := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
+ devPathLegacy := filepath.Join(c.DevicesPath(), devNameLegacy)
// Extra checks for nesting
if c.state.OS.RunningInUserNS {
@@ -5696,12 +5698,12 @@ func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
}
// Clean any existing entry
- if shared.PathExists(devPath) {
+ if shared.PathExists(devPathLegacy) {
if c.state.OS.RunningInUserNS {
- syscall.Unmount(devPath, syscall.MNT_DETACH)
+ syscall.Unmount(devPathLegacy, syscall.MNT_DETACH)
}
- err = os.Remove(devPath)
+ err = os.Remove(devPathLegacy)
if err != nil {
return nil, fmt.Errorf("Failed to remove existing entry: %s", err)
}
@@ -5710,17 +5712,17 @@ func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
// Create the new entry
if !c.state.OS.RunningInUserNS {
encoded_device_number := (minor & 0xff) | (major << 8) | ((minor & ^0xff) << 12)
- if err := syscall.Mknod(devPath, uint32(mode), encoded_device_number); err != nil {
- return nil, fmt.Errorf("Failed to create device %s for %s: %s", devPath, m["path"], err)
+ if err := syscall.Mknod(devPathLegacy, uint32(mode), encoded_device_number); err != nil {
+ return nil, fmt.Errorf("Failed to create device %s for %s: %s", devPathLegacy, m["path"], err)
}
- if err := os.Chown(devPath, uid, gid); err != nil {
- return nil, fmt.Errorf("Failed to chown device %s: %s", devPath, err)
+ if err := os.Chown(devPathLegacy, uid, gid); err != nil {
+ return nil, fmt.Errorf("Failed to chown device %s: %s", devPathLegacy, err)
}
// Needed as mknod respects the umask
- if err := os.Chmod(devPath, mode); err != nil {
- return nil, fmt.Errorf("Failed to chmod device %s: %s", devPath, err)
+ if err := os.Chmod(devPathLegacy, mode); err != nil {
+ return nil, fmt.Errorf("Failed to chmod device %s: %s", devPathLegacy, err)
}
idmapset, err := c.IdmapSet()
@@ -5729,19 +5731,19 @@ func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
}
if idmapset != nil {
- if err := idmapset.ShiftFile(devPath); err != nil {
+ if err := idmapset.ShiftFile(devPathLegacy); err != nil {
// uidshift failing is weird, but not a big problem. Log and proceed
logger.Debugf("Failed to uidshift device %s: %s\n", m["path"], err)
}
}
} else {
- f, err := os.Create(devPath)
+ f, err := os.Create(devPathLegacy)
if err != nil {
return nil, err
}
f.Close()
- err = deviceMountDisk(srcPath, devPath, false, false)
+ err = deviceMountDisk(srcPath, devPathLegacy, false, false)
if err != nil {
return nil, err
}
@@ -5753,17 +5755,17 @@ func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
tgtPath = m["source"]
}
relativeTgtPath := strings.TrimPrefix(tgtPath, "/")
- return []string{devPath, relativeTgtPath}, nil
+ return []string{devPathLegacy, relativeTgtPath}, nil
}
-func (c *containerLXC) insertUnixDevice(m types.Device) error {
+func (c *containerLXC) insertUnixDevice(name string, m types.Device) error {
// Check that the container is running
if !c.IsRunning() {
return fmt.Errorf("Can't insert device into stopped container")
}
// Create the device on the host
- paths, err := c.createUnixDevice(m)
+ paths, err := c.createUnixDevice(name, m)
if err != nil {
return fmt.Errorf("Failed to setup device: %s", err)
}
@@ -5818,7 +5820,7 @@ func (c *containerLXC) insertUnixDevice(m types.Device) error {
return nil
}
-func (c *containerLXC) insertUnixDeviceNum(m types.Device, major int, minor int, path string) error {
+func (c *containerLXC) insertUnixDeviceNum(name string, m types.Device, major int, minor int, path string) error {
temp := types.Device{}
if err := shared.DeepCopy(&m, &temp); err != nil {
return err
@@ -5828,10 +5830,10 @@ func (c *containerLXC) insertUnixDeviceNum(m types.Device, major int, minor int,
temp["minor"] = fmt.Sprintf("%d", minor)
temp["path"] = path
- return c.insertUnixDevice(temp)
+ return c.insertUnixDevice(name, temp)
}
-func (c *containerLXC) removeUnixDevice(m types.Device) error {
+func (c *containerLXC) removeUnixDevice(name string, m types.Device) error {
// Check that the container is running
pid := c.InitPID()
if pid == -1 {
@@ -5919,7 +5921,7 @@ func (c *containerLXC) removeUnixDevice(m types.Device) error {
return nil
}
-func (c *containerLXC) removeUnixDeviceNum(m types.Device, major int, minor int, path string) error {
+func (c *containerLXC) removeUnixDeviceNum(name string, m types.Device, major int, minor int, path string) error {
pid := c.InitPID()
if pid == -1 {
return fmt.Errorf("Can't remove device from stopped container")
@@ -5934,7 +5936,7 @@ func (c *containerLXC) removeUnixDeviceNum(m types.Device, major int, minor int,
temp["minor"] = fmt.Sprintf("%d", minor)
temp["path"] = path
- err := c.removeUnixDevice(temp)
+ err := c.removeUnixDevice(name, temp)
if err != nil {
logger.Error("failed to remove device", log.Ctx{"err": err, m["type"]: path, "container": c.Name()})
return err
diff --git a/lxd/devices.go b/lxd/devices.go
index bf2772a83..bda6fdfbb 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -795,13 +795,13 @@ func deviceUSBEvent(s *state.State, usb usbDevice) {
}
if usb.action == "add" {
- err := c.insertUnixDeviceNum(m, usb.major, usb.minor, usb.path)
+ err := c.insertUnixDeviceNum(name, m, usb.major, usb.minor, usb.path)
if err != nil {
logger.Error("failed to create usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
return
}
} else if usb.action == "remove" {
- err := c.removeUnixDeviceNum(m, usb.major, usb.minor, usb.path)
+ err := c.removeUnixDeviceNum(name, m, usb.major, usb.minor, usb.path)
if err != nil {
logger.Error("failed to remove usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
return
From de3df2d944d29a1b3e5af795879795b4dad25db4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Nov 2017 19:36:33 +0100
Subject: [PATCH 2/3] devices: add new unix-{char,block} format
The new device creation format encodes the device name into the device file:
/var/lib/lxd/devices/<container-name>/unix.<device name>.<container path>
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/container_lxc.go | 123 +++++++++++++++++++++++++++++----------------------
1 file changed, 71 insertions(+), 52 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index a47a6f84c..f508bb07c 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1339,22 +1339,16 @@ func (c *containerLXC) initLXC(config bool) error {
for _, k := range c.expandedDevices.DeviceNames() {
m := c.expandedDevices[k]
if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
- // Prepare all the paths
- srcPath, exist := m["source"]
+ // destination paths
+ destPath, exist := m["path"]
if !exist {
- srcPath = m["path"]
+ destPath = m["source"]
}
- relativeSrcPath := strings.TrimPrefix(srcPath, "/")
- devName := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
- devPath := filepath.Join(c.DevicesPath(), devName)
- tgtPath, exist := m["path"]
- if !exist {
- tgtPath = m["source"]
- }
- relativeTgtPath := strings.TrimPrefix(tgtPath, "/")
+ relativeDestPath := strings.TrimPrefix(destPath, "/")
+ sourceDevPath := filepath.Join(c.DevicesPath(), fmt.Sprintf("unix.%s.%s", k, strings.Replace(relativeDestPath, "/", "-", -1)))
- // Set the bind-mount entry
- err = lxcSetConfigItem(cc, "lxc.mount.entry", fmt.Sprintf("%s %s none bind,create=file", devPath, relativeTgtPath))
+ // inform liblxc about the mount
+ err = lxcSetConfigItem(cc, "lxc.mount.entry", fmt.Sprintf("%s %s none bind,create=file", sourceDevPath, relativeDestPath))
if err != nil {
return err
}
@@ -5603,9 +5597,18 @@ func (c *containerLXC) removeMount(mount string) error {
// Check if the unix device already exists.
func (c *containerLXC) deviceExists(name string, path string) bool {
- tgtPath := strings.TrimPrefix(path, "/")
- devName := fmt.Sprintf("unix.%s", strings.Replace(tgtPath, "/", "-", -1))
- devPath := filepath.Join(c.DevicesPath(), devName)
+ relativeDestPath := strings.TrimPrefix(path, "/")
+ devPath := ""
+ if name == "" {
+ // legacy style
+ devName := fmt.Sprintf("unix.%s", strings.Replace(relativeDestPath, "/", "-", -1))
+ devPath = filepath.Join(c.DevicesPath(), devName)
+ } else {
+ // new style
+ devName := fmt.Sprintf("unix.%s.%s", name, strings.Replace(relativeDestPath, "/", "-", -1))
+ devPath = filepath.Join(c.DevicesPath(), devName)
+ }
+
return shared.PathExists(devPath)
}
@@ -5614,17 +5617,6 @@ func (c *containerLXC) createUnixDevice(name string, m types.Device) ([]string,
var err error
var major, minor int
- // Our device paths
- srcPath, exist := m["source"]
- if !exist {
- srcPath = m["path"]
- }
-
- relativeSrcPath := strings.TrimPrefix(srcPath, "/")
-
- devNameLegacy := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
- devPathLegacy := filepath.Join(c.DevicesPath(), devNameLegacy)
-
// Extra checks for nesting
if c.state.OS.RunningInUserNS {
for key, value := range m {
@@ -5634,6 +5626,8 @@ func (c *containerLXC) createUnixDevice(name string, m types.Device) ([]string,
}
}
+ srcPath := shared.HostPath(m["source"])
+
// Get the major/minor of the device we want to create
if m["major"] == "" && m["minor"] == "" {
// If no major and minor are set, use those from the device on the host
@@ -5697,6 +5691,22 @@ func (c *containerLXC) createUnixDevice(name string, m types.Device) ([]string,
}
}
+ relativeSrcPath := strings.TrimPrefix(m["source"], "/")
+
+ // legacy style unix device creation
+ devName := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
+ devPathLegacy := filepath.Join(c.DevicesPath(), devName)
+
+ destPath, exist := m["path"]
+ if !exist {
+ destPath = m["source"]
+ }
+ relativeDestPath := strings.TrimPrefix(destPath, "/")
+
+ // new style unix device creation
+ devName = fmt.Sprintf("unix.%s.%s", name, strings.Replace(relativeDestPath, "/", "-", -1))
+ devPathDeviceNameEncoded := filepath.Join(c.DevicesPath(), devName)
+
// Clean any existing entry
if shared.PathExists(devPathLegacy) {
if c.state.OS.RunningInUserNS {
@@ -5712,17 +5722,17 @@ func (c *containerLXC) createUnixDevice(name string, m types.Device) ([]string,
// Create the new entry
if !c.state.OS.RunningInUserNS {
encoded_device_number := (minor & 0xff) | (major << 8) | ((minor & ^0xff) << 12)
- if err := syscall.Mknod(devPathLegacy, uint32(mode), encoded_device_number); err != nil {
- return nil, fmt.Errorf("Failed to create device %s for %s: %s", devPathLegacy, m["path"], err)
+ if err := syscall.Mknod(devPathDeviceNameEncoded, uint32(mode), encoded_device_number); err != nil {
+ return nil, fmt.Errorf("Failed to create device %s for %s: %s", devPathDeviceNameEncoded, m["path"], err)
}
- if err := os.Chown(devPathLegacy, uid, gid); err != nil {
- return nil, fmt.Errorf("Failed to chown device %s: %s", devPathLegacy, err)
+ if err := os.Chown(devPathDeviceNameEncoded, uid, gid); err != nil {
+ return nil, fmt.Errorf("Failed to chown device %s: %s", devPathDeviceNameEncoded, err)
}
// Needed as mknod respects the umask
- if err := os.Chmod(devPathLegacy, mode); err != nil {
- return nil, fmt.Errorf("Failed to chmod device %s: %s", devPathLegacy, err)
+ if err := os.Chmod(devPathDeviceNameEncoded, mode); err != nil {
+ return nil, fmt.Errorf("Failed to chmod device %s: %s", devPathDeviceNameEncoded, err)
}
idmapset, err := c.IdmapSet()
@@ -5731,31 +5741,25 @@ func (c *containerLXC) createUnixDevice(name string, m types.Device) ([]string,
}
if idmapset != nil {
- if err := idmapset.ShiftFile(devPathLegacy); err != nil {
+ if err := idmapset.ShiftFile(devPathDeviceNameEncoded); err != nil {
// uidshift failing is weird, but not a big problem. Log and proceed
logger.Debugf("Failed to uidshift device %s: %s\n", m["path"], err)
}
}
} else {
- f, err := os.Create(devPathLegacy)
+ f, err := os.Create(devPathDeviceNameEncoded)
if err != nil {
return nil, err
}
f.Close()
- err = deviceMountDisk(srcPath, devPathLegacy, false, false)
+ err = deviceMountDisk(srcPath, devPathDeviceNameEncoded, false, false)
if err != nil {
return nil, err
}
}
- // generate relative target path
- tgtPath, exist := m["path"]
- if !exist {
- tgtPath = m["source"]
- }
- relativeTgtPath := strings.TrimPrefix(tgtPath, "/")
- return []string{devPathLegacy, relativeTgtPath}, nil
+ return []string{devPathDeviceNameEncoded, relativeDestPath}, nil
}
func (c *containerLXC) insertUnixDevice(name string, m types.Device) error {
@@ -5840,15 +5844,6 @@ func (c *containerLXC) removeUnixDevice(name string, m types.Device) error {
return fmt.Errorf("Can't remove device from stopped container")
}
- // Figure out the paths
- srcPath, exist := m["source"]
- if !exist {
- srcPath = m["path"]
- }
- relativeSrcPath := strings.TrimPrefix(srcPath, "/")
- devName := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
- devPath := filepath.Join(c.DevicesPath(), devName)
-
// Check if we've been passed major and minor numbers already.
var tmp int
var err error
@@ -5875,6 +5870,30 @@ func (c *containerLXC) removeUnixDevice(name string, m types.Device) error {
dType = "b"
}
+ // Figure out the paths
+ srcPath, exist := m["source"]
+ if !exist {
+ srcPath = m["path"]
+ }
+
+ relativeSrcPath := strings.TrimPrefix(srcPath, "/")
+
+ // legacy style unix device creation
+ devName := fmt.Sprintf("unix.%s", strings.Replace(relativeSrcPath, "/", "-", -1))
+ devPath := filepath.Join(c.DevicesPath(), devName)
+ if !shared.PathExists(devPath) {
+ // Figure out the paths
+ destPath, exist := m["path"]
+ if !exist {
+ destPath = m["source"]
+ }
+
+ relativeDestPath := strings.TrimPrefix(destPath, "/")
+ // new style unix device creation
+ devName = fmt.Sprintf("unix.%s.%s", name, strings.Replace(relativeDestPath, "/", "-", -1))
+ devPath = filepath.Join(c.DevicesPath(), devName)
+ }
+
if dType == "" || dMajor < 0 || dMinor < 0 {
dType, dMajor, dMinor, err = deviceGetAttributes(devPath)
if err != nil {
From d32e404a597520cc3280d5ca2163a5467202e32a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Nov 2017 21:32:11 +0100
Subject: [PATCH 3/3] devices: add new disk-{char,block} format
The new device creation format encodes the device name into the device file:
/var/lib/lxd/devices/<container-name>/disk.<device name>.<container path>
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/container_lxc.go | 68 +++++++++++++++++++++++++++++++++-------------------
1 file changed, 44 insertions(+), 24 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f508bb07c..b747cbfc5 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1451,11 +1451,16 @@ func (c *containerLXC) initLXC(config bool) error {
// bump network index
networkidx++
} else if m["type"] == "disk" {
- // Prepare all the paths
+ isRootfs := isRootDiskDevice(m)
+
+ // source paths
srcPath := shared.HostPath(m["source"])
- tgtPath := strings.TrimPrefix(m["path"], "/")
- devName := fmt.Sprintf("disk.%s", strings.Replace(tgtPath, "/", "-", -1))
- devPath := filepath.Join(c.DevicesPath(), devName)
+
+ // destination paths
+ destPath := m["path"]
+ relativeDestPath := strings.TrimPrefix(destPath, "/")
+
+ sourceDevPath := filepath.Join(c.DevicesPath(), fmt.Sprintf("disk.%s.%s", k, strings.Replace(relativeDestPath, "/", "-", -1)))
// Various option checks
isOptional := shared.IsTrue(m["optional"])
@@ -1471,7 +1476,7 @@ func (c *containerLXC) initLXC(config bool) error {
}
// Deal with a rootfs
- if tgtPath == "" {
+ if isRootfs {
if !util.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
// Set the rootfs backend type if supported (must happen before any other lxc.rootfs)
err := lxcSetConfigItem(cc, "lxc.rootfs.backend", "dir")
@@ -1523,7 +1528,7 @@ func (c *containerLXC) initLXC(config bool) error {
options = append(options, "create=dir")
}
- err = lxcSetConfigItem(cc, "lxc.mount.entry", fmt.Sprintf("%s %s none %sbind,%s", devPath, tgtPath, rbind, strings.Join(options, ",")))
+ err = lxcSetConfigItem(cc, "lxc.mount.entry", fmt.Sprintf("%s %s none %sbind,%s", sourceDevPath, relativeDestPath, rbind, strings.Join(options, ",")))
if err != nil {
return err
}
@@ -6545,11 +6550,11 @@ func (c *containerLXC) removeNetworkDevice(name string, m types.Device) error {
// Disk device handling
func (c *containerLXC) createDiskDevice(name string, m types.Device) (string, error) {
- // Prepare all the paths
- srcPath := shared.HostPath(m["source"])
- tgtPath := strings.TrimPrefix(m["path"], "/")
- devName := fmt.Sprintf("disk.%s", strings.Replace(tgtPath, "/", "-", -1))
+ // source paths
+ relativeDestPath := strings.TrimPrefix(m["path"], "/")
+ devName := fmt.Sprintf("disk.%s.%s", name, strings.Replace(relativeDestPath, "/", "-", -1))
devPath := filepath.Join(c.DevicesPath(), devName)
+ srcPath := shared.HostPath(m["source"])
// Check if read-only
isOptional := shared.IsTrue(m["optional"])
@@ -6691,8 +6696,8 @@ func (c *containerLXC) insertDiskDevice(name string, m types.Device) error {
}
// Bind-mount it into the container
- tgtPath := strings.TrimSuffix(m["path"], "/")
- err = c.insertMount(devPath, tgtPath, "none", flags)
+ destPath := strings.TrimSuffix(m["path"], "/")
+ err = c.insertMount(devPath, destPath, "none", flags)
if err != nil {
return fmt.Errorf("Failed to add mount for device: %s", err)
}
@@ -6723,7 +6728,16 @@ func (c *containerLXC) addDiskDevices(devices map[string]types.Device, handler f
sort.Sort(ordered)
for _, d := range ordered {
- err := handler(d["path"], d)
+ key := ""
+ for k, dd := range devices {
+ key = ""
+ if reflect.DeepEqual(d, dd) {
+ key = k
+ break
+ }
+ }
+
+ err := handler(key, d)
if err != nil {
return err
}
@@ -6740,25 +6754,31 @@ func (c *containerLXC) removeDiskDevice(name string, m types.Device) error {
}
// Figure out the paths
- tgtPath := strings.TrimPrefix(m["path"], "/")
- devName := fmt.Sprintf("disk.%s", strings.Replace(tgtPath, "/", "-", -1))
+ destPath := strings.TrimPrefix(m["path"], "/")
+
+ // legacy style
+ devName := fmt.Sprintf("disk.%s", strings.Replace(destPath, "/", "-", -1))
devPath := filepath.Join(c.DevicesPath(), devName)
- // The dsk device doesn't exist and cannot be mounted.
if !shared.PathExists(devPath) {
- return nil
+ // new style
+ devName = fmt.Sprintf("disk.%s.%s", name, strings.Replace(destPath, "/", "-", -1))
+ devPath = filepath.Join(c.DevicesPath(), devName)
+
+ // The disk device doesn't exist.
+ if !shared.PathExists(devPath) {
+ return nil
+ }
}
// Remove the bind-mount from the container
- if c.FileExists(tgtPath) == nil {
- err := c.removeMount(m["path"])
- if err != nil {
- return fmt.Errorf("Error unmounting the device: %s", err)
- }
+ err := c.removeMount(m["path"])
+ if err != nil {
+ return fmt.Errorf("Error unmounting the device: %s", err)
}
// Unmount the host side
- err := syscall.Unmount(devPath, syscall.MNT_DETACH)
+ err = syscall.Unmount(devPath, syscall.MNT_DETACH)
if err != nil {
return err
}
@@ -6786,7 +6806,7 @@ func (c *containerLXC) removeDiskDevices() error {
// Go through all the unix devices
for _, f := range dents {
- // Skip non-Unix devices
+ // Skip non-disk devices
if !strings.HasPrefix(f.Name(), "disk.") {
continue
}
More information about the lxc-devel
mailing list