mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-08 22:49:22 +08:00
762 lines
21 KiB
Go
762 lines
21 KiB
Go
/*
|
|
* This file is part of the libvirt-go-xml project
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*
|
|
* Copyright (C) 2017 Red Hat, Inc.
|
|
*
|
|
*/
|
|
|
|
package libvirtxml
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type NodeDevice struct {
|
|
XMLName xml.Name `xml:"device"`
|
|
Name string `xml:"name"`
|
|
Path string `xml:"path,omitempty"`
|
|
DevNodes []NodeDeviceDevNode `xml:"devnode"`
|
|
Parent string `xml:"parent,omitempty"`
|
|
Driver *NodeDeviceDriver `xml:"driver"`
|
|
Capability NodeDeviceCapability `xml:"capability"`
|
|
}
|
|
|
|
type NodeDeviceDevNode struct {
|
|
Type string `xml:"type,attr,omitempty"`
|
|
Path string `xml:",chardata"`
|
|
}
|
|
|
|
type NodeDeviceDriver struct {
|
|
Name string `xml:"name"`
|
|
}
|
|
|
|
type NodeDeviceCapability struct {
|
|
System *NodeDeviceSystemCapability
|
|
PCI *NodeDevicePCICapability
|
|
USB *NodeDeviceUSBCapability
|
|
USBDevice *NodeDeviceUSBDeviceCapability
|
|
Net *NodeDeviceNetCapability
|
|
SCSIHost *NodeDeviceSCSIHostCapability
|
|
SCSITarget *NodeDeviceSCSITargetCapability
|
|
SCSI *NodeDeviceSCSICapability
|
|
Storage *NodeDeviceStorageCapability
|
|
DRM *NodeDeviceDRMCapability
|
|
CCW *NodeDeviceCCWCapability
|
|
MDev *NodeDeviceMDevCapability
|
|
}
|
|
|
|
type NodeDeviceIDName struct {
|
|
ID string `xml:"id,attr"`
|
|
Name string `xml:",chardata"`
|
|
}
|
|
|
|
type NodeDevicePCIExpress struct {
|
|
Links []NodeDevicePCIExpressLink `xml:"link"`
|
|
}
|
|
|
|
type NodeDevicePCIExpressLink struct {
|
|
Validity string `xml:"validity,attr,omitempty"`
|
|
Speed float64 `xml:"speed,attr,omitempty"`
|
|
Port *uint `xml:"port,attr"`
|
|
Width *uint `xml:"width,attr"`
|
|
}
|
|
|
|
type NodeDeviceIOMMUGroup struct {
|
|
Number int `xml:"number,attr"`
|
|
Address []NodeDevicePCIAddress `xml:"address"`
|
|
}
|
|
|
|
type NodeDeviceNUMA struct {
|
|
Node int `xml:"node,attr"`
|
|
}
|
|
|
|
type NodeDevicePCICapability struct {
|
|
Class string `xml:"class,omitempty"`
|
|
Domain *uint `xml:"domain"`
|
|
Bus *uint `xml:"bus"`
|
|
Slot *uint `xml:"slot"`
|
|
Function *uint `xml:"function"`
|
|
Product NodeDeviceIDName `xml:"product,omitempty"`
|
|
Vendor NodeDeviceIDName `xml:"vendor,omitempty"`
|
|
IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"`
|
|
NUMA *NodeDeviceNUMA `xml:"numa"`
|
|
PCIExpress *NodeDevicePCIExpress `xml:"pci-express"`
|
|
Capabilities []NodeDevicePCISubCapability `xml:"capability"`
|
|
}
|
|
|
|
type NodeDevicePCIAddress struct {
|
|
Domain *uint `xml:"domain,attr"`
|
|
Bus *uint `xml:"bus,attr"`
|
|
Slot *uint `xml:"slot,attr"`
|
|
Function *uint `xml:"function,attr"`
|
|
}
|
|
|
|
type NodeDevicePCISubCapability struct {
|
|
VirtFunctions *NodeDevicePCIVirtFunctionsCapability
|
|
PhysFunction *NodeDevicePCIPhysFunctionCapability
|
|
MDevTypes *NodeDevicePCIMDevTypesCapability
|
|
Bridge *NodeDevicePCIBridgeCapability
|
|
}
|
|
|
|
type NodeDevicePCIVirtFunctionsCapability struct {
|
|
Address []NodeDevicePCIAddress `xml:"address,omitempty"`
|
|
MaxCount int `xml:"maxCount,attr,omitempty"`
|
|
}
|
|
|
|
type NodeDevicePCIPhysFunctionCapability struct {
|
|
Address NodeDevicePCIAddress `xml:"address,omitempty"`
|
|
}
|
|
|
|
type NodeDevicePCIMDevTypesCapability struct {
|
|
Types []NodeDevicePCIMDevType `xml:"type"`
|
|
}
|
|
|
|
type NodeDevicePCIMDevType struct {
|
|
ID string `xml:"id,attr"`
|
|
Name string `xml:"name"`
|
|
DeviceAPI string `xml:"deviceAPI"`
|
|
AvailableInstances uint `xml:"availableInstances"`
|
|
}
|
|
|
|
type NodeDevicePCIBridgeCapability struct {
|
|
}
|
|
|
|
type NodeDeviceSystemHardware struct {
|
|
Vendor string `xml:"vendor"`
|
|
Version string `xml:"version"`
|
|
Serial string `xml:"serial"`
|
|
UUID string `xml:"uuid"`
|
|
}
|
|
|
|
type NodeDeviceSystemFirmware struct {
|
|
Vendor string `xml:"vendor"`
|
|
Version string `xml:"version"`
|
|
ReleaseData string `xml:"release_date"`
|
|
}
|
|
|
|
type NodeDeviceSystemCapability struct {
|
|
Product string `xml:"product,omitempty"`
|
|
Hardware *NodeDeviceSystemHardware `xml:"hardware"`
|
|
Firmware *NodeDeviceSystemFirmware `xml:"firmware"`
|
|
}
|
|
|
|
type NodeDeviceUSBDeviceCapability struct {
|
|
Bus int `xml:"bus"`
|
|
Device int `xml:"device"`
|
|
Product NodeDeviceIDName `xml:"product,omitempty"`
|
|
Vendor NodeDeviceIDName `xml:"vendor,omitempty"`
|
|
}
|
|
|
|
type NodeDeviceUSBCapability struct {
|
|
Number int `xml:"number"`
|
|
Class int `xml:"class"`
|
|
Subclass int `xml:"subclass"`
|
|
Protocol int `xml:"protocol"`
|
|
Description string `xml:"description,omitempty"`
|
|
}
|
|
|
|
type NodeDeviceNetOffloadFeatures struct {
|
|
Name string `xml:"name,attr"`
|
|
}
|
|
|
|
type NodeDeviceNetLink struct {
|
|
State string `xml:"state,attr"`
|
|
Speed string `xml:"speed,attr,omitempty"`
|
|
}
|
|
|
|
type NodeDeviceNetSubCapability struct {
|
|
Wireless80211 *NodeDeviceNet80211Capability
|
|
Ethernet80203 *NodeDeviceNet80203Capability
|
|
}
|
|
|
|
type NodeDeviceNet80211Capability struct {
|
|
}
|
|
|
|
type NodeDeviceNet80203Capability struct {
|
|
}
|
|
|
|
type NodeDeviceNetCapability struct {
|
|
Interface string `xml:"interface"`
|
|
Address string `xml:"address"`
|
|
Link *NodeDeviceNetLink `xml:"link"`
|
|
Features []NodeDeviceNetOffloadFeatures `xml:"feature,omitempty"`
|
|
Capability []NodeDeviceNetSubCapability `xml:"capability"`
|
|
}
|
|
|
|
type NodeDeviceSCSIVPortOpsCapability struct {
|
|
VPorts int `xml:"vports,omitempty"`
|
|
MaxVPorts int `xml:"maxvports,omitempty"`
|
|
}
|
|
|
|
type NodeDeviceSCSIFCHostCapability struct {
|
|
WWNN string `xml:"wwnn,omitempty"`
|
|
WWPN string `xml:"wwpn,omitempty"`
|
|
FabricWWN string `xml:"fabric_wwn,omitempty"`
|
|
}
|
|
|
|
type NodeDeviceSCSIHostSubCapability struct {
|
|
VPortOps *NodeDeviceSCSIVPortOpsCapability
|
|
FCHost *NodeDeviceSCSIFCHostCapability
|
|
}
|
|
|
|
type NodeDeviceSCSIHostCapability struct {
|
|
Host uint `xml:"host"`
|
|
UniqueID *uint `xml:"unique_id"`
|
|
Capability []NodeDeviceSCSIHostSubCapability `xml:"capability"`
|
|
}
|
|
|
|
type NodeDeviceSCSITargetCapability struct {
|
|
Target string `xml:"target"`
|
|
Capability []NodeDeviceSCSITargetSubCapability `xml:"capability"`
|
|
}
|
|
|
|
type NodeDeviceSCSITargetSubCapability struct {
|
|
FCRemotePort *NodeDeviceSCSIFCRemotePortCapability
|
|
}
|
|
|
|
type NodeDeviceSCSIFCRemotePortCapability struct {
|
|
RPort string `xml:"rport"`
|
|
WWPN string `xml:"wwpn"`
|
|
}
|
|
|
|
type NodeDeviceSCSICapability struct {
|
|
Host int `xml:"host"`
|
|
Bus int `xml:"bus"`
|
|
Target int `xml:"target"`
|
|
Lun int `xml:"lun"`
|
|
Type string `xml:"type"`
|
|
}
|
|
|
|
type NodeDeviceStorageSubCapability struct {
|
|
Removable *NodeDeviceStorageRemovableCapability
|
|
}
|
|
|
|
type NodeDeviceStorageRemovableCapability struct {
|
|
MediaAvailable *uint `xml:"media_available"`
|
|
MediaSize *uint `xml:"media_size"`
|
|
MediaLabel string `xml:"media_label,omitempty"`
|
|
LogicalBlockSize *uint `xml:"logical_block_size"`
|
|
NumBlocks *uint `xml:"num_blocks"`
|
|
}
|
|
|
|
type NodeDeviceStorageCapability struct {
|
|
Block string `xml:"block,omitempty"`
|
|
Bus string `xml:"bus,omitempty"`
|
|
DriverType string `xml:"drive_type,omitempty"`
|
|
Model string `xml:"model,omitempty"`
|
|
Vendor string `xml:"vendor,omitempty"`
|
|
Serial string `xml:"serial,omitempty"`
|
|
Size *uint `xml:"size"`
|
|
LogicalBlockSize *uint `xml:"logical_block_size"`
|
|
NumBlocks *uint `xml:"num_blocks"`
|
|
Capability []NodeDeviceStorageSubCapability `xml:"capability"`
|
|
}
|
|
|
|
type NodeDeviceDRMCapability struct {
|
|
Type string `xml:"type"`
|
|
}
|
|
|
|
type NodeDeviceCCWCapability struct {
|
|
CSSID *uint `xml:"cssid"`
|
|
SSID *uint `xml:"ssid"`
|
|
DevNo *uint `xml:"devno"`
|
|
}
|
|
|
|
type NodeDeviceMDevCapability struct {
|
|
Type *NodeDeviceMDevCapabilityType `xml:"type"`
|
|
IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"`
|
|
}
|
|
|
|
type NodeDeviceMDevCapabilityType struct {
|
|
ID string `xml:"id,attr"`
|
|
}
|
|
|
|
func (a *NodeDevicePCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
marshalUintAttr(&start, "domain", a.Domain, "0x%04x")
|
|
marshalUintAttr(&start, "bus", a.Bus, "0x%02x")
|
|
marshalUintAttr(&start, "slot", a.Slot, "0x%02x")
|
|
marshalUintAttr(&start, "function", a.Function, "0x%x")
|
|
e.EncodeToken(start)
|
|
e.EncodeToken(start.End())
|
|
return nil
|
|
}
|
|
|
|
func (a *NodeDevicePCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
for _, attr := range start.Attr {
|
|
if attr.Name.Local == "domain" {
|
|
if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil {
|
|
return err
|
|
}
|
|
} else if attr.Name.Local == "bus" {
|
|
if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil {
|
|
return err
|
|
}
|
|
} else if attr.Name.Local == "slot" {
|
|
if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil {
|
|
return err
|
|
}
|
|
} else if attr.Name.Local == "function" {
|
|
if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceCCWCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
e.EncodeToken(start)
|
|
if c.CSSID != nil {
|
|
cssid := xml.StartElement{
|
|
Name: xml.Name{Local: "cssid"},
|
|
}
|
|
e.EncodeToken(cssid)
|
|
e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID)))
|
|
e.EncodeToken(cssid.End())
|
|
}
|
|
if c.SSID != nil {
|
|
ssid := xml.StartElement{
|
|
Name: xml.Name{Local: "ssid"},
|
|
}
|
|
e.EncodeToken(ssid)
|
|
e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID)))
|
|
e.EncodeToken(ssid.End())
|
|
}
|
|
if c.DevNo != nil {
|
|
devno := xml.StartElement{
|
|
Name: xml.Name{Local: "devno"},
|
|
}
|
|
e.EncodeToken(devno)
|
|
e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo)))
|
|
e.EncodeToken(devno.End())
|
|
}
|
|
e.EncodeToken(start.End())
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceCCWCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
for {
|
|
tok, err := d.Token()
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch tok := tok.(type) {
|
|
case xml.StartElement:
|
|
cdata, err := d.Token()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if tok.Name.Local != "cssid" &&
|
|
tok.Name.Local != "ssid" &&
|
|
tok.Name.Local != "devno" {
|
|
continue
|
|
}
|
|
|
|
chardata, ok := cdata.(xml.CharData)
|
|
if !ok {
|
|
return fmt.Errorf("Expected text for CCW '%s'", tok.Name.Local)
|
|
}
|
|
|
|
valstr := strings.TrimPrefix(string(chardata), "0x")
|
|
val, err := strconv.ParseUint(valstr, 16, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
vali := uint(val)
|
|
if tok.Name.Local == "cssid" {
|
|
c.CSSID = &vali
|
|
} else if tok.Name.Local == "ssid" {
|
|
c.SSID = &vali
|
|
} else if tok.Name.Local == "devno" {
|
|
c.DevNo = &vali
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDevicePCISubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
typ, ok := getAttr(start.Attr, "type")
|
|
if !ok {
|
|
return fmt.Errorf("Missing node device capability type")
|
|
}
|
|
|
|
switch typ {
|
|
case "virt_functions":
|
|
var virtFuncCaps NodeDevicePCIVirtFunctionsCapability
|
|
if err := d.DecodeElement(&virtFuncCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.VirtFunctions = &virtFuncCaps
|
|
case "phys_function":
|
|
var physFuncCaps NodeDevicePCIPhysFunctionCapability
|
|
if err := d.DecodeElement(&physFuncCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.PhysFunction = &physFuncCaps
|
|
case "mdev_types":
|
|
var mdevTypeCaps NodeDevicePCIMDevTypesCapability
|
|
if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.MDevTypes = &mdevTypeCaps
|
|
case "pci-bridge":
|
|
var bridgeCaps NodeDevicePCIBridgeCapability
|
|
if err := d.DecodeElement(&bridgeCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.Bridge = &bridgeCaps
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDevicePCISubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
if c.VirtFunctions != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "virt_functions",
|
|
})
|
|
return e.EncodeElement(c.VirtFunctions, start)
|
|
} else if c.PhysFunction != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "phys_function",
|
|
})
|
|
return e.EncodeElement(c.PhysFunction, start)
|
|
} else if c.MDevTypes != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "mdev_types",
|
|
})
|
|
return e.EncodeElement(c.MDevTypes, start)
|
|
} else if c.Bridge != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "pci-bridge",
|
|
})
|
|
return e.EncodeElement(c.Bridge, start)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceSCSITargetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
typ, ok := getAttr(start.Attr, "type")
|
|
if !ok {
|
|
return fmt.Errorf("Missing node device capability type")
|
|
}
|
|
|
|
switch typ {
|
|
case "fc_remote_port":
|
|
var fcCaps NodeDeviceSCSIFCRemotePortCapability
|
|
if err := d.DecodeElement(&fcCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.FCRemotePort = &fcCaps
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceSCSITargetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
if c.FCRemotePort != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "fc_remote_port",
|
|
})
|
|
return e.EncodeElement(c.FCRemotePort, start)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceSCSIHostSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
typ, ok := getAttr(start.Attr, "type")
|
|
if !ok {
|
|
return fmt.Errorf("Missing node device capability type")
|
|
}
|
|
|
|
switch typ {
|
|
case "fc_host":
|
|
var fcCaps NodeDeviceSCSIFCHostCapability
|
|
if err := d.DecodeElement(&fcCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.FCHost = &fcCaps
|
|
case "vport_ops":
|
|
var vportCaps NodeDeviceSCSIVPortOpsCapability
|
|
if err := d.DecodeElement(&vportCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.VPortOps = &vportCaps
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceSCSIHostSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
if c.FCHost != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "fc_host",
|
|
})
|
|
return e.EncodeElement(c.FCHost, start)
|
|
} else if c.VPortOps != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "vport_ops",
|
|
})
|
|
return e.EncodeElement(c.VPortOps, start)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceStorageSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
typ, ok := getAttr(start.Attr, "type")
|
|
if !ok {
|
|
return fmt.Errorf("Missing node device capability type")
|
|
}
|
|
|
|
switch typ {
|
|
case "removable":
|
|
var removeCaps NodeDeviceStorageRemovableCapability
|
|
if err := d.DecodeElement(&removeCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.Removable = &removeCaps
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceStorageSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
if c.Removable != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "removable",
|
|
})
|
|
return e.EncodeElement(c.Removable, start)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceNetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
typ, ok := getAttr(start.Attr, "type")
|
|
if !ok {
|
|
return fmt.Errorf("Missing node device capability type")
|
|
}
|
|
|
|
switch typ {
|
|
case "80211":
|
|
var wlanCaps NodeDeviceNet80211Capability
|
|
if err := d.DecodeElement(&wlanCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.Wireless80211 = &wlanCaps
|
|
case "80203":
|
|
var ethCaps NodeDeviceNet80203Capability
|
|
if err := d.DecodeElement(ðCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.Ethernet80203 = ðCaps
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceNetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
if c.Wireless80211 != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "80211",
|
|
})
|
|
return e.EncodeElement(c.Wireless80211, start)
|
|
} else if c.Ethernet80203 != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "80203",
|
|
})
|
|
return e.EncodeElement(c.Ethernet80203, start)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
typ, ok := getAttr(start.Attr, "type")
|
|
if !ok {
|
|
return fmt.Errorf("Missing node device capability type")
|
|
}
|
|
|
|
switch typ {
|
|
case "pci":
|
|
var pciCaps NodeDevicePCICapability
|
|
if err := d.DecodeElement(&pciCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.PCI = &pciCaps
|
|
case "system":
|
|
var systemCaps NodeDeviceSystemCapability
|
|
if err := d.DecodeElement(&systemCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.System = &systemCaps
|
|
case "usb_device":
|
|
var usbdevCaps NodeDeviceUSBDeviceCapability
|
|
if err := d.DecodeElement(&usbdevCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.USBDevice = &usbdevCaps
|
|
case "usb":
|
|
var usbCaps NodeDeviceUSBCapability
|
|
if err := d.DecodeElement(&usbCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.USB = &usbCaps
|
|
case "net":
|
|
var netCaps NodeDeviceNetCapability
|
|
if err := d.DecodeElement(&netCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.Net = &netCaps
|
|
case "scsi_host":
|
|
var scsiHostCaps NodeDeviceSCSIHostCapability
|
|
if err := d.DecodeElement(&scsiHostCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.SCSIHost = &scsiHostCaps
|
|
case "scsi_target":
|
|
var scsiTargetCaps NodeDeviceSCSITargetCapability
|
|
if err := d.DecodeElement(&scsiTargetCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.SCSITarget = &scsiTargetCaps
|
|
case "scsi":
|
|
var scsiCaps NodeDeviceSCSICapability
|
|
if err := d.DecodeElement(&scsiCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.SCSI = &scsiCaps
|
|
case "storage":
|
|
var storageCaps NodeDeviceStorageCapability
|
|
if err := d.DecodeElement(&storageCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.Storage = &storageCaps
|
|
case "drm":
|
|
var drmCaps NodeDeviceDRMCapability
|
|
if err := d.DecodeElement(&drmCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.DRM = &drmCaps
|
|
case "ccw":
|
|
var ccwCaps NodeDeviceCCWCapability
|
|
if err := d.DecodeElement(&ccwCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.CCW = &ccwCaps
|
|
case "mdev":
|
|
var mdevCaps NodeDeviceMDevCapability
|
|
if err := d.DecodeElement(&mdevCaps, &start); err != nil {
|
|
return err
|
|
}
|
|
c.MDev = &mdevCaps
|
|
}
|
|
d.Skip()
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDeviceCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
if c.PCI != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "pci",
|
|
})
|
|
return e.EncodeElement(c.PCI, start)
|
|
} else if c.System != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "system",
|
|
})
|
|
return e.EncodeElement(c.System, start)
|
|
} else if c.USB != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "usb",
|
|
})
|
|
return e.EncodeElement(c.USB, start)
|
|
} else if c.USBDevice != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "usb_device",
|
|
})
|
|
return e.EncodeElement(c.USBDevice, start)
|
|
} else if c.Net != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "net",
|
|
})
|
|
return e.EncodeElement(c.Net, start)
|
|
} else if c.SCSI != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "scsi",
|
|
})
|
|
return e.EncodeElement(c.SCSI, start)
|
|
} else if c.SCSIHost != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "scsi_host",
|
|
})
|
|
return e.EncodeElement(c.SCSIHost, start)
|
|
} else if c.SCSITarget != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "scsi_target",
|
|
})
|
|
return e.EncodeElement(c.SCSITarget, start)
|
|
} else if c.Storage != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "storage",
|
|
})
|
|
return e.EncodeElement(c.Storage, start)
|
|
} else if c.DRM != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "drm",
|
|
})
|
|
return e.EncodeElement(c.DRM, start)
|
|
} else if c.CCW != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "ccw",
|
|
})
|
|
return e.EncodeElement(c.CCW, start)
|
|
} else if c.MDev != nil {
|
|
start.Attr = append(start.Attr, xml.Attr{
|
|
xml.Name{Local: "type"}, "mdev",
|
|
})
|
|
return e.EncodeElement(c.MDev, start)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *NodeDevice) Unmarshal(doc string) error {
|
|
return xml.Unmarshal([]byte(doc), c)
|
|
}
|
|
|
|
func (c *NodeDevice) Marshal() (string, error) {
|
|
doc, err := xml.MarshalIndent(c, "", " ")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(doc), nil
|
|
}
|