From fcf6fa71a90340c61ebeb0f1900f084f9aa54dfb Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Fri, 31 Aug 2018 14:44:41 -0500 Subject: [PATCH] agent: update resources list with the right device major-minor number Host device's major-minor numbers are mapped to guest major-minor numbers, for example in the host the major-minor number for /dev/loop0p1 is 259:1, when it's attached to the VM now the major-minor number is 8:0, this conversion must be reflected in devices and resources lists, the first list is used to mount the device in the container and the second one is to update the devices cgroup. fixes #351 Signed-off-by: Julio Montes --- device.go | 21 +++++++++++++-- device_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/device.go b/device.go index c03b7f3044..fdd84e9c36 100644 --- a/device.go +++ b/device.go @@ -216,16 +216,33 @@ func updateSpecDeviceList(device pb.Device, spec *pb.Spec) error { // Update the spec for idx, d := range spec.Linux.Devices { if d.Path == device.ContainerPath { + hostMajor := spec.Linux.Devices[idx].Major + hostMinor := spec.Linux.Devices[idx].Minor agentLog.WithFields(logrus.Fields{ "device-path": device.VmPath, - "host-device-major": spec.Linux.Devices[idx].Major, - "host-device-minor": spec.Linux.Devices[idx].Minor, + "host-device-major": hostMajor, + "host-device-minor": hostMinor, "guest-device-major": major, "guest-device-minor": minor, }).Info("updating block device major/minor into the spec") + spec.Linux.Devices[idx].Major = major spec.Linux.Devices[idx].Minor = minor + // there is no resource to update + if spec.Linux == nil || spec.Linux.Resources == nil { + return nil + } + + // Resources must be updated since they are used to identify the + // device in the devices cgroup. + for idxRsrc, dRsrc := range spec.Linux.Resources.Devices { + if dRsrc.Major == hostMajor && dRsrc.Minor == hostMinor { + spec.Linux.Resources.Devices[idxRsrc].Major = major + spec.Linux.Resources.Devices[idxRsrc].Minor = minor + } + } + return nil } } diff --git a/device_test.go b/device_test.go index a3874d7ee3..39416af2c2 100644 --- a/device_test.go +++ b/device_test.go @@ -373,3 +373,73 @@ func TestAddDevice(t *testing.T) { } } } + +func TestUpdateSpecDeviceList(t *testing.T) { + assert := assert.New(t) + + var err error + spec := &pb.Spec{} + device := pb.Device{} + major := int64(7) + minor := int64(2) + + //ContainerPath empty + err = updateSpecDeviceList(device, spec) + assert.Error(err) + + device.ContainerPath = "/dev/null" + + //Linux is nil + err = updateSpecDeviceList(device, spec) + assert.Error(err) + + spec.Linux = &pb.Linux{} + + /// Linux.Devices empty + err = updateSpecDeviceList(device, spec) + assert.Error(err) + + spec.Linux.Devices = []pb.LinuxDevice{ + { + Path: "/dev/null2", + Major: major, + Minor: minor, + }, + } + + // VmPath empty + err = updateSpecDeviceList(device, spec) + assert.Error(err) + + device.VmPath = "/dev/null" + + // guest and host path are not the same + err = updateSpecDeviceList(device, spec) + assert.Error(err) + + spec.Linux.Devices[0].Path = device.ContainerPath + + // spec.Linux.Resources is nil + err = updateSpecDeviceList(device, spec) + assert.NoError(err) + + // update both devices and cgroup lists + spec.Linux.Devices = []pb.LinuxDevice{ + { + Path: device.ContainerPath, + Major: major, + Minor: minor, + }, + } + spec.Linux.Resources = &pb.LinuxResources{ + Devices: []pb.LinuxDeviceCgroup{ + { + Major: major, + Minor: minor, + }, + }, + } + + err = updateSpecDeviceList(device, spec) + assert.NoError(err) +}