Skip to content
This repository has been archived by the owner on Feb 8, 2021. It is now read-only.

add dax support #495

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
537 changes: 70 additions & 467 deletions api/descriptions.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions api/descriptions.proto
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ message VolumeOption {
string keyring = 3;
int32 bytesPerSec = 4;
int32 iops = 5;
bool daxBlock = 6;
}

message UserGroupInfo {
Expand Down
2 changes: 1 addition & 1 deletion hack/update-generated-proto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -o errexit
set -o nounset
set -o pipefail

if [[ -z "$(which protoc)" || "$(protoc --version)" != "libprotoc 3.0."* ]]; then
if [[ -z "$(which protoc)" || "$(protoc --version)" != "libprotoc 3."* ]]; then
echo "Generating protobuf requires protoc 3.0.0-beta1 or newer. Please download and"
echo "install the platform appropriate Protobuf package for your OS: "
echo
Expand Down
10 changes: 10 additions & 0 deletions hypervisor/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
type VmHwStatus struct {
PciAddr int //next available pci addr for pci hotplug
ScsiId int //next available scsi id for scsi hotplug
PmemId int //next available pmem id for nvdimm hotplug
AttachId uint64 //next available attachId for attached tty
GuestCid uint32 //vsock guest cid
}
Expand Down Expand Up @@ -48,6 +49,7 @@ type VmContext struct {

pciAddr int //next available pci addr for pci hotplug
scsiId int //next available scsi id for scsi hotplug
pmemId int //next available pmem id for nvdimm hotplug

// InterfaceCount int

Expand Down Expand Up @@ -187,6 +189,14 @@ func (ctx *VmContext) unsetTimeout() {
}
}

func (ctx *VmContext) nextPmemId() int {
ctx.idLock.Lock()
id := ctx.pmemId
ctx.pmemId++
ctx.idLock.Unlock()
return id
}

func (ctx *VmContext) nextScsiId() int {
ctx.idLock.Lock()
id := ctx.scsiId
Expand Down
10 changes: 9 additions & 1 deletion hypervisor/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type DiskDescriptor struct {
DockerVolume bool
ReadOnly bool
Options map[string]string
Dax bool
PmemId int
}

func (d *DiskDescriptor) IsDir() bool {
Expand Down Expand Up @@ -67,6 +69,8 @@ func NewDiskContext(ctx *VmContext, vol *api.VolumeDescription) *DiskContext {
"bytespersec": strconv.Itoa(int(vol.Options.BytesPerSec)),
"iops": strconv.Itoa(int(vol.Options.Iops)),
}
} else if vol.Options != nil && vol.Options.DaxBlock {
dc.DiskDescriptor.Dax = true
}
return dc
}
Expand All @@ -80,7 +84,11 @@ func (dc *DiskContext) insert(result chan api.Result) {
return
}

dc.ScsiId = dc.sandbox.nextScsiId()
if dc.Dax {
dc.PmemId = dc.sandbox.nextPmemId()
} else {
dc.ScsiId = dc.sandbox.nextScsiId()
}
usage := "volume"
if dc.isRootVol {
usage = "image"
Expand Down
29 changes: 28 additions & 1 deletion hypervisor/libvirt/libvirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ func (lc *LibvirtContext) domainXml(ctx *hypervisor.VmContext) (string, error) {

dom.OS.Supported = "yes"
dom.OS.Type.Arch = "x86_64"
dom.OS.Type.Machine = "pc-i440fx-2.1"
dom.OS.Type.Machine = "pc-i440fx-2.1,nvdimm"
dom.OS.Type.Content = "hvm"

dom.SecLabel.Type = "none"
Expand Down Expand Up @@ -917,6 +917,33 @@ func (lc *LibvirtContext) AddDisk(ctx *hypervisor.VmContext, sourceType string,
return
}

if blockInfo.Dax {
// get the size
fi, e := os.Stat(blockInfo.Filename)
if e != nil {
result <- &hypervisor.DeviceFailed{}
return
}
size := fi.Size()
// compose hmp
hmp := fmt.Sprintf("object_add memory-backend-file,id=mem%d,share=on,mem-path=%s,size=%d", blockInfo.PmemId, blockInfo.Filename, size)
err := exec.Command("virsh", "-c", LibvirtdAddress, "qemu-monitor-command", ctx.Id, "--hmp", hmp).Run()
if err != nil {
result <- &hypervisor.DeviceFailed{}
return
}
hmp = fmt.Sprintf("device_add nvdimm,id=nvdimm%d,memdev=mem%d", blockInfo.PmemId, blockInfo.PmemId)
err = exec.Command("virsh", "-c", LibvirtdAddress, "qemu-monitor-command", ctx.Id, "--hmp", hmp).Run()
if err != nil {
result <- &hypervisor.DeviceFailed{}
return
}
result <- &hypervisor.BlockdevInsertedEvent{
DeviceName: "pmem" + strconv.Itoa(blockInfo.PmemId),
}
return
}

secretUUID, err := lc.diskSecretUUID(blockInfo)
if err != nil {
glog.Error("generate disk-get-secret failed, ", err.Error())
Expand Down
2 changes: 2 additions & 0 deletions hypervisor/persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func (ctx *VmContext) dumpHwInfo() *VmHwStatus {
return &VmHwStatus{
PciAddr: ctx.pciAddr,
ScsiId: ctx.scsiId,
PmemId: ctx.pmemId,
AttachId: ctx.hyperstart.LastStreamSeq(),
GuestCid: ctx.GuestCid,
}
Expand All @@ -144,6 +145,7 @@ func (ctx *VmContext) dumpHwInfo() *VmHwStatus {
func (ctx *VmContext) loadHwStatus(pinfo *PersistInfo) error {
ctx.pciAddr = pinfo.HwStat.PciAddr
ctx.scsiId = pinfo.HwStat.ScsiId
ctx.pmemId = pinfo.HwStat.PmemId
ctx.GuestCid = pinfo.HwStat.GuestCid
if ctx.GuestCid != 0 {
if !VsockCidManager.MarkCidInuse(ctx.GuestCid) {
Expand Down
58 changes: 57 additions & 1 deletion hypervisor/qemu/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,63 @@ func (qc *QemuContext) AddDisk(ctx *hypervisor.VmContext, sourceType string, blo
}
}

newDiskAddSession(ctx, qc, filename, format, id, readonly, result)
commands := make([]*QmpCommand, 2)
devName := scsiId2Name(id)
if !blockInfo.Dax {
hmp := "drive_add dummy file=" + filename + ",if=none,id=" + "drive" + strconv.Itoa(id) + ",format=" + format + ",cache=writeback"
if readonly {
hmp += ",readonly"
}
commands[0] = &QmpCommand{
Execute: "human-monitor-command",
Arguments: map[string]interface{}{
"command-line": hmp,
},
}
commands[1] = &QmpCommand{
Execute: "device_add",
Arguments: map[string]interface{}{
"driver": "scsi-hd", "bus": "scsi0.0", "scsi-id": strconv.Itoa(id),
"drive": "drive" + strconv.Itoa(id), "id": "scsi-disk" + strconv.Itoa(id),
},
}
} else {
// compose qmp commands
// hmp: object_add memory-backend-file,id=mem2,share=on,mem-path=/path/to/dax.img,size=10G
// hmp: device_add nvdimm,id=nvdimm2,memdev=mem2
hmp := "object_add memory-backend-file,id=mem" + strconv.Itoa(blockInfo.PmemId) + ",mem-path=" + filename
if readonly {
hmp += ",share=off"
} else {
hmp += ",share=on"
}
// get the size
fi, e := os.Stat(filename)
if e != nil {
result <- &hypervisor.DeviceFailed{}
return
}
hmp += ",size=" + strconv.FormatInt(fi.Size(), 10)
commands[0] = &QmpCommand{
Execute: "human-monitor-command",
Arguments: map[string]interface{}{
"command-line": hmp,
},
}
commands[1] = &QmpCommand{
Execute: "device_add",
Arguments: map[string]interface{}{
"driver": "nvdimm", "memdev": "mem" + strconv.Itoa(blockInfo.PmemId), "id": "nvdimm" + strconv.Itoa(blockInfo.PmemId),
},
}
devName = "pmem" + strconv.Itoa(blockInfo.PmemId)
}
qc.qmp <- &QmpSession{
commands: commands,
respond: defaultRespond(result, &hypervisor.BlockdevInsertedEvent{
DeviceName: devName,
}),
}
}

func (qc *QemuContext) RemoveDisk(ctx *hypervisor.VmContext, blockInfo *hypervisor.DiskDescriptor, callback hypervisor.VmEvent, result chan<- hypervisor.VmEvent) {
Expand Down
2 changes: 1 addition & 1 deletion hypervisor/qemu/qemu_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (qc *QemuContext) arguments(ctx *hypervisor.VmContext) []string {
qc.cpus = boot.CPU

var machineClass, memParams, cpuParams string
machineClass = "pc-i440fx-2.1"
machineClass = "pc-i440fx-2.1,nvdimm"
memParams = fmt.Sprintf("size=%d,slots=1,maxmem=%dM", boot.Memory, hypervisor.DefaultMaxMem) // TODO set maxmem to the total memory of the system
cpuParams = fmt.Sprintf("cpus=%d,maxcpus=%d", boot.CPU, hypervisor.DefaultMaxCpus) // TODO set it to the cpus of the system

Expand Down
28 changes: 0 additions & 28 deletions hypervisor/qemu/qmp_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,6 @@ func defaultRespond(result chan<- hypervisor.VmEvent, callback hypervisor.VmEven
}
}

func newDiskAddSession(ctx *hypervisor.VmContext, qc *QemuContext, filename, format string, id int, readonly bool, result chan<- hypervisor.VmEvent) {
args := "drive_add dummy file=" + filename + ",if=none,id=" + "drive" + strconv.Itoa(id) + ",format=" + format + ",cache=writeback"
if readonly {
args += ",readonly"
}
commands := make([]*QmpCommand, 2)
commands[0] = &QmpCommand{
Execute: "human-monitor-command",
Arguments: map[string]interface{}{
"command-line": args,
},
}
commands[1] = &QmpCommand{
Execute: "device_add",
Arguments: map[string]interface{}{
"driver": "scsi-hd", "bus": "scsi0.0", "scsi-id": strconv.Itoa(id),
"drive": "drive" + strconv.Itoa(id), "id": "scsi-disk" + strconv.Itoa(id),
},
}
devName := scsiId2Name(id)
qc.qmp <- &QmpSession{
commands: commands,
respond: defaultRespond(result, &hypervisor.BlockdevInsertedEvent{
DeviceName: devName,
}),
}
}

func newDiskDelSession(ctx *hypervisor.VmContext, qc *QemuContext, id int, callback hypervisor.VmEvent, result chan<- hypervisor.VmEvent) {
commands := make([]*QmpCommand, 2)
commands[1] = &QmpCommand{
Expand Down