Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kola/qemuexec: Add a wwn option for scsis disks #3772

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/cosa/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,15 @@ Additional disks CLI arguments support optional flags using the `--add-disk

- `mpath`: enables multipathing for the disk (see below for details).
- `4k`: sets the disk as 4Kn (4096 physical sector size)
- `channel=CHANNEL`: set the channel type (e.g. `virtio`, `nvme`)
- `channel=CHANNEL`: set the channel type (e.g. `virtio`, `nvme`, `scsi`)
- `serial=NAME`: sets the disk serial; this can then be used to customize the
default `diskN` naming documented above (e.g. `serial=foobar` will make the
device show up as `/dev/disk/by-id/virtio-foobar`)
- `wwn=ID`: sets the disk WWN identifier. Must be an integer. This will only
be used in with `channel=scsi` or `mpath`. Note that the link will be
created with the number converted to it's hexadecimal representation.
(e.g. `wwn=11` will make the device show up as
`/dev/disk/by-id/wwn-0x000000000000000b`)

## Additional kernel arguments

Expand Down
56 changes: 40 additions & 16 deletions mantle/platform/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"net"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -89,12 +90,13 @@ type Disk struct {
Size string // disk image size in bytes, optional suffixes "K", "M", "G", "T" allowed.
BackingFile string // raw disk image to use.
BackingFormat string // qcow2, raw, etc. If unspecified will be autodetected.
Channel string // virtio (default), nvme
Channel string // virtio (default), nvme, scsi
DeviceOpts []string // extra options to pass to qemu -device. "serial=XXXX" makes disks show up as /dev/disk/by-id/virtio-<serial>
DriveOpts []string // extra options to pass to -drive
SectorSize int // if not 0, override disk sector size
NbdDisk bool // if true, the disks should be presented over nbd:unix socket
MultiPathDisk bool // if true, present multiple paths
Wwn uint64 // Optional World wide name for the SCSI disk. If not set or set to 0, a random one will be generated. Used only with "channel=scsi". Must be an integer

attachEndPoint string // qemuPath to attach to
dstFileName string // the prepared file
Expand All @@ -106,6 +108,7 @@ func ParseDisk(spec string) (*Disk, error) {
sectorSize := 0
serialOpt := []string{}
multipathed := false
var wwn uint64

size, diskmap, err := util.ParseDiskSpec(spec)
if err != nil {
Expand All @@ -123,6 +126,11 @@ func ParseDisk(spec string) (*Disk, error) {
case "serial":
value = "serial=" + value
serialOpt = append(serialOpt, value)
case "wwn":
wwn, err = strconv.ParseUint(value, 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid value %s for wwn. Must be an integer", value)
}
default:
return nil, fmt.Errorf("invalid key %q", key)
}
Expand All @@ -134,6 +142,7 @@ func ParseDisk(spec string) (*Disk, error) {
DeviceOpts: serialOpt,
SectorSize: sectorSize,
MultiPathDisk: multipathed,
Wwn: wwn,
}, nil
}

Expand Down Expand Up @@ -1180,13 +1189,13 @@ func (builder *QemuBuilder) addDiskImpl(disk *Disk, primary bool) error {
defaultDiskOpts += "," + strings.Join(disk.DriveOpts, ",")
}

if disk.MultiPathDisk {
// Fake a NVME device with a fake WWN. All these attributes are needed in order
// to trick multipath-tools that this is a "real" multipath device.
// Each disk is presented on its own controller.

if disk.MultiPathDisk || channel == "scsi" {
// Fake a NVME or SCSI device with a fake WWN.
// The WWN needs to be a unique uint64 number
wwn := rand.Uint64()
wwn := disk.Wwn
if wwn == 0 {
wwn = rand.Uint64()
}

var bus string
switch builder.architecture {
Expand All @@ -1198,19 +1207,34 @@ func (builder *QemuBuilder) addDiskImpl(disk *Disk, primary bool) error {
panic(fmt.Sprintf("Mantle doesn't know which bus type to use on %s", builder.architecture))
}

for i := 0; i < 2; i++ {
if i == 1 {
opts = strings.Replace(opts, "bootindex=1", "bootindex=2", -1)
if disk.MultiPathDisk {
// All these attributes are needed in order
// to trick multipath-tools that this is a "real" multipath device.
// Each disk is presented on its own controller.

for i := 0; i < 2; i++ {
if i == 1 {
opts = strings.Replace(opts, "bootindex=1", "bootindex=2", -1)
}
pID := fmt.Sprintf("mpath%d%d", builder.diskID, i)
scsiID := fmt.Sprintf("scsi_%s", pID)
builder.Append("-device", fmt.Sprintf("virtio-scsi-%s,id=%s", bus, scsiID))
builder.Append("-device",
fmt.Sprintf("scsi-hd,bus=%s.0,drive=%s,vendor=NVME,product=VirtualMultipath,wwn=%d%s",
jbtrystram marked this conversation as resolved.
Show resolved Hide resolved
scsiID, pID, wwn, opts))
builder.Append("-drive", fmt.Sprintf("if=none,id=%s,format=raw,file=%s,media=disk,%s",
pID, disk.attachEndPoint, defaultDiskOpts))
}
pID := fmt.Sprintf("mpath%d%d", builder.diskID, i)
scsiID := fmt.Sprintf("scsi_%s", pID)
} else {
scsiID := fmt.Sprintf("scsi_%d", builder.diskID)
builder.Append("-device", fmt.Sprintf("virtio-scsi-%s,id=%s", bus, scsiID))
builder.Append("-device",
fmt.Sprintf("scsi-hd,bus=%s.0,drive=%s,vendor=NVME,product=VirtualMultipath,wwn=%d%s",
scsiID, pID, wwn, opts))
builder.Append("-drive", fmt.Sprintf("if=none,id=%s,format=raw,file=%s,media=disk,%s",
pID, disk.attachEndPoint, defaultDiskOpts))
fmt.Sprintf("scsi-hd,bus=%s.0,drive=%s,wwn=%d%s",
scsiID, id, wwn, opts))
builder.Append("-drive", fmt.Sprintf("if=none,id=%s,file=%s,media=disk,%s",
id, disk.attachEndPoint, defaultDiskOpts))
}

} else {
if !disk.NbdDisk {
// In the non-multipath/nbd case we can just unlink the disk now
Expand Down
Loading