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) +}