Skip to content
This repository has been archived by the owner on Apr 3, 2018. It is now read-only.

Add support for scsi for hotplugging block devices #584

Merged
merged 5 commits into from
Feb 26, 2018

Conversation

amshinde
Copy link
Collaborator

@amshinde amshinde commented Jan 26, 2018

With this PR, block devices are hotplugged using either virtio-scsi or virtio-block based on a configuration.

@amshinde amshinde force-pushed the switch-to-scsi branch 2 times, most recently from 8bd1c5b to 7b72bf1 Compare January 26, 2018 02:40
@@ -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
Copy link
Collaborator

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?

Copy link
Collaborator Author

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) {
Copy link
Collaborator

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)?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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) {
Copy link
Collaborator

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},
}
Copy link
Collaborator

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"
Copy link
Collaborator

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@amshinde amshinde force-pushed the switch-to-scsi branch 2 times, most recently from 9c09c7f to 1f6287f Compare February 21, 2018 22:53
@amshinde
Copy link
Collaborator Author

@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.

@sboeuf
Copy link
Collaborator

sboeuf commented Feb 22, 2018

@amshinde yes I'll review both PR (virtcontainers and agent) tomorrow !

Copy link
Collaborator

@sboeuf sboeuf left a 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 {
Copy link
Collaborator

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.

Copy link
Collaborator Author

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 {
Copy link
Collaborator

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 ?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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)
Copy link
Collaborator

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"`
Copy link
Collaborator

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 ?

Copy link
Collaborator Author

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.

Copy link
Collaborator

@sboeuf sboeuf Feb 22, 2018

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
Copy link
Collaborator

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 ?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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 {
Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

@@ -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 {
Copy link
Collaborator

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

Copy link
Collaborator Author

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>
@sboeuf
Copy link
Collaborator

sboeuf commented Feb 22, 2018

LGTM

@amshinde
Copy link
Collaborator Author

@jodh-intel Can you take another look at this?

@sboeuf
Copy link
Collaborator

sboeuf commented Feb 23, 2018

@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.

@jodh-intel
Copy link
Collaborator

jodh-intel commented Feb 23, 2018

lgtm

Approved with PullApprove Approved with PullApprove

@amshinde
Copy link
Collaborator Author

@sboeuf I reran the CI after agent SHA update. The CI has passed now. Can we merge this?
This does introduce SCSI as the default storage driver, which means we need to add support for SCSI for kata agent as well. We can change this to virtio-block in a follow up PR in the interim for kata.

@sboeuf
Copy link
Collaborator

sboeuf commented Feb 26, 2018

@amshinde yes perfect !

@sboeuf sboeuf merged commit 494b46c into containers:master Feb 26, 2018
sboeuf pushed a commit that referenced this pull request Mar 1, 2018
This reverts commit 494b46c, reversing
changes made to e475a8f.
sboeuf pushed a commit that referenced this pull request Mar 1, 2018
This reverts commit 494b46c, reversing
changes made to e475a8f.
sboeuf pushed a commit that referenced this pull request Mar 1, 2018
This reverts commit 494b46c, reversing
changes made to e475a8f.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants