Skip to content
This repository was archived by the owner on May 6, 2020. It is now read-only.

Add support for scsi#205

Merged
jodh-intel merged 2 commits intoclearcontainers:masterfrom
amshinde:add-support-for-scsi
Feb 23, 2018
Merged

Add support for scsi#205
jodh-intel merged 2 commits intoclearcontainers:masterfrom
amshinde:add-support-for-scsi

Conversation

@amshinde
Copy link
Copy Markdown
Contributor

@amshinde amshinde commented Jan 25, 2018

Add support for SCSI disks to be passed for container rootfs and volumes.
If SCSI address is provided, use that to get the SCSI disk name.
This eliminates the need to predict the drive name of the block
device on the host side. We do need to incur the cost of scanning SCSI bus.

@amshinde amshinde requested review from egernst and sboeuf January 25, 2018 23:06
Copy link
Copy Markdown

@jodh-intel jodh-intel left a comment

Choose a reason for hiding this comment

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

Hi @amshinde - thanks for raising. I've added a few comments.

Please could you add some tests for these changes as well?

syscall.go Outdated
for _, file := range files {
host := file.Name()
scanPath := filepath.Join(scsiHostPath, host, "scan")
if err := ioutil.WriteFile(scanPath, scanData, 0666); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This should be 0200 I think.

Copy link
Copy Markdown
Contributor Author

@amshinde amshinde Feb 22, 2018

Choose a reason for hiding this comment

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

Yes, it should be 0200. Fixed.

syscall.go Outdated
// but we do need to rescan SCSI bus for this.
func findSCSIDisk(scsiAddr string) (string, error) {
// Here in "0:0", the first number is the SCSI host number, while the second number is always 0.
scsiPath := fmt.Sprintf("/sys/class/scsi_disk/0:0:%s/device/block", scsiAddr)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This path prefix is also used in waitForBlockDevice(). Can you make it a file-global var as that will avoid the duplication and hard-coding, but also allow the value to be changed for testing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Have added tests as well.

}

if fsmap.SCSIAddr != "" {
source, err = getSCSIDisk(fsmap.SCSIAddr)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • This is resetting source so is it worth adding an extra check to see if source != "" here? Or is it guaranteed that if SCSIAddr is set that Source is irrelevant?

    Could you maybe add some comments to the Fsmap type to explain this?

  • Does this check need to come before the AbsolutePath check above as currently that code is being executed for no reason if we're using a SCSI device?

Copy link
Copy Markdown
Contributor Author

@amshinde amshinde Feb 22, 2018

Choose a reason for hiding this comment

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

I have added in comments.

syscall.go Outdated
if _, err := os.Stat(devicePath); err == nil {
if isSCSIAddr {
// Here in "0:0", the first number is the SCSI host number, while the second number is always 0.
scsiPrefix := "/sys/class/scsi_disk/0:0"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can you make this path prefix a file-global var to allow it to be re-used (and changed for testing)?

syscall.go Outdated
// Here in "0:0", the first number is the SCSI host number, while the second number is always 0.
scsiPrefix := "/sys/class/scsi_disk/0:0"

path := scsiPrefix + deviceName + "/device/block"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same comment as above.

syscall.go Outdated
if _, err := os.Stat(path); err == nil {
return nil
}
} else if _, err := os.Stat(devicePath); err == nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think it would be clearer if you moved the devicePath variable down to here and removed the else if:

if isSCSIAddr {
    :
}

devicePath := filepath.Join(devPath, deviceName)

if _, err := os.Stat(devicePath); err == nil {
    return nil
}


syscall.go Outdated
if d.Action() == "add" && filepath.Base(d.Devpath()) == deviceName {

if isSCSIAddr && d.Action() == "add" && strings.Contains(d.Devpath(), deviceName) {
fieldLogger.Info("Hotplug event received")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe "SCSI hotplug event received"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

syscall.go Outdated
return nil
}

// findSCSIDisk finds the SCSI disk name associated with the given SCSI address
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Missing period at end of sentence.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

syscall.go Outdated
return "", err
}

if len(files) > 1 {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There is an implicit assumption that a single file was read, so how about the following:

l := len(files)

if l == 0 || l > 1 {
    ...
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

agent.go Outdated
}

absoluteRootFs, err := mountContainerRootFs(payload.ID, payload.Image, payload.RootFs, payload.FsType)
absoluteRootFs, err := mountContainerRootFs(payload.ID, payload.Image, payload.RootFs, payload.FsType, payload.SCSIAddr)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We should pass the payload to this function, instead of extending its number of parameters, all being attributes of the same structure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I had done this to avoid introducing hyperstart specific structures in syscall.go.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There is no harm doing so. syscall.go is part of the agent, which makes it tied to hyperstart. I don't think this is an issue to pass an hyperstart structure to this function, and this would simplify things as I mentioned.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was just trying to avoid introducing any hyperstart structures here, as this is more like an utils package and is a good contender for moving into its own util package, but that is for the future.
I can simplify this for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have pushed changes for this.

SystemMountsInfo SystemMountsInfo `json:"systemMountsInfo"`

// SCSI address in the format SCSI-Id:LUN
SCSIAddr string `json:"scsiAddr,omitempty"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I am not sure this is the right place for this field. This is very specific to a type of rootfs. Maybe we should define a structure Rootfs so that we can actually include this type of information. WDYT ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is specific to rootfs, but we have other fields here like Rootfs, FsMap and FsType that are related to rootfs that Iwould be candidates for a combined structure. I would like to do that in a separate PR, as this involves a lot of components.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fair enough, but please open an issue to track this down ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure will do.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

thx

}

func waitForBlockDevice(deviceName string) error {
func waitForBlockDevice(deviceName string, isSCSIAddr bool) error {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You should rename this function into waitForDevice() and pass a more global structure. Once again, this looks very specific to SCSI here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Any comment on this ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I would prefer keeping this as is as we are waiting for a Block device here, the difference being if the device is passed with virtio-scsi or virtio-block, with the flag indicating this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yes I agree this is still a block device, forget this comment.

@amshinde amshinde force-pushed the add-support-for-scsi branch 2 times, most recently from 1ac4d30 to 66f12ab Compare February 22, 2018 00:39
syscall.go Outdated
var path string

if isSCSIAddr {
path = scsiDiskPrefix + deviceName + "/device/block"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This would be more consistent (and maybe safer) as:

path = filepath.Join(scsiDiskPrefix + deviceName, "/device/block")

You could also create a variable for the /device/block which is used multiple times.

syscall.go Outdated
if d.Action() == "add" && filepath.Base(d.Devpath()) == deviceName {
fieldLogger.Info("Hotplug event received")

//if isSCSIAddr && d.Action() == "add" && strings.Contains(d.Devpath(), deviceName) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Commented out line.

syscall.go Outdated
fieldLogger.Info("Hotplug event received")

//if isSCSIAddr && d.Action() == "add" && strings.Contains(d.Devpath(), deviceName) {
if isSCSIAddr && d.Action() == "add" && strings.Contains(d.Devpath(), "/0:0:"+deviceName+"/block") {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can you create a global private variable for the 0:0 (and ideally change scsiDiskPrefix to use it too)?

syscall.go Outdated

// scanSCSIBus scans SCSI bus for the given SCSI address(SCSI-Id and LUN)
func scanSCSIBus(scsiAddr string) error {
if _, err := os.Stat(scsiHostPath); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This call isn't needed as the ReadDir() below will detect ENOENT itself. Same comment for the Stat() in findSCSIDisk().

syscall.go Outdated
// If device node is not found, wait for udev event for the scsi disk,
// with the format "0:SCSIId:LUN/block"

//if err := waitForBlockDevice("0:"+scsiAddr+"/block", true); err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can you remove this line please.

@amshinde amshinde force-pushed the add-support-for-scsi branch 2 times, most recently from f946e73 to be3f50e Compare February 22, 2018 16:08
@amshinde
Copy link
Copy Markdown
Contributor Author

@jodh-intel I have pushed changes for your comments. Please have a look.

Add support for SCSI disks to be passed for container rootfs.
If SCSI address is provided, use that to get the SCSI disk name.
This eliminates the need to predict the drive name of the block
device on the host side. We do need to incur the cost of scanning SCSI bus.

Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
Similar to rootfs, add support for SCSI disk to be passed
for a volume mount.

Fixes clearcontainers#209

Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
@amshinde amshinde force-pushed the add-support-for-scsi branch from be3f50e to 3eacdd5 Compare February 22, 2018 18:56
@sboeuf
Copy link
Copy Markdown

sboeuf commented Feb 22, 2018

LGTM
@jodh-intel @egernst please make a new review !

@jodh-intel jodh-intel merged commit 6f6e9ec into clearcontainers:master Feb 23, 2018
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