Skip to content

Commit

Permalink
util: put ParseDiskSpec func to common
Browse files Browse the repository at this point in the history
  • Loading branch information
HuijingHei committed May 23, 2023
1 parent e34aea5 commit f841e42
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 36 deletions.
61 changes: 25 additions & 36 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 @@ -101,47 +102,35 @@ type Disk struct {
nbdServCmd exec.Cmd // command to serve the disk
}

// ParseDiskSpec converts a disk specification into a Disk. The format is:
// <size>[:<opt1>,<opt2>,...].
func ParseDiskSpec(spec string) (*Disk, error) {
split := strings.Split(spec, ":")
var size string
func ParseDisk(spec string) (*Disk, error) {
var diskmap map[string]string
var disksize string
var channel string
multipathed := false
sectorSize := 0
var sectorSize int64
serial_opt := []string{}
if len(split) == 1 {
size = split[0]
} else if len(split) == 2 {
size = split[0]
for _, opt := range strings.Split(split[1], ",") {
if opt == "mpath" {
multipathed = true
} else if opt == "4k" {
sectorSize = 4096
} else if strings.HasPrefix(opt, "channel=") {
channel = strings.TrimPrefix(opt, "channel=")
if channel == "" {
return nil, fmt.Errorf("invalid channel opt %s", opt)
}
} else if strings.HasPrefix(opt, "serial=") {
serial := strings.TrimPrefix(opt, "serial=")
if serial == "" {
return nil, fmt.Errorf("invalid serial opt %s", opt)
}
serial_opt = []string{"serial=" + serial}
} else {
return nil, fmt.Errorf("unknown disk option %s", opt)
}
}
} else {
return nil, fmt.Errorf("invalid disk spec %s", spec)
multipathed := false
var err error

if disksize, diskmap, err = util.ParseDiskSpec(spec); err != nil {
return nil, fmt.Errorf("failed to parse disk spec %s", spec)
}
if value, found := diskmap["Channel"]; found {
channel = value
}
if value, found := diskmap["SectorSize"]; found {
sectorSize, _ = strconv.ParseInt(value, 10, 32)
}
if value, found := diskmap["MultiPathDisk"]; found {
multipathed, _ = strconv.ParseBool(value)
}
if value, found := diskmap["DeviceOpts"]; found {
serial_opt = append(serial_opt, value)
}
return &Disk{
Size: size,
Size: disksize,
Channel: channel,
DeviceOpts: serial_opt,
SectorSize: sectorSize,
SectorSize: int(sectorSize),
MultiPathDisk: multipathed,
}, nil
}
Expand Down Expand Up @@ -1225,7 +1214,7 @@ func (builder *QemuBuilder) AddDisk(disk *Disk) error {
// AddDisksFromSpecs adds multiple secondary disks from their specs.
func (builder *QemuBuilder) AddDisksFromSpecs(specs []string) error {
for _, spec := range specs {
if disk, err := ParseDiskSpec(spec); err != nil {
if disk, err := ParseDisk(spec); err != nil {
return errors.Wrapf(err, "parsing additional disk spec '%s'", spec)
} else if err = builder.AddDisk(disk); err != nil {
return errors.Wrapf(err, "adding additional disk '%s'", spec)
Expand Down
38 changes: 38 additions & 0 deletions mantle/util/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"unsafe"

Expand Down Expand Up @@ -120,3 +121,40 @@ func RunCmdTimeout(timeout time.Duration, cmd string, args ...string) error {
return fmt.Errorf("%s timed out after %s", cmd, timeout)
}
}

// ParseDiskSpec converts a disk specification into a Disk. The format is:
// <size>[:<opt1>,<opt2>,...], like ["5G:interface=NVME"]
func ParseDiskSpec(spec string) (string, map[string]string, error) {
diskmap := map[string]string{}
split := strings.Split(spec, ":")
var disksize string
if len(split) == 1 {
disksize = split[0]
} else if len(split) == 2 {
disksize = split[0]
for _, opt := range strings.Split(split[1], ",") {
if opt == "mpath" {
diskmap["MultiPathDisk"] = "true"
} else if opt == "4k" {
diskmap["SectorSize"] = "4096"
} else if strings.HasPrefix(opt, "channel=") {
channel := strings.TrimPrefix(opt, "channel=")
if channel == "" {
return "", nil, fmt.Errorf("invalid channel opt %s", opt)
}
diskmap["Channel"] = channel
} else if strings.HasPrefix(opt, "serial=") {
serial := strings.TrimPrefix(opt, "serial=")
if serial == "" {
return "", nil, fmt.Errorf("invalid serial opt %s", opt)
}
diskmap["DeviceOpts"] = "serial=" + serial
} else {
return "", nil, fmt.Errorf("unknown disk option %s", opt)
}
}
} else {
return "", nil, fmt.Errorf("invalid disk spec %s", spec)
}
return disksize, diskmap, nil
}

0 comments on commit f841e42

Please sign in to comment.