libvirt.org/go/libvirtxml@v1.10003.0/node_device.go (about) 1 /* 2 * This file is part of the libvirt-go-xml-module 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 VPD *NodeDevicePCIVPDCapability 126 } 127 128 type NodeDevicePCIVirtFunctionsCapability struct { 129 Address []NodeDevicePCIAddress `xml:"address,omitempty"` 130 MaxCount int `xml:"maxCount,attr,omitempty"` 131 } 132 133 type NodeDevicePCIPhysFunctionCapability struct { 134 Address NodeDevicePCIAddress `xml:"address,omitempty"` 135 } 136 137 type NodeDevicePCIMDevTypesCapability struct { 138 Types []NodeDeviceMDevType `xml:"type"` 139 } 140 141 type NodeDeviceMDevType struct { 142 ID string `xml:"id,attr"` 143 Name string `xml:"name"` 144 DeviceAPI string `xml:"deviceAPI"` 145 AvailableInstances uint `xml:"availableInstances"` 146 } 147 148 type NodeDevicePCIBridgeCapability struct { 149 } 150 151 type NodeDevicePCIVPDCapability struct { 152 Name string `xml:"name,omitempty"` 153 ReadOnly *NodeDevicePCIVPDFieldsRO `xml:"-"` 154 ReadWrite *NodeDevicePCIVPDFieldsRW `xml:"-"` 155 } 156 157 type NodeDevicePCIVPDFieldsRO struct { 158 ChangeLevel string `xml:"change_level,omitempty"` 159 ManufactureID string `xml:"manufacture_id,omitempty"` 160 PartNumber string `xml:"part_number,omitempty"` 161 SerialNumber string `xml:"serial_number,omitempty"` 162 VendorFields []NodeDevicePCIVPDCustomField `xml:"vendor_field"` 163 } 164 165 type NodeDevicePCIVPDFieldsRW struct { 166 AssetTag string `xml:"asset_tag,omitempty"` 167 VendorFields []NodeDevicePCIVPDCustomField `xml:"vendor_field"` 168 SystemFields []NodeDevicePCIVPDCustomField `xml:"system_field"` 169 } 170 171 type NodeDevicePCIVPDCustomField struct { 172 Index string `xml:"index,attr"` 173 Value string `xml:",chardata"` 174 } 175 176 type NodeDeviceSystemHardware struct { 177 Vendor string `xml:"vendor"` 178 Version string `xml:"version"` 179 Serial string `xml:"serial"` 180 UUID string `xml:"uuid"` 181 } 182 183 type NodeDeviceSystemFirmware struct { 184 Vendor string `xml:"vendor"` 185 Version string `xml:"version"` 186 ReleaseData string `xml:"release_date"` 187 } 188 189 type NodeDeviceSystemCapability struct { 190 Product string `xml:"product,omitempty"` 191 Hardware *NodeDeviceSystemHardware `xml:"hardware"` 192 Firmware *NodeDeviceSystemFirmware `xml:"firmware"` 193 } 194 195 type NodeDeviceUSBDeviceCapability struct { 196 Bus int `xml:"bus"` 197 Device int `xml:"device"` 198 Product NodeDeviceIDName `xml:"product,omitempty"` 199 Vendor NodeDeviceIDName `xml:"vendor,omitempty"` 200 } 201 202 type NodeDeviceUSBCapability struct { 203 Number int `xml:"number"` 204 Class int `xml:"class"` 205 Subclass int `xml:"subclass"` 206 Protocol int `xml:"protocol"` 207 Description string `xml:"description,omitempty"` 208 } 209 210 type NodeDeviceNetOffloadFeatures struct { 211 Name string `xml:"name,attr"` 212 } 213 214 type NodeDeviceNetLink struct { 215 State string `xml:"state,attr"` 216 Speed string `xml:"speed,attr,omitempty"` 217 } 218 219 type NodeDeviceNetSubCapability struct { 220 Wireless80211 *NodeDeviceNet80211Capability 221 Ethernet80203 *NodeDeviceNet80203Capability 222 } 223 224 type NodeDeviceNet80211Capability struct { 225 } 226 227 type NodeDeviceNet80203Capability struct { 228 } 229 230 type NodeDeviceNetCapability struct { 231 Interface string `xml:"interface"` 232 Address string `xml:"address"` 233 Link *NodeDeviceNetLink `xml:"link"` 234 Features []NodeDeviceNetOffloadFeatures `xml:"feature,omitempty"` 235 Capability []NodeDeviceNetSubCapability `xml:"capability"` 236 } 237 238 type NodeDeviceSCSIVPortOpsCapability struct { 239 VPorts int `xml:"vports"` 240 MaxVPorts int `xml:"max_vports"` 241 } 242 243 type NodeDeviceSCSIFCHostCapability struct { 244 WWNN string `xml:"wwnn,omitempty"` 245 WWPN string `xml:"wwpn,omitempty"` 246 FabricWWN string `xml:"fabric_wwn,omitempty"` 247 } 248 249 type NodeDeviceSCSIHostSubCapability struct { 250 VPortOps *NodeDeviceSCSIVPortOpsCapability 251 FCHost *NodeDeviceSCSIFCHostCapability 252 } 253 254 type NodeDeviceSCSIHostCapability struct { 255 Host uint `xml:"host"` 256 UniqueID *uint `xml:"unique_id"` 257 Capability []NodeDeviceSCSIHostSubCapability `xml:"capability"` 258 } 259 260 type NodeDeviceSCSITargetCapability struct { 261 Target string `xml:"target"` 262 Capability []NodeDeviceSCSITargetSubCapability `xml:"capability"` 263 } 264 265 type NodeDeviceSCSITargetSubCapability struct { 266 FCRemotePort *NodeDeviceSCSIFCRemotePortCapability 267 } 268 269 type NodeDeviceSCSIFCRemotePortCapability struct { 270 RPort string `xml:"rport"` 271 WWPN string `xml:"wwpn"` 272 } 273 274 type NodeDeviceSCSICapability struct { 275 Host int `xml:"host"` 276 Bus int `xml:"bus"` 277 Target int `xml:"target"` 278 Lun int `xml:"lun"` 279 Type string `xml:"type"` 280 } 281 282 type NodeDeviceStorageSubCapability struct { 283 Removable *NodeDeviceStorageRemovableCapability 284 } 285 286 type NodeDeviceStorageRemovableCapability struct { 287 MediaAvailable *uint `xml:"media_available"` 288 MediaSize *uint `xml:"media_size"` 289 MediaLabel string `xml:"media_label,omitempty"` 290 LogicalBlockSize *uint `xml:"logical_block_size"` 291 NumBlocks *uint `xml:"num_blocks"` 292 } 293 294 type NodeDeviceStorageCapability struct { 295 Block string `xml:"block,omitempty"` 296 Bus string `xml:"bus,omitempty"` 297 DriverType string `xml:"drive_type,omitempty"` 298 Model string `xml:"model,omitempty"` 299 Vendor string `xml:"vendor,omitempty"` 300 Serial string `xml:"serial,omitempty"` 301 Size *uint `xml:"size"` 302 LogicalBlockSize *uint `xml:"logical_block_size"` 303 NumBlocks *uint `xml:"num_blocks"` 304 Capability []NodeDeviceStorageSubCapability `xml:"capability"` 305 } 306 307 type NodeDeviceDRMCapability struct { 308 Type string `xml:"type"` 309 } 310 311 type NodeDeviceCCWCapability struct { 312 CSSID *uint `xml:"cssid"` 313 SSID *uint `xml:"ssid"` 314 DevNo *uint `xml:"devno"` 315 } 316 317 type NodeDeviceMDevCapability struct { 318 Type *NodeDeviceMDevCapabilityType `xml:"type"` 319 IOMMUGroup *NodeDeviceIOMMUGroup `xml:"iommuGroup"` 320 UUID string `xml:"uuid,omitempty"` 321 ParentAddr string `xml:"parent_addr,omitempty"` 322 Attrs []NodeDeviceMDevCapabilityAttrs `xml:"attr,omitempty"` 323 } 324 325 type NodeDeviceMDevCapabilityType struct { 326 ID string `xml:"id,attr"` 327 } 328 329 type NodeDeviceMDevCapabilityAttrs struct { 330 Name string `xml:"name,attr"` 331 Value string `xml:"value,attr"` 332 } 333 334 type NodeDeviceCSSCapability struct { 335 CSSID *uint `xml:"cssid"` 336 SSID *uint `xml:"ssid"` 337 DevNo *uint `xml:"devno"` 338 ChannelDevAddr *NodeDeviceCSSChannelDevAddr `xml:"channel_dev_addr"` 339 Capabilities []NodeDeviceCSSSubCapability `xml:"capability"` 340 } 341 342 type NodeDeviceCSSChannelDevAddr struct { 343 CSSID *uint `xml:"cssid"` 344 SSID *uint `xml:"ssid"` 345 DevNo *uint `xml:"devno"` 346 } 347 348 type NodeDeviceCSSSubCapability struct { 349 MDevTypes *NodeDeviceCSSMDevTypesCapability 350 } 351 352 type NodeDeviceCSSMDevTypesCapability struct { 353 Types []NodeDeviceMDevType `xml:"type"` 354 } 355 356 type NodeDeviceAPQueueCapability struct { 357 APAdapter string `xml:"ap-adapter"` 358 APDomain string `xml:"ap-domain"` 359 } 360 361 type NodeDeviceAPCardCapability struct { 362 APAdapter string `xml:"ap-adapter"` 363 } 364 365 type NodeDeviceAPMatrixCapability struct { 366 Capabilities []NodeDeviceAPMatrixSubCapability `xml:"capability"` 367 } 368 369 type NodeDeviceAPMatrixSubCapability struct { 370 MDevTypes *NodeDeviceAPMatrixMDevTypesCapability 371 } 372 373 type NodeDeviceAPMatrixMDevTypesCapability struct { 374 Types []NodeDeviceMDevType `xml:"type"` 375 } 376 377 func (a *NodeDevicePCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 378 marshalUintAttr(&start, "domain", a.Domain, "0x%04x") 379 marshalUintAttr(&start, "bus", a.Bus, "0x%02x") 380 marshalUintAttr(&start, "slot", a.Slot, "0x%02x") 381 marshalUintAttr(&start, "function", a.Function, "0x%x") 382 e.EncodeToken(start) 383 e.EncodeToken(start.End()) 384 return nil 385 } 386 387 func (a *NodeDevicePCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 388 for _, attr := range start.Attr { 389 if attr.Name.Local == "domain" { 390 if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil { 391 return err 392 } 393 } else if attr.Name.Local == "bus" { 394 if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil { 395 return err 396 } 397 } else if attr.Name.Local == "slot" { 398 if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil { 399 return err 400 } 401 } else if attr.Name.Local == "function" { 402 if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil { 403 return err 404 } 405 } 406 } 407 d.Skip() 408 return nil 409 } 410 411 func (c *NodeDeviceCSSSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 412 typ, ok := getAttr(start.Attr, "type") 413 if !ok { 414 return fmt.Errorf("Missing node device capability type") 415 } 416 417 switch typ { 418 case "mdev_types": 419 var mdevTypesCaps NodeDeviceCSSMDevTypesCapability 420 if err := d.DecodeElement(&mdevTypesCaps, &start); err != nil { 421 return err 422 } 423 c.MDevTypes = &mdevTypesCaps 424 } 425 d.Skip() 426 return nil 427 } 428 429 func (c *NodeDeviceCSSSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 430 if c.MDevTypes != nil { 431 start.Attr = append(start.Attr, xml.Attr{ 432 xml.Name{Local: "type"}, "mdev_types", 433 }) 434 return e.EncodeElement(c.MDevTypes, start) 435 } 436 return nil 437 } 438 439 func (c *NodeDeviceCCWCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 440 e.EncodeToken(start) 441 if c.CSSID != nil { 442 cssid := xml.StartElement{ 443 Name: xml.Name{Local: "cssid"}, 444 } 445 e.EncodeToken(cssid) 446 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) 447 e.EncodeToken(cssid.End()) 448 } 449 if c.SSID != nil { 450 ssid := xml.StartElement{ 451 Name: xml.Name{Local: "ssid"}, 452 } 453 e.EncodeToken(ssid) 454 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) 455 e.EncodeToken(ssid.End()) 456 } 457 if c.DevNo != nil { 458 devno := xml.StartElement{ 459 Name: xml.Name{Local: "devno"}, 460 } 461 e.EncodeToken(devno) 462 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) 463 e.EncodeToken(devno.End()) 464 } 465 e.EncodeToken(start.End()) 466 return nil 467 } 468 469 func (c *NodeDeviceCCWCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 470 for { 471 tok, err := d.Token() 472 if err == io.EOF { 473 break 474 } 475 if err != nil { 476 return err 477 } 478 479 switch tok := tok.(type) { 480 case xml.StartElement: 481 cdata, err := d.Token() 482 if err != nil { 483 return err 484 } 485 486 if tok.Name.Local != "cssid" && 487 tok.Name.Local != "ssid" && 488 tok.Name.Local != "devno" { 489 continue 490 } 491 492 chardata, ok := cdata.(xml.CharData) 493 if !ok { 494 return fmt.Errorf("Expected text for CCW '%s'", tok.Name.Local) 495 } 496 497 valstr := strings.TrimPrefix(string(chardata), "0x") 498 val, err := strconv.ParseUint(valstr, 16, 64) 499 if err != nil { 500 return err 501 } 502 503 vali := uint(val) 504 if tok.Name.Local == "cssid" { 505 c.CSSID = &vali 506 } else if tok.Name.Local == "ssid" { 507 c.SSID = &vali 508 } else if tok.Name.Local == "devno" { 509 c.DevNo = &vali 510 } 511 } 512 } 513 return nil 514 } 515 516 func (c *NodeDeviceCSSCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 517 e.EncodeToken(start) 518 if c.CSSID != nil { 519 cssid := xml.StartElement{ 520 Name: xml.Name{Local: "cssid"}, 521 } 522 e.EncodeToken(cssid) 523 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) 524 e.EncodeToken(cssid.End()) 525 } 526 if c.SSID != nil { 527 ssid := xml.StartElement{ 528 Name: xml.Name{Local: "ssid"}, 529 } 530 e.EncodeToken(ssid) 531 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) 532 e.EncodeToken(ssid.End()) 533 } 534 if c.DevNo != nil { 535 devno := xml.StartElement{ 536 Name: xml.Name{Local: "devno"}, 537 } 538 e.EncodeToken(devno) 539 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) 540 e.EncodeToken(devno.End()) 541 } 542 if c.ChannelDevAddr != nil { 543 start := xml.StartElement{ 544 Name: xml.Name{Local: "channel_dev_addr"}, 545 } 546 e.EncodeElement(c.ChannelDevAddr, start) 547 } 548 if c.Capabilities != nil { 549 for _, subcap := range c.Capabilities { 550 start := xml.StartElement{ 551 Name: xml.Name{Local: "capability"}, 552 } 553 e.EncodeElement(&subcap, start) 554 } 555 } 556 e.EncodeToken(start.End()) 557 return nil 558 } 559 560 func (c *NodeDeviceCSSCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 561 for { 562 tok, err := d.Token() 563 if err == io.EOF { 564 break 565 } 566 if err != nil { 567 return err 568 } 569 570 switch tok := tok.(type) { 571 case xml.StartElement: 572 cdata, err := d.Token() 573 if err != nil { 574 return err 575 } 576 577 if tok.Name.Local == "capability" { 578 subcap := &NodeDeviceCSSSubCapability{} 579 err := d.DecodeElement(subcap, &tok) 580 if err != nil { 581 return err 582 } 583 c.Capabilities = append(c.Capabilities, *subcap) 584 continue 585 } else if tok.Name.Local == "channel_dev_addr" { 586 chandev := &NodeDeviceCSSChannelDevAddr{} 587 err := d.DecodeElement(chandev, &tok) 588 if err != nil { 589 return err 590 } 591 c.ChannelDevAddr = chandev 592 continue 593 } 594 595 if tok.Name.Local != "cssid" && 596 tok.Name.Local != "ssid" && 597 tok.Name.Local != "devno" { 598 continue 599 } 600 601 chardata, ok := cdata.(xml.CharData) 602 if !ok { 603 return fmt.Errorf("Expected text for CSS '%s'", tok.Name.Local) 604 } 605 606 valstr := strings.TrimPrefix(string(chardata), "0x") 607 val, err := strconv.ParseUint(valstr, 16, 64) 608 if err != nil { 609 return err 610 } 611 612 vali := uint(val) 613 if tok.Name.Local == "cssid" { 614 c.CSSID = &vali 615 } else if tok.Name.Local == "ssid" { 616 c.SSID = &vali 617 } else if tok.Name.Local == "devno" { 618 c.DevNo = &vali 619 } 620 } 621 } 622 return nil 623 } 624 625 func (c *NodeDeviceCSSChannelDevAddr) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 626 e.EncodeToken(start) 627 if c.CSSID != nil { 628 cssid := xml.StartElement{ 629 Name: xml.Name{Local: "cssid"}, 630 } 631 e.EncodeToken(cssid) 632 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID))) 633 e.EncodeToken(cssid.End()) 634 } 635 if c.SSID != nil { 636 ssid := xml.StartElement{ 637 Name: xml.Name{Local: "ssid"}, 638 } 639 e.EncodeToken(ssid) 640 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID))) 641 e.EncodeToken(ssid.End()) 642 } 643 if c.DevNo != nil { 644 devno := xml.StartElement{ 645 Name: xml.Name{Local: "devno"}, 646 } 647 e.EncodeToken(devno) 648 e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo))) 649 e.EncodeToken(devno.End()) 650 } 651 e.EncodeToken(start.End()) 652 return nil 653 } 654 655 func (c *NodeDeviceCSSChannelDevAddr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 656 for { 657 tok, err := d.Token() 658 if err == io.EOF { 659 break 660 } 661 if err != nil { 662 return err 663 } 664 665 switch tok := tok.(type) { 666 case xml.StartElement: 667 cdata, err := d.Token() 668 if err != nil { 669 return err 670 } 671 672 if tok.Name.Local != "cssid" && 673 tok.Name.Local != "ssid" && 674 tok.Name.Local != "devno" { 675 continue 676 } 677 678 chardata, ok := cdata.(xml.CharData) 679 if !ok { 680 return fmt.Errorf("Expected text for CSS '%s'", tok.Name.Local) 681 } 682 683 valstr := strings.TrimPrefix(string(chardata), "0x") 684 val, err := strconv.ParseUint(valstr, 16, 64) 685 if err != nil { 686 return err 687 } 688 689 vali := uint(val) 690 if tok.Name.Local == "cssid" { 691 c.CSSID = &vali 692 } else if tok.Name.Local == "ssid" { 693 c.SSID = &vali 694 } else if tok.Name.Local == "devno" { 695 c.DevNo = &vali 696 } 697 } 698 } 699 return nil 700 } 701 702 func (c *NodeDevicePCISubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 703 typ, ok := getAttr(start.Attr, "type") 704 if !ok { 705 return fmt.Errorf("Missing node device capability type") 706 } 707 708 switch typ { 709 case "virt_functions": 710 var virtFuncCaps NodeDevicePCIVirtFunctionsCapability 711 if err := d.DecodeElement(&virtFuncCaps, &start); err != nil { 712 return err 713 } 714 c.VirtFunctions = &virtFuncCaps 715 case "phys_function": 716 var physFuncCaps NodeDevicePCIPhysFunctionCapability 717 if err := d.DecodeElement(&physFuncCaps, &start); err != nil { 718 return err 719 } 720 c.PhysFunction = &physFuncCaps 721 case "mdev_types": 722 var mdevTypeCaps NodeDevicePCIMDevTypesCapability 723 if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil { 724 return err 725 } 726 c.MDevTypes = &mdevTypeCaps 727 case "pci-bridge": 728 var bridgeCaps NodeDevicePCIBridgeCapability 729 if err := d.DecodeElement(&bridgeCaps, &start); err != nil { 730 return err 731 } 732 c.Bridge = &bridgeCaps 733 case "vpd": 734 var vpdCaps NodeDevicePCIVPDCapability 735 if err := d.DecodeElement(&vpdCaps, &start); err != nil { 736 return err 737 } 738 c.VPD = &vpdCaps 739 } 740 d.Skip() 741 return nil 742 } 743 744 func (c *NodeDevicePCISubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 745 if c.VirtFunctions != nil { 746 start.Attr = append(start.Attr, xml.Attr{ 747 xml.Name{Local: "type"}, "virt_functions", 748 }) 749 return e.EncodeElement(c.VirtFunctions, start) 750 } else if c.PhysFunction != nil { 751 start.Attr = append(start.Attr, xml.Attr{ 752 xml.Name{Local: "type"}, "phys_function", 753 }) 754 return e.EncodeElement(c.PhysFunction, start) 755 } else if c.MDevTypes != nil { 756 start.Attr = append(start.Attr, xml.Attr{ 757 xml.Name{Local: "type"}, "mdev_types", 758 }) 759 return e.EncodeElement(c.MDevTypes, start) 760 } else if c.Bridge != nil { 761 start.Attr = append(start.Attr, xml.Attr{ 762 xml.Name{Local: "type"}, "pci-bridge", 763 }) 764 return e.EncodeElement(c.Bridge, start) 765 } else if c.VPD != nil { 766 start.Attr = append(start.Attr, xml.Attr{ 767 xml.Name{Local: "type"}, "vpd", 768 }) 769 return e.EncodeElement(c.VPD, start) 770 } 771 return nil 772 } 773 774 func (c *NodeDeviceSCSITargetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 775 typ, ok := getAttr(start.Attr, "type") 776 if !ok { 777 return fmt.Errorf("Missing node device capability type") 778 } 779 780 switch typ { 781 case "fc_remote_port": 782 var fcCaps NodeDeviceSCSIFCRemotePortCapability 783 if err := d.DecodeElement(&fcCaps, &start); err != nil { 784 return err 785 } 786 c.FCRemotePort = &fcCaps 787 } 788 d.Skip() 789 return nil 790 } 791 792 func (c *NodeDeviceSCSITargetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 793 if c.FCRemotePort != nil { 794 start.Attr = append(start.Attr, xml.Attr{ 795 xml.Name{Local: "type"}, "fc_remote_port", 796 }) 797 return e.EncodeElement(c.FCRemotePort, start) 798 } 799 return nil 800 } 801 802 func (c *NodeDeviceSCSIHostSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 803 typ, ok := getAttr(start.Attr, "type") 804 if !ok { 805 return fmt.Errorf("Missing node device capability type") 806 } 807 808 switch typ { 809 case "fc_host": 810 var fcCaps NodeDeviceSCSIFCHostCapability 811 if err := d.DecodeElement(&fcCaps, &start); err != nil { 812 return err 813 } 814 c.FCHost = &fcCaps 815 case "vport_ops": 816 var vportCaps NodeDeviceSCSIVPortOpsCapability 817 if err := d.DecodeElement(&vportCaps, &start); err != nil { 818 return err 819 } 820 c.VPortOps = &vportCaps 821 } 822 d.Skip() 823 return nil 824 } 825 826 func (c *NodeDeviceSCSIHostSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 827 if c.FCHost != nil { 828 start.Attr = append(start.Attr, xml.Attr{ 829 xml.Name{Local: "type"}, "fc_host", 830 }) 831 return e.EncodeElement(c.FCHost, start) 832 } else if c.VPortOps != nil { 833 start.Attr = append(start.Attr, xml.Attr{ 834 xml.Name{Local: "type"}, "vport_ops", 835 }) 836 return e.EncodeElement(c.VPortOps, start) 837 } 838 return nil 839 } 840 841 func (c *NodeDeviceStorageSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 842 typ, ok := getAttr(start.Attr, "type") 843 if !ok { 844 return fmt.Errorf("Missing node device capability type") 845 } 846 847 switch typ { 848 case "removable": 849 var removeCaps NodeDeviceStorageRemovableCapability 850 if err := d.DecodeElement(&removeCaps, &start); err != nil { 851 return err 852 } 853 c.Removable = &removeCaps 854 } 855 d.Skip() 856 return nil 857 } 858 859 func (c *NodeDeviceStorageSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 860 if c.Removable != nil { 861 start.Attr = append(start.Attr, xml.Attr{ 862 xml.Name{Local: "type"}, "removable", 863 }) 864 return e.EncodeElement(c.Removable, start) 865 } 866 return nil 867 } 868 869 func (c *NodeDeviceNetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 870 typ, ok := getAttr(start.Attr, "type") 871 if !ok { 872 return fmt.Errorf("Missing node device capability type") 873 } 874 875 switch typ { 876 case "80211": 877 var wlanCaps NodeDeviceNet80211Capability 878 if err := d.DecodeElement(&wlanCaps, &start); err != nil { 879 return err 880 } 881 c.Wireless80211 = &wlanCaps 882 case "80203": 883 var ethCaps NodeDeviceNet80203Capability 884 if err := d.DecodeElement(ðCaps, &start); err != nil { 885 return err 886 } 887 c.Ethernet80203 = ðCaps 888 } 889 d.Skip() 890 return nil 891 } 892 893 func (c *NodeDeviceNetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 894 if c.Wireless80211 != nil { 895 start.Attr = append(start.Attr, xml.Attr{ 896 xml.Name{Local: "type"}, "80211", 897 }) 898 return e.EncodeElement(c.Wireless80211, start) 899 } else if c.Ethernet80203 != nil { 900 start.Attr = append(start.Attr, xml.Attr{ 901 xml.Name{Local: "type"}, "80203", 902 }) 903 return e.EncodeElement(c.Ethernet80203, start) 904 } 905 return nil 906 } 907 908 func (c *NodeDeviceAPMatrixSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 909 typ, ok := getAttr(start.Attr, "type") 910 if !ok { 911 return fmt.Errorf("Missing node device capability type") 912 } 913 914 switch typ { 915 case "mdev_types": 916 var mdevTypeCaps NodeDeviceAPMatrixMDevTypesCapability 917 if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil { 918 return err 919 } 920 c.MDevTypes = &mdevTypeCaps 921 } 922 d.Skip() 923 return nil 924 } 925 926 func (c *NodeDeviceAPMatrixSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 927 if c.MDevTypes != nil { 928 start.Attr = append(start.Attr, xml.Attr{ 929 xml.Name{Local: "type"}, "mdev_types", 930 }) 931 return e.EncodeElement(c.MDevTypes, start) 932 } 933 return nil 934 } 935 936 type nodeDevicePCIVPDFields struct { 937 ReadOnly *NodeDevicePCIVPDFieldsRO 938 ReadWrite *NodeDevicePCIVPDFieldsRW 939 } 940 941 type nodeDevicePCIVPDCapability struct { 942 Name string `xml:"name,omitempty"` 943 Fields []nodeDevicePCIVPDFields `xml:"fields"` 944 } 945 946 func (c *nodeDevicePCIVPDFields) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 947 acc, ok := getAttr(start.Attr, "access") 948 if !ok { 949 return fmt.Errorf("Missing node device PCI VPD capability access") 950 } 951 952 switch acc { 953 case "readonly": 954 var ro NodeDevicePCIVPDFieldsRO 955 if err := d.DecodeElement(&ro, &start); err != nil { 956 return err 957 } 958 c.ReadOnly = &ro 959 case "readwrite": 960 var rw NodeDevicePCIVPDFieldsRW 961 if err := d.DecodeElement(&rw, &start); err != nil { 962 return err 963 } 964 c.ReadWrite = &rw 965 } 966 d.Skip() 967 return nil 968 } 969 970 func (c *NodeDevicePCIVPDCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 971 var ccopy nodeDevicePCIVPDCapability 972 ccopy.Name = c.Name 973 if c.ReadOnly != nil { 974 ccopy.Fields = append(ccopy.Fields, nodeDevicePCIVPDFields{ 975 ReadOnly: c.ReadOnly, 976 }) 977 } 978 if c.ReadWrite != nil { 979 ccopy.Fields = append(ccopy.Fields, nodeDevicePCIVPDFields{ 980 ReadWrite: c.ReadWrite, 981 }) 982 } 983 e.EncodeElement(&ccopy, start) 984 return nil 985 } 986 987 func (c *NodeDevicePCIVPDCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 988 var ccopy nodeDevicePCIVPDCapability 989 if err := d.DecodeElement(&ccopy, &start); err != nil { 990 return err 991 } 992 c.Name = ccopy.Name 993 for _, field := range ccopy.Fields { 994 if field.ReadOnly != nil { 995 c.ReadOnly = field.ReadOnly 996 } else if field.ReadWrite != nil { 997 c.ReadWrite = field.ReadWrite 998 } 999 } 1000 return nil 1001 } 1002 1003 func (c *nodeDevicePCIVPDFields) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 1004 if c.ReadOnly != nil { 1005 start.Attr = append(start.Attr, xml.Attr{ 1006 xml.Name{Local: "access"}, "readonly", 1007 }) 1008 return e.EncodeElement(c.ReadOnly, start) 1009 } else if c.ReadWrite != nil { 1010 start.Attr = append(start.Attr, xml.Attr{ 1011 xml.Name{Local: "access"}, "readwrite", 1012 }) 1013 return e.EncodeElement(c.ReadWrite, start) 1014 } 1015 return nil 1016 } 1017 1018 func (c *NodeDeviceCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 1019 typ, ok := getAttr(start.Attr, "type") 1020 if !ok { 1021 return fmt.Errorf("Missing node device capability type") 1022 } 1023 1024 switch typ { 1025 case "pci": 1026 var pciCaps NodeDevicePCICapability 1027 if err := d.DecodeElement(&pciCaps, &start); err != nil { 1028 return err 1029 } 1030 c.PCI = &pciCaps 1031 case "system": 1032 var systemCaps NodeDeviceSystemCapability 1033 if err := d.DecodeElement(&systemCaps, &start); err != nil { 1034 return err 1035 } 1036 c.System = &systemCaps 1037 case "usb_device": 1038 var usbdevCaps NodeDeviceUSBDeviceCapability 1039 if err := d.DecodeElement(&usbdevCaps, &start); err != nil { 1040 return err 1041 } 1042 c.USBDevice = &usbdevCaps 1043 case "usb": 1044 var usbCaps NodeDeviceUSBCapability 1045 if err := d.DecodeElement(&usbCaps, &start); err != nil { 1046 return err 1047 } 1048 c.USB = &usbCaps 1049 case "net": 1050 var netCaps NodeDeviceNetCapability 1051 if err := d.DecodeElement(&netCaps, &start); err != nil { 1052 return err 1053 } 1054 c.Net = &netCaps 1055 case "scsi_host": 1056 var scsiHostCaps NodeDeviceSCSIHostCapability 1057 if err := d.DecodeElement(&scsiHostCaps, &start); err != nil { 1058 return err 1059 } 1060 c.SCSIHost = &scsiHostCaps 1061 case "scsi_target": 1062 var scsiTargetCaps NodeDeviceSCSITargetCapability 1063 if err := d.DecodeElement(&scsiTargetCaps, &start); err != nil { 1064 return err 1065 } 1066 c.SCSITarget = &scsiTargetCaps 1067 case "scsi": 1068 var scsiCaps NodeDeviceSCSICapability 1069 if err := d.DecodeElement(&scsiCaps, &start); err != nil { 1070 return err 1071 } 1072 c.SCSI = &scsiCaps 1073 case "storage": 1074 var storageCaps NodeDeviceStorageCapability 1075 if err := d.DecodeElement(&storageCaps, &start); err != nil { 1076 return err 1077 } 1078 c.Storage = &storageCaps 1079 case "drm": 1080 var drmCaps NodeDeviceDRMCapability 1081 if err := d.DecodeElement(&drmCaps, &start); err != nil { 1082 return err 1083 } 1084 c.DRM = &drmCaps 1085 case "ccw": 1086 var ccwCaps NodeDeviceCCWCapability 1087 if err := d.DecodeElement(&ccwCaps, &start); err != nil { 1088 return err 1089 } 1090 c.CCW = &ccwCaps 1091 case "mdev": 1092 var mdevCaps NodeDeviceMDevCapability 1093 if err := d.DecodeElement(&mdevCaps, &start); err != nil { 1094 return err 1095 } 1096 c.MDev = &mdevCaps 1097 case "css": 1098 var cssCaps NodeDeviceCSSCapability 1099 if err := d.DecodeElement(&cssCaps, &start); err != nil { 1100 return err 1101 } 1102 c.CSS = &cssCaps 1103 case "ap_queue": 1104 var apCaps NodeDeviceAPQueueCapability 1105 if err := d.DecodeElement(&apCaps, &start); err != nil { 1106 return err 1107 } 1108 c.APQueue = &apCaps 1109 case "ap_matrix": 1110 var apCaps NodeDeviceAPMatrixCapability 1111 if err := d.DecodeElement(&apCaps, &start); err != nil { 1112 return err 1113 } 1114 c.APMatrix = &apCaps 1115 case "ap_card": 1116 var apCaps NodeDeviceAPCardCapability 1117 if err := d.DecodeElement(&apCaps, &start); err != nil { 1118 return err 1119 } 1120 c.APCard = &apCaps 1121 } 1122 d.Skip() 1123 return nil 1124 } 1125 1126 func (c *NodeDeviceCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 1127 if c.PCI != nil { 1128 start.Attr = append(start.Attr, xml.Attr{ 1129 xml.Name{Local: "type"}, "pci", 1130 }) 1131 return e.EncodeElement(c.PCI, start) 1132 } else if c.System != nil { 1133 start.Attr = append(start.Attr, xml.Attr{ 1134 xml.Name{Local: "type"}, "system", 1135 }) 1136 return e.EncodeElement(c.System, start) 1137 } else if c.USB != nil { 1138 start.Attr = append(start.Attr, xml.Attr{ 1139 xml.Name{Local: "type"}, "usb", 1140 }) 1141 return e.EncodeElement(c.USB, start) 1142 } else if c.USBDevice != nil { 1143 start.Attr = append(start.Attr, xml.Attr{ 1144 xml.Name{Local: "type"}, "usb_device", 1145 }) 1146 return e.EncodeElement(c.USBDevice, start) 1147 } else if c.Net != nil { 1148 start.Attr = append(start.Attr, xml.Attr{ 1149 xml.Name{Local: "type"}, "net", 1150 }) 1151 return e.EncodeElement(c.Net, start) 1152 } else if c.SCSI != nil { 1153 start.Attr = append(start.Attr, xml.Attr{ 1154 xml.Name{Local: "type"}, "scsi", 1155 }) 1156 return e.EncodeElement(c.SCSI, start) 1157 } else if c.SCSIHost != nil { 1158 start.Attr = append(start.Attr, xml.Attr{ 1159 xml.Name{Local: "type"}, "scsi_host", 1160 }) 1161 return e.EncodeElement(c.SCSIHost, start) 1162 } else if c.SCSITarget != nil { 1163 start.Attr = append(start.Attr, xml.Attr{ 1164 xml.Name{Local: "type"}, "scsi_target", 1165 }) 1166 return e.EncodeElement(c.SCSITarget, start) 1167 } else if c.Storage != nil { 1168 start.Attr = append(start.Attr, xml.Attr{ 1169 xml.Name{Local: "type"}, "storage", 1170 }) 1171 return e.EncodeElement(c.Storage, start) 1172 } else if c.DRM != nil { 1173 start.Attr = append(start.Attr, xml.Attr{ 1174 xml.Name{Local: "type"}, "drm", 1175 }) 1176 return e.EncodeElement(c.DRM, start) 1177 } else if c.CCW != nil { 1178 start.Attr = append(start.Attr, xml.Attr{ 1179 xml.Name{Local: "type"}, "ccw", 1180 }) 1181 return e.EncodeElement(c.CCW, start) 1182 } else if c.MDev != nil { 1183 start.Attr = append(start.Attr, xml.Attr{ 1184 xml.Name{Local: "type"}, "mdev", 1185 }) 1186 return e.EncodeElement(c.MDev, start) 1187 } else if c.CSS != nil { 1188 start.Attr = append(start.Attr, xml.Attr{ 1189 xml.Name{Local: "type"}, "css", 1190 }) 1191 return e.EncodeElement(c.CSS, start) 1192 } else if c.APQueue != nil { 1193 start.Attr = append(start.Attr, xml.Attr{ 1194 xml.Name{Local: "type"}, "ap_queue", 1195 }) 1196 return e.EncodeElement(c.APQueue, start) 1197 } else if c.APCard != nil { 1198 start.Attr = append(start.Attr, xml.Attr{ 1199 xml.Name{Local: "type"}, "ap_card", 1200 }) 1201 return e.EncodeElement(c.APCard, start) 1202 } else if c.APMatrix != nil { 1203 start.Attr = append(start.Attr, xml.Attr{ 1204 xml.Name{Local: "type"}, "ap_matrix", 1205 }) 1206 return e.EncodeElement(c.APMatrix, start) 1207 } 1208 return nil 1209 } 1210 1211 func (c *NodeDevice) Unmarshal(doc string) error { 1212 return xml.Unmarshal([]byte(doc), c) 1213 } 1214 1215 func (c *NodeDevice) Marshal() (string, error) { 1216 doc, err := xml.MarshalIndent(c, "", " ") 1217 if err != nil { 1218 return "", err 1219 } 1220 return string(doc), nil 1221 }