github.com/libvirt/libvirt-go-xml@v7.4.0+incompatible/node_device.go (about) 1 /* 2 * This file is part of the libvirt-go-xml project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 * THE SOFTWARE. 21 * 22 * Copyright (C) 2017 Red Hat, Inc. 23 * 24 */ 25 26 package libvirtxml 27 28 import ( 29 "encoding/xml" 30 "fmt" 31 "io" 32 "strconv" 33 "strings" 34 ) 35 36 type NodeDevice struct { 37 XMLName xml.Name `xml:"device"` 38 Name string `xml:"name"` 39 Path string `xml:"path,omitempty"` 40 DevNodes []NodeDeviceDevNode `xml:"devnode"` 41 Parent string `xml:"parent,omitempty"` 42 Driver *NodeDeviceDriver `xml:"driver"` 43 Capability NodeDeviceCapability `xml:"capability"` 44 } 45 46 type NodeDeviceDevNode struct { 47 Type string `xml:"type,attr,omitempty"` 48 Path string `xml:",chardata"` 49 } 50 51 type NodeDeviceDriver struct { 52 Name string `xml:"name"` 53 } 54 55 type NodeDeviceCapability struct { 56 System *NodeDeviceSystemCapability 57 PCI *NodeDevicePCICapability 58 USB *NodeDeviceUSBCapability 59 USBDevice *NodeDeviceUSBDeviceCapability 60 Net *NodeDeviceNetCapability 61 SCSIHost *NodeDeviceSCSIHostCapability 62 SCSITarget *NodeDeviceSCSITargetCapability 63 SCSI *NodeDeviceSCSICapability 64 Storage *NodeDeviceStorageCapability 65 DRM *NodeDeviceDRMCapability 66 CCW *NodeDeviceCCWCapability 67 MDev *NodeDeviceMDevCapability 68 CSS *NodeDeviceCSSCapability 69 APQueue *NodeDeviceAPQueueCapability 70 APCard *NodeDeviceAPCardCapability 71 APMatrix *NodeDeviceAPMatrixCapability 72 } 73 74 type NodeDeviceIDName struct { 75 ID string `xml:"id,attr"` 76 Name string `xml:",chardata"` 77 } 78 79 type NodeDevicePCIExpress struct { 80 Links []NodeDevicePCIExpressLink `xml:"link"` 81 } 82 83 type NodeDevicePCIExpressLink struct { 84 Validity string `xml:"validity,attr,omitempty"` 85 Speed float64 `xml:"speed,attr,omitempty"` 86 Port *uint `xml:"port,attr"` 87 Width *uint `xml:"width,attr"` 88 } 89 90 type NodeDeviceIOMMUGroup struct { 91 Number int `xml:"number,attr"` 92 Address []NodeDevicePCIAddress `xml:"address"` 93 } 94 95 type NodeDeviceNUMA struct { 96 Node int `xml:"node,attr"` 97 } 98 99 type NodeDevicePCICapability struct { 100 Class string `xml:"class,omitempty"` 101 Domain *uint `xml:"domain"` 102 Bus *uint `xml:"bus"` 103 Slot *uint `xml:"slot"` 104 Function *uint `xml:"function"` 105 Product NodeDeviceIDName `xml:"product,omitempty"` 106 Vendor NodeDeviceIDName `xml:"vendor,omitempty"` 107 IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"` 108 NUMA *NodeDeviceNUMA `xml:"numa"` 109 PCIExpress *NodeDevicePCIExpress `xml:"pci-express"` 110 Capabilities []NodeDevicePCISubCapability `xml:"capability"` 111 } 112 113 type NodeDevicePCIAddress struct { 114 Domain *uint `xml:"domain,attr"` 115 Bus *uint `xml:"bus,attr"` 116 Slot *uint `xml:"slot,attr"` 117 Function *uint `xml:"function,attr"` 118 } 119 120 type NodeDevicePCISubCapability struct { 121 VirtFunctions *NodeDevicePCIVirtFunctionsCapability 122 PhysFunction *NodeDevicePCIPhysFunctionCapability 123 MDevTypes *NodeDevicePCIMDevTypesCapability 124 Bridge *NodeDevicePCIBridgeCapability 125 } 126 127 type NodeDevicePCIVirtFunctionsCapability struct { 128 Address []NodeDevicePCIAddress `xml:"address,omitempty"` 129 MaxCount int `xml:"maxCount,attr,omitempty"` 130 } 131 132 type NodeDevicePCIPhysFunctionCapability struct { 133 Address NodeDevicePCIAddress `xml:"address,omitempty"` 134 } 135 136 type NodeDevicePCIMDevTypesCapability struct { 137 Types []NodeDeviceMDevType `xml:"type"` 138 } 139 140 type NodeDeviceMDevType struct { 141 ID string `xml:"id,attr"` 142 Name string `xml:"name"` 143 DeviceAPI string `xml:"deviceAPI"` 144 AvailableInstances uint `xml:"availableInstances"` 145 } 146 147 type NodeDevicePCIBridgeCapability struct { 148 } 149 150 type NodeDeviceSystemHardware struct { 151 Vendor string `xml:"vendor"` 152 Version string `xml:"version"` 153 Serial string `xml:"serial"` 154 UUID string `xml:"uuid"` 155 } 156 157 type NodeDeviceSystemFirmware struct { 158 Vendor string `xml:"vendor"` 159 Version string `xml:"version"` 160 ReleaseData string `xml:"release_date"` 161 } 162 163 type NodeDeviceSystemCapability struct { 164 Product string `xml:"product,omitempty"` 165 Hardware *NodeDeviceSystemHardware `xml:"hardware"` 166 Firmware *NodeDeviceSystemFirmware `xml:"firmware"` 167 } 168 169 type NodeDeviceUSBDeviceCapability struct { 170 Bus int `xml:"bus"` 171 Device int `xml:"device"` 172 Product NodeDeviceIDName `xml:"product,omitempty"` 173 Vendor NodeDeviceIDName `xml:"vendor,omitempty"` 174 } 175 176 type NodeDeviceUSBCapability struct { 177 Number int `xml:"number"` 178 Class int `xml:"class"` 179 Subclass int `xml:"subclass"` 180 Protocol int `xml:"protocol"` 181 Description string `xml:"description,omitempty"` 182 } 183 184 type NodeDeviceNetOffloadFeatures struct { 185 Name string `xml:"name,attr"` 186 } 187 188 type NodeDeviceNetLink struct { 189 State string `xml:"state,attr"` 190 Speed string `xml:"speed,attr,omitempty"` 191 } 192 193 type NodeDeviceNetSubCapability struct { 194 Wireless80211 *NodeDeviceNet80211Capability 195 Ethernet80203 *NodeDeviceNet80203Capability 196 } 197 198 type NodeDeviceNet80211Capability struct { 199 } 200 201 type NodeDeviceNet80203Capability struct { 202 } 203 204 type NodeDeviceNetCapability struct { 205 Interface string `xml:"interface"` 206 Address string `xml:"address"` 207 Link *NodeDeviceNetLink `xml:"link"` 208 Features []NodeDeviceNetOffloadFeatures `xml:"feature,omitempty"` 209 Capability []NodeDeviceNetSubCapability `xml:"capability"` 210 } 211 212 type NodeDeviceSCSIVPortOpsCapability struct { 213 VPorts int `xml:"vports,omitempty"` 214 MaxVPorts int `xml:"maxvports,omitempty"` 215 } 216 217 type NodeDeviceSCSIFCHostCapability struct { 218 WWNN string `xml:"wwnn,omitempty"` 219 WWPN string `xml:"wwpn,omitempty"` 220 FabricWWN string `xml:"fabric_wwn,omitempty"` 221 } 222 223 type NodeDeviceSCSIHostSubCapability struct { 224 VPortOps *NodeDeviceSCSIVPortOpsCapability 225 FCHost *NodeDeviceSCSIFCHostCapability 226 } 227 228 type NodeDeviceSCSIHostCapability struct { 229 Host uint `xml:"host"` 230 UniqueID *uint `xml:"unique_id"` 231 Capability []NodeDeviceSCSIHostSubCapability `xml:"capability"` 232 } 233 234 type NodeDeviceSCSITargetCapability struct { 235 Target string `xml:"target"` 236 Capability []NodeDeviceSCSITargetSubCapability `xml:"capability"` 237 } 238 239 type NodeDeviceSCSITargetSubCapability struct { 240 FCRemotePort *NodeDeviceSCSIFCRemotePortCapability 241 } 242 243 type NodeDeviceSCSIFCRemotePortCapability struct { 244 RPort string `xml:"rport"` 245 WWPN string `xml:"wwpn"` 246 } 247 248 type NodeDeviceSCSICapability struct { 249 Host int `xml:"host"` 250 Bus int `xml:"bus"` 251 Target int `xml:"target"` 252 Lun int `xml:"lun"` 253 Type string `xml:"type"` 254 } 255 256 type NodeDeviceStorageSubCapability struct { 257 Removable *NodeDeviceStorageRemovableCapability 258 } 259 260 type NodeDeviceStorageRemovableCapability struct { 261 MediaAvailable *uint `xml:"media_available"` 262 MediaSize *uint `xml:"media_size"` 263 MediaLabel string `xml:"media_label,omitempty"` 264 LogicalBlockSize *uint `xml:"logical_block_size"` 265 NumBlocks *uint `xml:"num_blocks"` 266 } 267 268 type NodeDeviceStorageCapability struct { 269 Block string `xml:"block,omitempty"` 270 Bus string `xml:"bus,omitempty"` 271 DriverType string `xml:"drive_type,omitempty"` 272 Model string `xml:"model,omitempty"` 273 Vendor string `xml:"vendor,omitempty"` 274 Serial string `xml:"serial,omitempty"` 275 Size *uint `xml:"size"` 276 LogicalBlockSize *uint `xml:"logical_block_size"` 277 NumBlocks *uint `xml:"num_blocks"` 278 Capability []NodeDeviceStorageSubCapability `xml:"capability"` 279 } 280 281 type NodeDeviceDRMCapability struct { 282 Type string `xml:"type"` 283 } 284 285 type NodeDeviceCCWCapability struct { 286 CSSID *uint `xml:"cssid"` 287 SSID *uint `xml:"ssid"` 288 DevNo *uint `xml:"devno"` 289 } 290 291 type NodeDeviceMDevCapability struct { 292 Type *NodeDeviceMDevCapabilityType `xml:"type"` 293 IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"` 294 UUID string `xml:"uuid,omitempty"` 295 Attrs []NodeDeviceMDevCapabilityAttrs `xml:"attr,omitempty"` 296 } 297 298 type NodeDeviceMDevCapabilityType struct { 299 ID string `xml:"id,attr"` 300 } 301 302 type NodeDeviceMDevCapabilityAttrs struct { 303 Name string `xml:"name,attr"` 304 Value string `xml:"value,attr"` 305 } 306 307 type NodeDeviceCSSCapability struct { 308 CSSID *uint `xml:"cssid"` 309 SSID *uint `xml:"ssid"` 310 DevNo *uint `xml:"devno"` 311 Capabilities []NodeDeviceCSSSubCapability `xml:"capability"` 312 } 313 314 type NodeDeviceCSSSubCapability struct { 315 MDevTypes *NodeDeviceCSSMDevTypesCapability 316 } 317 318 type NodeDeviceCSSMDevTypesCapability struct { 319 Types []NodeDeviceMDevType `xml:"type"` 320 } 321 322 type NodeDeviceAPQueueCapability struct { 323 APAdapter string `xml:"ap-adapter"` 324 APDomain string `xml:"ap-domain"` 325 } 326 327 type NodeDeviceAPCardCapability struct { 328 APAdapter string `xml:"ap-adapter"` 329 } 330 331 type NodeDeviceAPMatrixCapability struct { 332 Capabilities []NodeDeviceAPMatrixSubCapability `xml:"capability"` 333 } 334 335 type NodeDeviceAPMatrixSubCapability struct { 336 MDevTypes *NodeDeviceAPMatrixMDevTypesCapability 337 } 338 339 type NodeDeviceAPMatrixMDevTypesCapability struct { 340 Types []NodeDeviceMDevType `xml:"type"` 341 } 342 343 func (a *NodeDevicePCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 344 marshalUintAttr(&start, "domain", a.Domain, "0x%04x") 345 marshalUintAttr(&start, "bus", a.Bus, "0x%02x") 346 marshalUintAttr(&start, "slot", a.Slot, "0x%02x") 347 marshalUintAttr(&start, "function", a.Function, "0x%x") 348 e.EncodeToken(start) 349 e.EncodeToken(start.End()) 350 return nil 351 } 352 353 func (a *NodeDevicePCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 354 for _, attr := range start.Attr { 355 if attr.Name.Local == "domain" { 356 if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { 357 return err 358 } 359 } else if attr.Name.Local == "bus" { 360 if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { 361 return err 362 } 363 } else if attr.Name.Local == "slot" { 364 if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { 365 return err 366 } 367 } else if attr.Name.Local == "function" { 368 if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { 369 return err 370 } 371 } 372 } 373 d.Skip() 374 return nil 375 } 376 377 func (c *NodeDeviceCSSSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 378 typ, ok := getAttr(start.Attr, "type") 379 if !ok { 380 return fmt.Errorf("Missing node device capability type") 381 } 382 383 switch typ { 384 case "mdev_types": 385 var mdevTypesCaps NodeDeviceCSSMDevTypesCapability 386 if err := d.DecodeElement(&mdevTypesCaps, &start); err != nil { 387 return err 388 } 389 c.MDevTypes = &mdevTypesCaps 390 } 391 d.Skip() 392 return nil 393 } 394 395 func (c *NodeDeviceCSSSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 396 if c.MDevTypes != nil { 397 start.Attr = append(start.Attr, xml.Attr{ 398 xml.Name{Local: "type"}, "mdev_types", 399 }) 400 return e.EncodeElement(c.MDevTypes, start) 401 } 402 return nil 403 } 404 405 func (c *NodeDeviceCCWCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 406 e.EncodeToken(start) 407 if c.CSSID != nil { 408 cssid := xml.StartElement{ 409 Name: xml.Name{Local: "cssid"}, 410 } 411 e.EncodeToken(cssid) 412 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) 413 e.EncodeToken(cssid.End()) 414 } 415 if c.SSID != nil { 416 ssid := xml.StartElement{ 417 Name: xml.Name{Local: "ssid"}, 418 } 419 e.EncodeToken(ssid) 420 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) 421 e.EncodeToken(ssid.End()) 422 } 423 if c.DevNo != nil { 424 devno := xml.StartElement{ 425 Name: xml.Name{Local: "devno"}, 426 } 427 e.EncodeToken(devno) 428 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) 429 e.EncodeToken(devno.End()) 430 } 431 e.EncodeToken(start.End()) 432 return nil 433 } 434 435 func (c *NodeDeviceCCWCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 436 for { 437 tok, err := d.Token() 438 if err == io.EOF { 439 break 440 } 441 if err != nil { 442 return err 443 } 444 445 switch tok := tok.(type) { 446 case xml.StartElement: 447 cdata, err := d.Token() 448 if err != nil { 449 return err 450 } 451 452 if tok.Name.Local != "cssid" && 453 tok.Name.Local != "ssid" && 454 tok.Name.Local != "devno" { 455 continue 456 } 457 458 chardata, ok := cdata.(xml.CharData) 459 if !ok { 460 return fmt.Errorf("Expected text for CCW '%s'", tok.Name.Local) 461 } 462 463 valstr := strings.TrimPrefix(string(chardata), "0x") 464 val, err := strconv.ParseUint(valstr, 16, 64) 465 if err != nil { 466 return err 467 } 468 469 vali := uint(val) 470 if tok.Name.Local == "cssid" { 471 c.CSSID = &vali 472 } else if tok.Name.Local == "ssid" { 473 c.SSID = &vali 474 } else if tok.Name.Local == "devno" { 475 c.DevNo = &vali 476 } 477 } 478 } 479 return nil 480 } 481 482 func (c *NodeDeviceCSSCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 483 e.EncodeToken(start) 484 if c.CSSID != nil { 485 cssid := xml.StartElement{ 486 Name: xml.Name{Local: "cssid"}, 487 } 488 e.EncodeToken(cssid) 489 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) 490 e.EncodeToken(cssid.End()) 491 } 492 if c.SSID != nil { 493 ssid := xml.StartElement{ 494 Name: xml.Name{Local: "ssid"}, 495 } 496 e.EncodeToken(ssid) 497 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) 498 e.EncodeToken(ssid.End()) 499 } 500 if c.DevNo != nil { 501 devno := xml.StartElement{ 502 Name: xml.Name{Local: "devno"}, 503 } 504 e.EncodeToken(devno) 505 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) 506 e.EncodeToken(devno.End()) 507 } 508 if c.Capabilities != nil { 509 for _, subcap := range c.Capabilities { 510 start := xml.StartElement{ 511 Name: xml.Name{Local: "capability"}, 512 } 513 e.EncodeElement(&subcap, start) 514 } 515 } 516 e.EncodeToken(start.End()) 517 return nil 518 } 519 520 func (c *NodeDeviceCSSCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 521 for { 522 tok, err := d.Token() 523 if err == io.EOF { 524 break 525 } 526 if err != nil { 527 return err 528 } 529 530 switch tok := tok.(type) { 531 case xml.StartElement: 532 cdata, err := d.Token() 533 if err != nil { 534 return err 535 } 536 537 if tok.Name.Local == "capability" { 538 subcap := &NodeDeviceCSSSubCapability{} 539 err := d.DecodeElement(subcap, &tok) 540 if err != nil { 541 return err 542 } 543 c.Capabilities = append(c.Capabilities, *subcap) 544 continue 545 } 546 547 if tok.Name.Local != "cssid" && 548 tok.Name.Local != "ssid" && 549 tok.Name.Local != "devno" { 550 continue 551 } 552 553 chardata, ok := cdata.(xml.CharData) 554 if !ok { 555 return fmt.Errorf("Expected text for CSS '%s'", tok.Name.Local) 556 } 557 558 valstr := strings.TrimPrefix(string(chardata), "0x") 559 val, err := strconv.ParseUint(valstr, 16, 64) 560 if err != nil { 561 return err 562 } 563 564 vali := uint(val) 565 if tok.Name.Local == "cssid" { 566 c.CSSID = &vali 567 } else if tok.Name.Local == "ssid" { 568 c.SSID = &vali 569 } else if tok.Name.Local == "devno" { 570 c.DevNo = &vali 571 } 572 } 573 } 574 return nil 575 } 576 577 func (c *NodeDevicePCISubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 578 typ, ok := getAttr(start.Attr, "type") 579 if !ok { 580 return fmt.Errorf("Missing node device capability type") 581 } 582 583 switch typ { 584 case "virt_functions": 585 var virtFuncCaps NodeDevicePCIVirtFunctionsCapability 586 if err := d.DecodeElement(&virtFuncCaps, &start); err != nil { 587 return err 588 } 589 c.VirtFunctions = &virtFuncCaps 590 case "phys_function": 591 var physFuncCaps NodeDevicePCIPhysFunctionCapability 592 if err := d.DecodeElement(&physFuncCaps, &start); err != nil { 593 return err 594 } 595 c.PhysFunction = &physFuncCaps 596 case "mdev_types": 597 var mdevTypeCaps NodeDevicePCIMDevTypesCapability 598 if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil { 599 return err 600 } 601 c.MDevTypes = &mdevTypeCaps 602 case "pci-bridge": 603 var bridgeCaps NodeDevicePCIBridgeCapability 604 if err := d.DecodeElement(&bridgeCaps, &start); err != nil { 605 return err 606 } 607 c.Bridge = &bridgeCaps 608 } 609 d.Skip() 610 return nil 611 } 612 613 func (c *NodeDevicePCISubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 614 if c.VirtFunctions != nil { 615 start.Attr = append(start.Attr, xml.Attr{ 616 xml.Name{Local: "type"}, "virt_functions", 617 }) 618 return e.EncodeElement(c.VirtFunctions, start) 619 } else if c.PhysFunction != nil { 620 start.Attr = append(start.Attr, xml.Attr{ 621 xml.Name{Local: "type"}, "phys_function", 622 }) 623 return e.EncodeElement(c.PhysFunction, start) 624 } else if c.MDevTypes != nil { 625 start.Attr = append(start.Attr, xml.Attr{ 626 xml.Name{Local: "type"}, "mdev_types", 627 }) 628 return e.EncodeElement(c.MDevTypes, start) 629 } else if c.Bridge != nil { 630 start.Attr = append(start.Attr, xml.Attr{ 631 xml.Name{Local: "type"}, "pci-bridge", 632 }) 633 return e.EncodeElement(c.Bridge, start) 634 } 635 return nil 636 } 637 638 func (c *NodeDeviceSCSITargetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 639 typ, ok := getAttr(start.Attr, "type") 640 if !ok { 641 return fmt.Errorf("Missing node device capability type") 642 } 643 644 switch typ { 645 case "fc_remote_port": 646 var fcCaps NodeDeviceSCSIFCRemotePortCapability 647 if err := d.DecodeElement(&fcCaps, &start); err != nil { 648 return err 649 } 650 c.FCRemotePort = &fcCaps 651 } 652 d.Skip() 653 return nil 654 } 655 656 func (c *NodeDeviceSCSITargetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 657 if c.FCRemotePort != nil { 658 start.Attr = append(start.Attr, xml.Attr{ 659 xml.Name{Local: "type"}, "fc_remote_port", 660 }) 661 return e.EncodeElement(c.FCRemotePort, start) 662 } 663 return nil 664 } 665 666 func (c *NodeDeviceSCSIHostSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 667 typ, ok := getAttr(start.Attr, "type") 668 if !ok { 669 return fmt.Errorf("Missing node device capability type") 670 } 671 672 switch typ { 673 case "fc_host": 674 var fcCaps NodeDeviceSCSIFCHostCapability 675 if err := d.DecodeElement(&fcCaps, &start); err != nil { 676 return err 677 } 678 c.FCHost = &fcCaps 679 case "vport_ops": 680 var vportCaps NodeDeviceSCSIVPortOpsCapability 681 if err := d.DecodeElement(&vportCaps, &start); err != nil { 682 return err 683 } 684 c.VPortOps = &vportCaps 685 } 686 d.Skip() 687 return nil 688 } 689 690 func (c *NodeDeviceSCSIHostSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 691 if c.FCHost != nil { 692 start.Attr = append(start.Attr, xml.Attr{ 693 xml.Name{Local: "type"}, "fc_host", 694 }) 695 return e.EncodeElement(c.FCHost, start) 696 } else if c.VPortOps != nil { 697 start.Attr = append(start.Attr, xml.Attr{ 698 xml.Name{Local: "type"}, "vport_ops", 699 }) 700 return e.EncodeElement(c.VPortOps, start) 701 } 702 return nil 703 } 704 705 func (c *NodeDeviceStorageSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 706 typ, ok := getAttr(start.Attr, "type") 707 if !ok { 708 return fmt.Errorf("Missing node device capability type") 709 } 710 711 switch typ { 712 case "removable": 713 var removeCaps NodeDeviceStorageRemovableCapability 714 if err := d.DecodeElement(&removeCaps, &start); err != nil { 715 return err 716 } 717 c.Removable = &removeCaps 718 } 719 d.Skip() 720 return nil 721 } 722 723 func (c *NodeDeviceStorageSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 724 if c.Removable != nil { 725 start.Attr = append(start.Attr, xml.Attr{ 726 xml.Name{Local: "type"}, "removable", 727 }) 728 return e.EncodeElement(c.Removable, start) 729 } 730 return nil 731 } 732 733 func (c *NodeDeviceNetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 734 typ, ok := getAttr(start.Attr, "type") 735 if !ok { 736 return fmt.Errorf("Missing node device capability type") 737 } 738 739 switch typ { 740 case "80211": 741 var wlanCaps NodeDeviceNet80211Capability 742 if err := d.DecodeElement(&wlanCaps, &start); err != nil { 743 return err 744 } 745 c.Wireless80211 = &wlanCaps 746 case "80203": 747 var ethCaps NodeDeviceNet80203Capability 748 if err := d.DecodeElement(ðCaps, &start); err != nil { 749 return err 750 } 751 c.Ethernet80203 = ðCaps 752 } 753 d.Skip() 754 return nil 755 } 756 757 func (c *NodeDeviceNetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 758 if c.Wireless80211 != nil { 759 start.Attr = append(start.Attr, xml.Attr{ 760 xml.Name{Local: "type"}, "80211", 761 }) 762 return e.EncodeElement(c.Wireless80211, start) 763 } else if c.Ethernet80203 != nil { 764 start.Attr = append(start.Attr, xml.Attr{ 765 xml.Name{Local: "type"}, "80203", 766 }) 767 return e.EncodeElement(c.Ethernet80203, start) 768 } 769 return nil 770 } 771 772 func (c *NodeDeviceAPMatrixSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 773 typ, ok := getAttr(start.Attr, "type") 774 if !ok { 775 return fmt.Errorf("Missing node device capability type") 776 } 777 778 switch typ { 779 case "mdev_types": 780 var mdevTypeCaps NodeDeviceAPMatrixMDevTypesCapability 781 if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil { 782 return err 783 } 784 c.MDevTypes = &mdevTypeCaps 785 } 786 d.Skip() 787 return nil 788 } 789 790 func (c *NodeDeviceAPMatrixSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 791 if c.MDevTypes != nil { 792 start.Attr = append(start.Attr, xml.Attr{ 793 xml.Name{Local: "type"}, "mdev_types", 794 }) 795 return e.EncodeElement(c.MDevTypes, start) 796 } 797 return nil 798 } 799 800 func (c *NodeDeviceCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 801 typ, ok := getAttr(start.Attr, "type") 802 if !ok { 803 return fmt.Errorf("Missing node device capability type") 804 } 805 806 switch typ { 807 case "pci": 808 var pciCaps NodeDevicePCICapability 809 if err := d.DecodeElement(&pciCaps, &start); err != nil { 810 return err 811 } 812 c.PCI = &pciCaps 813 case "system": 814 var systemCaps NodeDeviceSystemCapability 815 if err := d.DecodeElement(&systemCaps, &start); err != nil { 816 return err 817 } 818 c.System = &systemCaps 819 case "usb_device": 820 var usbdevCaps NodeDeviceUSBDeviceCapability 821 if err := d.DecodeElement(&usbdevCaps, &start); err != nil { 822 return err 823 } 824 c.USBDevice = &usbdevCaps 825 case "usb": 826 var usbCaps NodeDeviceUSBCapability 827 if err := d.DecodeElement(&usbCaps, &start); err != nil { 828 return err 829 } 830 c.USB = &usbCaps 831 case "net": 832 var netCaps NodeDeviceNetCapability 833 if err := d.DecodeElement(&netCaps, &start); err != nil { 834 return err 835 } 836 c.Net = &netCaps 837 case "scsi_host": 838 var scsiHostCaps NodeDeviceSCSIHostCapability 839 if err := d.DecodeElement(&scsiHostCaps, &start); err != nil { 840 return err 841 } 842 c.SCSIHost = &scsiHostCaps 843 case "scsi_target": 844 var scsiTargetCaps NodeDeviceSCSITargetCapability 845 if err := d.DecodeElement(&scsiTargetCaps, &start); err != nil { 846 return err 847 } 848 c.SCSITarget = &scsiTargetCaps 849 case "scsi": 850 var scsiCaps NodeDeviceSCSICapability 851 if err := d.DecodeElement(&scsiCaps, &start); err != nil { 852 return err 853 } 854 c.SCSI = &scsiCaps 855 case "storage": 856 var storageCaps NodeDeviceStorageCapability 857 if err := d.DecodeElement(&storageCaps, &start); err != nil { 858 return err 859 } 860 c.Storage = &storageCaps 861 case "drm": 862 var drmCaps NodeDeviceDRMCapability 863 if err := d.DecodeElement(&drmCaps, &start); err != nil { 864 return err 865 } 866 c.DRM = &drmCaps 867 case "ccw": 868 var ccwCaps NodeDeviceCCWCapability 869 if err := d.DecodeElement(&ccwCaps, &start); err != nil { 870 return err 871 } 872 c.CCW = &ccwCaps 873 case "mdev": 874 var mdevCaps NodeDeviceMDevCapability 875 if err := d.DecodeElement(&mdevCaps, &start); err != nil { 876 return err 877 } 878 c.MDev = &mdevCaps 879 case "css": 880 var cssCaps NodeDeviceCSSCapability 881 if err := d.DecodeElement(&cssCaps, &start); err != nil { 882 return err 883 } 884 c.CSS = &cssCaps 885 case "ap_queue": 886 var apCaps NodeDeviceAPQueueCapability 887 if err := d.DecodeElement(&apCaps, &start); err != nil { 888 return err 889 } 890 c.APQueue = &apCaps 891 case "ap_matrix": 892 var apCaps NodeDeviceAPMatrixCapability 893 if err := d.DecodeElement(&apCaps, &start); err != nil { 894 return err 895 } 896 c.APMatrix = &apCaps 897 case "ap_card": 898 var apCaps NodeDeviceAPCardCapability 899 if err := d.DecodeElement(&apCaps, &start); err != nil { 900 return err 901 } 902 c.APCard = &apCaps 903 } 904 d.Skip() 905 return nil 906 } 907 908 func (c *NodeDeviceCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 909 if c.PCI != nil { 910 start.Attr = append(start.Attr, xml.Attr{ 911 xml.Name{Local: "type"}, "pci", 912 }) 913 return e.EncodeElement(c.PCI, start) 914 } else if c.System != nil { 915 start.Attr = append(start.Attr, xml.Attr{ 916 xml.Name{Local: "type"}, "system", 917 }) 918 return e.EncodeElement(c.System, start) 919 } else if c.USB != nil { 920 start.Attr = append(start.Attr, xml.Attr{ 921 xml.Name{Local: "type"}, "usb", 922 }) 923 return e.EncodeElement(c.USB, start) 924 } else if c.USBDevice != nil { 925 start.Attr = append(start.Attr, xml.Attr{ 926 xml.Name{Local: "type"}, "usb_device", 927 }) 928 return e.EncodeElement(c.USBDevice, start) 929 } else if c.Net != nil { 930 start.Attr = append(start.Attr, xml.Attr{ 931 xml.Name{Local: "type"}, "net", 932 }) 933 return e.EncodeElement(c.Net, start) 934 } else if c.SCSI != nil { 935 start.Attr = append(start.Attr, xml.Attr{ 936 xml.Name{Local: "type"}, "scsi", 937 }) 938 return e.EncodeElement(c.SCSI, start) 939 } else if c.SCSIHost != nil { 940 start.Attr = append(start.Attr, xml.Attr{ 941 xml.Name{Local: "type"}, "scsi_host", 942 }) 943 return e.EncodeElement(c.SCSIHost, start) 944 } else if c.SCSITarget != nil { 945 start.Attr = append(start.Attr, xml.Attr{ 946 xml.Name{Local: "type"}, "scsi_target", 947 }) 948 return e.EncodeElement(c.SCSITarget, start) 949 } else if c.Storage != nil { 950 start.Attr = append(start.Attr, xml.Attr{ 951 xml.Name{Local: "type"}, "storage", 952 }) 953 return e.EncodeElement(c.Storage, start) 954 } else if c.DRM != nil { 955 start.Attr = append(start.Attr, xml.Attr{ 956 xml.Name{Local: "type"}, "drm", 957 }) 958 return e.EncodeElement(c.DRM, start) 959 } else if c.CCW != nil { 960 start.Attr = append(start.Attr, xml.Attr{ 961 xml.Name{Local: "type"}, "ccw", 962 }) 963 return e.EncodeElement(c.CCW, start) 964 } else if c.MDev != nil { 965 start.Attr = append(start.Attr, xml.Attr{ 966 xml.Name{Local: "type"}, "mdev", 967 }) 968 return e.EncodeElement(c.MDev, start) 969 } else if c.CSS != nil { 970 start.Attr = append(start.Attr, xml.Attr{ 971 xml.Name{Local: "type"}, "css", 972 }) 973 return e.EncodeElement(c.CSS, start) 974 } else if c.APQueue != nil { 975 start.Attr = append(start.Attr, xml.Attr{ 976 xml.Name{Local: "type"}, "ap_queue", 977 }) 978 return e.EncodeElement(c.APQueue, start) 979 } else if c.APCard != nil { 980 start.Attr = append(start.Attr, xml.Attr{ 981 xml.Name{Local: "type"}, "ap_card", 982 }) 983 return e.EncodeElement(c.APCard, start) 984 } else if c.APMatrix != nil { 985 start.Attr = append(start.Attr, xml.Attr{ 986 xml.Name{Local: "type"}, "ap_matrix", 987 }) 988 return e.EncodeElement(c.APMatrix, start) 989 } 990 return nil 991 } 992 993 func (c *NodeDevice) Unmarshal(doc string) error { 994 return xml.Unmarshal([]byte(doc), c) 995 } 996 997 func (c *NodeDevice) Marshal() (string, error) { 998 doc, err := xml.MarshalIndent(c, "", " ") 999 if err != nil { 1000 return "", err 1001 } 1002 return string(doc), nil 1003 }