-
Notifications
You must be signed in to change notification settings - Fork 43
Add support for scsi for hotplugging block devices #584
Conversation
8bd1c5b
to
7b72bf1
Compare
@@ -340,7 +340,10 @@ type BlockDevice struct { | |||
DeviceType string | |||
DeviceInfo DeviceInfo | |||
|
|||
// Path at which the device appears inside the VM, outside of the container mount namespace. | |||
// SCSI Address of the block device, in case the device is attached using SCSI driver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add details of the format here as you did in clearcontainers/agent#205?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added details here.
// qemu code suggests that scsi-id can take values from 0 to 255 inclusive, while lun can | ||
// take values from 0 to 16383 inclusive. But lun values over 255 do not seem to follow | ||
// consistent SCSI addressing. Hence we limit to 255. | ||
func getSCSIIdLun(index int) (int, int, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you rename to scsiIDLun
or similar (https://golang.org/doc/effective_go.html#Getters)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jodh-intel This is not technically a getter for a struct field, but a function that derives the SCSI id and LUN based on an index.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah - fair point.
return index / 256, index % 256, nil | ||
} | ||
|
||
func getSCSIAddress(index int) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment - we don't need the get
prefix.
{258, 1, 2}, | ||
{512, 2, 0}, | ||
{513, 2, 1}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice :)
hypervisor.go
Outdated
@@ -154,6 +154,10 @@ type HypervisorConfig struct { | |||
// DisableBlockDeviceUse disallows a block device from being used. | |||
DisableBlockDeviceUse bool | |||
|
|||
// BlockDeviceDriver specifies the driver to be used for block device | |||
// either "virtio-scsi" or "virtio-blk" with the default driver being "virtio-scsi" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For maintenance, it's going to be safer if you refer to VirtioBlock
and VirtioSCSI
. But It could also be useful to define a DefaultVirtio
which could also be mentioned here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
9c09c7f
to
1f6287f
Compare
@sboeuf Can you take a look at this as well. CI is failing, likely due to lack of SCSI support on the agent side that needs to be merged first. |
@amshinde yes I'll review both PR (virtcontainers and agent) tomorrow ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR looks pretty good, I have a few comments.
As a global comment by looking at all this code related to devices and rootfs, I realize we have some kind of duplicates between what device.go
does for block devices and what hyperstart_agent.go
does for rootfs when it is a block device. I think there is room for factorization here, WDYT @amshinde ? (of course this would be done in a separate PR)
mount.go
Outdated
return -1, -1, fmt.Errorf("Index cannot be negative") | ||
} | ||
|
||
if index > 65535 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a constant for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
if err = q.qmpMonitorCh.qmp.ExecuteSCSIDeviceAdd(q.qmpMonitorCh.ctx, drive.ID, devID, driver, bus, scsiID, lun); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good but I have noticed that you're not handling the case where we want to remove a SCSI device. Am I missing something about the way SCSI works, or have you forgotten to implement this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way to remove SCSI device is the same as virtio-block device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks !
} | ||
container.Image = driveName | ||
} else { | ||
scsiAddr, err := getSCSIAddress(c.state.BlockIndex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice that we don't need to predict here ;)
@@ -207,7 +207,7 @@ type Container struct { | |||
Rootfs string `json:"rootfs"` | |||
Fstype string `json:"fstype,omitempty"` | |||
Image string `json:"image"` | |||
Addr string `json:"addr,omitempty"` | |||
SCSIAddr string `json:"scsiAddr,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you want to change the name ? Addr
is generic enough to include SCSI case , right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had this as Addr in the agent, but changed this to SCSIAddr following your review comment which I agree as SCSIAddr makes it clearer. Hence the change here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had forgotten...
// Path at which the device appears inside the VM, outside of the container mount namespace. | ||
// SCSI Address of the block device, in case the device is attached using SCSI driver | ||
// SCSI address is in the format SCSI-Id:LUN | ||
SCSIAddr string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think this should be part of the DeviceInfo
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No the DeviceInfo includes fields that are common to all devices. This is specific to Block device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense
container.go
Outdated
@@ -420,12 +420,14 @@ func createContainer(pod *Pod, contConfig ContainerConfig) (*Container, error) { | |||
return nil, err | |||
} | |||
|
|||
agentCaps := c.pod.agent.capabilities() | |||
hypervisorCaps := c.pod.hypervisor.capabilities() | |||
if !c.pod.config.HypervisorConfig.DisableBlockDeviceUse { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase, as this has been merged in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased. Moved some code from qemu.go to qemu_arch_base.go introduced with arm support.
1f6287f
to
e3bcd95
Compare
qemu_arch_base.go
Outdated
@@ -277,6 +285,16 @@ func (q *qemuArchBase) appendImage(devices []govmmQemu.Device, path string) ([]g | |||
return q.appendBlockDevice(devices, drive), nil | |||
} | |||
|
|||
func (q *qemu) appendSCSIController(devices []govmmQemu.Device, podConfig PodConfig) []govmmQemu.Device { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to be a function of qemuArchBase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Introduce a configuration option for using either virtio-scsi or virtio-block for hotplugging drives with virtio-scsi being the default driver. Hotplug block devices based on this confuration. In order to hotplug SCSI drives, we need to coldplug a SCSI controller while starting up qemu. With virtio-scsi, use the index at which the drive is attached to come up with a SCSI id and LUN. This will be used by the agent to detect the drive name. Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
Since virtio-scsi is used as default driver for block devices, modify tests to include this in the default config. Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
In case of SCSI driver, pass the SCSI address in the format "SCSI-id:LUN" to hyperstart agent. This will be used by the agent to find the device within the VM. This avoids predicting the drive name on the host side in case of SCSI. Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
Volumes can now be passed using SCSI. Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
Test for SCSI and block drivers while attaching block device. Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
e3bcd95
to
07c2c88
Compare
LGTM |
@jodh-intel Can you take another look at this? |
@amshinde please update the agent commit sha1 in the runtime, this way, after you get your PR on the runtime merged, this PR should be re-triggered and pass. |
@sboeuf I reran the CI after agent SHA update. The CI has passed now. Can we merge this? |
@amshinde yes perfect ! |
With this PR, block devices are hotplugged using either virtio-scsi or virtio-block based on a configuration.